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