feat: use Opus-MT-StarCitizen-zh-en model

This commit is contained in:
xkeyC 2025-11-16 15:09:56 +08:00
parent af15d106f0
commit 77c1b4f51a
5 changed files with 126 additions and 124 deletions

View File

@ -1,7 +1,7 @@
class ConstConf { class ConstConf {
static const String appVersion = "2.15.1 Beta"; static const String appVersion = "2.15.1 Beta2";
static const int appVersionCode = 71; static const int appVersionCode = 71;
static const String appVersionDate = "2025-11-15"; static const String appVersionDate = "2025-11-16";
static const _gameChannels = [ static const _gameChannels = [
"LIVE", "LIVE",
"4.0_PREVIEW", "4.0_PREVIEW",

View File

@ -77,7 +77,7 @@ class MultiWindowManager {
), ),
); );
await Future.delayed(Duration(milliseconds: 500)).then((_) async { await Future.delayed(Duration(milliseconds: 500)).then((_) async {
await controller.setFrame(const Rect.fromLTWH(0, 0, 800, 1200)); await controller.setFrame(const Rect.fromLTWH(0, 0, 720, 800));
await controller.setTitle(title); await controller.setTitle(title);
await controller.center(); await controller.center();
await controller.show(); await controller.show();

View File

@ -29,133 +29,135 @@ class InputMethodDialogUI extends HookConsumerWidget {
}, const []); }, const []);
return ContentDialog( 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), title: makeTitle(context, state, model, destTextCtrl),
content: state.keyMaps == null content: state.keyMaps == null
? makeLoading(context) ? makeLoading(context)
: Column( : Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SizedBox(height: 12), SizedBox(height: 12),
InfoBar( InfoBar(
title: Text(S.current.input_method_usage_instructions), title: Text(S.current.input_method_usage_instructions),
content: Text(S.current.input_method_input_text_instructions), content: Text(S.current.input_method_input_text_instructions),
), ),
SizedBox(height: 12), SizedBox(height: 12),
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
GestureDetector( GestureDetector(
child: Padding( child: Padding(
padding: const EdgeInsets.all(3), padding: const EdgeInsets.all(3),
child: Text( child: Text(
S.current.input_method_online_version_prompt, S.current.input_method_online_version_prompt,
style: TextStyle(color: Color(0xff4ca0e0), fontSize: 12), 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: 16), onTap: () {
TextFormBox( launchUrlString("https://ime.citizenwiki.cn/");
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), SizedBox(height: 12),
enabled: true, TextFormBox(
onChanged: (str) {}, placeholder: state.isEnableAutoTranslate
), ? "${S.current
SizedBox(height: 24), .input_method_input_placeholder}\n\n本地翻译模型对中英混合处理能力较差"
Row( : S.current.input_method_input_placeholder,
mainAxisAlignment: MainAxisAlignment.end, controller: srcTextCtrl,
children: [ maxLines: 5,
Row( placeholderStyle: TextStyle(color: Colors.white.withValues(alpha: .6)),
children: [ style: TextStyle(fontSize: 16, color: Colors.white),
Text(S.current.input_method_auto_translate), onChanged: (str) async {
SizedBox(width: 6), final text = model.onTextChange("src", str);
ToggleSwitch( destTextCtrl.text = text ?? "";
checked: state.isEnableAutoTranslate, if (text != null) {
onChanged: (b) => _onSwitchAutoTranslate(context, model, b), model.checkAutoTranslate();
), }
], },
), ),
SizedBox(width: 24), SizedBox(height: 16),
Row( Center(
children: [ child: Row(
Text(S.current.input_method_remote_input_service), mainAxisSize: MainAxisSize.min,
SizedBox(width: 6), children: [
if (serverState.isServerStartup) if (state.isAutoTranslateWorking)
Button( SizedBox(width: 24, height: 24, child: ProgressRing())
onPressed: () { else
showDialog(context: context, builder: (BuildContext context) => ServerQrDialogUI()); SizedBox(width: 24, height: 24, child: Icon(FluentIcons.down)),
},
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( Widget makeTitle(BuildContext context,
BuildContext context, InputMethodDialogUIState state,
InputMethodDialogUIState state, InputMethodDialogUIModel model,
InputMethodDialogUIModel model, TextEditingController destTextCtrl,) {
TextEditingController destTextCtrl,
) {
return Row( return Row(
children: [ children: [
IconButton( IconButton(
@ -223,8 +225,8 @@ class InputMethodDialogUI extends HookConsumerWidget {
"是否下载 AI 模型以使用翻译功能?", "是否下载 AI 模型以使用翻译功能?",
Text( Text(
"大约需要 200MB 的本地空间。" "大约需要 200MB 的本地空间。"
"\n\n我们使用本地模型进行翻译,您的翻译数据不会发送给任何第三方。" "\n\n我们使用本地模型进行翻译,您的翻译数据不会发送给任何第三方。"
"\n\n模型未对游戏术语优化,请自行判断使用", "\n\nOpus-MT-StarCitizen-zh-en 是汉化盒子团队基于 Opus-MT 模型微调得到的模型,对游戏术语进行了优化",
), ),
); );
if (userOK) { if (userOK) {

View File

@ -195,7 +195,7 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
} }
} }
String get _localTranslateModelName => "opus-mt-zh-en_onnx"; String get _localTranslateModelName => "Opus-MT-StarCitizen-zh-en";
String get _localTranslateModelDir => "${appGlobalState.applicationSupportDir}/onnx_models"; String get _localTranslateModelDir => "${appGlobalState.applicationSupportDir}/onnx_models";

View File

@ -393,11 +393,11 @@ mod tests {
#[test] #[test]
fn test_translation() { fn test_translation() {
let model = OpusMtModel::new( let model = OpusMtModel::new(
"C:\\Users\\xkeyc\\Downloads\\onnx_models\\opus-mt-zh-en", "E:\\Project\\StarCtizen\\Opus-MT-StarCitizen\\results\\final_model",
"_q4f16", "_q4f16",
) )
.unwrap(); .unwrap();
let result = model.translate("你好世界").unwrap(); let result = model.translate("北极星要炸了,快撤!").unwrap();
println!("Translation: {}", result); println!("Translation: {}", result);
} }
} }