feat(client/i18n): 新增 日/韩/俄/西 4 语,默认语种改英文
- AppLang enum 扩为 zh/en/ja/ko/ru/es;新增 strings_{ja,ko,ru,es}.dart
(各 161 条,照 strings_en.dart 结构逐条翻译,无红线词,scan-redline 过)
- app_providers: localeProvider 默认 AppLang.en(国际化默认);appTextProvider
三元改 switch 全覆盖 6 语
- AppLang.nativeLabel 扩展(各语言本地名);settings/account 两处 _LangSwitch
段控改下拉(6 语横排会挤)
- flutter analyze lib 仅剩 2 个既有 withOpacity deprecation info
注:节点/套餐名、错误消息等 ~11 处数据驱动的 zh/en 三元暂回退 en(非崩溃,
后续可扩多语字段)。localeProvider 暂无持久化(沿用原设计,后续可加)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -351,31 +351,37 @@ class _LangSwitch extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final c = context.pangolin;
|
||||
Widget seg(AppLang v, String label) {
|
||||
final active = lang == v;
|
||||
return GestureDetector(
|
||||
onTap: () => onChange(v),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: active ? c.accent : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(PangolinRadius.full),
|
||||
// 6 种语言用下拉(段控横排会挤)。
|
||||
return PopupMenuButton<AppLang>(
|
||||
initialValue: lang,
|
||||
onSelected: onChange,
|
||||
color: c.surface,
|
||||
elevation: 8,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(PangolinRadius.md)),
|
||||
itemBuilder: (_) => [
|
||||
for (final l in AppLang.values)
|
||||
PopupMenuItem<AppLang>(
|
||||
value: l,
|
||||
height: 42,
|
||||
child: Text(l.nativeLabel,
|
||||
style: PangolinText.caption.copyWith(
|
||||
color: l == lang ? c.accent : c.fg1,
|
||||
fontWeight: l == lang ? FontWeight.w700 : FontWeight.w500,
|
||||
fontSize: 13)),
|
||||
),
|
||||
child: Text(label,
|
||||
style: PangolinText.caption.copyWith(
|
||||
color: active ? c.fgOnAccent : c.fg3, fontWeight: FontWeight.w700, fontSize: 12.5)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.full)),
|
||||
child: Row(mainAxisSize: MainAxisSize.min, children: [
|
||||
seg(AppLang.zh, '中文'),
|
||||
const SizedBox(width: 2),
|
||||
seg(AppLang.en, 'EN'),
|
||||
]),
|
||||
],
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 6),
|
||||
decoration:
|
||||
BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.full)),
|
||||
child: Row(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text(lang.nativeLabel,
|
||||
style: PangolinText.caption
|
||||
.copyWith(color: c.fg2, fontWeight: FontWeight.w700, fontSize: 12.5)),
|
||||
const SizedBox(width: 4),
|
||||
Icon(PangolinIcons.chevronDown, size: 14, color: c.fg3),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,27 +148,37 @@ class _LangSwitch extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final c = context.pangolin;
|
||||
Widget seg(AppLang v, String label) {
|
||||
final on = lang == v;
|
||||
return GestureDetector(
|
||||
onTap: () => onPick(v),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: on ? c.accent : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(PangolinRadius.full),
|
||||
// 6 种语言用下拉(段控横排会挤)。当前语言以本地名 + 下拉箭头展示。
|
||||
return PopupMenuButton<AppLang>(
|
||||
initialValue: lang,
|
||||
onSelected: onPick,
|
||||
color: c.surface,
|
||||
elevation: 8,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(PangolinRadius.md)),
|
||||
itemBuilder: (_) => [
|
||||
for (final l in AppLang.values)
|
||||
PopupMenuItem<AppLang>(
|
||||
value: l,
|
||||
height: 42,
|
||||
child: Text(l.nativeLabel,
|
||||
style: PangolinText.caption.copyWith(
|
||||
color: l == lang ? c.accent : c.fg1,
|
||||
fontWeight: l == lang ? FontWeight.w700 : FontWeight.w500,
|
||||
fontSize: 13)),
|
||||
),
|
||||
child: Text(label,
|
||||
style: PangolinText.caption.copyWith(
|
||||
color: on ? c.fgOnAccent : c.fg3, fontWeight: FontWeight.w700, fontSize: 12)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.full)),
|
||||
child: Row(mainAxisSize: MainAxisSize.min, children: [seg(AppLang.zh, '中文'), seg(AppLang.en, 'EN')]),
|
||||
],
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration:
|
||||
BoxDecoration(color: c.bgSubtle, borderRadius: BorderRadius.circular(PangolinRadius.full)),
|
||||
child: Row(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text(lang.nativeLabel,
|
||||
style: PangolinText.caption
|
||||
.copyWith(color: c.fg2, fontWeight: FontWeight.w700, fontSize: 12)),
|
||||
const SizedBox(width: 4),
|
||||
Icon(PangolinIcons.chevronDown, size: 14, color: c.fg3),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user