mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
fix: changed settings are not persisting after force stop #821
This commit is contained in:
parent
694ddf07a3
commit
e29a38dfa4
@ -49,6 +49,7 @@ class ColorSchemePickerDialog extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
final scheme = preferences.accentColorScheme;
|
||||
final active = useState<String>(colorsMap.firstWhere(
|
||||
(element) {
|
||||
@ -57,7 +58,7 @@ class ColorSchemePickerDialog extends HookConsumerWidget {
|
||||
).name);
|
||||
|
||||
onOk() {
|
||||
preferences.setAccentColorScheme(
|
||||
preferencesNotifier.setAccentColorScheme(
|
||||
colorsMap.firstWhere(
|
||||
(element) {
|
||||
return element.name == active.value;
|
||||
|
@ -16,6 +16,7 @@ class SettingsAboutSection extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
|
||||
return SectionCardWithHeading(
|
||||
heading: context.l10n.about,
|
||||
@ -68,7 +69,7 @@ class SettingsAboutSection extends HookConsumerWidget {
|
||||
secondary: const Icon(SpotubeIcons.update),
|
||||
title: Text(context.l10n.check_for_updates),
|
||||
value: preferences.checkUpdate,
|
||||
onChanged: (checked) => preferences.setCheckUpdate(checked),
|
||||
onChanged: (checked) => preferencesNotifier.setCheckUpdate(checked),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(SpotubeIcons.info),
|
||||
|
@ -15,6 +15,7 @@ class SettingsAppearanceSection extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
final pickColorScheme = useCallback(() {
|
||||
return () => showDialog(
|
||||
context: context,
|
||||
@ -33,7 +34,7 @@ class SettingsAppearanceSection extends HookConsumerWidget {
|
||||
value: preferences.layoutMode,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setLayoutMode(value);
|
||||
preferencesNotifier.setLayoutMode(value);
|
||||
}
|
||||
},
|
||||
options: [
|
||||
@ -71,7 +72,7 @@ class SettingsAppearanceSection extends HookConsumerWidget {
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setThemeMode(value);
|
||||
preferencesNotifier.setThemeMode(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -80,7 +81,7 @@ class SettingsAppearanceSection extends HookConsumerWidget {
|
||||
title: Text(context.l10n.use_amoled_mode),
|
||||
subtitle: Text(context.l10n.pitch_dark_theme),
|
||||
value: preferences.amoledDarkTheme,
|
||||
onChanged: preferences.setAmoledDarkTheme,
|
||||
onChanged: preferencesNotifier.setAmoledDarkTheme,
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(SpotubeIcons.palette),
|
||||
@ -101,7 +102,7 @@ class SettingsAppearanceSection extends HookConsumerWidget {
|
||||
title: Text(context.l10n.sync_album_color),
|
||||
subtitle: Text(context.l10n.sync_album_color_description),
|
||||
value: preferences.albumColorSync,
|
||||
onChanged: preferences.setAlbumColorSync,
|
||||
onChanged: preferencesNotifier.setAlbumColorSync,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -12,6 +12,7 @@ class SettingsDesktopSection extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
|
||||
return SectionCardWithHeading(
|
||||
heading: context.l10n.desktop,
|
||||
@ -32,7 +33,7 @@ class SettingsDesktopSection extends HookConsumerWidget {
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setCloseBehavior(value);
|
||||
preferencesNotifier.setCloseBehavior(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -40,13 +41,13 @@ class SettingsDesktopSection extends HookConsumerWidget {
|
||||
secondary: const Icon(SpotubeIcons.tray),
|
||||
title: Text(context.l10n.show_tray_icon),
|
||||
value: preferences.showSystemTrayIcon,
|
||||
onChanged: preferences.setShowSystemTrayIcon,
|
||||
onChanged: preferencesNotifier.setShowSystemTrayIcon,
|
||||
),
|
||||
SwitchListTile(
|
||||
secondary: const Icon(SpotubeIcons.window),
|
||||
title: Text(context.l10n.use_system_title_bar),
|
||||
value: preferences.systemTitleBar,
|
||||
onChanged: preferences.setSystemTitleBar,
|
||||
onChanged: preferencesNotifier.setSystemTitleBar,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -14,6 +14,7 @@ class SettingsDownloadsSection extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
|
||||
final pickDownloadLocation = useCallback(() async {
|
||||
@ -22,13 +23,13 @@ class SettingsDownloadsSection extends HookConsumerWidget {
|
||||
initialDirectory: preferences.downloadLocation,
|
||||
);
|
||||
if (dirStr == null) return;
|
||||
preferences.setDownloadLocation(dirStr);
|
||||
preferencesNotifier.setDownloadLocation(dirStr);
|
||||
} else {
|
||||
String? dirStr = await getDirectoryPath(
|
||||
initialDirectory: preferences.downloadLocation,
|
||||
);
|
||||
if (dirStr == null) return;
|
||||
preferences.setDownloadLocation(dirStr);
|
||||
preferencesNotifier.setDownloadLocation(dirStr);
|
||||
}
|
||||
}, [preferences.downloadLocation]);
|
||||
|
||||
|
@ -17,6 +17,7 @@ class SettingsLanguageRegionSection extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
|
||||
return SectionCardWithHeading(
|
||||
@ -26,7 +27,7 @@ class SettingsLanguageRegionSection extends HookConsumerWidget {
|
||||
value: preferences.locale,
|
||||
onChanged: (locale) {
|
||||
if (locale == null) return;
|
||||
preferences.setLocale(locale);
|
||||
preferencesNotifier.setLocale(locale);
|
||||
},
|
||||
title: Text(context.l10n.language),
|
||||
secondary: const Icon(SpotubeIcons.language),
|
||||
@ -57,7 +58,7 @@ class SettingsLanguageRegionSection extends HookConsumerWidget {
|
||||
value: preferences.recommendationMarket,
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
preferences.setRecommendationMarket(value);
|
||||
preferencesNotifier.setRecommendationMarket(value);
|
||||
},
|
||||
options: spotifyMarkets
|
||||
.map(
|
||||
|
@ -18,6 +18,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return SectionCardWithHeading(
|
||||
@ -39,7 +40,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setAudioQuality(value);
|
||||
preferencesNotifier.setAudioQuality(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -55,7 +56,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
preferences.setYoutubeApiType(value);
|
||||
preferencesNotifier.setYoutubeApiType(value);
|
||||
},
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
@ -113,7 +114,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setPipedInstance(value);
|
||||
preferencesNotifier.setPipedInstance(value);
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -141,7 +142,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
preferences.setSearchMode(value);
|
||||
preferencesNotifier.setSearchMode(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -155,7 +156,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
title: Text(context.l10n.skip_non_music),
|
||||
value: preferences.skipNonMusic,
|
||||
onChanged: (state) {
|
||||
preferences.setSkipNonMusic(state);
|
||||
preferencesNotifier.setSkipNonMusic(state);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -172,7 +173,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
secondary: const Icon(SpotubeIcons.normalize),
|
||||
title: Text(context.l10n.normalize_audio),
|
||||
value: preferences.normalizeAudio,
|
||||
onChanged: preferences.setNormalizeAudio,
|
||||
onChanged: preferencesNotifier.setNormalizeAudio,
|
||||
),
|
||||
AdaptiveSelectTile<MusicCodec>(
|
||||
secondary: const Icon(SpotubeIcons.stream),
|
||||
@ -190,7 +191,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
preferences.setStreamMusicCodec(value);
|
||||
preferencesNotifier.setStreamMusicCodec(value);
|
||||
},
|
||||
),
|
||||
AdaptiveSelectTile<MusicCodec>(
|
||||
@ -209,7 +210,7 @@ class SettingsPlaybackSection extends HookConsumerWidget {
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
preferences.setDownloadMusicCodec(value);
|
||||
preferencesNotifier.setDownloadMusicCodec(value);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -20,7 +20,7 @@ class SettingsPage extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final preferencesNotifier = ref.watch(userPreferencesProvider.notifier);
|
||||
|
||||
return SafeArea(
|
||||
bottom: false,
|
||||
@ -49,7 +49,7 @@ class SettingsPage extends HookConsumerWidget {
|
||||
const SettingsAboutSection(),
|
||||
Center(
|
||||
child: FilledButton(
|
||||
onPressed: preferences.reset,
|
||||
onPressed: preferencesNotifier.reset,
|
||||
child: Text(context.l10n.restore_defaults),
|
||||
),
|
||||
),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@ -13,7 +12,7 @@ import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
|
||||
import 'package:spotube/services/audio_player/audio_player.dart';
|
||||
|
||||
import 'package:spotube/utils/persisted_change_notifier.dart';
|
||||
import 'package:spotube/utils/persisted_state_notifier.dart';
|
||||
import 'package:spotube/utils/platform.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
@ -48,220 +47,103 @@ enum MusicCodec {
|
||||
const MusicCodec._(this.label);
|
||||
}
|
||||
|
||||
class UserPreferences extends PersistedChangeNotifier {
|
||||
AudioQuality audioQuality;
|
||||
bool albumColorSync;
|
||||
bool amoledDarkTheme;
|
||||
bool checkUpdate;
|
||||
bool normalizeAudio;
|
||||
bool showSystemTrayIcon;
|
||||
bool skipNonMusic;
|
||||
bool systemTitleBar;
|
||||
CloseBehavior closeBehavior;
|
||||
late SpotubeColor accentColorScheme;
|
||||
LayoutMode layoutMode;
|
||||
Locale locale;
|
||||
Market recommendationMarket;
|
||||
SearchMode searchMode;
|
||||
class UserPreferences {
|
||||
final AudioQuality audioQuality;
|
||||
final bool albumColorSync;
|
||||
final bool amoledDarkTheme;
|
||||
final bool checkUpdate;
|
||||
final bool normalizeAudio;
|
||||
final bool showSystemTrayIcon;
|
||||
final bool skipNonMusic;
|
||||
final bool systemTitleBar;
|
||||
final CloseBehavior closeBehavior;
|
||||
final SpotubeColor accentColorScheme;
|
||||
final LayoutMode layoutMode;
|
||||
final Locale locale;
|
||||
final Market recommendationMarket;
|
||||
final SearchMode searchMode;
|
||||
String downloadLocation;
|
||||
String pipedInstance;
|
||||
ThemeMode themeMode;
|
||||
YoutubeApiType youtubeApiType;
|
||||
MusicCodec streamMusicCodec;
|
||||
MusicCodec downloadMusicCodec;
|
||||
final String pipedInstance;
|
||||
final ThemeMode themeMode;
|
||||
final YoutubeApiType youtubeApiType;
|
||||
final MusicCodec streamMusicCodec;
|
||||
final MusicCodec downloadMusicCodec;
|
||||
|
||||
final Ref ref;
|
||||
|
||||
UserPreferences(
|
||||
this.ref, {
|
||||
this.recommendationMarket = Market.US,
|
||||
this.themeMode = ThemeMode.system,
|
||||
this.layoutMode = LayoutMode.adaptive,
|
||||
this.albumColorSync = true,
|
||||
this.checkUpdate = true,
|
||||
this.audioQuality = AudioQuality.high,
|
||||
this.downloadLocation = "",
|
||||
this.closeBehavior = CloseBehavior.close,
|
||||
this.showSystemTrayIcon = true,
|
||||
this.locale = const Locale("system", "system"),
|
||||
this.pipedInstance = "https://pipedapi.kavin.rocks",
|
||||
this.searchMode = SearchMode.youtube,
|
||||
this.skipNonMusic = true,
|
||||
this.youtubeApiType = YoutubeApiType.youtube,
|
||||
this.systemTitleBar = false,
|
||||
this.amoledDarkTheme = false,
|
||||
this.normalizeAudio = true,
|
||||
this.streamMusicCodec = MusicCodec.weba,
|
||||
this.downloadMusicCodec = MusicCodec.m4a,
|
||||
SpotubeColor? accentColorScheme,
|
||||
}) : super() {
|
||||
this.accentColorScheme =
|
||||
accentColorScheme ?? SpotubeColor(Colors.blue.value, name: "Blue");
|
||||
if (downloadLocation.isEmpty && !kIsWeb) {
|
||||
UserPreferences({
|
||||
required AudioQuality? audioQuality,
|
||||
required bool? albumColorSync,
|
||||
required bool? amoledDarkTheme,
|
||||
required bool? checkUpdate,
|
||||
required bool? normalizeAudio,
|
||||
required bool? showSystemTrayIcon,
|
||||
required bool? skipNonMusic,
|
||||
required bool? systemTitleBar,
|
||||
required CloseBehavior? closeBehavior,
|
||||
required SpotubeColor? accentColorScheme,
|
||||
required LayoutMode? layoutMode,
|
||||
required Locale? locale,
|
||||
required Market? recommendationMarket,
|
||||
required SearchMode? searchMode,
|
||||
required String? downloadLocation,
|
||||
required String? pipedInstance,
|
||||
required ThemeMode? themeMode,
|
||||
required YoutubeApiType? youtubeApiType,
|
||||
required MusicCodec? streamMusicCodec,
|
||||
required MusicCodec? downloadMusicCodec,
|
||||
}) : accentColorScheme =
|
||||
accentColorScheme ?? const SpotubeColor(0xFF2196F3, name: "Blue"),
|
||||
albumColorSync = albumColorSync ?? true,
|
||||
amoledDarkTheme = amoledDarkTheme ?? false,
|
||||
audioQuality = audioQuality ?? AudioQuality.high,
|
||||
checkUpdate = checkUpdate ?? true,
|
||||
closeBehavior = closeBehavior ?? CloseBehavior.close,
|
||||
downloadLocation = downloadLocation ?? "",
|
||||
downloadMusicCodec = downloadMusicCodec ?? MusicCodec.m4a,
|
||||
layoutMode = layoutMode ?? LayoutMode.adaptive,
|
||||
locale = locale ?? const Locale("system", "system"),
|
||||
normalizeAudio = normalizeAudio ?? true,
|
||||
pipedInstance = pipedInstance ?? "https://pipedapi.kavin.rocks",
|
||||
recommendationMarket = recommendationMarket ?? Market.US,
|
||||
searchMode = searchMode ?? SearchMode.youtube,
|
||||
showSystemTrayIcon = showSystemTrayIcon ?? true,
|
||||
skipNonMusic = skipNonMusic ?? true,
|
||||
streamMusicCodec = streamMusicCodec ?? MusicCodec.weba,
|
||||
systemTitleBar = systemTitleBar ?? false,
|
||||
themeMode = themeMode ?? ThemeMode.system,
|
||||
youtubeApiType = youtubeApiType ?? YoutubeApiType.youtube {
|
||||
if (downloadLocation == null) {
|
||||
_getDefaultDownloadDirectory().then(
|
||||
(value) {
|
||||
downloadLocation = value;
|
||||
},
|
||||
(value) => this.downloadLocation = value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
setRecommendationMarket(Market.US);
|
||||
setThemeMode(ThemeMode.system);
|
||||
setLayoutMode(LayoutMode.adaptive);
|
||||
setAlbumColorSync(true);
|
||||
setCheckUpdate(true);
|
||||
setAudioQuality(AudioQuality.high);
|
||||
setDownloadLocation("");
|
||||
setCloseBehavior(CloseBehavior.close);
|
||||
setShowSystemTrayIcon(true);
|
||||
setLocale(const Locale("system", "system"));
|
||||
setPipedInstance("https://pipedapi.kavin.rocks");
|
||||
setSearchMode(SearchMode.youtube);
|
||||
setSkipNonMusic(true);
|
||||
setYoutubeApiType(YoutubeApiType.youtube);
|
||||
setSystemTitleBar(false);
|
||||
setAmoledDarkTheme(false);
|
||||
setNormalizeAudio(true);
|
||||
setAccentColorScheme(SpotubeColor(Colors.blue.value, name: "Blue"));
|
||||
setStreamMusicCodec(MusicCodec.weba);
|
||||
setDownloadMusicCodec(MusicCodec.m4a);
|
||||
factory UserPreferences.withDefaults() {
|
||||
return UserPreferences(
|
||||
audioQuality: null,
|
||||
albumColorSync: null,
|
||||
amoledDarkTheme: null,
|
||||
checkUpdate: null,
|
||||
normalizeAudio: null,
|
||||
showSystemTrayIcon: null,
|
||||
skipNonMusic: null,
|
||||
systemTitleBar: null,
|
||||
closeBehavior: null,
|
||||
accentColorScheme: null,
|
||||
layoutMode: null,
|
||||
locale: null,
|
||||
recommendationMarket: null,
|
||||
searchMode: null,
|
||||
downloadLocation: null,
|
||||
pipedInstance: null,
|
||||
themeMode: null,
|
||||
youtubeApiType: null,
|
||||
streamMusicCodec: null,
|
||||
downloadMusicCodec: null,
|
||||
);
|
||||
}
|
||||
|
||||
void setStreamMusicCodec(MusicCodec codec) {
|
||||
streamMusicCodec = codec;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setDownloadMusicCodec(MusicCodec codec) {
|
||||
downloadMusicCodec = codec;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setThemeMode(ThemeMode mode) {
|
||||
themeMode = mode;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setRecommendationMarket(Market country) {
|
||||
recommendationMarket = country;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAccentColorScheme(SpotubeColor color) {
|
||||
accentColorScheme = color;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAlbumColorSync(bool sync) {
|
||||
albumColorSync = sync;
|
||||
if (!sync) {
|
||||
ref.read(paletteProvider.notifier).state = null;
|
||||
} else {
|
||||
ref.read(ProxyPlaylistNotifier.notifier).updatePalette();
|
||||
}
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setCheckUpdate(bool check) {
|
||||
checkUpdate = check;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAudioQuality(AudioQuality quality) {
|
||||
audioQuality = quality;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setDownloadLocation(String downloadDir) {
|
||||
if (downloadDir.isEmpty) return;
|
||||
downloadLocation = downloadDir;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setLayoutMode(LayoutMode mode) {
|
||||
layoutMode = mode;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setCloseBehavior(CloseBehavior behavior) {
|
||||
closeBehavior = behavior;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setShowSystemTrayIcon(bool show) {
|
||||
showSystemTrayIcon = show;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setPipedInstance(String instance) {
|
||||
pipedInstance = instance;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setSearchMode(SearchMode mode) {
|
||||
searchMode = mode;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setSkipNonMusic(bool skip) {
|
||||
skipNonMusic = skip;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setYoutubeApiType(YoutubeApiType type) {
|
||||
youtubeApiType = type;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setSystemTitleBar(bool isSystemTitleBar) {
|
||||
systemTitleBar = isSystemTitleBar;
|
||||
if (DesktopTools.platform.isDesktop) {
|
||||
DesktopTools.window.setTitleBarStyle(
|
||||
systemTitleBar ? TitleBarStyle.normal : TitleBarStyle.hidden,
|
||||
);
|
||||
}
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAmoledDarkTheme(bool isAmoled) {
|
||||
amoledDarkTheme = isAmoled;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setNormalizeAudio(bool normalize) {
|
||||
normalizeAudio = normalize;
|
||||
audioPlayer.setAudioNormalization(normalize);
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
Future<String> _getDefaultDownloadDirectory() async {
|
||||
static Future<String> _getDefaultDownloadDirectory() async {
|
||||
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
||||
|
||||
if (kIsMacOS) {
|
||||
@ -273,102 +155,71 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> loadFromLocal(Map<String, dynamic> map) async {
|
||||
recommendationMarket = Market.values.firstWhere(
|
||||
(market) =>
|
||||
market.name == (map["recommendationMarket"] ?? recommendationMarket),
|
||||
orElse: () => Market.US,
|
||||
);
|
||||
checkUpdate = map["checkUpdate"] ?? checkUpdate;
|
||||
static Future<UserPreferences> fromJson(Map<String, dynamic> json) async {
|
||||
final localeMap =
|
||||
json["locale"] != null ? jsonDecode(json["locale"]) : null;
|
||||
|
||||
themeMode = ThemeMode.values[map["themeMode"] ?? 0];
|
||||
accentColorScheme = map["accentColorScheme"] != null
|
||||
? SpotubeColor.fromString(map["accentColorScheme"])
|
||||
: accentColorScheme;
|
||||
albumColorSync = map["albumColorSync"] ?? albumColorSync;
|
||||
audioQuality = map["audioQuality"] != null
|
||||
? AudioQuality.values[map["audioQuality"]]
|
||||
: audioQuality;
|
||||
|
||||
if (!kIsWeb) {
|
||||
downloadLocation =
|
||||
map["downloadLocation"] ?? await _getDefaultDownloadDirectory();
|
||||
final systemTitleBar = json["systemTitleBar"] ?? false;
|
||||
if (DesktopTools.platform.isDesktop) {
|
||||
await DesktopTools.window.setTitleBarStyle(
|
||||
systemTitleBar ? TitleBarStyle.normal : TitleBarStyle.hidden,
|
||||
);
|
||||
}
|
||||
|
||||
layoutMode = LayoutMode.values.firstWhere(
|
||||
(mode) => mode.name == map["layoutMode"],
|
||||
orElse: () => kIsDesktop ? LayoutMode.extended : LayoutMode.compact,
|
||||
);
|
||||
|
||||
closeBehavior = map["closeBehavior"] != null
|
||||
? CloseBehavior.values[map["closeBehavior"]]
|
||||
: closeBehavior;
|
||||
|
||||
showSystemTrayIcon = map["showSystemTrayIcon"] ?? showSystemTrayIcon;
|
||||
|
||||
final localeMap = map["locale"] != null ? jsonDecode(map["locale"]) : null;
|
||||
locale =
|
||||
localeMap != null ? Locale(localeMap?["lc"], localeMap?["cc"]) : locale;
|
||||
|
||||
pipedInstance = map["pipedInstance"] ?? pipedInstance;
|
||||
|
||||
searchMode = SearchMode.values.firstWhere(
|
||||
(mode) => mode.name == map["searchMode"],
|
||||
orElse: () => SearchMode.youtube,
|
||||
);
|
||||
|
||||
skipNonMusic = map["skipNonMusic"] ?? skipNonMusic;
|
||||
|
||||
youtubeApiType = YoutubeApiType.values.firstWhere(
|
||||
(type) => type.name == map["youtubeApiType"],
|
||||
orElse: () => YoutubeApiType.youtube,
|
||||
);
|
||||
|
||||
systemTitleBar = map["systemTitleBar"] ?? systemTitleBar;
|
||||
// updates the title bar
|
||||
setSystemTitleBar(systemTitleBar);
|
||||
|
||||
amoledDarkTheme = map["amoledDarkTheme"] ?? amoledDarkTheme;
|
||||
|
||||
normalizeAudio = map["normalizeAudio"] ?? normalizeAudio;
|
||||
final normalizeAudio = json["normalizeAudio"] ?? true;
|
||||
audioPlayer.setAudioNormalization(normalizeAudio);
|
||||
|
||||
streamMusicCodec = MusicCodec.values.firstWhere(
|
||||
(codec) => codec.name == map["streamMusicCodec"],
|
||||
orElse: () => MusicCodec.weba,
|
||||
);
|
||||
|
||||
downloadMusicCodec = MusicCodec.values.firstWhere(
|
||||
(codec) => codec.name == map["downloadMusicCodec"],
|
||||
orElse: () => MusicCodec.m4a,
|
||||
return UserPreferences(
|
||||
accentColorScheme: json["accentColorScheme"] == null
|
||||
? null
|
||||
: SpotubeColor.fromString(json["accentColorScheme"]),
|
||||
albumColorSync: json["albumColorSync"],
|
||||
amoledDarkTheme: json["amoledDarkTheme"],
|
||||
audioQuality: AudioQuality.values[json["audioQuality"]],
|
||||
checkUpdate: json["checkUpdate"],
|
||||
closeBehavior: CloseBehavior.values[json["closeBehavior"]],
|
||||
downloadLocation:
|
||||
json["downloadLocation"] ?? await _getDefaultDownloadDirectory(),
|
||||
downloadMusicCodec: MusicCodec.values[json["downloadMusicCodec"]],
|
||||
layoutMode: LayoutMode.values[json["layoutMode"]],
|
||||
locale:
|
||||
localeMap == null ? null : Locale(localeMap?["lc"], localeMap?["cc"]),
|
||||
normalizeAudio: json["normalizeAudio"],
|
||||
pipedInstance: json["pipedInstance"],
|
||||
recommendationMarket: Market.values[json["recommendationMarket"]],
|
||||
searchMode: SearchMode.values[json["searchMode"]],
|
||||
showSystemTrayIcon: json["showSystemTrayIcon"],
|
||||
skipNonMusic: json["skipNonMusic"],
|
||||
streamMusicCodec: MusicCodec.values[json["streamMusicCodec"]],
|
||||
systemTitleBar: json["systemTitleBar"],
|
||||
themeMode: ThemeMode.values[json["themeMode"]],
|
||||
youtubeApiType: YoutubeApiType.values[json["youtubeApiType"]],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<Map<String, dynamic>> toMap() {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"recommendationMarket": recommendationMarket.name,
|
||||
"recommendationMarket": recommendationMarket.index,
|
||||
"themeMode": themeMode.index,
|
||||
"accentColorScheme": accentColorScheme.toString(),
|
||||
"albumColorSync": albumColorSync,
|
||||
"checkUpdate": checkUpdate,
|
||||
"audioQuality": audioQuality.index,
|
||||
"downloadLocation": downloadLocation,
|
||||
"layoutMode": layoutMode.name,
|
||||
"layoutMode": layoutMode.index,
|
||||
"closeBehavior": closeBehavior.index,
|
||||
"showSystemTrayIcon": showSystemTrayIcon,
|
||||
"locale":
|
||||
jsonEncode({"lc": locale.languageCode, "cc": locale.countryCode}),
|
||||
"pipedInstance": pipedInstance,
|
||||
"searchMode": searchMode.name,
|
||||
"searchMode": searchMode.index,
|
||||
"skipNonMusic": skipNonMusic,
|
||||
"youtubeApiType": youtubeApiType.name,
|
||||
"youtubeApiType": youtubeApiType.index,
|
||||
'systemTitleBar': systemTitleBar,
|
||||
"amoledDarkTheme": amoledDarkTheme,
|
||||
"normalizeAudio": normalizeAudio,
|
||||
"streamMusicCodec": streamMusicCodec.name,
|
||||
"downloadMusicCodec": downloadMusicCodec.name,
|
||||
"streamMusicCodec": streamMusicCodec.index,
|
||||
"downloadMusicCodec": downloadMusicCodec.index,
|
||||
};
|
||||
}
|
||||
|
||||
@ -389,9 +240,13 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
YoutubeApiType? youtubeApiType,
|
||||
Market? recommendationMarket,
|
||||
bool? saveTrackLyrics,
|
||||
bool? amoledDarkTheme,
|
||||
bool? normalizeAudio,
|
||||
MusicCodec? downloadMusicCodec,
|
||||
MusicCodec? streamMusicCodec,
|
||||
bool? systemTitleBar,
|
||||
}) {
|
||||
return UserPreferences(
|
||||
ref,
|
||||
themeMode: themeMode ?? this.themeMode,
|
||||
accentColorScheme: accentColorScheme ?? this.accentColorScheme,
|
||||
albumColorSync: albumColorSync ?? this.albumColorSync,
|
||||
@ -407,10 +262,130 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
skipNonMusic: skipNonMusic ?? this.skipNonMusic,
|
||||
youtubeApiType: youtubeApiType ?? this.youtubeApiType,
|
||||
recommendationMarket: recommendationMarket ?? this.recommendationMarket,
|
||||
amoledDarkTheme: amoledDarkTheme ?? this.amoledDarkTheme,
|
||||
downloadMusicCodec: downloadMusicCodec ?? this.downloadMusicCodec,
|
||||
normalizeAudio: normalizeAudio ?? this.normalizeAudio,
|
||||
streamMusicCodec: streamMusicCodec ?? this.streamMusicCodec,
|
||||
systemTitleBar: systemTitleBar ?? this.systemTitleBar,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final userPreferencesProvider = ChangeNotifierProvider(
|
||||
(ref) => UserPreferences(ref),
|
||||
class UserPreferencesNotifier extends PersistedStateNotifier<UserPreferences> {
|
||||
final Ref ref;
|
||||
|
||||
UserPreferencesNotifier(this.ref)
|
||||
: super(UserPreferences.withDefaults(), "preferences");
|
||||
|
||||
void reset() {
|
||||
state = UserPreferences.withDefaults();
|
||||
}
|
||||
|
||||
void setStreamMusicCodec(MusicCodec codec) {
|
||||
state = state.copyWith(streamMusicCodec: codec);
|
||||
}
|
||||
|
||||
void setDownloadMusicCodec(MusicCodec codec) {
|
||||
state = state.copyWith(downloadMusicCodec: codec);
|
||||
}
|
||||
|
||||
void setThemeMode(ThemeMode mode) {
|
||||
state = state.copyWith(themeMode: mode);
|
||||
}
|
||||
|
||||
void setRecommendationMarket(Market country) {
|
||||
state = state.copyWith(recommendationMarket: country);
|
||||
}
|
||||
|
||||
void setAccentColorScheme(SpotubeColor color) {
|
||||
state = state.copyWith(accentColorScheme: color);
|
||||
}
|
||||
|
||||
void setAlbumColorSync(bool sync) {
|
||||
state = state.copyWith(albumColorSync: sync);
|
||||
|
||||
if (!sync) {
|
||||
ref.read(paletteProvider.notifier).state = null;
|
||||
} else {
|
||||
ref.read(ProxyPlaylistNotifier.notifier).updatePalette();
|
||||
}
|
||||
}
|
||||
|
||||
void setCheckUpdate(bool check) {
|
||||
state = state.copyWith(checkUpdate: check);
|
||||
}
|
||||
|
||||
void setAudioQuality(AudioQuality quality) {
|
||||
state = state.copyWith(audioQuality: quality);
|
||||
}
|
||||
|
||||
void setDownloadLocation(String downloadDir) {
|
||||
if (downloadDir.isEmpty) return;
|
||||
state = state.copyWith(downloadLocation: downloadDir);
|
||||
}
|
||||
|
||||
void setLayoutMode(LayoutMode mode) {
|
||||
state = state.copyWith(layoutMode: mode);
|
||||
}
|
||||
|
||||
void setCloseBehavior(CloseBehavior behavior) {
|
||||
state = state.copyWith(closeBehavior: behavior);
|
||||
}
|
||||
|
||||
void setShowSystemTrayIcon(bool show) {
|
||||
state = state.copyWith(showSystemTrayIcon: show);
|
||||
}
|
||||
|
||||
void setLocale(Locale locale) {
|
||||
state = state.copyWith(locale: locale);
|
||||
}
|
||||
|
||||
void setPipedInstance(String instance) {
|
||||
state = state.copyWith(pipedInstance: instance);
|
||||
}
|
||||
|
||||
void setSearchMode(SearchMode mode) {
|
||||
state = state.copyWith(searchMode: mode);
|
||||
}
|
||||
|
||||
void setSkipNonMusic(bool skip) {
|
||||
state = state.copyWith(skipNonMusic: skip);
|
||||
}
|
||||
|
||||
void setYoutubeApiType(YoutubeApiType type) {
|
||||
state = state.copyWith(youtubeApiType: type);
|
||||
}
|
||||
|
||||
void setSystemTitleBar(bool isSystemTitleBar) {
|
||||
state = state.copyWith(systemTitleBar: isSystemTitleBar);
|
||||
if (DesktopTools.platform.isDesktop) {
|
||||
DesktopTools.window.setTitleBarStyle(
|
||||
isSystemTitleBar ? TitleBarStyle.normal : TitleBarStyle.hidden,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void setAmoledDarkTheme(bool isAmoled) {
|
||||
state = state.copyWith(amoledDarkTheme: isAmoled);
|
||||
}
|
||||
|
||||
void setNormalizeAudio(bool normalize) {
|
||||
state = state.copyWith(normalizeAudio: normalize);
|
||||
audioPlayer.setAudioNormalization(normalize);
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<UserPreferences> fromJson(Map<String, dynamic> json) {
|
||||
return UserPreferences.fromJson(json);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return state.toJson();
|
||||
}
|
||||
}
|
||||
|
||||
final userPreferencesProvider =
|
||||
StateNotifierProvider<UserPreferencesNotifier, UserPreferences>(
|
||||
(ref) => UserPreferencesNotifier(ref),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user