From bd090b646dc6ddbd27d2577886d7aeda75627242 Mon Sep 17 00:00:00 2001 From: Aliaksei Tratseuski Date: Sun, 16 Jun 2024 04:12:59 +0400 Subject: [PATCH] feat: reset locale to system default from language settings, removed dead code theme_picker code --- lib/config/app_controller/app_controller.dart | 56 ++++++++----------- lib/config/localization.dart | 4 ++ .../datasources/preferences_datasource.dart | 5 +- .../preferences_hive_datasource.dart | 5 +- .../inherited_preferences_repository.dart | 1 + .../preferences_repository.dart | 16 +++--- .../graphql_maps/graphql_api_map.dart | 2 +- lib/logic/get_it/api_config.dart | 11 ++-- .../more/app_settings/language_picker.dart | 41 +++++++------- .../pages/more/app_settings/theme_picker.dart | 13 ----- 10 files changed, 68 insertions(+), 86 deletions(-) diff --git a/lib/config/app_controller/app_controller.dart b/lib/config/app_controller/app_controller.dart index a14eaa19..f78bae72 100644 --- a/lib/config/app_controller/app_controller.dart +++ b/lib/config/app_controller/app_controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:material_color_utilities/material_color_utilities.dart' as color_utils; import 'package:selfprivacy/config/get_it_config.dart'; +import 'package:selfprivacy/config/localization.dart'; import 'package:selfprivacy/config/preferences_repository/preferences_repository.dart'; /// A class that many Widgets can interact with to read current app @@ -45,18 +46,10 @@ class AppController with ChangeNotifier { : darkThemeModeActive ? ThemeMode.dark : ThemeMode.light; - // // Make ThemeMode a private variable so it is not updated directly without - // // also persisting the changes with the repo.. - // late ThemeMode _themeMode; - // // Allow Widgets to read the user's preferred ThemeMode. - // ThemeMode get themeMode => _themeMode; late bool _shouldShowOnboarding; bool get shouldShowOnboarding => _shouldShowOnboarding; - /// Load the user's settings from the SettingsService. It may load from a - /// local database or the internet. The controller only knows it can load the - /// settings from the service. Future init({ // required final AppPreferencesRepository repo, required final ThemeData lightThemeData, @@ -68,12 +61,17 @@ class AppController with ChangeNotifier { await Future.wait([ // load locale () async { - _supportedLocales = await _repo.getSupportedLocales(); + _supportedLocales = [ + Localization.systemLocale, + ...await _repo.getSupportedLocales(), + ]; _locale = await _repo.getActiveLocale(); - // preset value to other state holders - await _apiConfigModel.setLocaleCode(_locale.languageCode); - await _repo.setDelegateLocale(_locale); + if (_locale != Localization.systemLocale) { + // preset value to other state holders + await _apiConfigModel.setLocaleCode(_locale.languageCode); + await _repo.setDelegateLocale(_locale); + } }(), // load theme mode && initialize theme @@ -81,7 +79,6 @@ class AppController with ChangeNotifier { _lightTheme = lightThemeData; _darkTheme = darkThemeData; _corePalette = colorPalette; - // _themeMode = await _repo.getThemeMode(); _darkThemeModeActive = await _repo.getDarkThemeModeFlag(); _systemThemeModeActive = await _repo.getSystemThemeModeFlag(); }(), @@ -98,7 +95,6 @@ class AppController with ChangeNotifier { } // updateRepoReference - Future setShouldShowOnboarding(final bool newValue) async { // Do not perform any work if new and old flag values are identical if (newValue == shouldShowOnboarding) { @@ -107,7 +103,6 @@ class AppController with ChangeNotifier { // Store the flag in memory _shouldShowOnboarding = newValue; - notifyListeners(); // Persist the change @@ -146,23 +141,6 @@ class AppController with ChangeNotifier { await _repo.setDarkThemeModeFlag(newValue); } - // /// Update and persist the ThemeMode based on the user's selection. - // Future setThemeMode(final ThemeMode newThemeMode) async { - // // Do not perform any work if new and old ThemeMode are identical - // if (newThemeMode == themeMode) { - // return; - // } - - // // Store the new ThemeMode in memory - // _themeMode = newThemeMode; - - // // Inform listeners a change has occurred. - // notifyListeners(); - - // // Persist the change - // await _repo.setThemeMode(newThemeMode); - // } - Future setLocale(final Locale newLocale) async { // Do not perform any work if new and old Locales are identical if (newLocale == _locale) { @@ -172,6 +150,10 @@ class AppController with ChangeNotifier { // Store the new Locale in memory _locale = newLocale; + if (newLocale == Localization.systemLocale) { + return resetLocale(); + } + /// update locale delegate, which in turn should update deps await _repo.setDelegateLocale(newLocale); @@ -180,4 +162,14 @@ class AppController with ChangeNotifier { // Update other locale holders await _apiConfigModel.setLocaleCode(newLocale.languageCode); } + + Future resetLocale() async { + /// update locale delegate, which in turn should update deps + await _repo.resetDelegateLocale(); + + // Persist the change + await _repo.resetActiveLocale(); + // Update other locale holders + await _apiConfigModel.resetLocaleCode(); + } } diff --git a/lib/config/localization.dart b/lib/config/localization.dart index 697235b2..e5da63ad 100644 --- a/lib/config/localization.dart +++ b/lib/config/localization.dart @@ -7,6 +7,9 @@ class Localization extends StatelessWidget { super.key, }); + /// value for resetting locale in settings to system default + static const systemLocale = Locale('system'); + // when adding new locale, add corresponding native language name to mapper // below static const supportedLocales = [ @@ -34,6 +37,7 @@ class Localization extends StatelessWidget { // https://en.wikipedia.org/wiki/IETF_language_tag#List_of_common_primary_language_subtags static final _languageNames = { + systemLocale: 'System default', const Locale('ar'): 'العربية', const Locale('az'): 'Azərbaycan', const Locale('be'): 'беларуская', diff --git a/lib/config/preferences_repository/datasources/preferences_datasource.dart b/lib/config/preferences_repository/datasources/preferences_datasource.dart index 53ef8b09..8c8498dd 100644 --- a/lib/config/preferences_repository/datasources/preferences_datasource.dart +++ b/lib/config/preferences_repository/datasources/preferences_datasource.dart @@ -29,8 +29,5 @@ abstract class PreferencesDataSource { Future getLocale(); /// locale, as set by user - /// - /// - /// when null, app takes system locale - Future setLocale(final String newLocale); + Future setLocale(final String? newLocale); } diff --git a/lib/config/preferences_repository/datasources/preferences_hive_datasource.dart b/lib/config/preferences_repository/datasources/preferences_hive_datasource.dart index 80dd9f11..f4e30130 100644 --- a/lib/config/preferences_repository/datasources/preferences_hive_datasource.dart +++ b/lib/config/preferences_repository/datasources/preferences_hive_datasource.dart @@ -34,6 +34,7 @@ class PreferencesHiveDataSource implements PreferencesDataSource { Future getLocale() async => _appSettingsBox.get(BNames.appLocale); @override - Future setLocale(final String newLocale) async => - _appSettingsBox.put(BNames.appLocale, newLocale); + Future setLocale(final String? newLocale) async => newLocale == null + ? _appSettingsBox.delete(BNames.appLocale) + : _appSettingsBox.put(BNames.appLocale, newLocale); } diff --git a/lib/config/preferences_repository/inherited_preferences_repository.dart b/lib/config/preferences_repository/inherited_preferences_repository.dart index 4a2881b1..c90dc91b 100644 --- a/lib/config/preferences_repository/inherited_preferences_repository.dart +++ b/lib/config/preferences_repository/inherited_preferences_repository.dart @@ -50,6 +50,7 @@ class _InheritedPreferencesRepositoryState repo = PreferencesRepository( dataSource: widget.dataSource, setDelegateLocale: EasyLocalization.of(context)!.setLocale, + resetDelegateLocale: EasyLocalization.of(context)!.resetLocale, getDelegateLocale: () => EasyLocalization.of(context)!.locale, getSupportedLocales: () => EasyLocalization.of(context)!.supportedLocales, ); diff --git a/lib/config/preferences_repository/preferences_repository.dart b/lib/config/preferences_repository/preferences_repository.dart index b649d38a..086156e5 100644 --- a/lib/config/preferences_repository/preferences_repository.dart +++ b/lib/config/preferences_repository/preferences_repository.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:selfprivacy/config/localization.dart'; import 'package:selfprivacy/config/preferences_repository/datasources/preferences_datasource.dart'; class PreferencesRepository { @@ -9,6 +10,7 @@ class PreferencesRepository { required this.getSupportedLocales, required this.getDelegateLocale, required this.setDelegateLocale, + required this.resetDelegateLocale, }); final PreferencesDataSource dataSource; @@ -18,6 +20,7 @@ class PreferencesRepository { /// containing needed functions, but perceive it as boilerplate, because we /// don't need additional encapsulation level here) final FutureOr Function(Locale) setDelegateLocale; + final FutureOr Function() resetDelegateLocale; final FutureOr> Function() getSupportedLocales; final FutureOr Function() getDelegateLocale; @@ -36,13 +39,6 @@ class PreferencesRepository { Future setSystemModeFlag(final bool newValue) async => dataSource.setSystemThemeModeFlag(newValue); - // Future getThemeMode() async { - // final themeMode = await dataSource.getThemeMode()?? ThemeMode.system; - // } - // - // Future setThemeMode(final ThemeMode newThemeMode) => - // dataSource.setThemeMode(newThemeMode); - Future> supportedLocales() async => getSupportedLocales(); Future getActiveLocale() async { @@ -54,7 +50,7 @@ class PreferencesRepository { } // when it's null fallback on delegate locale - chosenLocale ??= await getDelegateLocale(); + chosenLocale ??= Localization.systemLocale; return chosenLocale; } @@ -63,6 +59,10 @@ class PreferencesRepository { await dataSource.setLocale(newLocale.toString()); } + Future resetActiveLocale() async { + await dataSource.setLocale(null); + } + /// true when we need to show onboarding Future getShouldShowOnboarding() async => dataSource.getOnboardingFlag(); diff --git a/lib/logic/api_maps/graphql_maps/graphql_api_map.dart b/lib/logic/api_maps/graphql_maps/graphql_api_map.dart index 6ae9fd20..d2823a56 100644 --- a/lib/logic/api_maps/graphql_maps/graphql_api_map.dart +++ b/lib/logic/api_maps/graphql_maps/graphql_api_map.dart @@ -116,7 +116,7 @@ abstract class GraphQLApiMap { ); } - String get _locale => getIt.get().localeCode ?? 'en'; + String get _locale => getIt.get().localeCode; String get _token { String token = ''; diff --git a/lib/logic/get_it/api_config.dart b/lib/logic/get_it/api_config.dart index 21f1bb17..33632f38 100644 --- a/lib/logic/get_it/api_config.dart +++ b/lib/logic/get_it/api_config.dart @@ -9,7 +9,6 @@ class ApiConfigModel { final Box _box = Hive.box(BNames.serverInstallationBox); ServerHostingDetails? get serverDetails => _serverDetails; - String? get localeCode => _localeCode; String? get serverProviderKey => _serverProviderKey; String? get serverLocation => _serverLocation; String? get serverType => _serverType; @@ -21,7 +20,12 @@ class ApiConfigModel { ServerDomain? get serverDomain => _serverDomain; BackblazeBucket? get backblazeBucket => _backblazeBucket; + static const localeCodeFallback = 'en'; String? _localeCode; + String get localeCode => _localeCode ?? localeCodeFallback; + Future setLocaleCode(final String value) async => _localeCode = value; + Future resetLocaleCode() async => _localeCode = null; + String? _serverProviderKey; String? _serverLocation; String? _dnsProviderKey; @@ -33,10 +37,6 @@ class ApiConfigModel { ServerDomain? _serverDomain; BackblazeBucket? _backblazeBucket; - Future setLocaleCode(final String value) async { - _localeCode = value; - } - Future storeServerProviderType(final ServerProviderType value) async { await _box.put(BNames.serverProvider, value); _serverProvider = value; @@ -101,7 +101,6 @@ class ApiConfigModel { } Future init() async { - _localeCode = 'en'; _serverProviderKey = _box.get(BNames.hetznerKey); _serverLocation = _box.get(BNames.serverLocation); _dnsProviderKey = _box.get(BNames.cloudFlareKey); diff --git a/lib/ui/pages/more/app_settings/language_picker.dart b/lib/ui/pages/more/app_settings/language_picker.dart index d4cb9607..ddd8dcbf 100644 --- a/lib/ui/pages/more/app_settings/language_picker.dart +++ b/lib/ui/pages/more/app_settings/language_picker.dart @@ -36,26 +36,27 @@ class _LanguagePickerDialog extends StatelessWidget { static const routeSettings = RouteSettings(name: 'LanguagePickerDialog'); @override - Widget build(final BuildContext context) => SimpleDialog( - title: Text('application_settings.language'.tr()), - children: [ - for (final locale - in InheritedAppController.of(context).supportedLocales) - RadioMenuButton( - groupValue: context.locale, - value: locale, - child: Text( - Localization.getLanguageName(locale), - style: TextStyle( - fontWeight: locale == context.locale - ? FontWeight.w800 - : FontWeight.w400, - ), + Widget build(final BuildContext context) { + final appController = InheritedAppController.of(context); + + return SimpleDialog( + title: Text('application_settings.language'.tr()), + children: [ + for (final locale in appController.supportedLocales) + RadioMenuButton( + groupValue: appController.locale, + value: locale, + child: Text( + Localization.getLanguageName(locale), + style: TextStyle( + fontWeight: locale == appController.locale + ? FontWeight.w800 + : FontWeight.w400, ), - onChanged: (final newValue) { - Navigator.of(context).pop(newValue); - }, ), - ], - ); + onChanged: (final newValue) => Navigator.of(context).pop(newValue), + ), + ], + ); + } } diff --git a/lib/ui/pages/more/app_settings/theme_picker.dart b/lib/ui/pages/more/app_settings/theme_picker.dart index 0e123045..d08371be 100644 --- a/lib/ui/pages/more/app_settings/theme_picker.dart +++ b/lib/ui/pages/more/app_settings/theme_picker.dart @@ -6,9 +6,6 @@ class _ThemePicker extends StatelessWidget { @override Widget build(final BuildContext context) { final appController = InheritedAppController.of(context); - // final themeMode = appController.themeMode; - // final bool isSystemThemeModeEnabled = themeMode == ThemeMode.system; - // final bool isDarkModeOn = themeMode == ThemeMode.dark; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -19,11 +16,6 @@ class _ThemePicker extends StatelessWidget { Text('application_settings.system_theme_mode_description'.tr()), value: appController.systemThemeModeActive, onChanged: appController.setSystemThemeModeFlag, - // onChanged: (final newValue) => appController.setThemeMode( - // newValue - // ? ThemeMode.system - // : (isDarkModeOn ? ThemeMode.dark : ThemeMode.light), - // ), ), SwitchListTile.adaptive( title: Text('application_settings.dark_theme_title'.tr()), @@ -32,11 +24,6 @@ class _ThemePicker extends StatelessWidget { onChanged: appController.systemThemeModeActive ? null : appController.setDarkThemeModeFlag, - // onChanged: isSystemThemeModeEnabled - // ? null - // : (final newValue) => appController.setThemeMode( - // newValue ? ThemeMode.dark : ThemeMode.light, - // ), ), ], );