From 73e9073407e525a42f3274b2a9f30615c3b2bbe0 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Tue, 9 Aug 2022 12:36:27 +0200 Subject: [PATCH] #275 system bar transparency review --- CHANGELOG.md | 16 ++--- android/app/src/main/AndroidManifest.xml | 12 ++-- .../deckers/thibault/aves/MainActivity.kt | 2 +- .../calls/fetchers/ThumbnailFetcher.kt | 4 +- .../calls/window/ActivityWindowHandler.kt | 5 -- .../streams/ActivityResultStreamHandler.kt | 2 +- .../model/provider/MediaStoreImageProvider.kt | 6 +- .../thibault/aves/utils/CollectionUtils.kt | 2 +- .../thibault/aves/utils/PermissionManager.kt | 8 +-- .../thibault/aves/utils/StorageUtils.kt | 8 +-- .../app/src/main/res/values-land/flags.xml | 4 -- .../app/src/main/res/values-night/styles.xml | 9 +++ .../app/src/main/res/values-v28/styles.xml | 7 --- android/app/src/main/res/values/flags.xml | 4 -- android/app/src/main/res/values/styles.xml | 9 ++- lib/theme/themes.dart | 14 ++--- lib/widgets/aves_app.dart | 63 +++++++++++++++---- lib/widgets/common/basic/insets.dart | 4 +- lib/widgets/home_page.dart | 2 +- lib/widgets/viewer/entry_viewer_stack.dart | 18 +++--- lib/widgets/viewer/panorama_page.dart | 10 +-- lib/widgets/wallpaper_page.dart | 5 +- 22 files changed, 124 insertions(+), 90 deletions(-) delete mode 100644 android/app/src/main/res/values-land/flags.xml create mode 100644 android/app/src/main/res/values-night/styles.xml delete mode 100644 android/app/src/main/res/values-v28/styles.xml delete mode 100644 android/app/src/main/res/values/flags.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 554a4261d..8dd0734f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ All notable changes to this project will be documented in this file. - slideshow - set wallpaper from any media -- optional dynamic accent color on Android 12+ +- optional dynamic accent color on Android >=12 - Search: date/dimension/size field equality (undocumented) - support Android 13 (API 33) - Turkish translation (thanks metezd) @@ -135,7 +135,7 @@ All notable changes to this project will be documented in this file. ### Fixed -- app launch despite faulty storage volumes on Android 11+ +- app launch despite faulty storage volumes on Android >=11 ## [v1.6.2] - 2022-03-07 @@ -320,7 +320,7 @@ All notable changes to this project will be documented in this file. - Info: improved display for PNG text metadata, XMP and others - Export: output format selection - Search: added raw filter -- Support modifying files in the Download folder on Android 11+ +- Support modifying files in the Download folder on Android >=11 ### Changed @@ -330,7 +330,7 @@ All notable changes to this project will be documented in this file. ### Fixed - hide root album of hidden path -- gesture & spacing handling for Android 10+ navigation gestures +- gesture & spacing handling for Android >=10 navigation gestures - renaming was leaving behind obsolete items in some cases - speeding up videos on Xiaomi devices @@ -393,7 +393,7 @@ All notable changes to this project will be documented in this file. - Map & Stats from selection - Map: item browsing, rotation control - Navigation menu customization -- shortcut support on older devices (API < 26) +- shortcut support on older devices (API <26) - support Android 12/S (API 31) ## [v1.4.8] - 2021-08-08 @@ -407,7 +407,7 @@ All notable changes to this project will be documented in this file. ### Fixed - auto album identification and naming -- opening HEIC images from downloads content URI on Android R+ +- opening HEIC images from downloads content URI on Android >=11 ## [v1.4.7] - 2021-08-06 [YANKED] @@ -611,7 +611,7 @@ All notable changes to this project will be documented in this file. - Viewer: support for multi-track HEIF - Viewer: export image (including multipage TIFF/HEIF and images embedded in XMP) -- Info: show owner app (Android Q and up) +- Info: show owner app (Android >=10) - listen to Media Store changes ### Changed @@ -638,7 +638,7 @@ upgraded libtiff to 4.2.0 for TIFF decoding ### Fixed -- prevent scrolling when using Android Q style gesture navigation +- prevent scrolling when using Android 10 style gesture navigation ## [v1.3.1] - 2021-01-04 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8e1be5b28..c6189d907 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -12,8 +12,8 @@ This change eventually prevents building the app with Flutter v3.0.2. android:installLocation="auto"> @@ -31,25 +31,25 @@ This change eventually prevents building the app with Flutter v3.0.2. - + - + - + diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index 81d468d32..ad2196561 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -285,7 +285,7 @@ open class MainActivity : FlutterActivity() { val filters = intent.getStringArrayExtra(EXTRA_KEY_FILTERS_ARRAY)?.toList() if (filters != null) return filters - // fallback for shortcuts created on API < 26 + // fallback for shortcuts created on API <26 val filterString = intent.getStringExtra(EXTRA_KEY_FILTERS_STRING) if (filterString != null) { return filterString.split(EXTRA_STRING_ARRAY_SEPARATOR) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt index a6b54573d..b518cd15a 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt @@ -56,7 +56,7 @@ class ThumbnailFetcher internal constructor( try { if (!customFetch && (width == defaultSize || height == defaultSize) && !isFlipped) { // Fetch low quality thumbnails when size is not specified. - // As of Android R, the Media Store content resolver may return a thumbnail + // As of Android 11, the Media Store content resolver may return a thumbnail // that is automatically rotated according to EXIF orientation, but not flipped, // so we skip this step for flipped entries. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -108,7 +108,7 @@ class ThumbnailFetcher internal constructor( } else { @Suppress("deprecation") var bitmap = MediaStore.Images.Thumbnails.getThumbnail(resolver, contentId, MediaStore.Images.Thumbnails.MINI_KIND, null) - // from Android Q, returned thumbnail is already rotated according to EXIF orientation + // from Android 10, returned thumbnail is already rotated according to EXIF orientation if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && bitmap != null) { bitmap = applyExifOrientation(context, bitmap, rotationDegrees, isFlipped) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt index 88bda61d4..0b01c4578 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt @@ -3,7 +3,6 @@ package deckers.thibault.aves.channel.calls.window import android.app.Activity import android.os.Build import android.view.WindowManager -import deckers.thibault.aves.utils.LogUtils import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel @@ -60,8 +59,4 @@ class ActivityWindowHandler(private val activity: Activity) : WindowHandler(acti } result.success(true) } - - companion object { - private val LOG_TAG = LogUtils.createTag() - } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt index e01adca3a..8d7c272cf 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt @@ -88,7 +88,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { - error("requestMediaFileAccess-unsupported", "media file bulk access is not allowed before Android R", null) + error("requestMediaFileAccess-unsupported", "media file bulk access is not allowed before Android 11", null) return } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt index e3e9ff736..965a6c897 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt @@ -193,7 +193,7 @@ class MediaStoreImageProvider : ImageProvider() { val dateModifiedColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED) val dateTakenColumn = cursor.getColumnIndex(MediaColumns.DATE_TAKEN) - // image & video for API >= Q, only for images for API < Q + // image & video for API >=29, only for images for API <29 val orientationColumn = cursor.getColumnIndex(MediaColumns.ORIENTATION) // video only @@ -347,7 +347,7 @@ class MediaStoreImageProvider : ImageProvider() { } } catch (securityException: SecurityException) { // even if the app has access permission granted on the containing directory, - // the delete request may yield a `RecoverableSecurityException` on Android 10+ + // the delete request may yield a `RecoverableSecurityException` on Android >=10 // when the underlying file no longer exists and this is an orphaned entry in the Media Store if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && contextWrapper is Activity) { Log.w(LOG_TAG, "caught a security exception when attempting to delete uri=$uri", securityException) @@ -876,7 +876,7 @@ class MediaStoreImageProvider : ImageProvider() { private val VIDEO_PROJECTION = arrayOf( *BASE_PROJECTION, MediaColumns.DURATION, - // `ORIENTATION` was only available for images before Android Q + // `ORIENTATION` was only available for images before Android 10 *if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) arrayOf( MediaStore.MediaColumns.ORIENTATION, ) else emptyArray() diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/CollectionUtils.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/CollectionUtils.kt index 56c78df1f..3875d1f3a 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/CollectionUtils.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/CollectionUtils.kt @@ -2,7 +2,7 @@ package deckers.thibault.aves.utils import android.os.Build -// compatibility extension for `removeIf` for API < N +// compatibility extension for `removeIf` for API <24 fun MutableList.compatRemoveIf(filter: (t: E) -> Boolean): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { this.removeIf(filter) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt index add315a11..4491eec38 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt @@ -98,7 +98,7 @@ object PermissionManager { segments.volumePath?.let { volumePath -> val dirSet = dirsPerVolume[volumePath] ?: HashSet() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // request primary directory on volume from Android R + // request primary directory on volume from Android 11 val relativeDir = segments.relativeDir if (relativeDir != null) { val dirSegments = relativeDir.split(File.separator).takeWhile { it.isNotEmpty() } @@ -111,11 +111,11 @@ object PermissionManager { } } else { // the requested path is the volume root itself - // which cannot be granted, due to Android R restrictions + // which cannot be granted, due to Android 11 restrictions dirSet.add("") } } else { - // request volume root until Android Q + // request volume root until Android 10 dirSet.add("") } dirsPerVolume[volumePath] = dirSet @@ -236,7 +236,7 @@ object PermissionManager { return dirs } - // As of Android R, `MediaStore.getDocumentUri` fails if any of the persisted + // As of Android 11, `MediaStore.getDocumentUri` fails if any of the persisted // URI permissions we hold points to a folder that no longer exists, // so we should remove these obsolete URIs before proceeding. @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 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 ba7d1537e..62400b4f2 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 @@ -468,7 +468,7 @@ object StorageUtils { fun requireAccessPermission(context: Context, anyPath: String): Boolean { if (isAppFile(context, anyPath)) return false - // on Android R, we should always require access permission, even on primary volume + // on Android 11, we should always require access permission, even on primary volume if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) return true val onPrimaryVolume = anyPath.startsWith(getPrimaryVolumePath(context)) @@ -487,7 +487,7 @@ object StorageUtils { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && isMediaStoreContentUri(uri)) { val path = uri.path path ?: return uri - // from Android R, accessing the original URI for a `file` or `downloads` media content yields a `SecurityException` + // from Android 11, accessing the original URI for a `file` or `downloads` media content yields a `SecurityException` if (path.startsWith("/external/images/") || path.startsWith("/external/video/")) { // "Caller must hold ACCESS_MEDIA_LOCATION permission to access original" if (context.checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION) == PackageManager.PERMISSION_GRANTED) { @@ -499,7 +499,7 @@ object StorageUtils { } // As of Glide v4.12.0, a special loader `QMediaStoreUriLoader` is automatically used - // to work around a bug from Android Q where metadata redaction corrupts HEIC images. + // to work around a bug from Android 10 where metadata redaction corrupts HEIC images. // This loader relies on `MediaStore.setRequireOriginal` but this yields a `SecurityException` // for some non image/video content URIs (e.g. `downloads`, `file`) fun getGlideSafeUri(context: Context, uri: Uri, mimeType: String): Uri { @@ -594,7 +594,7 @@ object StorageUtils { val effectiveUri = getOriginalUri(context, uri) return try { MediaMetadataRetriever().apply { - // on Android S preview, setting the data source works but yields an internal IOException + // on Android 12 preview, setting the data source works but yields an internal IOException // (`Input file descriptor already original`), whether we provide the original URI or not setDataSource(context, effectiveUri) } diff --git a/android/app/src/main/res/values-land/flags.xml b/android/app/src/main/res/values-land/flags.xml deleted file mode 100644 index 637d33153..000000000 --- a/android/app/src/main/res/values-land/flags.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - false - \ No newline at end of file diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..25046f02e --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,9 @@ + + + + diff --git a/android/app/src/main/res/values-v28/styles.xml b/android/app/src/main/res/values-v28/styles.xml deleted file mode 100644 index ecbc11c23..000000000 --- a/android/app/src/main/res/values-v28/styles.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android/app/src/main/res/values/flags.xml b/android/app/src/main/res/values/flags.xml deleted file mode 100644 index a02d00023..000000000 --- a/android/app/src/main/res/values/flags.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - true - \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index f5ce40ae0..0f75fc293 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,6 +1,9 @@ - - diff --git a/lib/theme/themes.dart b/lib/theme/themes.dart index b701deb0d..57d931862 100644 --- a/lib/theme/themes.dart +++ b/lib/theme/themes.dart @@ -2,8 +2,8 @@ import 'dart:ui'; import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/settings.dart'; +import 'package:aves/widgets/aves_app.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; class Themes { @@ -35,7 +35,7 @@ class Themes { static const _lightSecondLayer = Color(0xFFF5F5F5); // aka `Colors.grey[100]` static const _lightThirdLayer = Color(0xFFEEEEEE); // aka `Colors.grey[200]` - static ThemeData lightTheme(Color accentColor) => ThemeData( + static ThemeData lightTheme(Color accentColor, bool deviceInitialized) => ThemeData( colorScheme: ColorScheme.light( primary: accentColor, secondary: accentColor, @@ -58,7 +58,7 @@ class Themes { foregroundColor: _lightActionIconColor, // `titleTextStyle.color` is used by text titleTextStyle: _appBarTitleTextStyle.copyWith(color: _lightTitleColor), - systemOverlayStyle: SystemUiOverlayStyle.dark, + systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(Brightness.light, _lightFirstLayer) : null, ), listTileTheme: const ListTileThemeData( iconColor: _lightActionIconColor, @@ -87,7 +87,7 @@ class Themes { static const _darkSecondLayer = Color(0xFF363636); static const _darkThirdLayer = Color(0xFF424242); // aka `Colors.grey[800]` - static ThemeData darkTheme(Color accentColor) => ThemeData( + static ThemeData darkTheme(Color accentColor, bool deviceInitialized) => ThemeData( colorScheme: ColorScheme.dark( primary: accentColor, secondary: accentColor, @@ -112,7 +112,7 @@ class Themes { foregroundColor: _darkTitleColor, // `titleTextStyle.color` is used by text titleTextStyle: _appBarTitleTextStyle.copyWith(color: _darkTitleColor), - systemOverlayStyle: SystemUiOverlayStyle.light, + systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(Brightness.dark, _darkFirstLayer) : null, ), popupMenuTheme: const PopupMenuThemeData( color: _darkSecondLayer, @@ -138,8 +138,8 @@ class Themes { static const _blackSecondLayer = Color(0xFF212121); // aka `Colors.grey[900]` static const _blackThirdLayer = Color(0xFF303030); // aka `Colors.grey[850]` - static ThemeData blackTheme(Color accentColor) { - final baseTheme = darkTheme(accentColor); + static ThemeData blackTheme(Color accentColor, bool deviceInitialized) { + final baseTheme = darkTheme(accentColor, deviceInitialized); return baseTheme.copyWith( // `canvasColor` is used by `Drawer`, `DropdownButton` and `ExpansionTileCard` canvasColor: _blackSecondLayer, diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 87e43b8cb..6cb98f706 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -60,15 +60,44 @@ class AvesApp extends StatefulWidget { @override State createState() => _AvesAppState(); - static void showSystemUI() { + static void setSystemUIStyle(BuildContext context) { + final theme = Theme.of(context); + final style = systemUIStyleForBrightness(theme.brightness, theme.scaffoldBackgroundColor); + SystemChrome.setSystemUIOverlayStyle(style); + } + + static SystemUiOverlayStyle systemUIStyleForBrightness(Brightness themeBrightness, Color scaffoldBackgroundColor) { + final barBrightness = themeBrightness == Brightness.light ? Brightness.dark : Brightness.light; + const statusBarColor = Colors.transparent; + // as of Flutter v3.3.0-0.2.pre, setting `SystemUiOverlayStyle` (whether manually or automatically because of `AppBar`) + // prevents the canvas from drawing behind the nav bar on Android <10 (API <29), + // so the nav bar is opaque, even when requesting `SystemUiMode.edgeToEdge` from Flutter + // or setting `android:windowTranslucentNavigation` in Android themes. + final navBarColor = device.supportEdgeToEdgeUIMode ? Colors.transparent : scaffoldBackgroundColor; + return SystemUiOverlayStyle( + systemNavigationBarColor: navBarColor, + systemNavigationBarDividerColor: navBarColor, + systemNavigationBarIconBrightness: barBrightness, + // shows background scrim when using navigation buttons, but not when using gesture navigation + systemNavigationBarContrastEnforced: true, + statusBarColor: statusBarColor, + statusBarBrightness: barBrightness, + statusBarIconBrightness: barBrightness, + systemStatusBarContrastEnforced: false, + ); + } + + static Future showSystemUI() async { if (device.supportEdgeToEdgeUIMode) { - SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); } else { - SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); } } - static void hideSystemUI() => SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + static Future hideSystemUI() async { + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + } } class _AvesAppState extends State with WidgetsBindingObserver { @@ -121,6 +150,9 @@ class _AvesAppState extends State with WidgetsBindingObserver { future: _appSetup, builder: (context, snapshot) { final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done; + if (initialized) { + AvesApp.showSystemUI(); + } final home = initialized ? getFirstPage() : Scaffold( @@ -169,17 +201,22 @@ class _AvesAppState extends State with WidgetsBindingObserver { navigatorKey: AvesApp.navigatorKey, home: home, navigatorObservers: _navigatorObservers, - builder: (context, child) => AvesColorsProvider( - child: Theme( - data: Theme.of(context).copyWith( - pageTransitionsTheme: pageTransitionsTheme, + builder: (context, child) { + if (initialized) { + WidgetsBinding.instance.addPostFrameCallback((_) => AvesApp.setSystemUIStyle(context)); + } + return AvesColorsProvider( + child: Theme( + data: Theme.of(context).copyWith( + pageTransitionsTheme: pageTransitionsTheme, + ), + child: child!, ), - child: child!, - ), - ), + ); + }, onGenerateTitle: (context) => context.l10n.appName, - theme: Themes.lightTheme(lightAccent), - darkTheme: themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent) : Themes.darkTheme(darkAccent), + theme: Themes.lightTheme(lightAccent, initialized), + darkTheme: themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized), themeMode: themeBrightness.appThemeMode, locale: settingsLocale, localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/lib/widgets/common/basic/insets.dart b/lib/widgets/common/basic/insets.dart index 671c27738..f10133933 100644 --- a/lib/widgets/common/basic/insets.dart +++ b/lib/widgets/common/basic/insets.dart @@ -5,7 +5,7 @@ import 'package:provider/provider.dart'; // This widget should be added on top of Scaffolds with: // - `resizeToAvoidBottomInset` set to false, // - a vertically scrollable body. -// It will prevent the body from scrolling when a user swipe from bottom to use Android Q style navigation gestures. +// It will prevent the body from scrolling when a user swipe from bottom to use Android 10 style navigation gestures. class BottomGestureAreaProtector extends StatelessWidget { const BottomGestureAreaProtector({super.key}); @@ -45,7 +45,7 @@ class TopGestureAreaProtector extends StatelessWidget { } } -// It will prevent the body from scrolling when a user swipe from edges to use Android Q style navigation gestures. +// It will prevent the body from scrolling when a user swipe from edges to use Android 10 style navigation gestures. class SideGestureAreaProtector extends StatelessWidget { const SideGestureAreaProtector({super.key}); diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index 665a16a39..8b8482e2c 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -95,7 +95,7 @@ class _HomePageState extends State { // hide in some countries apps that force quit on permission denial await [ Permission.storage, - // to access media with unredacted metadata with scoped storage (Android 10+) + // to access media with unredacted metadata with scoped storage (Android >=10) Permission.accessMediaLocation, ].request(); } diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 05a3b6469..91741f943 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -652,19 +652,20 @@ class _EntryViewerStackState extends State with EntryViewContr } } - void _onLeave() { + Future _onLeave() async { if (!settings.viewerUseCutout) { - windowService.setCutoutMode(true); + await windowService.setCutoutMode(true); } if (settings.viewerMaxBrightness) { - ScreenBrightness().resetScreenBrightness(); + await ScreenBrightness().resetScreenBrightness(); } if (settings.keepScreenOn == KeepScreenOn.viewerOnly) { - windowService.keepScreenOn(false); + await windowService.keepScreenOn(false); } - AvesApp.showSystemUI(); - windowService.requestOrientation(); + await AvesApp.showSystemUI(); + AvesApp.setSystemUIStyle(context); + await windowService.requestOrientation(); } // overlay @@ -679,7 +680,8 @@ class _EntryViewerStackState extends State with EntryViewContr Future _onOverlayVisibleChange({bool animate = true}) async { if (_overlayVisible.value) { - AvesApp.showSystemUI(); + await AvesApp.showSystemUI(); + AvesApp.setSystemUIStyle(context); if (animate) { await _overlayAnimationController.forward(); } else { @@ -692,7 +694,7 @@ class _EntryViewerStackState extends State with EntryViewContr _frozenViewInsets = mediaQuery.viewInsets; _frozenViewPadding = mediaQuery.viewPadding; }); - AvesApp.hideSystemUI(); + await AvesApp.hideSystemUI(); if (animate) { await _overlayAnimationController.reverse(); } else { diff --git a/lib/widgets/viewer/panorama_page.dart b/lib/widgets/viewer/panorama_page.dart index f2822b1f8..6a6616f6b 100644 --- a/lib/widgets/viewer/panorama_page.dart +++ b/lib/widgets/viewer/panorama_page.dart @@ -159,8 +159,9 @@ class _PanoramaPageState extends State { } } - void _onLeave() { - AvesApp.showSystemUI(); + Future _onLeave() async { + await AvesApp.showSystemUI(); + AvesApp.setSystemUIStyle(context); } // system UI @@ -176,9 +177,10 @@ class _PanoramaPageState extends State { Future _onOverlayVisibleChange() async { if (_overlayVisible.value) { - AvesApp.showSystemUI(); + await AvesApp.showSystemUI(); + AvesApp.setSystemUIStyle(context); } else { - AvesApp.hideSystemUI(); + await AvesApp.hideSystemUI(); } } } diff --git a/lib/widgets/wallpaper_page.dart b/lib/widgets/wallpaper_page.dart index 50d51515a..1673f352e 100644 --- a/lib/widgets/wallpaper_page.dart +++ b/lib/widgets/wallpaper_page.dart @@ -234,7 +234,8 @@ class _EntryEditorState extends State with EntryViewControllerMixin Future _onOverlayVisibleChange({bool animate = true}) async { if (_overlayVisible.value) { - AvesApp.showSystemUI(); + await AvesApp.showSystemUI(); + AvesApp.setSystemUIStyle(context); if (animate) { await _overlayAnimationController.forward(); } else { @@ -246,7 +247,7 @@ class _EntryEditorState extends State with EntryViewControllerMixin _frozenViewInsets = mediaQuery.viewInsets; _frozenViewPadding = mediaQuery.viewPadding; }); - AvesApp.hideSystemUI(); + await AvesApp.hideSystemUI(); if (animate) { await _overlayAnimationController.reverse(); } else {