Polish mobile UX downloads and comments

This commit is contained in:
2026-05-23 12:15:20 +03:00
parent 63da741295
commit f9938e393d
24 changed files with 571 additions and 61 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="gel_rule_app"
android:label="RuleGel"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
@@ -1,5 +1,64 @@
package com.example.gel_rule_app
import android.content.ContentValues
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
class MainActivity : FlutterActivity()
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "rulegel/downloads")
.setMethodCallHandler { call, result ->
if (call.method != "saveToDownloads") {
result.notImplemented()
return@setMethodCallHandler
}
try {
val path = call.argument<String>("path") ?: error("Missing path")
val fileName = call.argument<String>("fileName") ?: File(path).name
val mimeType = call.argument<String>("mimeType") ?: "application/octet-stream"
result.success(saveToDownloads(path, fileName, mimeType))
} catch (error: Throwable) {
result.error("save_failed", error.message, null)
}
}
}
private fun saveToDownloads(path: String, fileName: String, mimeType: String): String {
val source = File(path)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val values = ContentValues().apply {
put(MediaStore.Downloads.DISPLAY_NAME, fileName)
put(MediaStore.Downloads.MIME_TYPE, mimeType)
put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
put(MediaStore.Downloads.IS_PENDING, 1)
}
val resolver = applicationContext.contentResolver
val uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
?: error("Could not create Downloads entry")
resolver.openOutputStream(uri)?.use { output ->
FileInputStream(source).use { input -> input.copyTo(output) }
} ?: error("Could not open Downloads output stream")
values.clear()
values.put(MediaStore.Downloads.IS_PENDING, 0)
resolver.update(uri, values, null, null)
return fileName
}
@Suppress("DEPRECATION")
val downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
downloads.mkdirs()
val destination = File(downloads, fileName)
FileInputStream(source).use { input ->
FileOutputStream(destination).use { output -> input.copyTo(output) }
}
return destination.absolutePath
}
}