feat: model l10n

This commit is contained in:
xkeyC
2025-11-16 20:13:23 +08:00
parent 77c1b4f51a
commit f98235f2f3
12 changed files with 651 additions and 560 deletions

View File

@@ -337,7 +337,7 @@ class HomeUI extends HookConsumerWidget {
children: [
Expanded(
child: Text(
"${index + 1}. ${(item?.title ?? "").replaceAll("【寰宇周刊】", "")}",
"${index + 1}. ${(item?.title ?? "").replaceAll(NoL10n.aniCatTitle, "")}",
style: TextStyle(fontSize: 12),
maxLines: 1,
overflow: TextOverflow.ellipsis,

View File

@@ -29,135 +29,133 @@ class InputMethodDialogUI extends HookConsumerWidget {
}, const []);
return ContentDialog(
constraints: BoxConstraints(maxWidth: MediaQuery
.of(context)
.size
.width * .8),
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .8),
title: makeTitle(context, state, model, destTextCtrl),
content: state.keyMaps == null
? makeLoading(context)
: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 12),
InfoBar(
title: Text(S.current.input_method_usage_instructions),
content: Text(S.current.input_method_input_text_instructions),
),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
child: Padding(
padding: const EdgeInsets.all(3),
child: Text(
S.current.input_method_online_version_prompt,
style: TextStyle(color: Color(0xff4ca0e0), fontSize: 12),
),
),
onTap: () {
launchUrlString("https://ime.citizenwiki.cn/");
},
),
],
),
SizedBox(height: 12),
TextFormBox(
placeholder: state.isEnableAutoTranslate
? "${S.current
.input_method_input_placeholder}\n\n本地翻译模型对中英混合处理能力较差,如有需要,建议分开发送。"
: S.current.input_method_input_placeholder,
controller: srcTextCtrl,
maxLines: 5,
placeholderStyle: TextStyle(color: Colors.white.withValues(alpha: .6)),
style: TextStyle(fontSize: 16, color: Colors.white),
onChanged: (str) async {
final text = model.onTextChange("src", str);
destTextCtrl.text = text ?? "";
if (text != null) {
model.checkAutoTranslate();
}
},
),
SizedBox(height: 16),
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (state.isAutoTranslateWorking)
SizedBox(width: 24, height: 24, child: ProgressRing())
else
SizedBox(width: 24, height: 24, child: Icon(FluentIcons.down)),
SizedBox(height: 12),
InfoBar(
title: Text(S.current.input_method_usage_instructions),
content: Text(S.current.input_method_input_text_instructions),
),
SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
child: Padding(
padding: const EdgeInsets.all(3),
child: Text(
S.current.input_method_online_version_prompt,
style: TextStyle(color: Color(0xff4ca0e0), fontSize: 12),
),
),
onTap: () {
launchUrlString("https://ime.citizenwiki.cn/");
},
),
],
),
SizedBox(height: 12),
TextFormBox(
placeholder: state.isEnableAutoTranslate
? S.current.input_method_auto_translate_model_tips(S.current.input_method_input_placeholder)
: S.current.input_method_input_placeholder,
controller: srcTextCtrl,
maxLines: 5,
placeholderStyle: TextStyle(color: Colors.white.withValues(alpha: .6)),
style: TextStyle(fontSize: 16, color: Colors.white),
onChanged: (str) async {
final text = model.onTextChange("src", str);
destTextCtrl.text = text ?? "";
if (text != null) {
model.checkAutoTranslate();
}
},
),
SizedBox(height: 16),
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (state.isAutoTranslateWorking)
SizedBox(width: 24, height: 24, child: ProgressRing())
else
SizedBox(width: 24, height: 24, child: Icon(FluentIcons.down)),
],
),
),
SizedBox(height: 16),
TextFormBox(
placeholder: S.current.input_method_encoded_text_placeholder,
controller: destTextCtrl,
maxLines: 5,
placeholderStyle: TextStyle(color: Colors.white.withValues(alpha: .6)),
style: TextStyle(fontSize: 16, color: Colors.white),
enabled: true,
onChanged: (str) {},
),
SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
Text(S.current.input_method_auto_translate),
SizedBox(width: 6),
ToggleSwitch(
checked: state.isEnableAutoTranslate,
onChanged: (b) => _onSwitchAutoTranslate(context, model, b),
),
],
),
SizedBox(width: 24),
Row(
children: [
Text(S.current.input_method_remote_input_service),
SizedBox(width: 6),
if (serverState.isServerStartup)
Button(
onPressed: () {
showDialog(context: context, builder: (BuildContext context) => ServerQrDialogUI());
},
child: Text(serverState.serverAddressText ?? "...", style: TextStyle(fontSize: 14)),
),
SizedBox(width: 14),
ToggleSwitch(
checked: serverState.isServerStartup,
onChanged: (b) => _onSwitchServer(context, b, serverModel),
),
],
),
],
),
SizedBox(height: 24),
Row(
children: [
Expanded(
child: Text(
textAlign: TextAlign.end,
S.current.input_method_disclaimer,
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .6)),
),
),
],
),
],
),
),
SizedBox(height: 16),
TextFormBox(
placeholder: S.current.input_method_encoded_text_placeholder,
controller: destTextCtrl,
maxLines: 5,
placeholderStyle: TextStyle(color: Colors.white.withValues(alpha: .6)),
style: TextStyle(fontSize: 16, color: Colors.white),
enabled: true,
onChanged: (str) {},
),
SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
Text(S.current.input_method_auto_translate),
SizedBox(width: 6),
ToggleSwitch(
checked: state.isEnableAutoTranslate,
onChanged: (b) => _onSwitchAutoTranslate(context, model, b),
),
],
),
SizedBox(width: 24),
Row(
children: [
Text(S.current.input_method_remote_input_service),
SizedBox(width: 6),
if (serverState.isServerStartup)
Button(
onPressed: () {
showDialog(context: context, builder: (BuildContext context) => ServerQrDialogUI());
},
child: Text(serverState.serverAddressText ?? "...", style: TextStyle(fontSize: 14)),
),
SizedBox(width: 14),
ToggleSwitch(
checked: serverState.isServerStartup,
onChanged: (b) => _onSwitchServer(context, b, serverModel),
),
],
),
],
),
SizedBox(height: 24),
Row(
children: [
Expanded(
child: Text(
textAlign: TextAlign.end,
S.current.input_method_disclaimer,
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .6)),
),
),
],
),
],
),
);
}
Widget makeTitle(BuildContext context,
InputMethodDialogUIState state,
InputMethodDialogUIModel model,
TextEditingController destTextCtrl,) {
Widget makeTitle(
BuildContext context,
InputMethodDialogUIState state,
InputMethodDialogUIModel model,
TextEditingController destTextCtrl,
) {
return Row(
children: [
IconButton(
@@ -213,7 +211,7 @@ class InputMethodDialogUI extends HookConsumerWidget {
// 检查下载任务
if (await model.isTranslateModelDownloading()) {
if (!context.mounted) return;
showToast(context, "模型正在下载中,请稍后...");
showToast(context, S.current.input_method_auto_translate_model_tips_downloading_tips);
return;
}
// 打开,检查本地模型
@@ -222,12 +220,8 @@ class InputMethodDialogUI extends HookConsumerWidget {
// 询问用户是否下载模型
final userOK = await showConfirmDialogs(
context,
"是否下载 AI 模型以使用翻译功能?",
Text(
"大约需要 200MB 的本地空间。"
"\n\n我们使用本地模型进行翻译,您的翻译数据不会发送给任何第三方。"
"\n\nOpus-MT-StarCitizen-zh-en 是汉化盒子团队基于 Opus-MT 模型微调得到的模型,对游戏术语进行了优化。",
),
S.current.input_method_auto_translate_dialog_title,
Text(S.current.input_method_auto_translate_dialog_title_content),
);
if (userOK) {
try {
@@ -237,14 +231,14 @@ class InputMethodDialogUI extends HookConsumerWidget {
context.go("/index/downloader");
await Future.delayed(Duration(seconds: 1)).then((_) {
if (!context.mounted) return;
showToast(context, "下载已开始,请在模型下载完成后重新启用翻译功能。");
showToast(context, S.current.input_method_auto_translate_model_download_start);
});
return;
}
} catch (e) {
dPrint("下载模型失败$e");
dPrint("Error$e");
if (context.mounted) {
showToast(context, "下载模型失败$e");
showToast(context, "Error$e");
}
return;
}

View File

@@ -286,7 +286,11 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
dPrint("[InputMethodDialogUIModel] mountOnnxTranslationProvider failed to init model");
if (context != null) {
if (!context.mounted) return;
final userOK = await showConfirmDialogs(context, "翻译模型加载失败", Text("是否删除本地文件,稍后您可以尝试重新下载。错误信息:\n$err"));
final userOK = await showConfirmDialogs(
context,
S.current.input_method_auto_translate_model_load_failed_title,
Text(S.current.input_method_auto_translate_model_load_failed_content(err)),
);
if (userOK) {
// 删除文件,并禁用开关
final dir = Directory("$_localTranslateModelDir/$_localTranslateModelName");