In-app language switcher

This commit is contained in:
LittleSheep 2025-01-28 23:09:07 +08:00
parent 0d1e18735e
commit 9471fe40fe
3 changed files with 83 additions and 30 deletions

View File

@ -199,6 +199,9 @@
"other": "{} comments" "other": "{} comments"
}, },
"settingsAppearance": "Appearance", "settingsAppearance": "Appearance",
"settingsDisplayLanguage": "Display Language",
"settingsDisplayLanguageDescription": "Set the application language.",
"settingsDisplayLanguageSystem": "Follow System",
"settingsAppBarTransparent": "Transparent App Bar", "settingsAppBarTransparent": "Transparent App Bar",
"settingsAppBarTransparentDescription": "Enable transparent effect for the app bar.", "settingsAppBarTransparentDescription": "Enable transparent effect for the app bar.",
"settingsDrawerPreferCollapse": "Prefer Drawer Collapse", "settingsDrawerPreferCollapse": "Prefer Drawer Collapse",

View File

@ -196,6 +196,9 @@
"other": "{} 条评论" "other": "{} 条评论"
}, },
"settingsAppearance": "外观", "settingsAppearance": "外观",
"settingsDisplayLanguage": "显示语言",
"settingsDisplayLanguageDescription": "设置应用程序使用的语言",
"settingsDisplayLanguageSystem": "跟随系统",
"settingsBackgroundImage": "背景图片", "settingsBackgroundImage": "背景图片",
"settingsBackgroundImageDescription": "设置应用全局生效的的背景图片。", "settingsBackgroundImageDescription": "设置应用全局生效的的背景图片。",
"settingsBackgroundImageClear": "清除现存背景图", "settingsBackgroundImageClear": "清除现存背景图",

View File

@ -82,6 +82,48 @@ class _SettingsScreenState extends State<SettingsScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('settingsAppearance').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4), Text('settingsAppearance').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4),
ListTile(
title: Text('settingsDisplayLanguage').tr(),
subtitle: Text('settingsDisplayLanguageDescription').tr(),
contentPadding: const EdgeInsets.only(left: 24, right: 17),
leading: const Icon(Symbols.translate),
trailing: DropdownButtonHideUnderline(
child: DropdownButton2<Locale?>(
isExpanded: true,
items: [
...EasyLocalization.of(context)!.supportedLocales.mapIndexed((idx, ele) {
return DropdownMenuItem<Locale?>(
value: ele,
child: Text('${ele.languageCode}-${ele.countryCode}').fontSize(14),
);
}),
DropdownMenuItem<Locale?>(
value: null,
child: Text('settingsDisplayLanguageSystem').tr().fontSize(14),
),
],
value: EasyLocalization.of(context)!.currentLocale,
onChanged: (Locale? value) {
if (value != null) {
EasyLocalization.of(context)!.setLocale(value);
} else {
EasyLocalization.of(context)!.resetLocale();
}
},
buttonStyleData: const ButtonStyleData(
padding: EdgeInsets.symmetric(
horizontal: 16,
vertical: 5,
),
height: 40,
width: 160,
),
menuItemStyleData: const MenuItemStyleData(
height: 40,
),
),
),
),
if (!kIsWeb) if (!kIsWeb)
ListTile( ListTile(
title: Text('settingsBackgroundImage').tr(), title: Text('settingsBackgroundImage').tr(),
@ -147,30 +189,31 @@ class _SettingsScreenState extends State<SettingsScreen> {
Color pickerColor = Color(_prefs.getInt(kAppColorSchemeStoreKey) ?? Colors.indigo.value); Color pickerColor = Color(_prefs.getInt(kAppColorSchemeStoreKey) ?? Colors.indigo.value);
final color = await showDialog<Color?>( final color = await showDialog<Color?>(
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) =>
content: SingleChildScrollView( AlertDialog(
child: ColorPicker( content: SingleChildScrollView(
pickerColor: pickerColor, child: ColorPicker(
onColorChanged: (color) => pickerColor = color, pickerColor: pickerColor,
enableAlpha: false, onColorChanged: (color) => pickerColor = color,
hexInputBar: true, enableAlpha: false,
hexInputBar: true,
),
),
actions: <Widget>[
TextButton(
child: const Text('dialogDismiss').tr(),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('dialogConfirm').tr(),
onPressed: () {
Navigator.of(context).pop(pickerColor);
},
),
],
), ),
),
actions: <Widget>[
TextButton(
child: const Text('dialogDismiss').tr(),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('dialogConfirm').tr(),
onPressed: () {
Navigator.of(context).pop(pickerColor);
},
),
],
),
); );
if (color == null || !context.mounted) return; if (color == null || !context.mounted) return;
@ -206,11 +249,13 @@ class _SettingsScreenState extends State<SettingsScreen> {
value: _prefs.getInt(kAppColorSchemeStoreKey) == null value: _prefs.getInt(kAppColorSchemeStoreKey) == null
? 1 ? 1
: kColorSchemes.values : kColorSchemes.values
.toList() .toList()
.indexWhere((ele) => ele.value == _prefs.getInt(kAppColorSchemeStoreKey)), .indexWhere((ele) => ele.value == _prefs.getInt(kAppColorSchemeStoreKey)),
onChanged: (int? value) { onChanged: (int? value) {
if (value != null && value != -1) { if (value != null && value != -1) {
_prefs.setInt(kAppColorSchemeStoreKey, kColorSchemes.values.elementAt(value).value); _prefs.setInt(kAppColorSchemeStoreKey, kColorSchemes.values
.elementAt(value)
.value);
final th = context.read<ThemeProvider>(); final th = context.read<ThemeProvider>();
th.reloadTheme(seedColorOverride: kColorSchemes.values.elementAt(value)); th.reloadTheme(seedColorOverride: kColorSchemes.values.elementAt(value));
setState(() {}); setState(() {});
@ -342,7 +387,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
('Custom', _serverUrlController.text), ('Custom', _serverUrlController.text),
] ]
.map( .map(
(item) => DropdownMenuItem<String>( (item) =>
DropdownMenuItem<String>(
value: item.$2, value: item.$2,
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@ -354,7 +400,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
], ],
), ),
), ),
) )
.toList(), .toList(),
value: _serverUrlController.text, value: _serverUrlController.text,
onChanged: (String? value) { onChanged: (String? value) {
@ -409,11 +455,12 @@ class _SettingsScreenState extends State<SettingsScreen> {
isExpanded: true, isExpanded: true,
items: kImageQualityLevel.entries items: kImageQualityLevel.entries
.map( .map(
(item) => DropdownMenuItem<FilterQuality>( (item) =>
DropdownMenuItem<FilterQuality>(
value: item.value, value: item.value,
child: Text(item.key).tr().fontSize(14), child: Text(item.key).tr().fontSize(14),
), ),
) )
.toList(), .toList(),
onChanged: (FilterQuality? value) { onChanged: (FilterQuality? value) {
if (value == null) return; if (value == null) return;