fix: 修复语言设置为简体中文而非繁体翻译
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -426,7 +424,6 @@ class _ResultHeader extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Row(
|
||||
children: [
|
||||
@@ -436,29 +433,6 @@ class _ResultHeader extends StatelessWidget {
|
||||
context,
|
||||
).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w700),
|
||||
),
|
||||
const Spacer(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final payload = <String, dynamic>{
|
||||
'signType': data.signType,
|
||||
'question': data.params.question,
|
||||
'keywords': data.keywords,
|
||||
'conclusion': data.conclusion,
|
||||
};
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: const JsonEncoder.withIndent(' ').convert(payload),
|
||||
),
|
||||
);
|
||||
Toast.show(
|
||||
context,
|
||||
l10n.toastContentCopied,
|
||||
type: ToastType.success,
|
||||
);
|
||||
},
|
||||
style: TextButton.styleFrom(foregroundColor: colors.primary),
|
||||
child: Text(l10n.resultShare),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -799,6 +773,8 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final isTraditionalChinese =
|
||||
Localizations.localeOf(context).scriptCode == 'Hant';
|
||||
return Column(
|
||||
children: [
|
||||
Card(
|
||||
@@ -826,14 +802,14 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _miniKV(
|
||||
context,
|
||||
DivinationTerms.yueJian,
|
||||
l10n.termYueJian,
|
||||
data.ganzhi.yueJian,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _miniKV(
|
||||
context,
|
||||
DivinationTerms.riChen,
|
||||
l10n.termRiChen,
|
||||
data.ganzhi.riChen,
|
||||
),
|
||||
),
|
||||
@@ -845,14 +821,14 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _miniKV(
|
||||
context,
|
||||
DivinationTerms.yuePo,
|
||||
l10n.termYuePo,
|
||||
data.ganzhi.yuePo,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _miniKV(
|
||||
context,
|
||||
DivinationTerms.riChong,
|
||||
l10n.termRiChong,
|
||||
data.ganzhi.riChong,
|
||||
),
|
||||
),
|
||||
@@ -898,7 +874,11 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
data.guaName,
|
||||
_toTraditionalGuaNameIfNeeded(
|
||||
data.guaName,
|
||||
isTraditionalChinese,
|
||||
l10n,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.titleMedium
|
||||
?.copyWith(fontWeight: FontWeight.w700),
|
||||
@@ -907,7 +887,11 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
if (data.hasChangingYao)
|
||||
Expanded(
|
||||
child: Text(
|
||||
data.targetGuaName,
|
||||
_toTraditionalGuaNameIfNeeded(
|
||||
data.targetGuaName,
|
||||
isTraditionalChinese,
|
||||
l10n,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.titleMedium
|
||||
?.copyWith(fontWeight: FontWeight.w700),
|
||||
@@ -943,6 +927,24 @@ class _HexagramDetailCard extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _toTraditionalGuaNameIfNeeded(
|
||||
String value,
|
||||
bool isTraditionalChinese,
|
||||
AppLocalizations l10n,
|
||||
) {
|
||||
if (!isTraditionalChinese || value.isEmpty) {
|
||||
return value;
|
||||
}
|
||||
final from = l10n.guaNameSimplifiedChars;
|
||||
final to = l10n.guaNameTraditionalChars;
|
||||
final map = <String, String>{};
|
||||
final length = from.length < to.length ? from.length : to.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
map[from[i]] = to[i];
|
||||
}
|
||||
return value.split('').map((char) => map[char] ?? char).join();
|
||||
}
|
||||
|
||||
class _WuXingTable extends StatelessWidget {
|
||||
const _WuXingTable({required this.data});
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import '../../../../l10n/app_localizations.dart';
|
||||
String displayLanguageLabel(AppLocalizations l10n, String languageTag) {
|
||||
return switch (languageTag) {
|
||||
'en-US' => l10n.english,
|
||||
_ => l10n.chinese,
|
||||
'zh-Hant' => '繁體中文',
|
||||
'zh-CN' => '简体中文',
|
||||
_ => '简体中文',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,6 +115,10 @@ String languageTagFromLocale(Locale locale) {
|
||||
case 'en':
|
||||
return 'en-US';
|
||||
case 'zh':
|
||||
if (locale.scriptCode == 'Hant') {
|
||||
return 'zh-Hant';
|
||||
}
|
||||
return 'zh-CN';
|
||||
default:
|
||||
return 'zh-CN';
|
||||
}
|
||||
@@ -122,5 +128,8 @@ Locale localeFromLanguageTag(String tag) {
|
||||
if (tag.toLowerCase().startsWith('en')) {
|
||||
return const Locale('en');
|
||||
}
|
||||
if (tag == 'zh-Hant') {
|
||||
return const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant');
|
||||
}
|
||||
return const Locale('zh');
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class _GeneralSettingsScreenState extends State<GeneralSettingsScreen> {
|
||||
),
|
||||
tint: colors.primary,
|
||||
background: colors.surfaceContainerHighest,
|
||||
showDivider: true,
|
||||
showDivider: false,
|
||||
onTap: () => _selectLanguage(
|
||||
_settings.preferences.aiLanguage,
|
||||
(lang) => setState(() {
|
||||
@@ -101,24 +101,6 @@ class _GeneralSettingsScreenState extends State<GeneralSettingsScreen> {
|
||||
}),
|
||||
),
|
||||
),
|
||||
SettingsMenuTile(
|
||||
icon: Icons.access_time_rounded,
|
||||
title: l10n.settingsTimezone,
|
||||
subtitle: _settings.preferences.timezone,
|
||||
tint: colors.primary,
|
||||
background: colors.surfaceContainerHighest,
|
||||
showDivider: true,
|
||||
onTap: () => _selectTimezone(context),
|
||||
),
|
||||
SettingsMenuTile(
|
||||
icon: Icons.public_rounded,
|
||||
title: l10n.settingsCountry,
|
||||
subtitle: _settings.preferences.country,
|
||||
tint: colors.primary,
|
||||
background: colors.surfaceContainerHighest,
|
||||
showDivider: false,
|
||||
onTap: () => _selectCountry(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
@@ -169,44 +151,6 @@ class _GeneralSettingsScreenState extends State<GeneralSettingsScreen> {
|
||||
await widget.onSettingsChanged(_settings);
|
||||
}
|
||||
|
||||
Future<void> _selectTimezone(BuildContext context) async {
|
||||
final result = await Navigator.of(context).push<String>(
|
||||
MaterialPageRoute<String>(
|
||||
builder: (_) => TimezoneSettingsScreen(
|
||||
selectedTimezone: _settings.preferences.timezone,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (result == null || result == _settings.preferences.timezone) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_settings = _settings.copyWith(
|
||||
preferences: _settings.preferences.copyWith(timezone: result),
|
||||
);
|
||||
});
|
||||
await widget.onSettingsChanged(_settings);
|
||||
}
|
||||
|
||||
Future<void> _selectCountry(BuildContext context) async {
|
||||
final result = await Navigator.of(context).push<String>(
|
||||
MaterialPageRoute<String>(
|
||||
builder: (_) => CountrySettingsScreen(
|
||||
selectedCountry: _settings.preferences.country,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (result == null || result == _settings.preferences.country) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_settings = _settings.copyWith(
|
||||
preferences: _settings.preferences.copyWith(country: result),
|
||||
);
|
||||
});
|
||||
await widget.onSettingsChanged(_settings);
|
||||
}
|
||||
|
||||
void _updateNotification({bool? allowNotifications, bool? allowVibration}) {
|
||||
final newNotification = _settings.notification.copyWith(
|
||||
allowNotifications: allowNotifications,
|
||||
@@ -219,114 +163,3 @@ class _GeneralSettingsScreenState extends State<GeneralSettingsScreen> {
|
||||
widget.onSettingsChanged(newSettings);
|
||||
}
|
||||
}
|
||||
|
||||
class TimezoneSettingsScreen extends StatelessWidget {
|
||||
const TimezoneSettingsScreen({super.key, required this.selectedTimezone});
|
||||
|
||||
final String selectedTimezone;
|
||||
|
||||
static const _timezones = [
|
||||
'Asia/Shanghai',
|
||||
'Asia/Hong_Kong',
|
||||
'Asia/Tokyo',
|
||||
'America/New_York',
|
||||
'America/Los_Angeles',
|
||||
'Europe/London',
|
||||
'Europe/Paris',
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colors.surfaceContainerLow,
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.settingsTimezone),
|
||||
centerTitle: true,
|
||||
backgroundColor: colors.surfaceContainerLow,
|
||||
surfaceTintColor: colors.surfaceContainerLow,
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
children: [
|
||||
SettingsGroupCard(
|
||||
children: [
|
||||
for (int i = 0; i < _timezones.length; i++)
|
||||
SettingsMenuTile(
|
||||
icon: Icons.access_time_rounded,
|
||||
title: _timezones[i],
|
||||
subtitle: '',
|
||||
tint: colors.primary,
|
||||
background: colors.surfaceContainerHighest,
|
||||
showDivider: i != _timezones.length - 1,
|
||||
showChevron: false,
|
||||
trailing: selectedTimezone == _timezones[i]
|
||||
? Icon(Icons.check_rounded, color: colors.primary)
|
||||
: null,
|
||||
onTap: () => Navigator.of(context).pop(_timezones[i]),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CountrySettingsScreen extends StatelessWidget {
|
||||
const CountrySettingsScreen({super.key, required this.selectedCountry});
|
||||
|
||||
final String selectedCountry;
|
||||
|
||||
static const _countries = ['CN', 'HK', 'TW', 'US', 'JP', 'GB', 'FR'];
|
||||
static const _labels = [
|
||||
'China',
|
||||
'Hong Kong',
|
||||
'Taiwan',
|
||||
'USA',
|
||||
'Japan',
|
||||
'UK',
|
||||
'France',
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: colors.surfaceContainerLow,
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.settingsCountry),
|
||||
centerTitle: true,
|
||||
backgroundColor: colors.surfaceContainerLow,
|
||||
surfaceTintColor: colors.surfaceContainerLow,
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
children: [
|
||||
SettingsGroupCard(
|
||||
children: [
|
||||
for (int i = 0; i < _countries.length; i++)
|
||||
SettingsMenuTile(
|
||||
icon: Icons.public_rounded,
|
||||
title: _labels[i],
|
||||
subtitle: _countries[i],
|
||||
tint: colors.primary,
|
||||
background: colors.surfaceContainerHighest,
|
||||
showDivider: i != _countries.length - 1,
|
||||
showChevron: false,
|
||||
trailing: selectedCountry == _countries[i]
|
||||
? Icon(Icons.check_rounded, color: colors.primary)
|
||||
: null,
|
||||
onTap: () => Navigator.of(context).pop(_countries[i]),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ class LanguageSettingsScreen extends StatelessWidget {
|
||||
return '$lang-$script-$country';
|
||||
} else if (country != null) {
|
||||
return '$lang-$country';
|
||||
} else if (script != null) {
|
||||
return '$lang-$script';
|
||||
}
|
||||
return _mapToBackendTag(lang);
|
||||
}
|
||||
@@ -80,10 +82,13 @@ class LanguageSettingsScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
String _getLocaleLabel(Locale locale, AppLocalizations l10n) {
|
||||
if (locale.languageCode == 'zh') {
|
||||
return l10n.chinese;
|
||||
} else if (locale.languageCode == 'en') {
|
||||
if (locale.languageCode == 'en') {
|
||||
return l10n.english;
|
||||
} else if (locale.languageCode == 'zh') {
|
||||
if (locale.scriptCode == 'Hant') {
|
||||
return '繁體中文';
|
||||
}
|
||||
return '简体中文';
|
||||
}
|
||||
return locale.languageCode;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user