From ef79c09033bf5eedbb01ca0bec4e0345e8ff63dc Mon Sep 17 00:00:00 2001 From: Hamlet Jiang Su <30667958+hjiangsu@users.noreply.github.com> Date: Tue, 18 Feb 2025 05:51:02 -0800 Subject: [PATCH] Improve UX for toggling pure black theme (#1690) * feat: improve UX for toggling pure black theme * feat: update localization string for pure black theme --- lib/core/enums/local_settings.dart | 2 +- lib/core/theme/bloc/theme_bloc.dart | 22 +++++++++------------ lib/l10n/app_en.arb | 8 ++++---- lib/settings/pages/theme_settings_page.dart | 22 ++++++++++----------- lib/utils/preferences.dart | 8 ++++++++ 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/lib/core/enums/local_settings.dart b/lib/core/enums/local_settings.dart index c76b1fb71..c67e4ab18 100644 --- a/lib/core/enums/local_settings.dart +++ b/lib/core/enums/local_settings.dart @@ -199,7 +199,7 @@ enum LocalSettings { /// -------------------------- Theme Related Settings -------------------------- // Theme Settings appTheme(name: 'setting_theme_app_theme', key: 'theme', category: LocalSettingsCategories.theming, subCategory: LocalSettingsSubCategories.theme), - systemThemePureBlack(name: 'setting_theme_system_pure_black', key: 'systemThemePureBlack', category: LocalSettingsCategories.theming, subCategory: LocalSettingsSubCategories.theme), + usePureBlackTheme(name: 'setting_theme_system_pure_black', key: 'systemThemePureBlack', category: LocalSettingsCategories.theming, subCategory: LocalSettingsSubCategories.theme), appThemeAccentColor(name: 'setting_theme_custom_app_theme', key: 'themeAccentColor', category: LocalSettingsCategories.theming, subCategory: LocalSettingsSubCategories.theme), useMaterialYouTheme(name: 'setting_theme_use_material_you', key: 'useMaterialYouTheme', category: LocalSettingsCategories.theming, subCategory: LocalSettingsSubCategories.theme), diff --git a/lib/core/theme/bloc/theme_bloc.dart b/lib/core/theme/bloc/theme_bloc.dart index b3eee1fba..84c651148 100644 --- a/lib/core/theme/bloc/theme_bloc.dart +++ b/lib/core/theme/bloc/theme_bloc.dart @@ -35,27 +35,23 @@ class ThemeBloc extends Bloc { SharedPreferences prefs = (await UserPreferences.instance).sharedPreferences; + // Fetch the ThemeType from preferences (system, light, dark) ThemeType themeType = ThemeType.values[prefs.getInt(LocalSettings.appTheme.name) ?? ThemeType.system.index]; + Brightness brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness; + + // Check if the user has selected to use a pure black theme, if so override the themeType to pureBlack + bool usePureBlackTheme = prefs.getBool(LocalSettings.usePureBlackTheme.name) ?? false; + if (usePureBlackTheme && (themeType == ThemeType.dark || (themeType == ThemeType.system && brightness == Brightness.dark))) themeType = ThemeType.pureBlack; + + bool useDarkTheme = themeType == ThemeType.dark || themeType == ThemeType.pureBlack; + CustomThemeType selectedTheme = CustomThemeType.values.byName(prefs.getString(LocalSettings.appThemeAccentColor.name) ?? CustomThemeType.deepBlue.name); - bool useSystemThemePureBlack = prefs.getBool(LocalSettings.systemThemePureBlack.name) ?? false; bool useMaterialYouTheme = prefs.getBool(LocalSettings.useMaterialYouTheme.name) ?? false; // Fetch reduce animations preferences to remove overscrolling effects bool reduceAnimations = prefs.getBool(LocalSettings.reduceAnimations.name) ?? false; - // Check what the system theme is (light/dark) - Brightness brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness; - bool useDarkTheme = themeType != ThemeType.light; - - if (themeType == ThemeType.system) { - useDarkTheme = brightness == Brightness.dark; - } - - if (themeType == ThemeType.system && useSystemThemePureBlack && useDarkTheme) { - themeType = ThemeType.pureBlack; - } - return emit( state.copyWith( status: ThemeStatus.success, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 7b68056a5..dadd5ba1f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2435,13 +2435,13 @@ "@system": { "description": "Describes using the system settings for theme" }, - "systemDarkMode": "System Dark Mode", + "systemDarkMode": "Pure Black", "@systemDarkMode": { - "description": "Setting which toggles the dark theme type when the system theme is selected" + "description": "Setting which toggles the pure black theme type when the theme is dark" }, - "systemDarkModeDescription": "Enable pure black theme in system dark mode", + "systemDarkModeDescription": "Enable pure black theme for dark mode", "@systemDarkModeDescription": { - "description": "Toggle which enables the pure black theme when using system theme, and is using the dark mode version" + "description": "Toggle which enables the pure black theme when dark mode is selected" }, "tabletMode": "Tablet Mode (2-column view)", "@tabletMode": { diff --git a/lib/settings/pages/theme_settings_page.dart b/lib/settings/pages/theme_settings_page.dart index c9685b9e1..cca6830d2 100644 --- a/lib/settings/pages/theme_settings_page.dart +++ b/lib/settings/pages/theme_settings_page.dart @@ -38,7 +38,7 @@ class _ThemeSettingsPageState extends State { /// -------------------------- Theme Related Settings -------------------------- // Theme Settings ThemeType themeType = ThemeType.system; - bool useSystemBlackTheme = false; + bool usePureBlackTheme = false; bool useMaterialYouTheme = false; CustomThemeType selectedTheme = CustomThemeType.deepBlue; @@ -116,9 +116,9 @@ class _ThemeSettingsPageState extends State { if (context.mounted) context.read().add(ThemeChangeEvent()); Future.delayed(const Duration(milliseconds: 300), () => _initFontScaleOptions()); // Refresh the font scale options since the textTheme has most likely changed (dark -> light and vice versa) break; - case LocalSettings.systemThemePureBlack: - await prefs.setBool(LocalSettings.systemThemePureBlack.name, value); - setState(() => useSystemBlackTheme = value); + case LocalSettings.usePureBlackTheme: + await prefs.setBool(LocalSettings.usePureBlackTheme.name, value); + setState(() => usePureBlackTheme = value); if (context.mounted) context.read().add(ThemeChangeEvent()); break; case LocalSettings.appThemeAccentColor: @@ -243,7 +243,7 @@ class _ThemeSettingsPageState extends State { /// -------------------------- Theme Related Settings -------------------------- // Theme Settings themeType = ThemeType.values[prefs.getInt(LocalSettings.appTheme.name) ?? ThemeType.system.index]; - useSystemBlackTheme = prefs.getBool(LocalSettings.systemThemePureBlack.name) ?? false; + usePureBlackTheme = prefs.getBool(LocalSettings.usePureBlackTheme.name) ?? false; selectedTheme = CustomThemeType.values.byName(prefs.getString(LocalSettings.appThemeAccentColor.name) ?? CustomThemeType.deepBlue.name); useMaterialYouTheme = prefs.getBool(LocalSettings.useMaterialYouTheme.name) ?? false; @@ -306,7 +306,6 @@ class _ThemeSettingsPageState extends State { ListPickerItem(icon: Icons.phonelink_setup_rounded, label: l10n.system, payload: ThemeType.system), ListPickerItem(icon: Icons.light_mode_rounded, label: l10n.light, payload: ThemeType.light), ListPickerItem(icon: Icons.dark_mode_outlined, label: l10n.dark, payload: ThemeType.dark), - ListPickerItem(icon: Icons.dark_mode, label: l10n.pureBlack, payload: ThemeType.pureBlack) ]; WidgetsBinding.instance.addPostFrameCallback((_) => _initPreferences()); @@ -373,18 +372,17 @@ class _ThemeSettingsPageState extends State { AnimatedSize( duration: const Duration(milliseconds: 250), curve: Curves.easeInOutCubicEmphasized, - child: themeType == ThemeType.system + child: themeType == ThemeType.dark || themeType == ThemeType.system ? ToggleOption( - description: l10n.systemDarkMode, + description: l10n.pureBlack, subtitle: l10n.systemDarkModeDescription, - value: useSystemBlackTheme, + value: usePureBlackTheme, iconEnabled: Icons.dark_mode_rounded, iconDisabled: Icons.dark_mode_outlined, - onToggle: (bool value) => setPreferences(LocalSettings.systemThemePureBlack, value), + onToggle: (bool value) => setPreferences(LocalSettings.usePureBlackTheme, value), highlightKey: settingToHighlightKey, - setting: LocalSettings.systemThemePureBlack, + setting: LocalSettings.usePureBlackTheme, highlightedSetting: settingToHighlight, - disabled: themeType != ThemeType.system, ) : Container(), ), diff --git a/lib/utils/preferences.dart b/lib/utils/preferences.dart index 5a63b5694..d8a6f53a9 100644 --- a/lib/utils/preferences.dart +++ b/lib/utils/preferences.dart @@ -10,6 +10,7 @@ import 'package:thunder/community/pages/create_post_page.dart'; import 'package:thunder/core/enums/browser_mode.dart'; import 'package:thunder/core/enums/full_name.dart'; import 'package:thunder/core/enums/local_settings.dart'; +import 'package:thunder/core/enums/theme_type.dart'; import 'package:thunder/drafts/draft_type.dart'; import 'package:thunder/notification/enums/notification_type.dart'; import 'package:thunder/core/singletons/preferences.dart'; @@ -129,4 +130,11 @@ Future performSharedPreferencesMigration() async { } catch (e) { debugPrint('Cannot migrate anonymous instances from SharedPreferences: $e'); } + + // Migrate theme settings for pure black to use dark theme + pure black setting + ThemeType themeType = ThemeType.values[prefs.getInt(LocalSettings.appTheme.name) ?? ThemeType.system.index]; + if (themeType == ThemeType.pureBlack) { + await prefs.setInt(LocalSettings.appTheme.name, ThemeType.dark.index); + await prefs.setBool(LocalSettings.usePureBlackTheme.name, true); + } }