From 5c5dbf69ecea95c92d3c3900ad690a500d75b4e2 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 16 Sep 2023 12:35:46 +0600 Subject: [PATCH] feat: add Amoled theme #724 --- lib/collections/spotube_icons.dart | 1 + lib/l10n/app_en.arb | 3 +- lib/main.dart | 12 +++-- lib/pages/settings/settings.dart | 6 +++ lib/provider/user_preferences_provider.dart | 12 +++++ lib/services/audio_player/audio_player.dart | 8 +++- .../audio_player/mk_state_player.dart | 3 +- lib/themes/theme.dart | 4 +- untranslated_messages.json | 46 ++++++++++++++++++- 9 files changed, 86 insertions(+), 9 deletions(-) diff --git a/lib/collections/spotube_icons.dart b/lib/collections/spotube_icons.dart index 4781050dd..8a4e63da3 100644 --- a/lib/collections/spotube_icons.dart +++ b/lib/collections/spotube_icons.dart @@ -97,4 +97,5 @@ abstract class SpotubeIcons { static const user = FeatherIcons.user; static const edit = FeatherIcons.edit; static const web = FeatherIcons.globe; + static const amoled = FeatherIcons.sunset; } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index fa81450b1..860118d1a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -263,5 +263,6 @@ "connection_restored": "Your internet connection was restored", "use_system_title_bar": "Use system title bar", "crunching_results": "Crunching results...", - "search_to_get_results": "Search to get results" + "search_to_get_results": "Search to get results", + "use_amoled_dark_theme": "Use AMOLED (Pitch Black) dark theme" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index ee6fdf17b..519544ff7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -163,6 +163,8 @@ class SpotubeState extends ConsumerState { ref.watch(userPreferencesProvider.select((s) => s.themeMode)); final accentMaterialColor = ref.watch(userPreferencesProvider.select((s) => s.accentColorScheme)); + final isAmoledTheme = + ref.watch(userPreferencesProvider.select((s) => s.amoledDarkTheme)); final locale = ref.watch(userPreferencesProvider.select((s) => s.locale)); final paletteColor = ref.watch(paletteProvider.select((s) => s?.dominantColor?.color)); @@ -182,12 +184,16 @@ class SpotubeState extends ConsumerState { useDisableBatteryOptimizations(); final lightTheme = useMemoized( - () => theme(paletteColor ?? accentMaterialColor, Brightness.light), + () => theme(paletteColor ?? accentMaterialColor, Brightness.light, false), [paletteColor, accentMaterialColor], ); final darkTheme = useMemoized( - () => theme(paletteColor ?? accentMaterialColor, Brightness.dark), - [paletteColor, accentMaterialColor], + () => theme( + paletteColor ?? accentMaterialColor, + Brightness.dark, + isAmoledTheme, + ), + [paletteColor, accentMaterialColor, isAmoledTheme], ); return MaterialApp.router( diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index a6efdc8f5..e209e47b0 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -253,6 +253,12 @@ class SettingsPage extends HookConsumerWidget { } }, ), + SwitchListTile( + secondary: const Icon(SpotubeIcons.amoled), + title: Text(context.l10n.use_amoled_dark_theme), + value: preferences.amoledDarkTheme, + onChanged: preferences.setAmoledDarkTheme, + ), ListTile( leading: const Icon(SpotubeIcons.palette), title: Text(context.l10n.accent_color), diff --git a/lib/provider/user_preferences_provider.dart b/lib/provider/user_preferences_provider.dart index cedf6273c..01494f5af 100644 --- a/lib/provider/user_preferences_provider.dart +++ b/lib/provider/user_preferences_provider.dart @@ -68,6 +68,8 @@ class UserPreferences extends PersistedChangeNotifier { bool systemTitleBar; + bool amoledDarkTheme; + final Ref ref; UserPreferences( @@ -89,6 +91,7 @@ class UserPreferences extends PersistedChangeNotifier { this.skipNonMusic = true, this.youtubeApiType = YoutubeApiType.youtube, this.systemTitleBar = false, + this.amoledDarkTheme = false, }) : super() { if (downloadLocation.isEmpty && !kIsWeb) { _getDefaultDownloadDirectory().then( @@ -210,6 +213,12 @@ class UserPreferences extends PersistedChangeNotifier { updatePersistence(); } + void setAmoledDarkTheme(bool isAmoled) { + amoledDarkTheme = isAmoled; + notifyListeners(); + updatePersistence(); + } + Future _getDefaultDownloadDirectory() async { if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; @@ -274,6 +283,8 @@ class UserPreferences extends PersistedChangeNotifier { systemTitleBar = map["systemTitleBar"] ?? systemTitleBar; // updates the title bar setSystemTitleBar(systemTitleBar); + + amoledDarkTheme = map["amoledDarkTheme"] ?? amoledDarkTheme; } @override @@ -297,6 +308,7 @@ class UserPreferences extends PersistedChangeNotifier { "skipNonMusic": skipNonMusic, "youtubeApiType": youtubeApiType.name, 'systemTitleBar': systemTitleBar, + "amoledDarkTheme": amoledDarkTheme, }; } diff --git a/lib/services/audio_player/audio_player.dart b/lib/services/audio_player/audio_player.dart index f468e87a6..78dc149b4 100644 --- a/lib/services/audio_player/audio_player.dart +++ b/lib/services/audio_player/audio_player.dart @@ -16,8 +16,12 @@ abstract class AudioPlayerInterface { final MkPlayerWithState _mkPlayer; // final ja.AudioPlayer? _justAudio; - AudioPlayerInterface() : _mkPlayer = MkPlayerWithState() - // _mkPlayer = _mkSupportedPlatform ? MkPlayerWithState() : null, + AudioPlayerInterface() + : _mkPlayer = MkPlayerWithState( + configuration: const mk.PlayerConfiguration( + title: "Spotube", + ), + ) // _justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null { _mkPlayer.stream.error.listen((event) { diff --git a/lib/services/audio_player/mk_state_player.dart b/lib/services/audio_player/mk_state_player.dart index 945b2ce07..aeb59e597 100644 --- a/lib/services/audio_player/mk_state_player.dart +++ b/lib/services/audio_player/mk_state_player.dart @@ -4,7 +4,6 @@ import 'package:catcher/catcher.dart'; import 'package:collection/collection.dart'; import 'package:media_kit/media_kit.dart'; // ignore: implementation_imports -import 'package:media_kit/src/models/playable.dart'; import 'package:spotube/services/audio_player/playback_state.dart'; /// MediaKit [Player] by default doesn't have a state stream. @@ -124,7 +123,9 @@ class MkPlayerWithState extends Player { _loopModeStream.add(playlistMode); } + @override Future stop() async { + await super.stop(); await pause(); await seek(Duration.zero); diff --git a/lib/themes/theme.dart b/lib/themes/theme.dart index e11f0cc20..57a0beb68 100644 --- a/lib/themes/theme.dart +++ b/lib/themes/theme.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; -ThemeData theme(Color seed, Brightness brightness) { +ThemeData theme(Color seed, Brightness brightness, bool isAmoled) { final scheme = ColorScheme.fromSeed( seedColor: seed, shadow: Colors.black12, + background: isAmoled ? Colors.black : null, + surface: isAmoled ? Colors.black : null, brightness: brightness, ); return ThemeData( diff --git a/untranslated_messages.json b/untranslated_messages.json index 9e26dfeeb..f1a9cb16c 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1 +1,45 @@ -{} \ No newline at end of file +{ + "bn": [ + "use_amoled_dark_theme" + ], + + "ca": [ + "use_amoled_dark_theme" + ], + + "de": [ + "use_amoled_dark_theme" + ], + + "es": [ + "use_amoled_dark_theme" + ], + + "fr": [ + "use_amoled_dark_theme" + ], + + "hi": [ + "use_amoled_dark_theme" + ], + + "ja": [ + "use_amoled_dark_theme" + ], + + "pl": [ + "use_amoled_dark_theme" + ], + + "pt": [ + "use_amoled_dark_theme" + ], + + "ru": [ + "use_amoled_dark_theme" + ], + + "zh": [ + "use_amoled_dark_theme" + ] +}