From 6a3e830d14b1a4d2e85d9c3df6af6d56ef244c10 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 12:03:32 +0900 Subject: [PATCH 1/6] fixed copy to clipboard action on older devices --- .../aves/channel/calls/AppAdapterHandler.kt | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt index 04afd10b8..ef30b56ab 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt @@ -4,6 +4,8 @@ import android.content.* import android.content.pm.ApplicationInfo import android.content.res.Configuration import android.net.Uri +import android.os.Handler +import android.os.Looper import android.util.Log import androidx.core.content.FileProvider import com.bumptech.glide.Glide @@ -141,13 +143,21 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { return } - val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager - if (clipboard != null) { - val clip = ClipData.newUri(context.contentResolver, label, getShareableUri(uri)) - clipboard.setPrimaryClip(clip) - result.success(true) - } else { - result.success(false) + // on older devices, `ClipboardManager` initialization must happen on the main thread + // (e.g. Samsung S7 with Android 8.0 / API 26, but not on Tab A 10.1 with Android 8.1 / API 27) + Handler(Looper.getMainLooper()).post { + try { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager + if (clipboard != null) { + val clip = ClipData.newUri(context.contentResolver, label, getShareableUri(uri)) + clipboard.setPrimaryClip(clip) + result.success(true) + } else { + result.success(false) + } + } catch (e: Exception) { + result.error("copyToClipboard-exception", "failed to set clip", e.message) + } } } From 9a0334814eba079f4acc433ed3ca7282f7a55462 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 12:27:21 +0900 Subject: [PATCH 2/6] search: fixed leading icon animation --- lib/widgets/home_page.dart | 1 + lib/widgets/search/search_delegate.dart | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index 86e15c017..d16d53954 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -161,6 +161,7 @@ class _HomePageState extends State { return SearchPageRoute( delegate: CollectionSearchDelegate( source: source, + canPop: false, initialQuery: _shortcutSearchQuery, ), ); diff --git a/lib/widgets/search/search_delegate.dart b/lib/widgets/search/search_delegate.dart index 65d8f6dbe..2e5e8c438 100644 --- a/lib/widgets/search/search_delegate.dart +++ b/lib/widgets/search/search_delegate.dart @@ -28,6 +28,7 @@ class CollectionSearchDelegate { final CollectionSource source; final CollectionLens? parentCollection; final ValueNotifier expandedSectionNotifier = ValueNotifier(null); + final bool canPop; static const searchHistoryCount = 10; static final typeFilters = [ @@ -45,13 +46,17 @@ class CollectionSearchDelegate { CollectionSearchDelegate({ required this.source, this.parentCollection, + this.canPop = true, String? initialQuery, }) { query = initialQuery ?? ''; } Widget buildLeading(BuildContext context) { - return Navigator.canPop(context) + // use a property instead of checking `Navigator.canPop(context)` + // because the navigator state changes as soon as we press back + // so the leading may mistakenly switch to the close button + return canPop ? IconButton( icon: AnimatedIcon( icon: AnimatedIcons.menu_arrow, From 7ea309de912d63d1027747a1d0ba065aeb82179e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 12:27:54 +0900 Subject: [PATCH 3/6] fixed initialization when handling new intent in existing activity --- lib/utils/android_file_utils.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/utils/android_file_utils.dart b/lib/utils/android_file_utils.dart index 7ae61645c..0c57ca95f 100644 --- a/lib/utils/android_file_utils.dart +++ b/lib/utils/android_file_utils.dart @@ -14,6 +14,7 @@ class AndroidFileUtils { Set storageVolumes = {}; Set _packages = {}; List _potentialAppDirs = []; + bool _initialized = false; AChangeNotifier appNameChangeNotifier = AChangeNotifier(); @@ -22,6 +23,8 @@ class AndroidFileUtils { AndroidFileUtils._private(); Future init() async { + if (_initialized) return; + separator = pContext.separator; storageVolumes = await storageService.getStorageVolumes(); primaryStorage = storageVolumes.firstWhereOrNull((volume) => volume.isPrimary)?.path ?? separator; @@ -32,6 +35,8 @@ class AndroidFileUtils { picturesPath = pContext.join(primaryStorage, 'Pictures'); // from Aves videoCapturesPath = pContext.join(dcimPath, 'Video Captures'); + + _initialized = true; } Future initAppNames() async { From 6b9ead5139bfb11338fc12b0f59c1c48a0c89fdf Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 12:35:12 +0900 Subject: [PATCH 4/6] minor change --- lib/utils/android_file_utils.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/utils/android_file_utils.dart b/lib/utils/android_file_utils.dart index 0c57ca95f..8c557d716 100644 --- a/lib/utils/android_file_utils.dart +++ b/lib/utils/android_file_utils.dart @@ -40,9 +40,11 @@ class AndroidFileUtils { } Future initAppNames() async { - _packages = await AndroidAppService.getPackages(); - _potentialAppDirs = _launcherPackages.expand((package) => package.potentialDirs).toList(); - appNameChangeNotifier.notifyListeners(); + if (_packages.isEmpty) { + _packages = await AndroidAppService.getPackages(); + _potentialAppDirs = _launcherPackages.expand((package) => package.potentialDirs).toList(); + appNameChangeNotifier.notifyListeners(); + } } bool isCameraPath(String path) => path.startsWith(dcimPath) && (path.endsWith('${separator}Camera') || path.endsWith('${separator}100ANDRO')); From bb06b9d0f01171e365c203f46133d3512efd1dd9 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 15:23:35 +0900 Subject: [PATCH 5/6] fixed opening file content URI in non-indexed directory --- .../aves/channel/streams/ImageByteStreamHandler.kt | 2 +- .../deckers/thibault/aves/utils/StorageUtils.kt | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt index 59dfd47d7..8e9ae3001 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt @@ -140,7 +140,7 @@ class ImageByteStreamHandler(private val activity: Activity, private val argumen error("streamImage-image-decode-null", "failed to get image from uri=$uri", null) } } catch (e: Exception) { - error("streamImage-image-decode-exception", "failed to get image from uri=$uri", toErrorDetails(e)) + error("streamImage-image-decode-exception", "failed to get image from uri=$uri model=$model", toErrorDetails(e)) } finally { Glide.with(activity).clear(target) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt index 84d51ecf3..0692d7deb 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/StorageUtils.kt @@ -429,11 +429,15 @@ object StorageUtils { // so we build a typical `images` or `videos` content URI from the original content ID. fun getGlideSafeUri(uri: Uri, mimeType: String): Uri { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && isMediaStoreContentUri(uri)) { - uri.tryParseId()?.let { id -> - return when { - isImage(mimeType) -> ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id) - isVideo(mimeType) -> ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id) - else -> uri + // we cannot safely apply this to a file content URI, as it may point to a file not indexed + // by the Media Store (via `.nomedia`), and therefore has no matching image/video content URI + if (uri.path?.contains("/downloads/") == true) { + uri.tryParseId()?.let { id -> + return when { + isImage(mimeType) -> ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id) + isVideo(mimeType) -> ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id) + else -> uri + } } } } From 26849817658d6208f160f52c262b22948f321a35 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 8 Aug 2021 15:25:44 +0900 Subject: [PATCH 6/6] version bump --- CHANGELOG.md | 4 +++- pubspec.yaml | 2 +- whatsnew/whatsnew-en-US | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1208f5714..e409b9f58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] -## [v1.4.7] - 2021-08-06 +## [v1.4.8] - 2021-08-08 ### Added - Map - Viewer: action to copy to clipboard @@ -13,6 +13,8 @@ All notable changes to this project will be documented in this file. - auto album identification and naming - opening HEIC images from downloads content URI on Android R+ +## [v1.4.7] - 2021-08-06 [YANKED] + ## [v1.4.6] - 2021-07-22 ### Added - Albums / Countries / Tags: multiple selection diff --git a/pubspec.yaml b/pubspec.yaml index 38da7420e..e8c22c1d3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: aves description: A visual media gallery and metadata explorer app. repository: https://github.com/deckerst/aves -version: 1.4.7+51 +version: 1.4.8+52 publish_to: none environment: diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US index 6a41abb90..2eff3dbb6 100644 --- a/whatsnew/whatsnew-en-US +++ b/whatsnew/whatsnew-en-US @@ -1,5 +1,5 @@ Thanks for using Aves! -v1.4.7: +v1.4.8: - map page - viewer action to copy to clipboard - integration with OS global search