various edge case fixes

This commit is contained in:
Thibault Deckers 2022-03-17 11:17:44 +09:00
parent d8fca48ef8
commit a074ff5dd6
8 changed files with 51 additions and 16 deletions

View file

@ -33,7 +33,10 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.util.PathUtils
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException
@ -84,7 +87,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
}
}.mapValues { it.value?.path }.toMutableMap()
dirs["externalCacheDirs"] = context.externalCacheDirs.joinToString { it.path }
dirs["externalFilesDirs"] = context.getExternalFilesDirs(null).joinToString { it.path }
dirs["externalFilesDirs"] = context.getExternalFilesDirs(null).joinToString { it?.path ?: "null" }
// used by flutter plugin `path_provider`
dirs.putAll(

View file

@ -13,6 +13,7 @@ import deckers.thibault.aves.PendingStorageAccessResultHandler
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.PermissionManager
import deckers.thibault.aves.utils.StorageUtils
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import kotlinx.coroutines.CoroutineScope
@ -80,6 +81,11 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
return
}
if (uris.any { !StorageUtils.isMediaStoreContentUri(it) }) {
error("requestMediaFileAccess-nonmediastore", "request is only valid for Media Store content URIs, uris=$uris", null)
return
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
error("requestMediaFileAccess-unsupported", "media file bulk access is not allowed before Android R", null)
return
@ -148,12 +154,17 @@ class StorageAccessStreamHandler(private val activity: Activity, arguments: Any?
fun onGranted(uri: Uri) {
ioScope.launch {
try {
activity.contentResolver.openInputStream(uri)?.use { input ->
val buffer = ByteArray(BUFFER_SIZE)
var len: Int
while (input.read(buffer).also { len = it } != -1) {
success(buffer.copyOf(len))
}
}
} catch (e: Exception) {
Log.e(LOG_TAG, "failed to open input stream for uri=$uri", e)
} finally {
endOfStream()
}
}

View file

@ -36,13 +36,14 @@ object StorageUtils {
const val TRASH_PATH_PLACEHOLDER = "#trash"
private fun isAppFile(context: Context, path: String): Boolean {
return context.getExternalFilesDirs(null).any { filesDir -> path.startsWith(filesDir.path) }
val filesDirs = context.getExternalFilesDirs(null).filterNotNull()
return filesDirs.any { path.startsWith(it.path) }
}
private fun appExternalFilesDirFor(context: Context, path: String): File? {
val filesDirs = context.getExternalFilesDirs(null)
val filesDirs = context.getExternalFilesDirs(null).filterNotNull()
val volumePath = getVolumePath(context, path)
return volumePath?.let { filesDirs.firstOrNull { it.startsWith(volumePath) } } ?: filesDirs.first()
return volumePath?.let { filesDirs.firstOrNull { it.startsWith(volumePath) } } ?: filesDirs.firstOrNull()
}
fun trashDirFor(context: Context, path: String): File? {

View file

@ -154,5 +154,9 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
_isValidNotifier.value = name.isNotEmpty;
}
void _submit(BuildContext context) => Navigator.pop(context, Tuple2<AvesEntry?, String>(_coverEntry, _nameController.text));
void _submit(BuildContext context) {
if (_isValidNotifier.value) {
Navigator.pop(context, Tuple2<AvesEntry?, String>(_coverEntry, _nameController.text));
}
}
}

View file

@ -87,5 +87,9 @@ class _RenameEntryDialogState extends State<RenameEntryDialog> {
_isValidNotifier.value = newName.isNotEmpty && !exists;
}
void _submit(BuildContext context) => Navigator.pop(context, _nameController.text);
void _submit(BuildContext context) {
if (_isValidNotifier.value) {
Navigator.pop(context, _nameController.text);
}
}
}

View file

@ -157,5 +157,9 @@ class _CreateAlbumDialogState extends State<CreateAlbumDialog> {
_isValidNotifier.value = newName.isNotEmpty && !exists;
}
void _submit(BuildContext context) => Navigator.pop(context, _buildAlbumPath(_nameController.text));
void _submit(BuildContext context) {
if (_isValidNotifier.value) {
Navigator.pop(context, _buildAlbumPath(_nameController.text));
}
}
}

View file

@ -84,8 +84,12 @@ class _RenameAlbumDialogState extends State<RenameAlbumDialog> {
final path = _buildAlbumPath(newName);
final exists = newName.isNotEmpty && await FileSystemEntity.type(path) != FileSystemEntityType.notFound;
_existsNotifier.value = exists && newName != initialValue;
_isValidNotifier.value = newName.isNotEmpty && !exists;
_isValidNotifier.value = newName.isNotEmpty;
}
void _submit(BuildContext context) => Navigator.pop(context, _nameController.text);
void _submit(BuildContext context) {
if (_isValidNotifier.value) {
Navigator.pop(context, _nameController.text);
}
}
}

View file

@ -62,5 +62,9 @@ class _ViewerThumbnailPreviewState extends State<ViewerThumbnailPreview> {
);
}
void _onScrollerIndexChange() => _debouncer(() => ViewEntryNotification(index: _entryIndexNotifier.value).dispatch(context));
void _onScrollerIndexChange() => _debouncer(() {
if (mounted) {
ViewEntryNotification(index: _entryIndexNotifier.value).dispatch(context);
}
});
}