From 24ee630d3a81fdf6261f44108bf1fe5f519a6243 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Wed, 23 Jun 2021 16:15:25 +0800 Subject: [PATCH] Set display language --- lib/event/event.dart | 2 ++ lib/l10n/app_en.arb | 4 ++++ lib/language_util.dart | 40 ++++++++++++++++++++++++++++++++++++++++ lib/pref.dart | 3 +++ lib/widget/my_app.dart | 10 ++++++++++ lib/widget/settings.dart | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 94 insertions(+) create mode 100644 lib/language_util.dart diff --git a/lib/event/event.dart b/lib/event/event.dart index c67139b2..36b9dd3c 100644 --- a/lib/event/event.dart +++ b/lib/event/event.dart @@ -70,6 +70,8 @@ class FileRemovedEvent { class ThemeChangedEvent {} +class LanguageChangedEvent {} + extension FilePropertyUpdatedEventExtension on FilePropertyUpdatedEvent { bool hasAnyProperties(List properties) => properties.any((p) => this.properties & p != 0); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index cba2e538..3a3f666b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -309,6 +309,10 @@ "@settingsWidgetTitle": { "description": "Title of the Settings widget" }, + "settingsLanguageTitle": "Language", + "@settingsLanguageTitle": { + "description": "Set display language" + }, "settingsExifSupportTitle": "EXIF support", "@settingsExifSupportTitle": { "description": "Title of the EXIF support setting" diff --git a/lib/language_util.dart b/lib/language_util.dart new file mode 100644 index 00000000..89a0730f --- /dev/null +++ b/lib/language_util.dart @@ -0,0 +1,40 @@ +import 'package:flutter/widgets.dart'; +import 'package:nc_photos/pref.dart'; + +class AppLanguage { + const AppLanguage(this.langId, this.nativeName, this.locale); + + final int langId; + final String nativeName; + final Locale locale; +} + +String getSelectedLanguageName(BuildContext context) => + _getSelectedLanguage(context).nativeName; +Locale getSelectedLocale(BuildContext context) => + _getSelectedLanguage(context).locale; + +final supportedLanguages = { + _AppLanguageEnum.systemDefault.index: + AppLanguage(_AppLanguageEnum.systemDefault.index, "System default", null), + _AppLanguageEnum.english.index: AppLanguage( + _AppLanguageEnum.english.index, "English", const Locale("en")), + _AppLanguageEnum.spanish.index: AppLanguage( + _AppLanguageEnum.spanish.index, "EspaƱol", const Locale("es")), +}; + +enum _AppLanguageEnum { + // the order must not be changed + systemDefault, + english, + spanish, +} + +AppLanguage _getSelectedLanguage(BuildContext context) { + try { + final lang = Pref.inst().getLanguage(); + return supportedLanguages[lang]; + } catch (_) { + return supportedLanguages[_AppLanguageEnum.systemDefault.index]; + } +} diff --git a/lib/pref.dart b/lib/pref.dart index f495c0db..30706ee3 100644 --- a/lib/pref.dart +++ b/lib/pref.dart @@ -60,6 +60,9 @@ class Pref { Future setDarkTheme(bool value) => _pref.setBool("isDarkTheme", value); + int getLanguage([int def = 0]) => _pref.getInt("language") ?? def; + Future setLanguage(int value) => _pref.setInt("language", value); + Pref._(); static final _inst = Pref._(); diff --git a/lib/widget/my_app.dart b/lib/widget/my_app.dart index 4dd33304..b691a75c 100644 --- a/lib/widget/my_app.dart +++ b/lib/widget/my_app.dart @@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/event/event.dart'; +import 'package:nc_photos/language_util.dart' as language_util; import 'package:nc_photos/pref.dart'; import 'package:nc_photos/snack_bar_manager.dart'; import 'package:nc_photos/theme.dart'; @@ -29,6 +30,8 @@ class _MyAppState extends State implements SnackBarHandler { SnackBarManager().registerHandler(this); _themeChangedListener = AppEventListener(_onThemeChangedEvent)..begin(); + _langChangedListener = + AppEventListener(_onLangChangedEvent)..begin(); } @override @@ -41,6 +44,7 @@ class _MyAppState extends State implements SnackBarHandler { initialRoute: Splash.routeName, onGenerateRoute: _onGenerateRoute, scaffoldMessengerKey: _scaffoldMessengerKey, + locale: language_util.getSelectedLocale(context), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, debugShowCheckedModeBanner: false, @@ -52,6 +56,7 @@ class _MyAppState extends State implements SnackBarHandler { super.dispose(); SnackBarManager().unregisterHandler(this); _themeChangedListener.end(); + _langChangedListener.end(); } @override @@ -92,6 +97,10 @@ class _MyAppState extends State implements SnackBarHandler { setState(() {}); } + void _onLangChangedEvent(LanguageChangedEvent ev) { + setState(() {}); + } + Route _handleBasicRoute(RouteSettings settings) { for (final e in _getRouter().entries) { if (e.key == settings.name) { @@ -206,6 +215,7 @@ class _MyAppState extends State implements SnackBarHandler { final _scaffoldMessengerKey = GlobalKey(); AppEventListener _themeChangedListener; + AppEventListener _langChangedListener; static final _log = Logger("widget.my_app.MyAppState"); } diff --git a/lib/widget/settings.dart b/lib/widget/settings.dart index 9a6a1f68..ec3fec95 100644 --- a/lib/widget/settings.dart +++ b/lib/widget/settings.dart @@ -1,10 +1,14 @@ +import 'package:event_bus/event_bus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; +import 'package:nc_photos/app_db.dart'; +import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/k.dart' as k; +import 'package:nc_photos/language_util.dart' as language_util; import 'package:nc_photos/metadata_task_manager.dart'; import 'package:nc_photos/pref.dart'; import 'package:nc_photos/snack_bar_manager.dart'; @@ -65,6 +69,11 @@ class _SettingsState extends State { SliverList( delegate: SliverChildListDelegate( [ + ListTile( + title: Text(AppLocalizations.of(context).settingsLanguageTitle), + subtitle: Text(language_util.getSelectedLanguageName(context)), + onTap: () => _onLanguageTap(context), + ), SwitchListTile( title: Text(AppLocalizations.of(context).settingsExifSupportTitle), @@ -128,6 +137,32 @@ class _SettingsState extends State { ); } + void _onLanguageTap(BuildContext context) { + showDialog( + context: context, + builder: (context) => SimpleDialog( + children: language_util.supportedLanguages.values + .map((lang) => SimpleDialogOption( + onPressed: () { + _log.info( + "[_onLanguageTap] Set language: ${lang.nativeName}"); + Navigator.of(context).pop(lang.langId); + }, + child: ListTile( + title: Text(lang.nativeName), + ), + )) + .toList(), + ), + ).then((value) { + if (value != null) { + Pref.inst().setLanguage(value).then((_) { + KiwiContainer().resolve().fire(LanguageChangedEvent()); + }); + } + }); + } + void _onExifSupportChanged(BuildContext context, bool value) { if (value) { showDialog(