diff --git a/lib/hooks/utils/use_custom_status_bar_color.dart b/lib/hooks/utils/use_custom_status_bar_color.dart index 7c5c7b27..8afc6a59 100644 --- a/lib/hooks/utils/use_custom_status_bar_color.dart +++ b/lib/hooks/utils/use_custom_status_bar_color.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -void useCustomStatusBarColor( +VoidCallback useCustomStatusBarColor( Color color, bool isCurrentRoute, { bool noSetBGColor = false, @@ -10,14 +10,19 @@ void useCustomStatusBarColor( }) { final context = useContext(); final backgroundColor = Theme.of(context).scaffoldBackgroundColor; - resetStatusbar() => SystemChrome.setSystemUIOverlayStyle( - SystemUiOverlayStyle( - statusBarColor: backgroundColor, // status bar color - statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179 - ? Brightness.dark - : Brightness.light, - ), - ); + // ignore: invalid_use_of_visible_for_testing_member + final previousState = SystemChrome.latestStyle; + + void resetStatusbar() => previousState != null + ? SystemChrome.setSystemUIOverlayStyle(previousState) + : SystemChrome.setSystemUIOverlayStyle( + SystemUiOverlayStyle( + statusBarColor: backgroundColor, // status bar color + statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179 + ? Brightness.dark + : Brightness.light, + ), + ); // ignore: invalid_use_of_visible_for_testing_member final statusBarColor = SystemChrome.latestStyle?.statusBarColor; @@ -54,4 +59,6 @@ void useCustomStatusBarColor( useEffect(() { return resetStatusbar; }, []); + + return resetStatusbar; } diff --git a/lib/models/database/tables/preferences.dart b/lib/models/database/tables/preferences.dart index fd446ce5..c3904c84 100644 --- a/lib/models/database/tables/preferences.dart +++ b/lib/models/database/tables/preferences.dart @@ -120,7 +120,7 @@ class PreferencesTable extends Table { invidiousInstance: "https://inv.nadeko.net", themeMode: ThemeMode.system, audioSource: AudioSource.youtube, - streamMusicCodec: SourceCodecs.weba, + streamMusicCodec: SourceCodecs.m4a, downloadMusicCodec: SourceCodecs.m4a, discordPresence: true, endlessPlayback: true, diff --git a/lib/modules/library/local_folder/local_folder_item.dart b/lib/modules/library/local_folder/local_folder_item.dart index 8e08b6db..a965a42d 100644 --- a/lib/modules/library/local_folder/local_folder_item.dart +++ b/lib/modules/library/local_folder/local_folder_item.dart @@ -11,6 +11,7 @@ import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/image.dart'; +import 'package:spotube/extensions/string.dart'; import 'package:spotube/hooks/utils/use_brightness_value.dart'; import 'package:spotube/pages/library/local_folder.dart'; import 'package:spotube/provider/local_tracks/local_tracks_provider.dart'; @@ -127,7 +128,9 @@ class LocalFolderItem extends HookConsumerWidget { child: Text( isDownloadFolder ? context.l10n.downloads - : basename(folder), + : isCacheFolder + ? context.l10n.cache_folder.capitalize() + : basename(folder), style: const TextStyle(fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), diff --git a/lib/pages/home/genres/genre_playlists.dart b/lib/pages/home/genres/genre_playlists.dart index 58436bcf..04658965 100644 --- a/lib/pages/home/genres/genre_playlists.dart +++ b/lib/pages/home/genres/genre_playlists.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; +import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:spotify/spotify.dart' hide Offset; import 'package:spotube/collections/fake.dart'; +import 'package:spotube/hooks/utils/use_custom_status_bar_color.dart'; import 'package:spotube/modules/playlist/playlist_card.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/titlebar/titlebar.dart'; @@ -27,6 +29,14 @@ class GenrePlaylistsPage extends HookConsumerWidget { final playlistsNotifier = ref.read(categoryPlaylistsProvider(category.id!).notifier); final scrollController = useScrollController(); + final routeName = GoRouterState.of(context).name; + + useCustomStatusBarColor( + Colors.black, + routeName == GenrePlaylistsPage.name, + noSetBGColor: true, + automaticSystemUiAdjustment: false, + ); return Scaffold( appBar: kIsDesktop diff --git a/lib/pages/lyrics/lyrics.dart b/lib/pages/lyrics/lyrics.dart index 423212f3..0f4f9473 100644 --- a/lib/pages/lyrics/lyrics.dart +++ b/lib/pages/lyrics/lyrics.dart @@ -38,10 +38,11 @@ class LyricsPage extends HookConsumerWidget { ); final palette = usePaletteColor(albumArt, ref); final mediaQuery = MediaQuery.of(context); + final route = ModalRoute.of(context); - useCustomStatusBarColor( + final resetStatusBar = useCustomStatusBarColor( palette.color, - true, + route?.isCurrent ?? false, noSetBGColor: true, ); @@ -81,53 +82,57 @@ class LyricsPage extends HookConsumerWidget { ); if (isModal) { - return DefaultTabController( - length: 2, - child: SafeArea( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), - child: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface.withOpacity(.4), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10), + return PopScope( + canPop: true, + onPopInvokedWithResult: (_, __) => resetStatusBar(), + child: DefaultTabController( + length: 2, + child: SafeArea( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), + child: Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface.withOpacity(.4), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + ), ), - ), - child: Column( - children: [ - const SizedBox(height: 5), - Container( - height: 7, - width: 150, - decoration: BoxDecoration( - color: palette.titleTextColor, - borderRadius: BorderRadius.circular(10), - ), - ), - AppBar( - leadingWidth: double.infinity, - leading: tabbar, - backgroundColor: Colors.transparent, - automaticallyImplyLeading: false, - actions: [ - IconButton( - icon: const Icon(SpotubeIcons.minimize), - onPressed: () => Navigator.of(context).pop(), + child: Column( + children: [ + const SizedBox(height: 5), + Container( + height: 7, + width: 150, + decoration: BoxDecoration( + color: palette.titleTextColor, + borderRadius: BorderRadius.circular(10), ), - const SizedBox(width: 5), - ], - ), - Expanded( - child: TabBarView( - children: [ - SyncedLyrics(palette: palette, isModal: isModal), - PlainLyrics(palette: palette, isModal: isModal), + ), + AppBar( + leadingWidth: double.infinity, + leading: tabbar, + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + actions: [ + IconButton( + icon: const Icon(SpotubeIcons.minimize), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 5), ], ), - ), - ], + Expanded( + child: TabBarView( + children: [ + SyncedLyrics(palette: palette, isModal: isModal), + PlainLyrics(palette: palette, isModal: isModal), + ], + ), + ), + ], + ), ), ), ), diff --git a/lib/pages/settings/sections/playback.dart b/lib/pages/settings/sections/playback.dart index d91e2394..f8868789 100644 --- a/lib/pages/settings/sections/playback.dart +++ b/lib/pages/settings/sections/playback.dart @@ -16,6 +16,7 @@ import 'package:spotube/provider/audio_player/sources/piped_instances_provider.d import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/services/sourced_track/enums.dart'; +import 'package:spotube/utils/platform.dart'; class SettingsPlaybackSection extends HookConsumerWidget { const SettingsPlaybackSection({super.key}); @@ -242,22 +243,24 @@ class SettingsPlaybackSection extends HookConsumerWidget { ), SwitchListTile( title: Text(context.l10n.cache_music), - subtitle: Text.rich( - TextSpan( - children: [ - TextSpan(text: "${context.l10n.open} "), - TextSpan( - text: context.l10n.cache_folder.toLowerCase(), - recognizer: TapGestureRecognizer() - ..onTap = preferencesNotifier.openCacheFolder, - style: theme.textTheme.bodyMedium?.copyWith( - color: theme.colorScheme.primary, - decoration: TextDecoration.underline, + subtitle: kIsMobile + ? null + : Text.rich( + TextSpan( + children: [ + TextSpan(text: "${context.l10n.open} "), + TextSpan( + text: context.l10n.cache_folder.toLowerCase(), + recognizer: TapGestureRecognizer() + ..onTap = preferencesNotifier.openCacheFolder, + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.primary, + decoration: TextDecoration.underline, + ), + ) + ], ), - ) - ], - ), - ), + ), secondary: const Icon(SpotubeIcons.cache), value: preferences.cacheMusic, onChanged: preferencesNotifier.setCacheMusic, diff --git a/lib/provider/user_preferences/user_preferences_provider.dart b/lib/provider/user_preferences/user_preferences_provider.dart index 13c2cae4..053f0994 100644 --- a/lib/provider/user_preferences/user_preferences_provider.dart +++ b/lib/provider/user_preferences/user_preferences_provider.dart @@ -2,7 +2,7 @@ import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:path/path.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:path_provider/path_provider.dart' as paths; import 'package:spotify/spotify.dart'; import 'package:spotube/models/database/database.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; @@ -72,10 +72,10 @@ class UserPreferencesNotifier extends Notifier { if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; if (kIsMacOS) { - return join((await getLibraryDirectory()).path, "Caches"); + return join((await paths.getLibraryDirectory()).path, "Caches"); } - return getDownloadsDirectory().then((dir) { + return paths.getDownloadsDirectory().then((dir) { return join(dir!.path, "Spotube"); }); } @@ -96,14 +96,28 @@ class UserPreferencesNotifier extends Notifier { await query.replace(PreferencesTableCompanion.insert()); } - static Future getMusicCacheDir() async => join( - await getApplicationCacheDirectory().then((value) => value.path), - 'cached_tracks', - ); + static Future getMusicCacheDir() async { + if (kIsAndroid) { + final dir = + await paths.getExternalCacheDirectories().then((dirs) => dirs!.first); + if (!await dir.exists()) { + await dir.create(recursive: true); + } + return join(dir.path, 'Cached Tracks'); + } + + final dir = await paths.getApplicationCacheDirectory(); + return join(dir.path, 'cached_tracks'); + } Future openCacheFolder() async { - final filePath = await getMusicCacheDir(); - await OpenFile.open(filePath); + try { + final filePath = await getMusicCacheDir(); + + await OpenFile.open(filePath); + } catch (e, stack) { + AppLogger.reportError(e, stack); + } } void setStreamMusicCodec(SourceCodecs codec) {