fix(mobile): cache dir not open-able

This commit is contained in:
Kingkor Roy Tirtho 2024-12-08 17:03:11 +06:00
parent ccb18e81a9
commit 8eb99b0ef6
7 changed files with 122 additions and 80 deletions

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
void useCustomStatusBarColor( VoidCallback useCustomStatusBarColor(
Color color, Color color,
bool isCurrentRoute, { bool isCurrentRoute, {
bool noSetBGColor = false, bool noSetBGColor = false,
@ -10,14 +10,19 @@ void useCustomStatusBarColor(
}) { }) {
final context = useContext(); final context = useContext();
final backgroundColor = Theme.of(context).scaffoldBackgroundColor; final backgroundColor = Theme.of(context).scaffoldBackgroundColor;
resetStatusbar() => SystemChrome.setSystemUIOverlayStyle( // ignore: invalid_use_of_visible_for_testing_member
SystemUiOverlayStyle( final previousState = SystemChrome.latestStyle;
statusBarColor: backgroundColor, // status bar color
statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179 void resetStatusbar() => previousState != null
? Brightness.dark ? SystemChrome.setSystemUIOverlayStyle(previousState)
: Brightness.light, : 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 // ignore: invalid_use_of_visible_for_testing_member
final statusBarColor = SystemChrome.latestStyle?.statusBarColor; final statusBarColor = SystemChrome.latestStyle?.statusBarColor;
@ -54,4 +59,6 @@ void useCustomStatusBarColor(
useEffect(() { useEffect(() {
return resetStatusbar; return resetStatusbar;
}, []); }, []);
return resetStatusbar;
} }

View File

@ -120,7 +120,7 @@ class PreferencesTable extends Table {
invidiousInstance: "https://inv.nadeko.net", invidiousInstance: "https://inv.nadeko.net",
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
audioSource: AudioSource.youtube, audioSource: AudioSource.youtube,
streamMusicCodec: SourceCodecs.weba, streamMusicCodec: SourceCodecs.m4a,
downloadMusicCodec: SourceCodecs.m4a, downloadMusicCodec: SourceCodecs.m4a,
discordPresence: true, discordPresence: true,
endlessPlayback: true, endlessPlayback: true,

View File

@ -11,6 +11,7 @@ import 'package:spotube/components/image/universal_image.dart';
import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/image.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/hooks/utils/use_brightness_value.dart';
import 'package:spotube/pages/library/local_folder.dart'; import 'package:spotube/pages/library/local_folder.dart';
import 'package:spotube/provider/local_tracks/local_tracks_provider.dart'; import 'package:spotube/provider/local_tracks/local_tracks_provider.dart';
@ -127,7 +128,9 @@ class LocalFolderItem extends HookConsumerWidget {
child: Text( child: Text(
isDownloadFolder isDownloadFolder
? context.l10n.downloads ? context.l10n.downloads
: basename(folder), : isCacheFolder
? context.l10n.cache_folder.capitalize()
: basename(folder),
style: const TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),

View File

@ -1,10 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:skeletonizer/skeletonizer.dart'; import 'package:skeletonizer/skeletonizer.dart';
import 'package:spotify/spotify.dart' hide Offset; import 'package:spotify/spotify.dart' hide Offset;
import 'package:spotube/collections/fake.dart'; 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/modules/playlist/playlist_card.dart';
import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/image/universal_image.dart';
import 'package:spotube/components/titlebar/titlebar.dart'; import 'package:spotube/components/titlebar/titlebar.dart';
@ -27,6 +29,14 @@ class GenrePlaylistsPage extends HookConsumerWidget {
final playlistsNotifier = final playlistsNotifier =
ref.read(categoryPlaylistsProvider(category.id!).notifier); ref.read(categoryPlaylistsProvider(category.id!).notifier);
final scrollController = useScrollController(); final scrollController = useScrollController();
final routeName = GoRouterState.of(context).name;
useCustomStatusBarColor(
Colors.black,
routeName == GenrePlaylistsPage.name,
noSetBGColor: true,
automaticSystemUiAdjustment: false,
);
return Scaffold( return Scaffold(
appBar: kIsDesktop appBar: kIsDesktop

View File

@ -38,10 +38,11 @@ class LyricsPage extends HookConsumerWidget {
); );
final palette = usePaletteColor(albumArt, ref); final palette = usePaletteColor(albumArt, ref);
final mediaQuery = MediaQuery.of(context); final mediaQuery = MediaQuery.of(context);
final route = ModalRoute.of(context);
useCustomStatusBarColor( final resetStatusBar = useCustomStatusBarColor(
palette.color, palette.color,
true, route?.isCurrent ?? false,
noSetBGColor: true, noSetBGColor: true,
); );
@ -81,53 +82,57 @@ class LyricsPage extends HookConsumerWidget {
); );
if (isModal) { if (isModal) {
return DefaultTabController( return PopScope(
length: 2, canPop: true,
child: SafeArea( onPopInvokedWithResult: (_, __) => resetStatusBar(),
child: BackdropFilter( child: DefaultTabController(
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), length: 2,
child: Container( child: SafeArea(
clipBehavior: Clip.hardEdge, child: BackdropFilter(
decoration: BoxDecoration( filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
color: Theme.of(context).colorScheme.surface.withOpacity(.4), child: Container(
borderRadius: const BorderRadius.only( clipBehavior: Clip.hardEdge,
topLeft: Radius.circular(10), decoration: BoxDecoration(
topRight: Radius.circular(10), color: Theme.of(context).colorScheme.surface.withOpacity(.4),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
), ),
), child: Column(
child: Column( children: [
children: [ const SizedBox(height: 5),
const SizedBox(height: 5), Container(
Container( height: 7,
height: 7, width: 150,
width: 150, decoration: BoxDecoration(
decoration: BoxDecoration( color: palette.titleTextColor,
color: palette.titleTextColor, borderRadius: BorderRadius.circular(10),
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(),
), ),
const SizedBox(width: 5), ),
], AppBar(
), leadingWidth: double.infinity,
Expanded( leading: tabbar,
child: TabBarView( backgroundColor: Colors.transparent,
children: [ automaticallyImplyLeading: false,
SyncedLyrics(palette: palette, isModal: isModal), actions: [
PlainLyrics(palette: palette, isModal: isModal), 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),
],
),
),
],
),
), ),
), ),
), ),

View File

@ -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/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/services/sourced_track/enums.dart'; import 'package:spotube/services/sourced_track/enums.dart';
import 'package:spotube/utils/platform.dart';
class SettingsPlaybackSection extends HookConsumerWidget { class SettingsPlaybackSection extends HookConsumerWidget {
const SettingsPlaybackSection({super.key}); const SettingsPlaybackSection({super.key});
@ -242,22 +243,24 @@ class SettingsPlaybackSection extends HookConsumerWidget {
), ),
SwitchListTile( SwitchListTile(
title: Text(context.l10n.cache_music), title: Text(context.l10n.cache_music),
subtitle: Text.rich( subtitle: kIsMobile
TextSpan( ? null
children: [ : Text.rich(
TextSpan(text: "${context.l10n.open} "), TextSpan(
TextSpan( children: [
text: context.l10n.cache_folder.toLowerCase(), TextSpan(text: "${context.l10n.open} "),
recognizer: TapGestureRecognizer() TextSpan(
..onTap = preferencesNotifier.openCacheFolder, text: context.l10n.cache_folder.toLowerCase(),
style: theme.textTheme.bodyMedium?.copyWith( recognizer: TapGestureRecognizer()
color: theme.colorScheme.primary, ..onTap = preferencesNotifier.openCacheFolder,
decoration: TextDecoration.underline, style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.primary,
decoration: TextDecoration.underline,
),
)
],
), ),
) ),
],
),
),
secondary: const Icon(SpotubeIcons.cache), secondary: const Icon(SpotubeIcons.cache),
value: preferences.cacheMusic, value: preferences.cacheMusic,
onChanged: preferencesNotifier.setCacheMusic, onChanged: preferencesNotifier.setCacheMusic,

View File

@ -2,7 +2,7 @@ import 'package:drift/drift.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:path/path.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:spotify/spotify.dart';
import 'package:spotube/models/database/database.dart'; import 'package:spotube/models/database/database.dart';
import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart';
@ -72,10 +72,10 @@ class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
if (kIsMacOS) { 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"); return join(dir!.path, "Spotube");
}); });
} }
@ -96,14 +96,28 @@ class UserPreferencesNotifier extends Notifier<PreferencesTableData> {
await query.replace(PreferencesTableCompanion.insert()); await query.replace(PreferencesTableCompanion.insert());
} }
static Future<String> getMusicCacheDir() async => join( static Future<String> getMusicCacheDir() async {
await getApplicationCacheDirectory().then((value) => value.path), if (kIsAndroid) {
'cached_tracks', 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<void> openCacheFolder() async { Future<void> openCacheFolder() async {
final filePath = await getMusicCacheDir(); try {
await OpenFile.open(filePath); final filePath = await getMusicCacheDir();
await OpenFile.open(filePath);
} catch (e, stack) {
AppLogger.reportError(e, stack);
}
} }
void setStreamMusicCodec(SourceCodecs codec) { void setStreamMusicCodec(SourceCodecs codec) {