Set display language

This commit is contained in:
Ming Ming 2021-06-23 16:15:25 +08:00
parent cf0824fa22
commit 24ee630d3a
6 changed files with 94 additions and 0 deletions

View file

@ -70,6 +70,8 @@ class FileRemovedEvent {
class ThemeChangedEvent {}
class LanguageChangedEvent {}
extension FilePropertyUpdatedEventExtension on FilePropertyUpdatedEvent {
bool hasAnyProperties(List<int> properties) =>
properties.any((p) => this.properties & p != 0);

View file

@ -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"

40
lib/language_util.dart Normal file
View file

@ -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];
}
}

View file

@ -60,6 +60,9 @@ class Pref {
Future<bool> setDarkTheme(bool value) => _pref.setBool("isDarkTheme", value);
int getLanguage([int def = 0]) => _pref.getInt("language") ?? def;
Future<bool> setLanguage(int value) => _pref.setInt("language", value);
Pref._();
static final _inst = Pref._();

View file

@ -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<MyApp> implements SnackBarHandler {
SnackBarManager().registerHandler(this);
_themeChangedListener =
AppEventListener<ThemeChangedEvent>(_onThemeChangedEvent)..begin();
_langChangedListener =
AppEventListener<LanguageChangedEvent>(_onLangChangedEvent)..begin();
}
@override
@ -41,6 +44,7 @@ class _MyAppState extends State<MyApp> 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<MyApp> implements SnackBarHandler {
super.dispose();
SnackBarManager().unregisterHandler(this);
_themeChangedListener.end();
_langChangedListener.end();
}
@override
@ -92,6 +97,10 @@ class _MyAppState extends State<MyApp> implements SnackBarHandler {
setState(() {});
}
void _onLangChangedEvent(LanguageChangedEvent ev) {
setState(() {});
}
Route<dynamic> _handleBasicRoute(RouteSettings settings) {
for (final e in _getRouter().entries) {
if (e.key == settings.name) {
@ -206,6 +215,7 @@ class _MyAppState extends State<MyApp> implements SnackBarHandler {
final _scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
AppEventListener<ThemeChangedEvent> _themeChangedListener;
AppEventListener<LanguageChangedEvent> _langChangedListener;
static final _log = Logger("widget.my_app.MyAppState");
}

View file

@ -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<Settings> {
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<Settings> {
);
}
void _onLanguageTap(BuildContext context) {
showDialog(
context: context,
builder: (context) => SimpleDialog(
children: language_util.supportedLanguages.values
.map<Widget>((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<EventBus>().fire(LanguageChangedEvent());
});
}
});
}
void _onExifSupportChanged(BuildContext context, bool value) {
if (value) {
showDialog(