feat: reset locale to system default from language settings, removed dead code theme_picker code

This commit is contained in:
Aliaksei Tratseuski 2024-06-16 04:12:59 +04:00
parent 38a896ec2e
commit bd090b646d
10 changed files with 68 additions and 86 deletions

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart' import 'package:material_color_utilities/material_color_utilities.dart'
as color_utils; as color_utils;
import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/config/localization.dart';
import 'package:selfprivacy/config/preferences_repository/preferences_repository.dart'; import 'package:selfprivacy/config/preferences_repository/preferences_repository.dart';
/// A class that many Widgets can interact with to read current app /// A class that many Widgets can interact with to read current app
@ -45,18 +46,10 @@ class AppController with ChangeNotifier {
: darkThemeModeActive : darkThemeModeActive
? ThemeMode.dark ? ThemeMode.dark
: ThemeMode.light; : 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; late bool _shouldShowOnboarding;
bool get shouldShowOnboarding => _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<void> init({ Future<void> init({
// required final AppPreferencesRepository repo, // required final AppPreferencesRepository repo,
required final ThemeData lightThemeData, required final ThemeData lightThemeData,
@ -68,12 +61,17 @@ class AppController with ChangeNotifier {
await Future.wait(<Future>[ await Future.wait(<Future>[
// load locale // load locale
() async { () async {
_supportedLocales = await _repo.getSupportedLocales(); _supportedLocales = [
Localization.systemLocale,
...await _repo.getSupportedLocales(),
];
_locale = await _repo.getActiveLocale(); _locale = await _repo.getActiveLocale();
// preset value to other state holders if (_locale != Localization.systemLocale) {
await _apiConfigModel.setLocaleCode(_locale.languageCode); // preset value to other state holders
await _repo.setDelegateLocale(_locale); await _apiConfigModel.setLocaleCode(_locale.languageCode);
await _repo.setDelegateLocale(_locale);
}
}(), }(),
// load theme mode && initialize theme // load theme mode && initialize theme
@ -81,7 +79,6 @@ class AppController with ChangeNotifier {
_lightTheme = lightThemeData; _lightTheme = lightThemeData;
_darkTheme = darkThemeData; _darkTheme = darkThemeData;
_corePalette = colorPalette; _corePalette = colorPalette;
// _themeMode = await _repo.getThemeMode();
_darkThemeModeActive = await _repo.getDarkThemeModeFlag(); _darkThemeModeActive = await _repo.getDarkThemeModeFlag();
_systemThemeModeActive = await _repo.getSystemThemeModeFlag(); _systemThemeModeActive = await _repo.getSystemThemeModeFlag();
}(), }(),
@ -98,7 +95,6 @@ class AppController with ChangeNotifier {
} }
// updateRepoReference // updateRepoReference
Future<void> setShouldShowOnboarding(final bool newValue) async { Future<void> setShouldShowOnboarding(final bool newValue) async {
// Do not perform any work if new and old flag values are identical // Do not perform any work if new and old flag values are identical
if (newValue == shouldShowOnboarding) { if (newValue == shouldShowOnboarding) {
@ -107,7 +103,6 @@ class AppController with ChangeNotifier {
// Store the flag in memory // Store the flag in memory
_shouldShowOnboarding = newValue; _shouldShowOnboarding = newValue;
notifyListeners(); notifyListeners();
// Persist the change // Persist the change
@ -146,23 +141,6 @@ class AppController with ChangeNotifier {
await _repo.setDarkThemeModeFlag(newValue); await _repo.setDarkThemeModeFlag(newValue);
} }
// /// Update and persist the ThemeMode based on the user's selection.
// Future<void> 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<void> setLocale(final Locale newLocale) async { Future<void> setLocale(final Locale newLocale) async {
// Do not perform any work if new and old Locales are identical // Do not perform any work if new and old Locales are identical
if (newLocale == _locale) { if (newLocale == _locale) {
@ -172,6 +150,10 @@ class AppController with ChangeNotifier {
// Store the new Locale in memory // Store the new Locale in memory
_locale = newLocale; _locale = newLocale;
if (newLocale == Localization.systemLocale) {
return resetLocale();
}
/// update locale delegate, which in turn should update deps /// update locale delegate, which in turn should update deps
await _repo.setDelegateLocale(newLocale); await _repo.setDelegateLocale(newLocale);
@ -180,4 +162,14 @@ class AppController with ChangeNotifier {
// Update other locale holders // Update other locale holders
await _apiConfigModel.setLocaleCode(newLocale.languageCode); await _apiConfigModel.setLocaleCode(newLocale.languageCode);
} }
Future<void> 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();
}
} }

View file

@ -7,6 +7,9 @@ class Localization extends StatelessWidget {
super.key, 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 // when adding new locale, add corresponding native language name to mapper
// below // below
static const supportedLocales = [ 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 // https://en.wikipedia.org/wiki/IETF_language_tag#List_of_common_primary_language_subtags
static final _languageNames = { static final _languageNames = {
systemLocale: 'System default',
const Locale('ar'): 'العربية', const Locale('ar'): 'العربية',
const Locale('az'): 'Azərbaycan', const Locale('az'): 'Azərbaycan',
const Locale('be'): 'беларуская', const Locale('be'): 'беларуская',

View file

@ -29,8 +29,5 @@ abstract class PreferencesDataSource {
Future<String?> getLocale(); Future<String?> getLocale();
/// locale, as set by user /// locale, as set by user
/// Future<void> setLocale(final String? newLocale);
///
/// when null, app takes system locale
Future<void> setLocale(final String newLocale);
} }

View file

@ -34,6 +34,7 @@ class PreferencesHiveDataSource implements PreferencesDataSource {
Future<String?> getLocale() async => _appSettingsBox.get(BNames.appLocale); Future<String?> getLocale() async => _appSettingsBox.get(BNames.appLocale);
@override @override
Future<void> setLocale(final String newLocale) async => Future<void> setLocale(final String? newLocale) async => newLocale == null
_appSettingsBox.put(BNames.appLocale, newLocale); ? _appSettingsBox.delete(BNames.appLocale)
: _appSettingsBox.put(BNames.appLocale, newLocale);
} }

View file

@ -50,6 +50,7 @@ class _InheritedPreferencesRepositoryState
repo = PreferencesRepository( repo = PreferencesRepository(
dataSource: widget.dataSource, dataSource: widget.dataSource,
setDelegateLocale: EasyLocalization.of(context)!.setLocale, setDelegateLocale: EasyLocalization.of(context)!.setLocale,
resetDelegateLocale: EasyLocalization.of(context)!.resetLocale,
getDelegateLocale: () => EasyLocalization.of(context)!.locale, getDelegateLocale: () => EasyLocalization.of(context)!.locale,
getSupportedLocales: () => EasyLocalization.of(context)!.supportedLocales, getSupportedLocales: () => EasyLocalization.of(context)!.supportedLocales,
); );

View file

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:selfprivacy/config/localization.dart';
import 'package:selfprivacy/config/preferences_repository/datasources/preferences_datasource.dart'; import 'package:selfprivacy/config/preferences_repository/datasources/preferences_datasource.dart';
class PreferencesRepository { class PreferencesRepository {
@ -9,6 +10,7 @@ class PreferencesRepository {
required this.getSupportedLocales, required this.getSupportedLocales,
required this.getDelegateLocale, required this.getDelegateLocale,
required this.setDelegateLocale, required this.setDelegateLocale,
required this.resetDelegateLocale,
}); });
final PreferencesDataSource dataSource; final PreferencesDataSource dataSource;
@ -18,6 +20,7 @@ class PreferencesRepository {
/// containing needed functions, but perceive it as boilerplate, because we /// containing needed functions, but perceive it as boilerplate, because we
/// don't need additional encapsulation level here) /// don't need additional encapsulation level here)
final FutureOr<void> Function(Locale) setDelegateLocale; final FutureOr<void> Function(Locale) setDelegateLocale;
final FutureOr<void> Function() resetDelegateLocale;
final FutureOr<List<Locale>> Function() getSupportedLocales; final FutureOr<List<Locale>> Function() getSupportedLocales;
final FutureOr<Locale> Function() getDelegateLocale; final FutureOr<Locale> Function() getDelegateLocale;
@ -36,13 +39,6 @@ class PreferencesRepository {
Future<void> setSystemModeFlag(final bool newValue) async => Future<void> setSystemModeFlag(final bool newValue) async =>
dataSource.setSystemThemeModeFlag(newValue); dataSource.setSystemThemeModeFlag(newValue);
// Future<ThemeMode> getThemeMode() async {
// final themeMode = await dataSource.getThemeMode()?? ThemeMode.system;
// }
//
// Future<void> setThemeMode(final ThemeMode newThemeMode) =>
// dataSource.setThemeMode(newThemeMode);
Future<List<Locale>> supportedLocales() async => getSupportedLocales(); Future<List<Locale>> supportedLocales() async => getSupportedLocales();
Future<Locale> getActiveLocale() async { Future<Locale> getActiveLocale() async {
@ -54,7 +50,7 @@ class PreferencesRepository {
} }
// when it's null fallback on delegate locale // when it's null fallback on delegate locale
chosenLocale ??= await getDelegateLocale(); chosenLocale ??= Localization.systemLocale;
return chosenLocale; return chosenLocale;
} }
@ -63,6 +59,10 @@ class PreferencesRepository {
await dataSource.setLocale(newLocale.toString()); await dataSource.setLocale(newLocale.toString());
} }
Future<void> resetActiveLocale() async {
await dataSource.setLocale(null);
}
/// true when we need to show onboarding /// true when we need to show onboarding
Future<bool> getShouldShowOnboarding() async => Future<bool> getShouldShowOnboarding() async =>
dataSource.getOnboardingFlag(); dataSource.getOnboardingFlag();

View file

@ -116,7 +116,7 @@ abstract class GraphQLApiMap {
); );
} }
String get _locale => getIt.get<ApiConfigModel>().localeCode ?? 'en'; String get _locale => getIt.get<ApiConfigModel>().localeCode;
String get _token { String get _token {
String token = ''; String token = '';

View file

@ -9,7 +9,6 @@ class ApiConfigModel {
final Box _box = Hive.box(BNames.serverInstallationBox); final Box _box = Hive.box(BNames.serverInstallationBox);
ServerHostingDetails? get serverDetails => _serverDetails; ServerHostingDetails? get serverDetails => _serverDetails;
String? get localeCode => _localeCode;
String? get serverProviderKey => _serverProviderKey; String? get serverProviderKey => _serverProviderKey;
String? get serverLocation => _serverLocation; String? get serverLocation => _serverLocation;
String? get serverType => _serverType; String? get serverType => _serverType;
@ -21,7 +20,12 @@ class ApiConfigModel {
ServerDomain? get serverDomain => _serverDomain; ServerDomain? get serverDomain => _serverDomain;
BackblazeBucket? get backblazeBucket => _backblazeBucket; BackblazeBucket? get backblazeBucket => _backblazeBucket;
static const localeCodeFallback = 'en';
String? _localeCode; String? _localeCode;
String get localeCode => _localeCode ?? localeCodeFallback;
Future<void> setLocaleCode(final String value) async => _localeCode = value;
Future<void> resetLocaleCode() async => _localeCode = null;
String? _serverProviderKey; String? _serverProviderKey;
String? _serverLocation; String? _serverLocation;
String? _dnsProviderKey; String? _dnsProviderKey;
@ -33,10 +37,6 @@ class ApiConfigModel {
ServerDomain? _serverDomain; ServerDomain? _serverDomain;
BackblazeBucket? _backblazeBucket; BackblazeBucket? _backblazeBucket;
Future<void> setLocaleCode(final String value) async {
_localeCode = value;
}
Future<void> storeServerProviderType(final ServerProviderType value) async { Future<void> storeServerProviderType(final ServerProviderType value) async {
await _box.put(BNames.serverProvider, value); await _box.put(BNames.serverProvider, value);
_serverProvider = value; _serverProvider = value;
@ -101,7 +101,6 @@ class ApiConfigModel {
} }
Future<void> init() async { Future<void> init() async {
_localeCode = 'en';
_serverProviderKey = _box.get(BNames.hetznerKey); _serverProviderKey = _box.get(BNames.hetznerKey);
_serverLocation = _box.get(BNames.serverLocation); _serverLocation = _box.get(BNames.serverLocation);
_dnsProviderKey = _box.get(BNames.cloudFlareKey); _dnsProviderKey = _box.get(BNames.cloudFlareKey);

View file

@ -36,26 +36,27 @@ class _LanguagePickerDialog extends StatelessWidget {
static const routeSettings = RouteSettings(name: 'LanguagePickerDialog'); static const routeSettings = RouteSettings(name: 'LanguagePickerDialog');
@override @override
Widget build(final BuildContext context) => SimpleDialog( Widget build(final BuildContext context) {
title: Text('application_settings.language'.tr()), final appController = InheritedAppController.of(context);
children: [
for (final locale return SimpleDialog(
in InheritedAppController.of(context).supportedLocales) title: Text('application_settings.language'.tr()),
RadioMenuButton( children: [
groupValue: context.locale, for (final locale in appController.supportedLocales)
value: locale, RadioMenuButton(
child: Text( groupValue: appController.locale,
Localization.getLanguageName(locale), value: locale,
style: TextStyle( child: Text(
fontWeight: locale == context.locale Localization.getLanguageName(locale),
? FontWeight.w800 style: TextStyle(
: FontWeight.w400, fontWeight: locale == appController.locale
), ? FontWeight.w800
: FontWeight.w400,
), ),
onChanged: (final newValue) {
Navigator.of(context).pop(newValue);
},
), ),
], onChanged: (final newValue) => Navigator.of(context).pop(newValue),
); ),
],
);
}
} }

View file

@ -6,9 +6,6 @@ class _ThemePicker extends StatelessWidget {
@override @override
Widget build(final BuildContext context) { Widget build(final BuildContext context) {
final appController = InheritedAppController.of(context); final appController = InheritedAppController.of(context);
// final themeMode = appController.themeMode;
// final bool isSystemThemeModeEnabled = themeMode == ThemeMode.system;
// final bool isDarkModeOn = themeMode == ThemeMode.dark;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
@ -19,11 +16,6 @@ class _ThemePicker extends StatelessWidget {
Text('application_settings.system_theme_mode_description'.tr()), Text('application_settings.system_theme_mode_description'.tr()),
value: appController.systemThemeModeActive, value: appController.systemThemeModeActive,
onChanged: appController.setSystemThemeModeFlag, onChanged: appController.setSystemThemeModeFlag,
// onChanged: (final newValue) => appController.setThemeMode(
// newValue
// ? ThemeMode.system
// : (isDarkModeOn ? ThemeMode.dark : ThemeMode.light),
// ),
), ),
SwitchListTile.adaptive( SwitchListTile.adaptive(
title: Text('application_settings.dark_theme_title'.tr()), title: Text('application_settings.dark_theme_title'.tr()),
@ -32,11 +24,6 @@ class _ThemePicker extends StatelessWidget {
onChanged: appController.systemThemeModeActive onChanged: appController.systemThemeModeActive
? null ? null
: appController.setDarkThemeModeFlag, : appController.setDarkThemeModeFlag,
// onChanged: isSystemThemeModeEnabled
// ? null
// : (final newValue) => appController.setThemeMode(
// newValue ? ThemeMode.dark : ThemeMode.light,
// ),
), ),
], ],
); );