From b2c13a8a6fc9009db701f8b6a2cd27fe67151c81 Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Fri, 15 Mar 2024 00:01:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=9A=E8=AF=AD=E8=A8=80=20=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/utils/log.dart | 2 + lib/main.dart | 28 +++++-- lib/ui/about/about_ui.dart | 32 +++---- .../dialogs/home_countdown_dialog_ui.dart | 6 +- .../dialogs/home_game_login_dialog_ui.dart | 18 ++-- .../home_game_login_dialog_ui_model.dart | 24 +++--- ...me_game_login_dialog_ui_model.freezed.dart | 4 +- .../home_game_login_dialog_ui_model.g.dart | 2 +- .../dialogs/home_md_content_dialog_ui.dart | 8 +- .../home/downloader/home_downloader_ui.dart | 28 +++---- .../downloader/home_downloader_ui_model.dart | 40 ++++----- .../home_downloader_ui_model.freezed.dart | 4 +- .../home_downloader_ui_model.g.dart | 2 +- lib/ui/home/game_doctor/game_doctor_ui.dart | 56 ++++++------- .../game_doctor/game_doctor_ui_model.dart | 40 ++++----- .../game_doctor_ui_model.freezed.dart | 4 +- .../game_doctor/game_doctor_ui_model.g.dart | 2 +- lib/ui/home/home_ui.dart | 58 ++++++------- lib/ui/home/home_ui_model.dart | 32 ++++--- lib/ui/home/home_ui_model.g.dart | 2 +- .../localization/localization_dialog_ui.dart | 84 ++++++++++--------- .../localization/localization_ui_model.dart | 16 ++-- .../localization_ui_model.freezed.dart | 4 +- .../localization/localization_ui_model.g.dart | 2 +- lib/ui/home/performance/performance_ui.dart | 44 +++++----- .../performance/performance_ui_model.dart | 33 ++++---- .../performance_ui_model.freezed.dart | 4 +- .../performance/performance_ui_model.g.dart | 2 +- lib/ui/index_ui.dart | 12 +-- lib/ui/party_room/party_room_ui.dart | 17 ++-- lib/ui/settings/settings_ui.dart | 29 +++---- lib/ui/settings/settings_ui_model.dart | 32 +++---- .../settings/settings_ui_model.freezed.dart | 4 +- lib/ui/settings/settings_ui_model.g.dart | 2 +- lib/ui/settings/upgrade_dialog.dart | 30 +++---- lib/ui/splash_ui.dart | 10 +-- .../dialogs/hosts_booster_dialog_ui.dart | 54 ++++++------ lib/ui/tools/tools_ui.dart | 22 ++--- lib/ui/tools/tools_ui_model.dart | 70 ++++++++-------- lib/ui/tools/tools_ui_model.freezed.dart | 4 +- lib/ui/tools/tools_ui_model.g.dart | 2 +- lib/ui/webview/webview.dart | 27 ++++-- packages/sct_dev_tools/bin/auto_l10n.dart | 69 ++++++++++----- packages/sct_dev_tools/bin/sct_dev_tools.dart | 4 +- pubspec.yaml | 2 + 45 files changed, 525 insertions(+), 446 deletions(-) diff --git a/lib/common/utils/log.dart b/lib/common/utils/log.dart index b08e260..7e07ae0 100644 --- a/lib/common/utils/log.dart +++ b/lib/common/utils/log.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:synchronized/synchronized.dart'; +export 'package:starcitizen_doctor/generated/l10n.dart'; + var _logLock = Lock(); File? _logFile; diff --git a/lib/main.dart b/lib/main.dart index cab0b00..9ec0db5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,9 @@ import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:starcitizen_doctor/generated/l10n.dart'; import 'package:window_manager/window_manager.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'app.dart'; @@ -38,10 +40,18 @@ class App extends HookConsumerWidget { title: "StarCitizenToolBox", restorationScopeId: "StarCitizenToolBox", themeMode: ThemeMode.dark, + localizationsDelegates: const [ + S.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + FluentLocalizations.delegate, + ], + supportedLocales: S.delegate.supportedLocales, builder: (context, child) { return MediaQuery( data: - MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling), + MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling), child: child ?? const SizedBox(), ); }, @@ -55,10 +65,10 @@ class App extends HookConsumerWidget { micaBackgroundColor: appState.themeConf.micaColor, buttonTheme: ButtonThemeData( defaultButtonStyle: ButtonStyle( - shape: ButtonState.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(4), - side: BorderSide(color: Colors.white.withOpacity(.01)))), - ))), + shape: ButtonState.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + side: BorderSide(color: Colors.white.withOpacity(.01)))), + ))), debugShowCheckedModeBanner: false, routeInformationParser: router.routeInformationParser, routerDelegate: router.routerDelegate, @@ -98,10 +108,10 @@ Widget _defaultWebviewTitleBar(BuildContext context) { const SizedBox(width: 12), (state.isLoading) ? const SizedBox( - width: 24, - height: 24, - child: ProgressRing(), - ) + width: 24, + height: 24, + child: ProgressRing(), + ) : const SizedBox(width: 24), const SizedBox(width: 12), SelectableText(state.url ?? ""), diff --git a/lib/ui/about/about_ui.dart b/lib/ui/about/about_ui.dart index 75b5948..6688b38 100644 --- a/lib/ui/about/about_ui.dart +++ b/lib/ui/about/about_ui.dart @@ -31,9 +31,9 @@ class AboutUI extends HookConsumerWidget { const SizedBox(height: 12), Button( onPressed: () => _onCheckUpdate(context, ref), - child: const Padding( - padding: EdgeInsets.all(4), - child: Text("检查更新"), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text(S.current.about_check_update), )), const SizedBox(height: 32), Container( @@ -103,7 +103,7 @@ class AboutUI extends HookConsumerWidget { const Icon(FontAwesomeIcons.link), const SizedBox(width: 8), Text( - "在线反馈", + S.current.about_online_feedback, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.6)), ), @@ -120,7 +120,7 @@ class AboutUI extends HookConsumerWidget { const Icon(FontAwesomeIcons.qq), const SizedBox(width: 8), Text( - "QQ群: 940696487", + S.current.about_action_qq_group, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.6)), ), @@ -138,7 +138,7 @@ class AboutUI extends HookConsumerWidget { const Icon(FontAwesomeIcons.envelope), const SizedBox(width: 8), Text( - "邮箱: scbox@xkeyc.com", + S.current.about_action_email, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.6)), ), @@ -155,7 +155,7 @@ class AboutUI extends HookConsumerWidget { const Icon(FontAwesomeIcons.github), const SizedBox(width: 8), Text( - "开源", + S.current.about_action_open_source, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.6)), ), @@ -209,13 +209,13 @@ class AboutUI extends HookConsumerWidget { {required BuildContext context, required String name, required int value}) { - const names = { - "launch": "启动", - "gameLaunch": "启动游戏", - "firstLaunch": "累计用户", - "install_localization": "汉化安装", - "performance_apply": "性能调优", - "p4k_download": "P4K分流" + final names = { + "launch": S.current.about_analytics_launch, + "gameLaunch": S.current.about_analytics_launch_game, + "firstLaunch": S.current.about_analytics_total_users, + "install_localization": S.current.about_analytics_install_translation, + "performance_apply": S.current.about_analytics_performance_optimization, + "p4k_download": S.current.about_analytics_p4k_redirection }; return Container( padding: const EdgeInsets.all(12), @@ -256,8 +256,8 @@ class AboutUI extends HookConsumerWidget { await ref.read(appGlobalModelProvider.notifier).checkUpdate(context); if (!hasUpdate) { if (!context.mounted) return; - showToast(context, "已经是最新版本!"); + showToast(context, S.current.about_info_latest_version); } } } -} +} \ No newline at end of file diff --git a/lib/ui/home/dialogs/home_countdown_dialog_ui.dart b/lib/ui/home/dialogs/home_countdown_dialog_ui.dart index 9e1e035..2852a77 100644 --- a/lib/ui/home/dialogs/home_countdown_dialog_ui.dart +++ b/lib/ui/home/dialogs/home_countdown_dialog_ui.dart @@ -24,7 +24,7 @@ class HomeCountdownDialogUI extends HookConsumerWidget { Navigator.of(context).pop(); }), const SizedBox(width: 12), - const Text("节日倒计时"), + Text(S.current.home_holiday_countdown), ], ), content: homeState.countdownFestivalListData == null @@ -85,7 +85,7 @@ class HomeCountdownDialogUI extends HookConsumerWidget { ), const SizedBox(height: 12), Text( - "* 以上节日日期由人工收录、维护,可能存在错误,欢迎反馈!", + S.current.home_holiday_countdown_disclaimer, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(.3)), ) @@ -95,4 +95,4 @@ class HomeCountdownDialogUI extends HookConsumerWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/ui/home/dialogs/home_game_login_dialog_ui.dart b/lib/ui/home/dialogs/home_game_login_dialog_ui.dart index 16c4681..8829375 100644 --- a/lib/ui/home/dialogs/home_game_login_dialog_ui.dart +++ b/lib/ui/home/dialogs/home_game_login_dialog_ui.dart @@ -14,12 +14,12 @@ class HomeGameLoginDialogUI extends HookConsumerWidget { useEffect(() { ref.read(homeGameLoginUIModelProvider.notifier).launchWebLogin(context); return null; - }, const []); + }, []); return ContentDialog( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * .56, ), - title: (loginState.loginStatus == 2) ? null : const Text("一键启动"), + title: (loginState.loginStatus == 2) ? null : Text(S.current.home_action_one_click_launch), content: AnimatedSize( duration: const Duration(milliseconds: 230), child: Padding( @@ -33,13 +33,13 @@ class HomeGameLoginDialogUI extends HookConsumerWidget { Center( child: Column( children: [ - const Text("登录中..."), + Text(S.current.home_title_logging_in), const SizedBox(height: 12), const ProgressRing(), if (loginState.isDeviceSupportWinHello ?? false) const SizedBox(height: 24), Text( - "* 若开启了自动填充,请留意弹出的 Windows Hello 窗口", + S.current.home_info_auto_fill_notice, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(.6)), ) @@ -52,9 +52,9 @@ class HomeGameLoginDialogUI extends HookConsumerWidget { child: Column( children: [ const SizedBox(height: 12), - const Text( - "欢迎回来!", - style: TextStyle(fontSize: 20), + Text( + S.current.home_login_title_welcome_back, + style: const TextStyle(fontSize: 20), ), const SizedBox(height: 24), if (loginState.avatarUrl != null) @@ -74,7 +74,7 @@ class HomeGameLoginDialogUI extends HookConsumerWidget { fontSize: 24, fontWeight: FontWeight.bold), ), const SizedBox(height: 32), - const Text("正在为您启动游戏..."), + Text(S.current.home_login_title_launching_game), const SizedBox(height: 12), const ProgressRing(), ], @@ -87,4 +87,4 @@ class HomeGameLoginDialogUI extends HookConsumerWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.dart b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.dart index c49fdac..e20dbd4 100644 --- a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.dart +++ b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.dart @@ -25,7 +25,7 @@ part 'home_game_login_dialog_ui_model.g.dart'; @freezed class HomeGameLoginState with _$HomeGameLoginState { - const factory HomeGameLoginState({ + factory HomeGameLoginState({ required int loginStatus, String? nickname, String? avatarUrl, @@ -41,7 +41,7 @@ class HomeGameLoginState with _$HomeGameLoginState { class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { @override HomeGameLoginState build() { - return const HomeGameLoginState(loginStatus: 0); + return HomeGameLoginState(loginStatus: 0); } final LocalAuthentication _localAuth = LocalAuthentication(); @@ -53,9 +53,9 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { state = state.copyWith(isDeviceSupportWinHello: isDeviceSupportWinHello); if (!context.mounted) return; - goWebView( - context, "登录 RSI 账户", "https://robertsspaceindustries.com/connect", - loginMode: true, rsiLoginCallback: (message, ok) async { + goWebView(context, S.current.home_action_login_rsi_account, + "https://robertsspaceindustries.com/connect", loginMode: true, + rsiLoginCallback: (message, ok) async { // dPrint( // "======rsiLoginCallback=== $ok ===== data==\n${json.encode(message)}"); if (message == null || !ok) { @@ -98,12 +98,13 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "是否开启自动密码填充?", + S.current.home_action_q_auto_password_fill_prompt, const Text( "盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时,您只需授权PIN即可自动填充登录。")); if (ok == true) { if (await _localAuth.authenticate( - localizedReason: "输入PIN以启用加密") == + localizedReason: + S.current.home_login_info_enter_pin_to_encrypt) == true) { await _savePwd(inputEmail, inputPassword); } @@ -129,12 +130,12 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "游戏版本过期", + S.current.home_login_info_game_version_outdated, Text( "RSI 服务器报告版本号:${releaseInfo?["versionLabel"]} \n\n本地版本号:${buildInfo["RequestedP4ChangeNum"]} \n\n建议使用 RSI Launcher 更新游戏!"), constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * .4), - cancel: "忽略"); + cancel: S.current.home_login_info_action_ignore); if (ok == true) { if (!context.mounted) return; Navigator.pop(context); @@ -163,7 +164,7 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "盒子一键启动", + S.current.home_login_action_title_box_one_click_launch, const Text( "本功能可以帮您更加便利的启动游戏。\n\n为确保账户安全 ,本功能使用汉化浏览器保留登录状态,且不会保存您的密码信息(除非你启用了自动填充功能)。" "\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。", @@ -182,7 +183,8 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel { } if (!await WebviewWindow.isWebviewAvailable()) { if (!context.mounted) return; - await showToast(context, "需要安装 WebView2 Runtime"); + await showToast(context, + S.current.home_login_action_title_need_webview2_runtime); if (!context.mounted) return; await launchUrlString( "https://developer.microsoft.com/en-us/microsoft-edge/webview2/"); diff --git a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.freezed.dart b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.freezed.dart index 5bd18ae..8dcd459 100644 --- a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.freezed.dart +++ b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.freezed.dart @@ -185,7 +185,7 @@ class __$$LoginStatusImplCopyWithImpl<$Res> /// @nodoc class _$LoginStatusImpl implements _LoginStatus { - const _$LoginStatusImpl( + _$LoginStatusImpl( {required this.loginStatus, this.nickname, this.avatarUrl, @@ -270,7 +270,7 @@ class _$LoginStatusImpl implements _LoginStatus { } abstract class _LoginStatus implements HomeGameLoginState { - const factory _LoginStatus( + factory _LoginStatus( {required final int loginStatus, final String? nickname, final String? avatarUrl, diff --git a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.g.dart b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.g.dart index 048de58..6686f5b 100644 --- a/lib/ui/home/dialogs/home_game_login_dialog_ui_model.g.dart +++ b/lib/ui/home/dialogs/home_game_login_dialog_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'home_game_login_dialog_ui_model.dart'; // ************************************************************************** String _$homeGameLoginUIModelHash() => - r'c26dfd89985ff9246104135c288b673b7f15acf0'; + r'bcd5fc6d85345207797dd51253b2608035e1fc36'; /// See also [HomeGameLoginUIModel]. @ProviderFor(HomeGameLoginUIModel) diff --git a/lib/ui/home/dialogs/home_md_content_dialog_ui.dart b/lib/ui/home/dialogs/home_md_content_dialog_ui.dart index 9e28b6b..decad33 100644 --- a/lib/ui/home/dialogs/home_md_content_dialog_ui.dart +++ b/lib/ui/home/dialogs/home_md_content_dialog_ui.dart @@ -36,9 +36,9 @@ class HomeMdContentDialogUI extends HookConsumerWidget { ), actions: [ FilledButton( - child: const Padding( - padding: EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2), - child: Text("关闭"), + child: Padding( + padding: const EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2), + child: Text(S.current.action_close), ), onPressed: () { Navigator.pop(context); @@ -52,4 +52,4 @@ class HomeMdContentDialogUI extends HookConsumerWidget { final r = await RSHttp.getText(url); return r; } -} +} \ No newline at end of file diff --git a/lib/ui/home/downloader/home_downloader_ui.dart b/lib/ui/home/downloader/home_downloader_ui.dart index 54c8740..f956646 100644 --- a/lib/ui/home/downloader/home_downloader_ui.dart +++ b/lib/ui/home/downloader/home_downloader_ui.dart @@ -24,13 +24,13 @@ class HomeDownloaderUI extends HookConsumerWidget { const SizedBox(width: 24), const SizedBox(width: 12), for (final item in , String>{ - const MapEntry("settings", FluentIcons.settings): "限速设置", + const MapEntry("settings", FluentIcons.settings): S.current.downloader_speed_limit_settings, if (state.tasks.isNotEmpty) - const MapEntry("pause_all", FluentIcons.pause): "全部暂停", + const MapEntry("pause_all", FluentIcons.pause): S.current.downloader_action_pause_all, if (state.waitingTasks.isNotEmpty) - const MapEntry("resume_all", FluentIcons.download): "恢复全部", + const MapEntry("resume_all", FluentIcons.download): S.current.downloader_action_resume_all, if (state.tasks.isNotEmpty || state.waitingTasks.isNotEmpty) - const MapEntry("cancel_all", FluentIcons.cancel): "全部取消", + const MapEntry("cancel_all", FluentIcons.cancel): S.current.downloader_action_cancel_all, }.entries) Padding( padding: const EdgeInsets.only(left: 6, right: 6), @@ -52,9 +52,9 @@ class HomeDownloaderUI extends HookConsumerWidget { ], ), if (model.getTasksLen() == 0) - const Expanded( + Expanded( child: Center( - child: Text("无下载任务"), + child: Text(S.current.downloader_info_no_download_tasks), )) else Expanded( @@ -171,22 +171,22 @@ class HomeDownloaderUI extends HookConsumerWidget { if (type != "stopped") DropDownButton( closeAfterClick: false, - title: const Padding( - padding: EdgeInsets.all(3), - child: Text('选项'), + title: Padding( + padding: const EdgeInsets.all(3), + child: Text(S.current.downloader_action_options), ), items: [ if (task.status == "paused") MenuFlyoutItem( leading: const Icon(FluentIcons.download), - text: const Text('继续下载'), + text: Text(S.current.downloader_action_continue_download), onPressed: () => model.resumeTask(task.gid)) else if (task.status == "active") MenuFlyoutItem( leading: const Icon(FluentIcons.pause), - text: const Text('暂停下载'), + text: Text(S.current.downloader_action_pause_download), onPressed: () => model.pauseTask(task.gid)), const MenuFlyoutSeparator(), @@ -195,7 +195,7 @@ class HomeDownloaderUI extends HookConsumerWidget { FluentIcons.chrome_close, size: 14, ), - text: const Text('取消下载'), + text: Text(S.current.downloader_action_cancel_download), onPressed: () => model.cancelTask(context, task.gid)), MenuFlyoutItem( @@ -203,7 +203,7 @@ class HomeDownloaderUI extends HookConsumerWidget { FluentIcons.folder_open, size: 14, ), - text: const Text('打开文件夹'), + text: Text(S.current.action_open_folder), onPressed: () => model.openFolder(task)), ], ), @@ -243,4 +243,4 @@ class HomeDownloaderUI extends HookConsumerWidget { ), useBodyContainer: true); } -} +} \ No newline at end of file diff --git a/lib/ui/home/downloader/home_downloader_ui_model.dart b/lib/ui/home/downloader/home_downloader_ui_model.dart index 2039a34..3d38ca5 100644 --- a/lib/ui/home/downloader/home_downloader_ui_model.dart +++ b/lib/ui/home/downloader/home_downloader_ui_model.dart @@ -21,7 +21,7 @@ part 'home_downloader_ui_model.freezed.dart'; @freezed class HomeDownloaderUIState with _$HomeDownloaderUIState { - const factory HomeDownloaderUIState({ + factory HomeDownloaderUIState({ @Default([]) List tasks, @Default([]) List waitingTasks, @Default([]) List stoppedTasks, @@ -40,23 +40,23 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { bool _disposed = false; final statusMap = { - "active": "下载中...", - "waiting": "等待中", - "paused": "已暂停", - "error": "下载失败", - "complete": "下载完成", - "removed": "已删除", + "active": S.current.downloader_info_downloading_status, + "waiting": S.current.downloader_info_waiting, + "paused": S.current.downloader_info_paused, + "error": S.current.downloader_info_download_failed, + "complete": S.current.downloader_info_download_completed, + "removed": S.current.downloader_info_deleted, }; final listHeaderStatusMap = { - "active": "下载中", - "waiting": "等待中", - "stopped": "已结束", + "active": S.current.downloader_title_downloading, + "waiting": S.current.downloader_info_waiting, + "stopped": S.current.downloader_title_ended, }; @override HomeDownloaderUIState build() { - state = const HomeDownloaderUIState(); + state = HomeDownloaderUIState(); _listenDownloader(); ref.onDispose(() { _disposed = true; @@ -79,7 +79,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { return; case "cancel_all": final userOK = await showConfirmDialogs( - context, "确认取消全部任务?", const Text("如果文件不再需要,你可能需要手动删除下载文件。")); + context, "确认取消全部任务?", Text(S.current.downloader_info_manual_file_deletion_note)); if (userOK == true) { if (!aria2cState.isRunning) return; try { @@ -170,7 +170,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { if (gid != null) { if (!context.mounted) return; final ok = await showConfirmDialogs( - context, "确认取消下载?", const Text("如果文件不再需要,你可能需要手动删除下载文件。")); + context, "确认取消下载?", Text(S.current.downloader_info_manual_file_deletion_note)); if (ok == true) { final aria2c = ref.read(aria2cModelProvider).aria2c; await aria2c?.remove(gid); @@ -242,22 +242,22 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "限速设置", + S.current.downloader_speed_limit_settings, Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "SC 汉化盒子使用 p2p 网络来加速文件下载,如果您流量有限,可在此处将上传带宽设置为 1(byte)。", + S.current.downloader_info_p2p_network_note, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.6), ), ), const SizedBox(height: 24), - const Text("请输入下载单位,如:1、100k、10m, 0或留空为不限速。"), + Text(S.current.downloader_info_download_unit_input_prompt), const SizedBox(height: 12), - const Text("上传限速:"), + Text(S.current.downloader_input_upload_speed_limit), const SizedBox(height: 6), TextFormBox( placeholder: "1、100k、10m、0", @@ -266,7 +266,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { inputFormatters: [ifr], ), const SizedBox(height: 12), - const Text("下载限速:"), + Text(S.current.downloader_input_download_speed_limit), const SizedBox(height: 6), TextFormBox( placeholder: "1、100k、10m、0", @@ -276,7 +276,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { ), const SizedBox(height: 24), Text( - "* P2P 上传仅在下载文件时进行,下载完成后会关闭 p2p 连接。如您想参与做种,请通过关于页面联系我们。", + S.current.downloader_input_info_p2p_upload_note, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(.6), @@ -303,4 +303,4 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel { } } } -} +} \ No newline at end of file diff --git a/lib/ui/home/downloader/home_downloader_ui_model.freezed.dart b/lib/ui/home/downloader/home_downloader_ui_model.freezed.dart index efec400..392d994 100644 --- a/lib/ui/home/downloader/home_downloader_ui_model.freezed.dart +++ b/lib/ui/home/downloader/home_downloader_ui_model.freezed.dart @@ -136,7 +136,7 @@ class __$$HomeDownloaderUIStateImplCopyWithImpl<$Res> /// @nodoc class _$HomeDownloaderUIStateImpl implements _HomeDownloaderUIState { - const _$HomeDownloaderUIStateImpl( + _$HomeDownloaderUIStateImpl( {final List tasks = const [], final List waitingTasks = const [], final List stoppedTasks = const [], @@ -211,7 +211,7 @@ class _$HomeDownloaderUIStateImpl implements _HomeDownloaderUIState { } abstract class _HomeDownloaderUIState implements HomeDownloaderUIState { - const factory _HomeDownloaderUIState( + factory _HomeDownloaderUIState( {final List tasks, final List waitingTasks, final List stoppedTasks, diff --git a/lib/ui/home/downloader/home_downloader_ui_model.g.dart b/lib/ui/home/downloader/home_downloader_ui_model.g.dart index c211874..beac953 100644 --- a/lib/ui/home/downloader/home_downloader_ui_model.g.dart +++ b/lib/ui/home/downloader/home_downloader_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'home_downloader_ui_model.dart'; // ************************************************************************** String _$homeDownloaderUIModelHash() => - r'947ebb9abb262aea6121c74481753da0eebb9a79'; + r'88e1c9a667672d303cb244305dc0aec89d77ffe5'; /// See also [HomeDownloaderUIModel]. @ProviderFor(HomeDownloaderUIModel) diff --git a/lib/ui/home/game_doctor/game_doctor_ui.dart b/lib/ui/home/game_doctor/game_doctor_ui.dart index 11ff98d..7bba454 100644 --- a/lib/ui/home/game_doctor/game_doctor_ui.dart +++ b/lib/ui/home/game_doctor/game_doctor_ui.dart @@ -27,7 +27,7 @@ class HomeGameDoctorUI extends HookConsumerWidget { model.doCheck(context); }); return null; - }, const []); + }, []); return makeDefaultPage(context, title: "一键诊断 -> ${homeState.scInstalledPath}", @@ -40,9 +40,9 @@ class HomeGameDoctorUI extends HookConsumerWidget { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - for (final item in const { - "rsi_log": "RSI启动器log", - "game_log": "游戏运行log", + for (final item in { + "rsi_log": S.current.doctor_action_rsi_launcher_log, + "game_log": S.current.doctor_action_game_run_log, }.entries) Padding( padding: const EdgeInsets.only(left: 6, right: 6), @@ -76,14 +76,14 @@ class HomeGameDoctorUI extends HookConsumerWidget { )) else if (state.checkResult == null || state.checkResult!.isEmpty) ...[ - const Expanded( + Expanded( child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - SizedBox(height: 12), - Text("扫描完毕,没有找到问题!", maxLines: 1), - SizedBox(height: 64), + const SizedBox(height: 12), + Text(S.current.doctor_info_scan_complete_no_issues, maxLines: 1), + const SizedBox(height: 64), ], ), )) @@ -104,7 +104,7 @@ class HomeGameDoctorUI extends HookConsumerWidget { const SizedBox(height: 12), Text(state.isFixingString.isNotEmpty ? state.isFixingString - : "正在处理..."), + : S.current.doctor_info_processing), ], ), ), @@ -122,7 +122,7 @@ class HomeGameDoctorUI extends HookConsumerWidget { return GestureDetector( onTap: () async { await showToast(context, - "您即将前往由 深空治疗中心(QQ群号:536454632 ) 提供的游戏异常救援服务,主要解决游戏安装失败与频繁闪退,如游戏玩法问题,请勿加群。"); + S.current.doctor_info_game_rescue_service_note); launchUrlString( "https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=-M4wEme_bCXbUGT4LFKLH0bAYTFt70Ad&authKey=vHVr0TNgRmKu%2BHwywoJV6EiLa7La2VX74Vkyixr05KA0H9TqB6qWlCdY%2B9jLQ4Ha&noverify=0&group_code=536454632"); }, @@ -140,7 +140,7 @@ class HomeGameDoctorUI extends HookConsumerWidget { children: [ Image.asset("assets/rescue.png", width: 24, height: 24), const SizedBox(width: 12), - const Text("需要帮助? 点击加群寻求免费人工支援!"), + Text(S.current.doctor_info_need_help), ], ), )), @@ -155,7 +155,7 @@ class HomeGameDoctorUI extends HookConsumerWidget { Text(state.lastScreenInfo, maxLines: 1), const SizedBox(height: 12), Text( - "注意:本工具检测结果仅供参考,若您不理解以下操作,请提供截图给有经验的玩家!", + S.current.doctor_info_tool_check_result_note, style: TextStyle(color: Colors.red, fontSize: 16), ), const SizedBox(height: 24), @@ -177,17 +177,17 @@ class HomeGameDoctorUI extends HookConsumerWidget { final errorNames = { "unSupport_system": MapEntry("不支持的操作系统,游戏可能无法运行", "请升级您的系统 (${item.value})"), - "no_live_path": MapEntry("安装目录缺少LIVE文件夹,可能导致安装失败", + "no_live_path": MapEntry(S.current.doctor_info_result_missing_live_folder, "点击修复为您创建 LIVE 文件夹,完成后重试安装。(${item.value})"), - "nvme_PhysicalBytes": MapEntry("新型 NVME 设备,与 RSI 启动器暂不兼容,可能导致安装失败", + "nvme_PhysicalBytes": MapEntry(S.current.doctor_info_result_incompatible_nvme_device, "为注册表项添加 ForcedPhysicalSectorSizeInBytes 值 模拟旧设备。硬盘分区(${item.value})"), - "eac_file_miss": const MapEntry("EasyAntiCheat 文件丢失", - "未在 LIVE 文件夹找到 EasyAntiCheat 文件 或 文件不完整,请使用 RSI 启动器校验文件"), - "eac_not_install": const MapEntry("EasyAntiCheat 未安装 或 未正常退出", - "EasyAntiCheat 未安装,请点击修复为您一键安装。(在游戏正常启动并结束前,该问题会一直出现,若您因为其他原因游戏闪退,可忽略此条目)"), + "eac_file_miss": MapEntry(S.current.doctor_info_result_missing_easyanticheat_files, + S.current.doctor_info_result_verify_files_with_rsi_launcher), + "eac_not_install": MapEntry(S.current.doctor_info_result_easyanticheat_not_installed, + S.current.doctor_info_result_install_easyanticheat), "cn_user_name": - const MapEntry("中文用户名!", "中文用户名可能会导致游戏启动/安装错误! 点击修复按钮查看修改教程!"), - "cn_install_path": MapEntry("中文安装路径!", + MapEntry("中文用户名!", S.current.doctor_info_result_chinese_username_error), + "cn_install_path": MapEntry(S.current.doctor_info_result_chinese_install_path, "中文安装路径!这可能会导致游戏 启动/安装 错误!(${item.value}),请在RSI启动器更换安装路径。"), "low_ram": MapEntry( "物理内存过低", "您至少需要 16GB 的物理内存(Memory)才可运行此游戏。(当前大小:${item.value})"), @@ -224,9 +224,9 @@ class HomeGameDoctorUI extends HookConsumerWidget { : () async { await model.doFix(context, item); }, - child: const Padding( - padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4), - child: Text("修复"), + child: Padding( + padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4), + child: Text(S.current.doctor_info_action_fix), ), ), ), @@ -262,10 +262,10 @@ class HomeGameDoctorUI extends HookConsumerWidget { onPressed: () { launchUrlString(item.value); }, - child: const Padding( + child: Padding( padding: - EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4), - child: Text("查看解决方案"), + const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4), + child: Text(S.current.doctor_action_view_solution), ), ) : null, @@ -284,11 +284,11 @@ class HomeGameDoctorUI extends HookConsumerWidget { case "game_log": if (homeState.scInstalledPath == "not_install" || homeState.scInstalledPath == null) { - showToast(context, "请在首页选择游戏安装目录。"); + showToast(context, S.current.doctor_tip_title_select_game_directory); return; } SystemHelper.openDir("${homeState.scInstalledPath}\\Game.log"); return; } } -} +} \ No newline at end of file diff --git a/lib/ui/home/game_doctor/game_doctor_ui_model.dart b/lib/ui/home/game_doctor/game_doctor_ui_model.dart index 8f186f7..89ffbd9 100644 --- a/lib/ui/home/game_doctor/game_doctor_ui_model.dart +++ b/lib/ui/home/game_doctor/game_doctor_ui_model.dart @@ -17,7 +17,7 @@ part 'game_doctor_ui_model.freezed.dart'; @freezed class HomeGameDoctorState with _$HomeGameDoctorState { - const factory HomeGameDoctorState({ + factory HomeGameDoctorState({ @Default(false) bool isChecking, @Default(false) bool isFixing, @Default("") String lastScreenInfo, @@ -30,7 +30,7 @@ class HomeGameDoctorState with _$HomeGameDoctorState { class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { @override HomeGameDoctorState build() { - state = const HomeGameDoctorState(); + state = HomeGameDoctorState(); return state; } @@ -43,13 +43,13 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { state = state.copyWith(isFixing: true, isFixingString: ""); switch (item.key) { case "unSupport_system": - showToast(context, "若您的硬件达标,请尝试安装最新的 Windows 系统。"); + showToast(context, S.current.doctor_action_result_try_latest_windows); break; case "no_live_path": try { await Directory(item.value).create(recursive: true); if (!context.mounted) break; - showToast(context, "创建文件夹成功,请尝试继续下载游戏!"); + showToast(context, S.current.doctor_action_result_create_folder_success); checkResult.remove(item); state = state.copyWith(checkResult: checkResult); } catch (e) { @@ -61,7 +61,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { if (r == "") { if (!context.mounted) break; showToast(context, - "修复成功,请尝试重启后继续安装游戏! 若注册表修改操作导致其他软件出现兼容问题,请使用 工具 中的 NVME 注册表清理。"); + S.current.doctor_action_result_fix_success); checkResult.remove(item); state = state.copyWith(checkResult: checkResult); } else { @@ -71,7 +71,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { break; case "eac_file_miss": showToast( - context, "未在 LIVE 文件夹找到 EasyAntiCheat 文件 或 文件不完整,请使用 RSI 启动器校验文件"); + context, S.current.doctor_info_result_verify_files_with_rsi_launcher); break; case "eac_not_install": final eacJsonPath = "${item.value}\\Settings.json"; @@ -84,7 +84,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { dPrint("${item.value}\\EasyAntiCheat_EOS_Setup.exe install $eacID"); if (result.stderr == "") { if (!context.mounted) break; - showToast(context, "修复成功,请尝试启动游戏。(若问题无法解决,请使用工具箱的 《重装 EAC》)"); + showToast(context, S.current.doctor_action_result_game_start_success); checkResult.remove(item); state = state.copyWith(checkResult: checkResult); } else { @@ -97,13 +97,13 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { } break; case "cn_user_name": - showToast(context, "即将跳转,教程来自互联网,请谨慎操作..."); + showToast(context, S.current.doctor_action_result_redirect_warning); await Future.delayed(const Duration(milliseconds: 300)); launchUrlString( "https://btfy.eu.org/?q=5L+u5pS5d2luZG93c+eUqOaIt+WQjeS7juS4reaWh+WIsOiLseaWhw=="); break; default: - showToast(context, "该问题暂不支持自动处理,请提供截图寻求帮助"); + showToast(context, S.current.doctor_action_result_issue_not_supported); break; } state = state.copyWith(isFixing: false, isFixingString: ""); @@ -112,7 +112,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { // ignore: avoid_build_context_in_providers doCheck(BuildContext context) async { if (state.isChecking) return; - state = state.copyWith(isChecking: true, lastScreenInfo: "正在分析..."); + state = state.copyWith(isChecking: true, lastScreenInfo: S.current.doctor_action_analyzing); dPrint("-------- start docker check -----"); if (!context.mounted) return; await _statCheck(context); @@ -126,9 +126,9 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { final checkResult = >[]; // TODO for debug - // checkResult?.add(const MapEntry("unSupport_system", "android")); - // checkResult?.add(const MapEntry("nvme_PhysicalBytes", "C")); - // checkResult?.add(const MapEntry("no_live_path", "")); + // checkResult?.add(MapEntry("unSupport_system", "android")); + // checkResult?.add(MapEntry("nvme_PhysicalBytes", "C")); + // checkResult?.add(MapEntry("no_live_path", "")); await _checkPreInstall(context, scInstalledPath, checkResult); if (!context.mounted) return; @@ -137,7 +137,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { await _checkGameRunningLog(context, scInstalledPath, checkResult); if (checkResult.isEmpty) { - const lastScreenInfo = "分析完毕,没有发现问题"; + final lastScreenInfo = S.current.doctor_action_result_analysis_no_issue; state = state.copyWith(checkResult: null, lastScreenInfo: lastScreenInfo); } else { final lastScreenInfo = "分析完毕,发现 ${checkResult.length} 个问题"; @@ -147,7 +147,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { if (scInstalledPath == "not_install" && (checkResult.isEmpty)) { if (!context.mounted) return; - showToast(context, "扫描完毕,没有发现问题,若仍然安装失败,请尝试使用工具箱中的 RSI启动器管理员模式。"); + showToast(context, S.current.doctor_action_result_toast_scan_no_issue); } } @@ -155,7 +155,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { Future _checkGameRunningLog(BuildContext context, String scInstalledPath, List> checkResult) async { if (scInstalledPath == "not_install") return; - const lastScreenInfo = "正在检查:Game.log"; + final lastScreenInfo = S.current.doctor_action_tip_checking_game_log; state = state.copyWith(lastScreenInfo: lastScreenInfo); final logs = await SCLoggerHelper.getGameRunningLogs(scInstalledPath); if (logs == null) return; @@ -174,7 +174,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { Future _checkEAC(BuildContext context, String scInstalledPath, List> checkResult) async { if (scInstalledPath == "not_install") return; - const lastScreenInfo = "正在检查:EAC"; + final lastScreenInfo = S.current.doctor_action_info_checking_eac; state = state.copyWith(lastScreenInfo: lastScreenInfo); final eacPath = "$scInstalledPath\\EasyAntiCheat"; @@ -205,7 +205,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { // ignore: avoid_build_context_in_providers Future _checkPreInstall(BuildContext context, String scInstalledPath, List> checkResult) async { - const lastScreenInfo = "正在检查:运行环境"; + final lastScreenInfo = S.current.doctor_action_info_checking_runtime; state = state.copyWith(lastScreenInfo: lastScreenInfo); if (!(Platform.operatingSystemVersion.contains("Windows 10") || @@ -226,7 +226,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { if (ramSize < 16) { checkResult.add(MapEntry("low_ram", "$ramSize")); } - state = state.copyWith(lastScreenInfo: "正在检查:安装信息"); + state = state.copyWith(lastScreenInfo: S.current.doctor_action_info_checking_install_info); // 检查安装分区 try { final listData = await SCLoggerHelper.getGameInstallPath( @@ -270,4 +270,4 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel { dPrint(e); } } -} +} \ No newline at end of file diff --git a/lib/ui/home/game_doctor/game_doctor_ui_model.freezed.dart b/lib/ui/home/game_doctor/game_doctor_ui_model.freezed.dart index 8289532..51e2d07 100644 --- a/lib/ui/home/game_doctor/game_doctor_ui_model.freezed.dart +++ b/lib/ui/home/game_doctor/game_doctor_ui_model.freezed.dart @@ -147,7 +147,7 @@ class __$$HomeGameDoctorStateImplCopyWithImpl<$Res> /// @nodoc class _$HomeGameDoctorStateImpl implements _HomeGameDoctorState { - const _$HomeGameDoctorStateImpl( + _$HomeGameDoctorStateImpl( {this.isChecking = false, this.isFixing = false, this.lastScreenInfo = "", @@ -217,7 +217,7 @@ class _$HomeGameDoctorStateImpl implements _HomeGameDoctorState { } abstract class _HomeGameDoctorState implements HomeGameDoctorState { - const factory _HomeGameDoctorState( + factory _HomeGameDoctorState( {final bool isChecking, final bool isFixing, final String lastScreenInfo, diff --git a/lib/ui/home/game_doctor/game_doctor_ui_model.g.dart b/lib/ui/home/game_doctor/game_doctor_ui_model.g.dart index 61883ab..59e1ea8 100644 --- a/lib/ui/home/game_doctor/game_doctor_ui_model.g.dart +++ b/lib/ui/home/game_doctor/game_doctor_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'game_doctor_ui_model.dart'; // ************************************************************************** String _$homeGameDoctorUIModelHash() => - r'1e32d75095de065cf2cdedf444f74ffc753ce66f'; + r'10e8103fca9565ee6363c093e1d0bf2bc9e68f41'; /// See also [HomeGameDoctorUIModel]. @ProviderFor(HomeGameDoctorUIModel) diff --git a/lib/ui/home/home_ui.dart b/lib/ui/home/home_ui.dart index 95ce996..1f59ea9 100644 --- a/lib/ui/home/home_ui.dart +++ b/lib/ui/home/home_ui.dart @@ -41,7 +41,7 @@ class HomeUI extends HookConsumerWidget { action: homeState.appPlacardData?.link == null ? null : Button( - child: const Text('查看详情'), + child: Text(S.current.doctor_action_view_details), onPressed: () => _showPlacard(context, homeState), ), onClose: homeState.appPlacardData?.alwaysShow == true @@ -68,7 +68,7 @@ class HomeUI extends HookConsumerWidget { const SizedBox(height: 12), Text(homeState.isFixingString.isNotEmpty ? homeState.isFixingString - : "正在处理..."), + : S.current.doctor_info_processing), ], ), ), @@ -79,7 +79,7 @@ class HomeUI extends HookConsumerWidget { List makeIndex(BuildContext context, HomeUIModel model, HomeUIModelState homeState, WidgetRef ref) { - const double width = 280; + double width = 280; return [ Stack( children: [ @@ -122,16 +122,16 @@ class HomeUI extends HookConsumerWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Text("安装位置:"), + Text(S.current.home_install_location), const SizedBox(width: 6), Expanded( child: ComboBox( value: homeState.scInstalledPath, isExpanded: true, items: [ - const ComboBoxItem( + ComboBoxItem( value: "not_install", - child: Text("未安装 或 安装失败"), + child: Text(S.current.home_not_installed_or_failed), ), for (final path in homeState.scInstallPaths) ComboBoxItem( @@ -207,10 +207,10 @@ class HomeUI extends HookConsumerWidget { colorFilter: makeSvgColor(Colors.white), height: 18, ), - name: "星际公民官网汉化", - webTitle: "星际公民官网汉化", + name: S.current.home_action_star_citizen_website_localization, + webTitle: S.current.home_action_star_citizen_website_localization, webURL: "https://robertsspaceindustries.com", - info: "罗伯茨航天工业公司,万物的起源", + info: S.current.home_action_info_roberts_space_industries_origin, useLocalization: true, width: width, touchKey: "webLocalization_rsi"), @@ -225,10 +225,10 @@ class HomeUI extends HookConsumerWidget { const SizedBox(width: 12), ], ), - name: "UEX 汉化", - webTitle: "UEX 汉化", + name: S.current.home_action_uex_localization, + webTitle: S.current.home_action_uex_localization, webURL: "https://uexcorp.space/", - info: "采矿、精炼、贸易计算器、价格、船信息", + info: S.current.home_action_info_mining_refining_trade_calculator, useLocalization: true, width: width, touchKey: "webLocalization_uex"), @@ -243,15 +243,15 @@ class HomeUI extends HookConsumerWidget { const SizedBox(width: 12), ], ), - name: "DPS计算器汉化", - webTitle: "DPS计算器汉化", + name: S.current.home_action_dps_calculator_localization, + webTitle: S.current.home_action_dps_calculator_localization, webURL: "https://www.erkul.games/live/calculator", - info: "在线改船,查询伤害数值和配件购买地点", + info: S.current.home_action_info_ship_upgrade_damage_value_query, useLocalization: true, width: width, touchKey: "webLocalization_dps"), const SizedBox(height: 12), - const Text("外部浏览器拓展:"), + Text(S.current.home_action_external_browser_extension), const SizedBox(height: 12), Row( children: [ @@ -434,11 +434,11 @@ class HomeUI extends HookConsumerWidget { Widget makeIndexActionLists(BuildContext context, HomeUIModel model, HomeUIModelState homeState, WidgetRef ref) { final items = [ - _HomeItemData("game_doctor", "一键诊断", "一键诊断星际公民常见问题", + _HomeItemData("game_doctor", "一键诊断", S.current.home_action_info_one_click_diagnosis_star_citizen, FluentIcons.auto_deploy_settings), _HomeItemData( - "localization", "汉化管理", "快捷安装汉化资源", FluentIcons.locale_language), - _HomeItemData("performance", "性能优化", "调整引擎配置文件,优化游戏性能", + "localization", "汉化管理", S.current.home_action_info_quick_install_localization_resources, FluentIcons.locale_language), + _HomeItemData("performance", "性能优化", S.current.home_action_info_engine_config_optimization, FluentIcons.process_meta_task), ]; return Padding( @@ -589,11 +589,11 @@ class HomeUI extends HookConsumerWidget { Widget makeGameStatusCard(BuildContext context, HomeUIModel model, double width, HomeUIModelState homeState) { - const statusCnName = { - "Platform": "平台", - "Persistent Universe": "持续宇宙", - "Electronic Access": "电子访问", - "Arena Commander": "竞技场指挥官" + final statusCnName = { + "Platform": S.current.home_action_rsi_status_platform, + "Persistent Universe": S.current.home_action_rsi_status_persistent_universe, + "Electronic Access": S.current.home_action_rsi_status_electronic_access, + "Arena Commander": S.current.home_action_rsi_status_arena_commander }; return Tilt( @@ -601,7 +601,7 @@ class HomeUI extends HookConsumerWidget { borderRadius: BorderRadius.circular(12), child: GestureDetector( onTap: () { - model.goWebView(context, "RSI 服务器状态", + model.goWebView(context, S.current.home_action_rsi_status_rsi_server_status, "https://status.robertsspaceindustries.com/", useLocalization: true); }, @@ -619,7 +619,7 @@ class HomeUI extends HookConsumerWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text("状态:"), + Text(S.current.home_action_rsi_status_status), for (final item in homeState.scServerStatus ?? []) Row( children: [ @@ -741,7 +741,7 @@ class HomeUI extends HookConsumerWidget { context: context, builder: (context) { return HomeMdContentDialogUI( - title: homeState.appPlacardData?.title ?? "公告详情", + title: homeState.appPlacardData?.title ?? S.current.home_announcement_details, url: homeState.appPlacardData?.link, ); }); @@ -756,7 +756,7 @@ class HomeUI extends HookConsumerWidget { _onMenuTap(BuildContext context, String key, HomeUIModelState homeState, WidgetRef ref) async { - const String gameInstallReqInfo = + String gameInstallReqInfo = "该功能需要一个有效的安装位置\n\n如果您的游戏未下载完成,请等待下载完毕后使用此功能。\n\n如果您的游戏已下载完毕但未识别,请启动一次游戏后重新打开盒子 或 在设置选项中手动设置安装位置。"; switch (key) { case "localization": @@ -786,4 +786,4 @@ class _HomeItemData { String name; String infoString; IconData icon; -} +} \ No newline at end of file diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index 6fc8764..825490f 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -77,7 +77,8 @@ class HomeUIModel extends _$HomeUIModel { Future reScanPath() async { state = state.copyWith( - scInstalledPath: "not_install", lastScreenInfo: "正在扫描 ..."); + scInstalledPath: "not_install", + lastScreenInfo: S.current.home_action_info_scanning); try { final listData = await SCLoggerHelper.getLauncherLogList(); if (listData == null) { @@ -97,10 +98,11 @@ class HomeUIModel extends _$HomeUIModel { lastScreenInfo: lastScreenInfo); } catch (e) { state = state.copyWith( - scInstalledPath: "not_install", lastScreenInfo: "解析 log 文件失败!"); + scInstalledPath: "not_install", + lastScreenInfo: S.current.home_action_info_log_file_parse_fail); AnalyticsApi.touch("error_launchLogs"); // showToast(context!, - // "解析 log 文件失败! \n请关闭游戏,退出RSI启动器后重试,若仍有问题,请使用工具箱中的 RSI Launcher log 修复。"); + // "${S.current.home_action_info_log_file_parse_fail} \n请关闭游戏,退出RSI启动器后重试,若仍有问题,请使用工具箱中的 RSI Launcher log 修复。"); } } @@ -138,7 +140,7 @@ class HomeUIModel extends _$HomeUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "星际公民网站汉化", + S.current.home_action_title_star_citizen_website_localization, const Text( "本插功能件仅供大致浏览使用,不对任何有关本功能产生的问题负责!在涉及账号操作前请注意确认网站的原本内容!" "\n\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。", @@ -157,7 +159,8 @@ class HomeUIModel extends _$HomeUIModel { } if (!await WebviewWindow.isWebviewAvailable()) { if (!context.mounted) return; - showToast(context, "需要安装 WebView2 Runtime"); + showToast(context, + S.current.home_login_action_title_need_webview2_runtime); launchUrlString( "https://developer.microsoft.com/en-us/microsoft-edge/webview2/"); return; @@ -166,7 +169,10 @@ class HomeUIModel extends _$HomeUIModel { final webViewModel = WebViewModel(context, loginMode: loginMode, loginCallback: rsiLoginCallback); if (useLocalization) { - state = state.copyWith(isFixing: true, isFixingString: "正在初始化汉化资源..."); + state = state.copyWith( + isFixing: true, + isFixingString: + S.current.home_action_info_initializing_resources); try { await webViewModel.initLocalization(state.webLocalizationVersionsData!); } catch (e) { @@ -280,14 +286,14 @@ class HomeUIModel extends _$HomeUIModel { _appUpdateTimer?.cancel(); _appUpdateTimer = null; // 发送通知 - final toastNotifier = - ToastNotificationManager.createToastNotifierWithId("SC汉化盒子"); + final toastNotifier = ToastNotificationManager.createToastNotifierWithId( + S.current.home_title_app_name); if (toastNotifier != null) { final toastContent = ToastNotificationManager.getTemplateContent( ToastTemplateType.toastText02); if (toastContent != null) { final xmlNodeList = toastContent.getElementsByTagName('text'); - const title = '汉化有新版本!'; + final title = S.current.home_localization_new_version_available; final content = '您在 ${updates.first} 安装的汉化有新版本啦!'; xmlNodeList.item(0)?.appendChild(toastContent.createTextNode(title)); xmlNodeList @@ -304,7 +310,7 @@ class HomeUIModel extends _$HomeUIModel { // ignore: avoid_build_context_in_providers launchRSI(BuildContext context) async { if (state.scInstalledPath == "not_install") { - showToast(context, "该功能需要一个有效的安装位置"); + showToast(context, S.current.home_info_valid_installation_required); return; } @@ -322,11 +328,11 @@ class HomeUIModel extends _$HomeUIModel { } else { final ok = await showConfirmDialogs( context, - "一键启动功能提示", + S.current.home_info_one_click_launch_warning, const Text("为确保账户安全,一键启动功能已在开发版中禁用,我们将在微软商店版本中提供此功能。" "\n\n微软商店版由微软提供可靠的分发下载与数字签名,可有效防止软件被恶意篡改。\n\n提示:您无需使用盒子启动游戏也可使用汉化。"), - confirm: "安装微软商店版本", - cancel: "取消"); + confirm: S.current.home_action_install_microsoft_store_version, + cancel: S.current.home_action_cancel); if (ok == true) { await launchUrlString( "https://apps.microsoft.com/detail/9NF3SWFWNKL1?launch=true"); diff --git a/lib/ui/home/home_ui_model.g.dart b/lib/ui/home/home_ui_model.g.dart index 9a7d2c9..a9f4233 100644 --- a/lib/ui/home/home_ui_model.g.dart +++ b/lib/ui/home/home_ui_model.g.dart @@ -6,7 +6,7 @@ part of 'home_ui_model.dart'; // RiverpodGenerator // ************************************************************************** -String _$homeUIModelHash() => r'a911826a7b852408123bf4b8999ac80c3c582fd4'; +String _$homeUIModelHash() => r'8268fab911b162f2f3f8a5a86449ea15a759569b'; /// See also [HomeUIModel]. @ProviderFor(HomeUIModel) diff --git a/lib/ui/home/localization/localization_dialog_ui.dart b/lib/ui/home/localization/localization_dialog_ui.dart index aba0d12..bf6a6e4 100644 --- a/lib/ui/home/localization/localization_dialog_ui.dart +++ b/lib/ui/home/localization/localization_dialog_ui.dart @@ -35,13 +35,14 @@ class LocalizationDialogUI extends HookConsumerWidget { AnimatedSize( duration: const Duration(milliseconds: 130), child: state.patchStatus?.key == true && - state.patchStatus?.value == "游戏内置" + state.patchStatus?.value == + S.current.home_action_info_game_built_in ? Padding( padding: const EdgeInsets.only(bottom: 12), child: InfoBar( - title: const Text("警告"), - content: const Text( - "您正在使用游戏内置文本,官方文本目前为机器翻译(截至3.21.0),建议您在下方安装社区汉化。"), + title: Text(S.current.home_action_info_warning), + content: Text( + S.current.localization_info_machine_translation_warning), severity: InfoBarSeverity.info, style: InfoBarThemeData(decoration: (severity) { return const BoxDecoration( @@ -56,7 +57,7 @@ class LocalizationDialogUI extends HookConsumerWidget { ), ), makeListContainer( - "汉化状态", + S.current.localization_info_translation_status, [ if (state.patchStatus == null) makeLoading(context) @@ -80,31 +81,34 @@ class LocalizationDialogUI extends HookConsumerWidget { children: [ Text("已安装版本:${state.patchStatus?.value}"), const Spacer(), - if (state.patchStatus?.value != "游戏内置") + if (state.patchStatus?.value != + S.current.home_action_info_game_built_in) Row( children: [ Button( onPressed: model.goFeedback, - child: const Padding( - padding: EdgeInsets.all(4), + child: Padding( + padding: const EdgeInsets.all(4), child: Row( children: [ - Icon(FluentIcons.feedback), - SizedBox(width: 6), - Text("汉化反馈"), + const Icon(FluentIcons.feedback), + const SizedBox(width: 6), + Text( + S.current.localization_action_translation_feedback), ], ), )), const SizedBox(width: 16), Button( onPressed: model.doDelIniFile(), - child: const Padding( - padding: EdgeInsets.all(4), + child: Padding( + padding: const EdgeInsets.all(4), child: Row( children: [ - Icon(FluentIcons.delete), - SizedBox(width: 6), - Text("卸载汉化"), + const Icon(FluentIcons.delete), + const SizedBox(width: 6), + Text( + S.current.localization_action_uninstall_translation), ], ), )), @@ -130,9 +134,9 @@ class LocalizationDialogUI extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - "备注:", - style: TextStyle(fontSize: 18), + Text( + S.current.localization_info_note, + style: const TextStyle(fontSize: 18), ), const SizedBox(height: 6), Text( @@ -154,14 +158,14 @@ class LocalizationDialogUI extends HookConsumerWidget { ], context), makeListContainer( - "社区汉化", + S.current.localization_info_community_translation, [ if (state.apiLocalizationData == null) makeLoading(context) else if (state.apiLocalizationData!.isEmpty) Center( child: Text( - "该语言/版本 暂无可用汉化,敬请期待!", + S.current.localization_info_no_translation_available, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(.8)), @@ -181,7 +185,8 @@ class LocalizationDialogUI extends HookConsumerWidget { ? FluentIcons.chevron_up : FluentIcons.chevron_down), const SizedBox(width: 12), - const Text("高级功能"), + Text( + S.current.localization_action_advanced_features), ], ), onPressed: model.toggleCustomize), @@ -192,14 +197,14 @@ class LocalizationDialogUI extends HookConsumerWidget { const SizedBox(height: 12), state.enableCustomize ? makeListContainer( - "自定义文本", + S.current.localization_info_custom_text, [ if (state.customizeList == null) makeLoading(context) else if (state.customizeList!.isEmpty) Center( child: Text( - "暂无自定义文本", + S.current.localization_info_no_custom_text, style: TextStyle( fontSize: 13, color: Colors.white.withOpacity(.8)), @@ -222,13 +227,14 @@ class LocalizationDialogUI extends HookConsumerWidget { Button( onPressed: model.doLocalInstall(file), - child: const Padding( - padding: EdgeInsets.only( + child: Padding( + padding: const EdgeInsets.only( left: 8, right: 8, top: 4, bottom: 4), - child: Text("安装"), + child: Text( + S.current.localization_action_install), )) ], ) @@ -238,13 +244,13 @@ class LocalizationDialogUI extends HookConsumerWidget { actions: [ Button( onPressed: () => model.openDir(context), - child: const Padding( - padding: EdgeInsets.all(4), + child: Padding( + padding: const EdgeInsets.all(4), child: Row( children: [ - Icon(FluentIcons.folder_open), - SizedBox(width: 6), - Text("打开文件夹"), + const Icon(FluentIcons.folder_open), + const SizedBox(width: 6), + Text(S.current.action_open_folder), ], ), )), @@ -324,8 +330,10 @@ class LocalizationDialogUI extends HookConsumerWidget { : FluentIcons.disable_updates), ), Text(isInstalled - ? "已安装" - : ((item.value.enable ?? false) ? "安装" : "不可用")), + ? S.current.localization_info_installed + : ((item.value.enable ?? false) + ? "安装" + : S.current.localization_info_unavailable)), ], ), )), @@ -396,7 +404,7 @@ class LocalizationDialogUI extends HookConsumerWidget { ), onPressed: model.onBack(context)), const SizedBox(width: 12), - const Text("汉化管理"), + Text(S.current.home_action_localization_management), const SizedBox(width: 24), Text( "${model.getScInstallPath()}", @@ -407,9 +415,9 @@ class LocalizationDialogUI extends HookConsumerWidget { height: 36, child: Row( children: [ - const Text( - "语言: ", - style: TextStyle(fontSize: 16), + Text( + S.current.localization_info_language, + style: const TextStyle(fontSize: 16), ), ComboBox( value: state.selectedLanguage, diff --git a/lib/ui/home/localization/localization_ui_model.dart b/lib/ui/home/localization/localization_ui_model.dart index f8d2a4f..9611d47 100644 --- a/lib/ui/home/localization/localization_ui_model.dart +++ b/lib/ui/home/localization/localization_ui_model.dart @@ -26,7 +26,7 @@ part 'localization_ui_model.freezed.dart'; @freezed class LocalizationUIState with _$LocalizationUIState { - const factory LocalizationUIState({ + factory LocalizationUIState({ String? selectedLanguage, Map? apiLocalizationData, @Default("") String workingVersion, @@ -38,7 +38,7 @@ class LocalizationUIState with _$LocalizationUIState { @riverpod class LocalizationUIModel extends _$LocalizationUIModel { - static const languageSupport = { + static const languageSupport = { "chinese_(simplified)": "简体中文", "chinese_(traditional)": "繁體中文", }; @@ -122,7 +122,7 @@ class LocalizationUIModel extends _$LocalizationUIModel { if (!context.mounted) return; final ok = await showConfirmDialogs( context, - "是否移除不兼容的汉化参数", + S.current.localization_info_remove_incompatible_translation_params, const Text( "USER.cfg 包含不兼容的汉化参数,这可能是以前的汉化文件的残留信息。\n\n这将可能导致汉化无效或乱码,点击确认为您一键移除(不会影响其他配置)。"), constraints: BoxConstraints( @@ -288,7 +288,7 @@ class LocalizationUIModel extends _$LocalizationUIModel { // check file final globalIni = await compute(_readArchive, savePath.absolute.path); if (globalIni.isEmpty) { - throw "文件受损,请重新下载"; + throw S.current.localization_info_corrupted_file; } await _installFormString(globalIni, value.versionName ?? ""); } catch (e) { @@ -371,7 +371,7 @@ class LocalizationUIModel extends _$LocalizationUIModel { static Future _getInstalledIniVersion(String iniPath) async { final iniFile = File(iniPath); - if (!await iniFile.exists()) return "游戏内置"; + if (!await iniFile.exists()) return S.current.home_action_info_game_built_in; final iniStringSplit = (await iniFile.readAsString()).split("\n"); for (var i = iniStringSplit.length - 1; i > 0; i--) { if (iniStringSplit[i] @@ -382,7 +382,7 @@ class LocalizationUIModel extends _$LocalizationUIModel { return v; } } - return "自定义文件"; + return S.current.localization_info_custom_files; } Future> checkLangUpdate({bool skipReload = false}) async { @@ -408,7 +408,7 @@ class LocalizationUIModel extends _$LocalizationUIModel { if (element.path.contains(lang)) { final installedVersion = await _getInstalledIniVersion("${element.path}\\global.ini"); - if (installedVersion == "游戏内置") continue; + if (installedVersion == S.current.home_action_info_game_built_in) continue; final curData = _allVersionLocalizationData[lang]; dPrint("check Localization update $scInstallPath"); if (!(curData?.keys.contains(installedVersion) ?? false)) { @@ -428,4 +428,4 @@ class LocalizationUIModel extends _$LocalizationUIModel { } return updates; } -} +} \ No newline at end of file diff --git a/lib/ui/home/localization/localization_ui_model.freezed.dart b/lib/ui/home/localization/localization_ui_model.freezed.dart index 9f1bf50..4e9e57d 100644 --- a/lib/ui/home/localization/localization_ui_model.freezed.dart +++ b/lib/ui/home/localization/localization_ui_model.freezed.dart @@ -160,7 +160,7 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res> /// @nodoc class _$LocalizationUIStateImpl implements _LocalizationUIState { - const _$LocalizationUIStateImpl( + _$LocalizationUIStateImpl( {this.selectedLanguage, final Map? apiLocalizationData, this.workingVersion = "", @@ -245,7 +245,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState { } abstract class _LocalizationUIState implements LocalizationUIState { - const factory _LocalizationUIState( + factory _LocalizationUIState( {final String? selectedLanguage, final Map? apiLocalizationData, final String workingVersion, diff --git a/lib/ui/home/localization/localization_ui_model.g.dart b/lib/ui/home/localization/localization_ui_model.g.dart index cfdaf16..accced6 100644 --- a/lib/ui/home/localization/localization_ui_model.g.dart +++ b/lib/ui/home/localization/localization_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'localization_ui_model.dart'; // ************************************************************************** String _$localizationUIModelHash() => - r'654fd38b5f38bee5fd2cab69ab003846a311a4ff'; + r'33c538abcdbfd667e844d0dcb5b8b7d6264794ab'; /// See also [LocalizationUIModel]. @ProviderFor(LocalizationUIModel) diff --git a/lib/ui/home/performance/performance_ui.dart b/lib/ui/home/performance/performance_ui.dart index 8087db5..166aa49 100644 --- a/lib/ui/home/performance/performance_ui.dart +++ b/lib/ui/home/performance/performance_ui.dart @@ -30,9 +30,10 @@ class HomePerformanceUI extends HookConsumerWidget { children: [ if (state.showGraphicsPerformanceTip) InfoBar( - title: const Text("图形优化提示"), - content: const Text( - "该功能对优化显卡瓶颈有很大帮助,但对 CPU 瓶颈可能起反效果,如果您显卡性能强劲,可以尝试使用更好的画质来获得更高的显卡利用率。", + title: Text( + S.current.performance_info_graphic_optimization_hint), + content: Text( + S.current.performance_info_graphic_optimization_warning, ), onClose: () => model.closeTip(), ), @@ -44,15 +45,15 @@ class HomePerformanceUI extends HookConsumerWidget { style: const TextStyle(fontSize: 18), ), const SizedBox(width: 32), - const Text( - "预设:", - style: TextStyle(fontSize: 18), + Text( + S.current.performance_action_preset, + style: const TextStyle(fontSize: 18), ), - for (final item in const { - "low": "低", - "medium": "中", - "high": "高", - "ultra": "超级" + for (final item in { + "low": S.current.performance_action_low, + "medium": S.current.performance_action_medium, + "high": S.current.performance_action_high, + "ultra": S.current.performance_action_super }.entries) Padding( padding: const EdgeInsets.only(left: 6, right: 6), @@ -65,7 +66,8 @@ class HomePerformanceUI extends HookConsumerWidget { onPressed: () => model.onChangePreProfile(item.key)), ), - const Text("(预设只修改图形设置)"), + Text( + S.current.performance_action_info_preset_only_changes_graphics), const Spacer(), Button( onPressed: () => model.refresh(), @@ -76,23 +78,23 @@ class HomePerformanceUI extends HookConsumerWidget { ), const SizedBox(width: 12), Button( - child: const Text( - " 恢复默认 ", - style: TextStyle(fontSize: 16), + child: Text( + S.current.performance_action_reset_to_default, + style: const TextStyle(fontSize: 16), ), onPressed: () => model.clean(context)), const SizedBox(width: 24), Button( - child: const Text( - "应用", - style: TextStyle(fontSize: 16), + child: Text( + S.current.performance_action_apply, + style: const TextStyle(fontSize: 16), ), onPressed: () => model.applyProfile(false)), const SizedBox(width: 6), Button( - child: const Text( - "应用并清理着色器(推荐)", - style: TextStyle(fontSize: 16), + child: Text( + S.current.performance_action_apply_and_clear_shaders, + style: const TextStyle(fontSize: 16), ), onPressed: () => model.applyProfile(true)), ], diff --git a/lib/ui/home/performance/performance_ui_model.dart b/lib/ui/home/performance/performance_ui_model.dart index db2398d..c74e091 100644 --- a/lib/ui/home/performance/performance_ui_model.dart +++ b/lib/ui/home/performance/performance_ui_model.dart @@ -11,6 +11,7 @@ import 'package:starcitizen_doctor/api/analytics.dart'; import 'package:starcitizen_doctor/common/helper/log_helper.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart'; import 'package:starcitizen_doctor/data/game_performance_data.dart'; +import 'package:starcitizen_doctor/generated/l10n.dart'; import 'package:starcitizen_doctor/ui/home/home_ui_model.dart'; part 'performance_ui_model.freezed.dart'; @@ -19,7 +20,7 @@ part 'performance_ui_model.g.dart'; @freezed class HomePerformanceUIState with _$HomePerformanceUIState { - const factory HomePerformanceUIState({ + factory HomePerformanceUIState({ @Default(true) bool showGraphicsPerformanceTip, @Default(false) bool enabled, Map>? performanceMap, @@ -41,7 +42,7 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { @override HomePerformanceUIState build() { - state = const HomePerformanceUIState(); + state = HomePerformanceUIState(); _init(); return state; } @@ -111,7 +112,7 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { switch (key) { case "low": state.performanceMap?.forEach((key, v) { - if (key.contains("图形")) { + if (key.contains(S.current.performance_info_graphics)) { for (var element in v) { element.value = element.min; } @@ -120,7 +121,7 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { break; case "medium": state.performanceMap?.forEach((key, v) { - if (key.contains("图形")) { + if (key.contains(S.current.performance_info_graphics)) { for (var element in v) { element.value = ((element.max ?? 0) ~/ 2); } @@ -129,7 +130,7 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { break; case "high": state.performanceMap?.forEach((key, v) { - if (key.contains("图形")) { + if (key.contains(S.current.performance_info_graphics)) { for (var element in v) { element.value = ((element.max ?? 0) / 1.5).ceil(); } @@ -138,7 +139,7 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { break; case "ultra": state.performanceMap?.forEach((key, v) { - if (key.contains("图形")) { + if (key.contains(S.current.performance_info_graphics)) { for (var element in v) { element.value = element.max; } @@ -154,14 +155,14 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { } clean(BuildContext context) async { - state = state.copyWith(workingString: "删除配置文件..."); + state = state.copyWith(workingString: S.current.performance_info_delete_config_file); if (await confFile.exists()) { await confFile.delete(recursive: true); } - state = state.copyWith(workingString: "清理着色器"); + state = state.copyWith(workingString: S.current.performance_action_clear_shaders); if (!context.mounted) return; await cleanShaderCache(context); - state = state.copyWith(workingString: "完成..."); + state = state.copyWith(workingString: S.current.performance_info_done); await await Future.delayed(const Duration(milliseconds: 300)); await _init(); state = state.copyWith(workingString: ""); @@ -180,14 +181,14 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { } await Future.delayed(const Duration(milliseconds: 300)); if (context != null && context.mounted) { - showToast(context, "清理着色器后首次进入游戏可能会出现卡顿,请耐心等待游戏初始化完毕。"); + showToast(context, S.current.performance_info_shader_clearing_warning); } } applyProfile(bool cleanShader) async { if (state.performanceMap == null) return; AnalyticsApi.touch("performance_apply"); - state = state.copyWith(workingString: "生成配置文件"); + state = state.copyWith(workingString: S.current.performance_info_generate_config_file); String conf = ""; for (var v in state.performanceMap!.entries) { for (var c in v.value) { @@ -206,23 +207,23 @@ class HomePerformanceUIModel extends _$HomePerformanceUIModel { } } } - state = state.copyWith(workingString: "写出配置文件"); + state = state.copyWith(workingString: S.current.performance_info_write_out_config_file); if (await confFile.exists()) { await confFile.delete(); } await confFile.create(); await confFile.writeAsString(conf); if (cleanShader) { - state = state.copyWith(workingString: "清理着色器"); + state = state.copyWith(workingString: S.current.performance_action_clear_shaders); await cleanShaderCache(null); } - state = state.copyWith(workingString: "完成..."); + state = state.copyWith(workingString: S.current.performance_info_done); await await Future.delayed(const Duration(milliseconds: 300)); await _init(); - state = state.copyWith(workingString: "清理着色器"); + state = state.copyWith(workingString: S.current.performance_action_clear_shaders); } updateState() { state = state.copyWith(); } -} +} \ No newline at end of file diff --git a/lib/ui/home/performance/performance_ui_model.freezed.dart b/lib/ui/home/performance/performance_ui_model.freezed.dart index 16b4f23..2f09f66 100644 --- a/lib/ui/home/performance/performance_ui_model.freezed.dart +++ b/lib/ui/home/performance/performance_ui_model.freezed.dart @@ -138,7 +138,7 @@ class __$$HomePerformanceUIStateImplCopyWithImpl<$Res> /// @nodoc class _$HomePerformanceUIStateImpl implements _HomePerformanceUIState { - const _$HomePerformanceUIStateImpl( + _$HomePerformanceUIStateImpl( {this.showGraphicsPerformanceTip = true, this.enabled = false, final Map>? performanceMap, @@ -203,7 +203,7 @@ class _$HomePerformanceUIStateImpl implements _HomePerformanceUIState { } abstract class _HomePerformanceUIState implements HomePerformanceUIState { - const factory _HomePerformanceUIState( + factory _HomePerformanceUIState( {final bool showGraphicsPerformanceTip, final bool enabled, final Map>? performanceMap, diff --git a/lib/ui/home/performance/performance_ui_model.g.dart b/lib/ui/home/performance/performance_ui_model.g.dart index aeb365c..43c5ce2 100644 --- a/lib/ui/home/performance/performance_ui_model.g.dart +++ b/lib/ui/home/performance/performance_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'performance_ui_model.dart'; // ************************************************************************** String _$homePerformanceUIModelHash() => - r'85e3390e954b35ffeb7cbacf85619b5a61f866bb'; + r'0519b95b68b4bffcd940513fa800654c81da2502'; /// See also [HomePerformanceUIModel]. @ProviderFor(HomePerformanceUIModel) diff --git a/lib/ui/index_ui.dart b/lib/ui/index_ui.dart index 210db0e..eaa6450 100644 --- a/lib/ui/index_ui.dart +++ b/lib/ui/index_ui.dart @@ -87,11 +87,11 @@ class IndexUI extends HookConsumerWidget { } Map get pageMenus => { - FluentIcons.home: "首页", - FluentIcons.game: "大厅", - FluentIcons.toolbox: "工具", - FluentIcons.settings: "设置", - FluentIcons.info: "关于", + FluentIcons.home: S.current.app_index_menu_home, + FluentIcons.game: S.current.app_index_menu_lobby, + FluentIcons.toolbox: S.current.app_index_menu_tools, + FluentIcons.settings: S.current.app_index_menu_settings, + FluentIcons.info: S.current.app_index_menu_about, }; List getNavigationPaneItems( @@ -181,4 +181,4 @@ class IndexUI extends HookConsumerWidget { _goDownloader(BuildContext context) { context.push('/index/downloader'); } -} +} \ No newline at end of file diff --git a/lib/ui/party_room/party_room_ui.dart b/lib/ui/party_room/party_room_ui.dart index 2e7cdfd..4ed41dc 100644 --- a/lib/ui/party_room/party_room_ui.dart +++ b/lib/ui/party_room/party_room_ui.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:starcitizen_doctor/generated/l10n.dart'; import 'package:url_launcher/url_launcher_string.dart'; class PartyRoomUI extends HookConsumerWidget { @@ -11,22 +12,22 @@ class PartyRoomUI extends HookConsumerWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const Text( - "联机大厅,敬请期待 !", - style: TextStyle(fontSize: 20), + Text( + S.current.lobby_online_lobby_coming_soon, + style: const TextStyle(fontSize: 20), ), const SizedBox(height: 12), GestureDetector( onTap: () { launchUrlString("https://wj.qq.com/s2/14112124/f4c8/"); }, - child: const Row( + child: Row( mainAxisSize: MainAxisSize.min, children: [ - Text("诚邀您参与 "), + Text(S.current.lobby_invitation_to_participate), Text( - "问卷调查。", - style: TextStyle( + S.current.lobby_survey, + style: const TextStyle( color: Colors.blue, ), ) @@ -37,4 +38,4 @@ class PartyRoomUI extends HookConsumerWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/ui/settings/settings_ui.dart b/lib/ui/settings/settings_ui.dart index c1bfe15..23756ce 100644 --- a/lib/ui/settings/settings_ui.dart +++ b/lib/ui/settings/settings_ui.dart @@ -2,6 +2,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:starcitizen_doctor/common/conf/const_conf.dart'; +import 'package:starcitizen_doctor/generated/l10n.dart'; import 'package:starcitizen_doctor/ui/settings/settings_ui_model.dart'; class SettingsUI extends HookConsumerWidget { @@ -17,59 +18,59 @@ class SettingsUI extends HookConsumerWidget { margin: const EdgeInsets.all(16), child: Column( children: [ - makeSettingsItem(const Icon(FluentIcons.link, size: 20), "创建设置快捷方式", - subTitle: "在桌面创建《SC汉化盒子》快捷方式", onTap: ()=> model.addShortCut(context)), + makeSettingsItem(const Icon(FluentIcons.link, size: 20), S.current.setting_action_create_settings_shortcut, + subTitle: S.current.setting_action_create_desktop_shortcut, onTap: ()=> model.addShortCut(context)), if (ConstConf.isMSE) ...[ const SizedBox(height: 12), makeSettingsItem( - const Icon(FluentIcons.reset_device, size: 20), "重置自动密码填充", + const Icon(FluentIcons.reset_device, size: 20), S.current.setting_action_reset_auto_password_fill, subTitle: "启用:${sate.isEnableAutoLogin ? "已启用" : "已禁用"} 设备支持:${sate.isDeviceSupportWinHello ? "支持" : "不支持"} 邮箱:${sate.autoLoginEmail} 密码:${sate.isEnableAutoLoginPwd ? "已加密保存" : "未保存"}", onTap: ()=> model.onResetAutoLogin(context)), ], const SizedBox(height: 12), makeSettingsItem(const Icon(FontAwesomeIcons.microchip, size: 20), - "启动游戏时忽略能效核心( 适用于Intel 12th+ 处理器 )", + S.current.setting_action_ignore_efficiency_cores_on_launch, subTitle: "已设置的核心数量:${sate.inputGameLaunchECore} (此功能适用于首页的盒子一键启动 或 工具中的RSI启动器管理员模式,当为 0 时不启用此功能 )", onTap:()=> model.setGameLaunchECore(context)), const SizedBox(height: 12), makeSettingsItem(const Icon(FluentIcons.folder_open, size: 20), - "设置启动器文件(RSI Launcher.exe)", + S.current.setting_action_set_launcher_file, subTitle: sate.customLauncherPath != null ? "${sate.customLauncherPath}" - : "手动设置启动器位置,建议仅在无法自动扫描安装位置时使用", + : S.current.setting_action_info_manual_launcher_location_setting, onTap: ()=> model.setLauncherPath(context), onDel: () { model.delName("custom_launcher_path"); }), const SizedBox(height: 12), makeSettingsItem(const Icon(FluentIcons.game, size: 20), - "设置游戏文件 (StarCitizen.exe)", + S.current.setting_action_set_game_file, subTitle: sate.customGamePath != null ? "${sate.customGamePath}" - : "手动设置游戏安装位置,建议仅在无法自动扫描安装位置时使用", + : S.current.setting_action_info_manual_game_location_setting, onTap: ()=> model.setGamePath(context), onDel: () { model.delName("custom_game_path"); }), const SizedBox(height: 12), - makeSettingsItem(const Icon(FluentIcons.delete, size: 20), "清理汉化文件缓存", + makeSettingsItem(const Icon(FluentIcons.delete, size: 20), S.current.setting_action_clear_translation_file_cache, subTitle: "缓存大小 ${(sate.locationCacheSize / 1024 / 1024).toStringAsFixed(2)}MB,清理盒子下载的汉化文件缓存,不会影响已安装的汉化", onTap: ()=> model.cleanLocationCache(context)), const SizedBox(height: 12), makeSettingsItem( - const Icon(FluentIcons.speed_high, size: 20), "工具站访问加速", + const Icon(FluentIcons.speed_high, size: 20), S.current.setting_action_tool_site_access_acceleration, onTap: () => model.onChangeToolSiteMirror(!sate.isEnableToolSiteMirrors), subTitle: - "使用镜像服务器加速访问 Dps Uex 等工具网站,若访问异常请关闭该功能。 为保护账户安全,任何情况下都不会加速RSI官网。", + S.current.setting_action_info_mirror_server_info, onSwitch: model.onChangeToolSiteMirror, switchStatus: sate.isEnableToolSiteMirrors), const SizedBox(height: 12), makeSettingsItem( - const Icon(FluentIcons.document_set, size: 20), "查看log", + const Icon(FluentIcons.document_set, size: 20), S.current.setting_action_view_log, onTap: () => model.showLogs(), - subTitle: "查看汉化盒子的 log 文件,以定位盒子的 bug"), + subTitle: S.current.setting_action_info_view_log_file), ], ), ); @@ -128,4 +129,4 @@ class SettingsUI extends HookConsumerWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/ui/settings/settings_ui_model.dart b/lib/ui/settings/settings_ui_model.dart index fe7eb02..ecd7448 100644 --- a/lib/ui/settings/settings_ui_model.dart +++ b/lib/ui/settings/settings_ui_model.dart @@ -21,7 +21,7 @@ part 'settings_ui_model.freezed.dart'; @freezed class SettingsUIState with _$SettingsUIState { - const factory SettingsUIState({ + factory SettingsUIState({ @Default(false) isDeviceSupportWinHello, @Default("-") String autoLoginEmail, @Default(false) bool isEnableAutoLogin, @@ -38,7 +38,7 @@ class SettingsUIState with _$SettingsUIState { class SettingsUIModel extends _$SettingsUIModel { @override SettingsUIState build() { - state = const SettingsUIState(); + state = SettingsUIState(); _initState(); return state; } @@ -57,15 +57,15 @@ class SettingsUIModel extends _$SettingsUIModel { } Future onResetAutoLogin(BuildContext context) async { - final ok = await showConfirmDialogs(context, "确认重置自动填充?", - const Text("这将会删除本地的账号记录,或在下次启动游戏时将自动填充选择 ‘否’ 以禁用自动填充。")); + final ok = await showConfirmDialogs(context, S.current.setting_action_info_confirm_reset_autofill, + Text(S.current.setting_action_info_delete_local_account_warning)); if (ok) { final userBox = await Hive.openBox("rsi_account_data"); await userBox.deleteFromDisk(); Win32Credentials.delete("SCToolbox_RSI_Account_secret"); if (!context.mounted) return; - showToast(context, "已清理自动填充数据"); + showToast(context, S.current.setting_action_info_autofill_data_cleared); _initState(); } } @@ -89,7 +89,7 @@ class SettingsUIModel extends _$SettingsUIModel { userBox.get("gameLaunch_eCore_count", defaultValue: "0"); if (!context.mounted) return; final input = await showInputDialogs(context, - title: "请输入要忽略的 CPU 核心数", + title: S.current.setting_action_info_enter_cpu_core_to_ignore, content: "Tip:您的设备拥有几个能效核心就输入几,非大小核设备请保持 0\n\n此功能适用于首页的盒子一键启动 或 工具中的 RSI启动器管理员模式,当为 0 时不启用此功能。", initialValue: defaultInput, @@ -108,7 +108,7 @@ class SettingsUIModel extends _$SettingsUIModel { Future setLauncherPath(BuildContext context) async { final r = await FilePicker.platform.pickFiles( - dialogTitle: "请选择RSI启动器位置(RSI Launcher.exe)", + dialogTitle: S.current.setting_action_info_select_rsi_launcher_location, type: FileType.custom, allowedExtensions: ["exe"]); if (r == null || r.files.firstOrNull?.path == null) return; @@ -116,17 +116,17 @@ class SettingsUIModel extends _$SettingsUIModel { if (fileName.endsWith("\\RSI Launcher.exe")) { await _saveCustomPath("custom_launcher_path", fileName); if (!context.mounted) return; - showToast(context, "设置成功,在对应页面点击刷新即可扫描出新路径"); + showToast(context, S.current.setting_action_info_setting_success); _initState(); } else { if (!context.mounted) return; - showToast(context, "文件有误!"); + showToast(context, S.current.setting_action_info_file_error); } } Future setGamePath(BuildContext context) async { final r = await FilePicker.platform.pickFiles( - dialogTitle: "请选择游戏安装位置(StarCitizen.exe)", + dialogTitle: S.current.setting_action_info_select_game_install_location, type: FileType.custom, allowedExtensions: ["exe"]); if (r == null || r.files.firstOrNull?.path == null) return; @@ -139,11 +139,11 @@ class SettingsUIModel extends _$SettingsUIModel { String extractedPath = fileName.replaceFirst(pathRegex, ''); await _saveCustomPath("custom_game_path", extractedPath); if (!context.mounted) return; - showToast(context, "设置成功,在对应页面点击刷新即可扫描出新路径"); + showToast(context, S.current.setting_action_info_setting_success); _initState(); } else { if (!context.mounted) return; - showToast(context, "文件有误!"); + showToast(context, S.current.setting_action_info_file_error); } } @@ -175,7 +175,7 @@ class SettingsUIModel extends _$SettingsUIModel { Future cleanLocationCache(BuildContext context) async { final ok = await showConfirmDialogs( - context, "确认清理汉化缓存?", const Text("这不会影响已安装的汉化。")); + context, "确认清理汉化缓存?", Text(S.current.setting_action_info_clear_cache_warning)); if (ok == true) { final dir = Directory("${appGlobalState.applicationSupportDir}/Localizations"); @@ -187,7 +187,7 @@ class SettingsUIModel extends _$SettingsUIModel { Future addShortCut(BuildContext context) async { if (ConstConf.isMSE) { - showToast(context, "因微软版功能限制,请在接下来打开的窗口中 手动将《SC汉化盒子》拖动到桌面,即可创建快捷方式。"); + showToast(context, S.current.setting_action_info_microsoft_version_limitation); await Future.delayed(const Duration(seconds: 1)); Process.run("explorer.exe", ["shell:AppsFolder"]); return; @@ -208,7 +208,7 @@ class SettingsUIModel extends _$SettingsUIModel { """; await Process.run(SystemHelper.powershellPath, [script]); if (!context.mounted) return; - showToast(context, "创建完毕,请返回桌面查看"); + showToast(context, S.current.setting_action_info_shortcut_created); } _loadToolSiteMirrorState() async { @@ -228,4 +228,4 @@ class SettingsUIModel extends _$SettingsUIModel { showLogs() async { SystemHelper.openDir(getDPrintFile()?.absolute.path.replaceAll("/", "\\")); } -} +} \ No newline at end of file diff --git a/lib/ui/settings/settings_ui_model.freezed.dart b/lib/ui/settings/settings_ui_model.freezed.dart index df28db8..c308822 100644 --- a/lib/ui/settings/settings_ui_model.freezed.dart +++ b/lib/ui/settings/settings_ui_model.freezed.dart @@ -197,7 +197,7 @@ class __$$SettingsUIStateImplCopyWithImpl<$Res> /// @nodoc class _$SettingsUIStateImpl implements _SettingsUIState { - const _$SettingsUIStateImpl( + _$SettingsUIStateImpl( {this.isDeviceSupportWinHello = false, this.autoLoginEmail = "-", this.isEnableAutoLogin = false, @@ -287,7 +287,7 @@ class _$SettingsUIStateImpl implements _SettingsUIState { } abstract class _SettingsUIState implements SettingsUIState { - const factory _SettingsUIState( + factory _SettingsUIState( {final dynamic isDeviceSupportWinHello, final String autoLoginEmail, final bool isEnableAutoLogin, diff --git a/lib/ui/settings/settings_ui_model.g.dart b/lib/ui/settings/settings_ui_model.g.dart index c79a21a..1d06df4 100644 --- a/lib/ui/settings/settings_ui_model.g.dart +++ b/lib/ui/settings/settings_ui_model.g.dart @@ -6,7 +6,7 @@ part of 'settings_ui_model.dart'; // RiverpodGenerator // ************************************************************************** -String _$settingsUIModelHash() => r'34ac24f658a081350be7d2b3bda810d101b888a1'; +String _$settingsUIModelHash() => r'de69e289c526d61a6287a9ca7bae848a4d594c20'; /// See also [SettingsUIModel]. @ProviderFor(SettingsUIModel) diff --git a/lib/ui/settings/upgrade_dialog.dart b/lib/ui/settings/upgrade_dialog.dart index 1e4db2d..3d4da24 100644 --- a/lib/ui/settings/upgrade_dialog.dart +++ b/lib/ui/settings/upgrade_dialog.dart @@ -59,12 +59,12 @@ class UpgradeDialogUI extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ if (description.value == null) ...[ - const Center( + Center( child: Column( children: [ - ProgressRing(), - SizedBox(height: 16), - Text("正在获取新版本详情...") + const ProgressRing(), + const SizedBox(height: 16), + Text(S.current.app_upgrade_info_getting_new_version_details) ], ), ) @@ -85,7 +85,7 @@ class UpgradeDialogUI extends HookConsumerWidget { color: Colors.white.withOpacity(.1), borderRadius: BorderRadius.circular(7)), child: Text( - "提示:当前正在使用分流服务器进行更新,可能会出现下载速度下降,但有助于我们进行成本控制,若下载异常请点击这里跳转手动安装。", + S.current.app_upgrade_info_update_server_tip, style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(.7)), ), @@ -97,7 +97,7 @@ class UpgradeDialogUI extends HookConsumerWidget { Row( children: [ Text(progress.value == 100 - ? "正在安装: " + ? S.current.app_upgrade_info_installing : "正在下载: ${progress.value.toStringAsFixed(2)}% "), Expanded( child: ProgressBar( @@ -122,18 +122,18 @@ class UpgradeDialogUI extends HookConsumerWidget { description, isUsingDiversion, progress), - child: const Padding( - padding: EdgeInsets.only( + child: Padding( + padding: const EdgeInsets.only( top: 4, bottom: 4, left: 8, right: 8), - child: Text("立即更新"), + child: Text(S.current.app_upgrade_action_update_now), )), if (ConstConf.appVersionCode >= (minVersionCode ?? 0)) Button( onPressed: () => _doCancel(context), - child: const Padding( - padding: EdgeInsets.only( + child: Padding( + padding: const EdgeInsets.only( top: 4, bottom: 4, left: 8, right: 8), - child: Text("下次吧"), + child: Text(S.current.app_upgrade_action_next_time), )), ], ), @@ -240,7 +240,7 @@ class UpgradeDialogUI extends HookConsumerWidget { isUpgrading.value = false; progress.value = 0; if (!context.mounted) return; - showToast(context, "下载失败,请尝试手动安装!"); + showToast(context, S.current.app_upgrade_info_download_failed); return; } @@ -255,9 +255,9 @@ class UpgradeDialogUI extends HookConsumerWidget { isUpgrading.value = false; progress.value = 0; if (!context.mounted) return; - showToast(context, "运行失败,请尝试手动安装!"); + showToast(context, S.current.app_upgrade_info_run_failed); Process.run(SystemHelper.powershellPath, ["explorer.exe", "/select,\"$fileName\""]); } } -} +} \ No newline at end of file diff --git a/lib/ui/splash_ui.dart b/lib/ui/splash_ui.dart index b964d53..f9cbc75 100644 --- a/lib/ui/splash_ui.dart +++ b/lib/ui/splash_ui.dart @@ -22,7 +22,7 @@ class SplashUI extends HookConsumerWidget { final appModel = ref.read(appGlobalModelProvider.notifier); _initApp(context, appModel, stepState, ref); return null; - }, const []); + }, []); return makeDefaultPage(context, content: Center( @@ -33,9 +33,9 @@ class SplashUI extends HookConsumerWidget { const SizedBox(height: 32), const ProgressRing(), const SizedBox(height: 32), - if (step == 0) const Text("正在检测可用性,这可能需要一点时间..."), - if (step == 1) const Text("正在检查更新..."), - if (step == 2) const Text("即将完成..."), + if (step == 0) Text(S.current.app_splash_checking_availability), + if (step == 1) Text(S.current.app_splash_checking_for_updates), + if (step == 2) Text(S.current.app_splash_almost_done), ], ), ), @@ -75,4 +75,4 @@ class SplashUI extends HookConsumerWidget { if (!context.mounted) return; context.go("/index"); } -} +} \ No newline at end of file diff --git a/lib/ui/tools/dialogs/hosts_booster_dialog_ui.dart b/lib/ui/tools/dialogs/hosts_booster_dialog_ui.dart index fc408f0..08d8f8e 100644 --- a/lib/ui/tools/dialogs/hosts_booster_dialog_ui.dart +++ b/lib/ui/tools/dialogs/hosts_booster_dialog_ui.dart @@ -12,11 +12,11 @@ import 'package:starcitizen_doctor/common/utils/log.dart'; class HostsBoosterDialogUI extends HookConsumerWidget { const HostsBoosterDialogUI({super.key}); - static const _hostsMap = { + static final _hostsMap = { "Recaptcha": ["www.recaptcha.net", "recaptcha.net"], - "RSI 官网": ["robertsspaceindustries.com"], - "RSI Zendesk 客服站": ["cloudimperiumservicesllc.zendesk.com"], - "RSI 客服站": ["support.robertsspaceindustries.com"], + S.current.tools_hosts_info_rsi_official_website: ["robertsspaceindustries.com"], + S.current.tools_hosts_info_rsi_zendesk: ["cloudimperiumservicesllc.zendesk.com"], + S.current.tools_hosts_info_rsi_customer_service: ["support.robertsspaceindustries.com"], }; @override @@ -37,12 +37,12 @@ class HostsBoosterDialogUI extends HookConsumerWidget { checkedMap.value = Map.from(checkedMap.value); } } - workingText.value = "正在查询 DNS 并测试可访问性 请耐心等待..."; + workingText.value = S.current.tools_hosts_info_dns_query_and_test; final ipsMap = await _doCheckDns(workingMap, checkedMap); - workingText.value = "正在写入 Hosts ..."; + workingText.value = S.current.tools_hosts_info_writing_hosts; if (!context.mounted) return; await _doWriteHosts(ipsMap).unwrap(context: context); - workingText.value = "读取配置 ..."; + workingText.value = S.current.tools_hosts_info_reading_config; await _readHostsState(workingMap, checkedMap); workingText.value = ""; } @@ -51,7 +51,7 @@ class HostsBoosterDialogUI extends HookConsumerWidget { // 监听 Hosts 文件变更 _readHostsState(workingMap, checkedMap); return null; - }, const []); + }, []); return ContentDialog( constraints: @@ -66,17 +66,17 @@ class HostsBoosterDialogUI extends HookConsumerWidget { onPressed: workingText.value.isEmpty ? Navigator.of(context).pop : null), const SizedBox(width: 12), - const Text("Hosts 加速"), + Text(S.current.tools_hosts_info_hosts_acceleration), const Spacer(), Button( onPressed: () => _openHostsFile(context), - child: const Padding( - padding: EdgeInsets.all(3), + child: Padding( + padding: const EdgeInsets.all(3), child: Row( children: [ - Icon(FluentIcons.open_file), - SizedBox(width: 6), - Text("打开 Hosts 文件"), + const Icon(FluentIcons.open_file), + const SizedBox(width: 6), + Text(S.current.tools_hosts_info_open_hosts_file), ], ), )) @@ -88,15 +88,15 @@ class HostsBoosterDialogUI extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 12), - const Row( + Row( children: [ - SizedBox(width: 12), - Text("状态"), - SizedBox(width: 38), - Text("站点"), - Spacer(), - Text("是否启用"), - SizedBox(width: 12), + const SizedBox(width: 12), + Text(S.current.tools_hosts_info_status), + const SizedBox(width: 38), + Text(S.current.tools_hosts_info_site), + const Spacer(), + Text(S.current.tools_hosts_info_enable), + const SizedBox(width: 12), ], ), const SizedBox(height: 12), @@ -163,10 +163,10 @@ class HostsBoosterDialogUI extends HookConsumerWidget { padding: const EdgeInsets.all(12), child: FilledButton( onPressed: () => doHost(context), - child: const Padding( + child: Padding( padding: - EdgeInsets.only(top: 3, bottom: 3, left: 12, right: 12), - child: Text("一键加速"), + const EdgeInsets.only(top: 3, bottom: 3, left: 12, right: 12), + child: Text(S.current.tools_hosts_action_one_click_acceleration), ), ), ), @@ -177,7 +177,7 @@ class HostsBoosterDialogUI extends HookConsumerWidget { } Future _openHostsFile(BuildContext context) async { - // 使用管理员权限调用记事本打开 Hosts 文件 + // 使用管理员权限调用记事本${S.current.tools_hosts_info_open_hosts_file} Process.run(SystemHelper.powershellPath, [ "-Command", "Start-Process notepad.exe -Verb runAs -ArgumentList ${SystemHelper.getHostsFilePath()}" @@ -287,4 +287,4 @@ class HostsBoosterDialogUI extends HookConsumerWidget { } } } -} +} \ No newline at end of file diff --git a/lib/ui/tools/tools_ui.dart b/lib/ui/tools/tools_ui.dart index 85c0bf8..7100ee7 100644 --- a/lib/ui/tools/tools_ui.dart +++ b/lib/ui/tools/tools_ui.dart @@ -55,14 +55,14 @@ class ToolsUI extends HookConsumerWidget { ), const SizedBox(height: 12), if (state.items.isEmpty) - const Expanded( + Expanded( child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - ProgressRing(), - SizedBox(height: 12), - Text("正在扫描..."), + const ProgressRing(), + const SizedBox(height: 12), + Text(S.current.tools_info_scanning), ], ), ), @@ -170,13 +170,13 @@ class ToolsUI extends HookConsumerWidget { decoration: BoxDecoration( color: Colors.black.withAlpha(150), ), - child: const Center( + child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ - ProgressRing(), - SizedBox(height: 12), - Text("正在处理..."), + const ProgressRing(), + const SizedBox(height: 12), + Text(S.current.doctor_info_processing), ], ), ), @@ -190,7 +190,7 @@ class ToolsUI extends HookConsumerWidget { return Row( mainAxisSize: MainAxisSize.min, children: [ - const Text("游戏安装位置: "), + Text(S.current.tools_info_game_install_location), const SizedBox(width: 6), Expanded( child: SizedBox( @@ -228,7 +228,7 @@ class ToolsUI extends HookConsumerWidget { return Row( mainAxisSize: MainAxisSize.min, children: [ - const Text("RSI启动器位置:"), + Text(S.current.tools_info_rsi_launcher_location), const SizedBox(width: 6), Expanded( child: SizedBox( @@ -260,4 +260,4 @@ class ToolsUI extends HookConsumerWidget { ], ); } -} +} \ No newline at end of file diff --git a/lib/ui/tools/tools_ui_model.dart b/lib/ui/tools/tools_ui_model.dart index 737c646..5f23fe1 100644 --- a/lib/ui/tools/tools_ui_model.dart +++ b/lib/ui/tools/tools_ui_model.dart @@ -41,7 +41,7 @@ class ToolsItemData { @freezed class ToolsUIState with _$ToolsUIState { - const factory ToolsUIState({ + factory ToolsUIState({ @Default(false) bool working, @Default("") String scInstalledPath, @Default("") String rsiLauncherInstalledPath, @@ -56,7 +56,7 @@ class ToolsUIState with _$ToolsUIState { class ToolsUIModel extends _$ToolsUIModel { @override ToolsUIState build() { - state = const ToolsUIState(); + state = ToolsUIState(); return state; } @@ -71,35 +71,35 @@ class ToolsUIModel extends _$ToolsUIModel { items = [ ToolsItemData( "systemnfo", - "查看系统信息", + S.current.tools_action_view_system_info, "查看系统关键信息,用于快速问诊 \n\n耗时操作,请耐心等待。", const Icon(FluentIcons.system, size: 24), onTap: () => _showSystemInfo(context), ), ToolsItemData( "p4k_downloader", - "P4K 分流下载 / 修复", + S.current.tools_action_p4k_download_repair, "使用星际公民中文百科提供的分流下载服务,可用于下载或修复 p4k。 \n资源有限,请勿滥用。", const Icon(FontAwesomeIcons.download, size: 24), onTap: () => _downloadP4k(context), ), ToolsItemData( "hosts_booster", - "Hosts 加速(实验性)", + S.current.tools_action_hosts_acceleration_experimental, "将 IP 信息写入 Hosts 文件,解决部分地区的 DNS 污染导致无法登录官网等问题。\n该功能正在进行第一阶段测试,遇到问题请及时反馈。", const Icon(FluentIcons.virtual_network, size: 24), onTap: () => _doHostsBooster(context), ), ToolsItemData( "reinstall_eac", - "重装 EasyAntiCheat 反作弊", - "若您遇到 EAC 错误,且自动修复无效,请尝试使用此功能重装 EAC。", + S.current.tools_action_reinstall_easyanticheat, + S.current.tools_action_info_reinstall_eac, const Icon(FluentIcons.game, size: 24), onTap: () => _reinstallEAC(context), ), ToolsItemData( "rsilauncher_admin_mode", - "RSI Launcher 管理员模式", + S.current.tools_action_rsi_launcher_admin_mode, "以管理员身份运行RSI启动器,可能会解决一些问题。\n\n若设置了能效核心屏蔽参数,也会在此应用。", const Icon(FluentIcons.admin, size: 24), onTap: () => _adminRSILauncher(context), @@ -136,7 +136,7 @@ class ToolsUIModel extends _$ToolsUIModel { return [ ToolsItemData( "rsilauncher_log_fix", - "RSI Launcher Log 修复", + S.current.tools_action_rsi_launcher_log_fix, "在某些情况下 RSI启动器 的 log 文件会损坏,导致无法完成问题扫描,使用此工具清理损坏的 log 文件。\n\n当前日志文件大小:${(logPathLen.toStringAsFixed(4))} MB", const Icon(FontAwesomeIcons.bookBible, size: 24), onTap: () => _rsiLogFix(context), @@ -150,7 +150,7 @@ class ToolsUIModel extends _$ToolsUIModel { if (nvmePatchStatus) ToolsItemData( "remove_nvme_settings", - "移除 nvme 注册表补丁", + S.current.tools_action_remove_nvme_registry_patch, "若您使用 nvme 补丁出现问题,请运行此工具。(可能导致游戏 安装/更新 不可用。)\n\n当前补丁状态:${(nvmePatchStatus) ? "已安装" : "未安装"}", const Icon(FluentIcons.hard_drive, size: 24), onTap: nvmePatchStatus @@ -159,7 +159,7 @@ class ToolsUIModel extends _$ToolsUIModel { await SystemHelper.doRemoveNvmePath(); state = state.copyWith(working: false); if (!context.mounted) return; - showToast(context, "已移除,重启电脑生效!"); + showToast(context, S.current.tools_action_info_removed_restart_effective); loadToolsCard(context, skipPathScan: true); } : null, @@ -167,8 +167,8 @@ class ToolsUIModel extends _$ToolsUIModel { if (!nvmePatchStatus) ToolsItemData( "add_nvme_settings", - "写入 nvme 注册表补丁", - "手动写入NVM补丁,该功能仅在您知道自己在作什么的情况下使用", + S.current.tools_action_write_nvme_registry_patch, + S.current.tools_action_info_manual_nvme_patch, const Icon(FontAwesomeIcons.cashRegister, size: 24), onTap: () async { state = state.copyWith(working: true); @@ -176,7 +176,7 @@ class ToolsUIModel extends _$ToolsUIModel { if (r == "") { if (!context.mounted) return; showToast(context, - "修复成功,请尝试重启电脑后继续安装游戏! 若注册表修改操作导致其他软件出现兼容问题,请使用 工具 中的 NVME 注册表清理。"); + S.current.tools_action_info_fix_success_restart); } else { if (!context.mounted) return; showToast(context, "修复失败,$r"); @@ -192,7 +192,7 @@ class ToolsUIModel extends _$ToolsUIModel { final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath(); return ToolsItemData( "clean_shaders", - "清理着色器缓存", + S.current.tools_action_clear_shader_cache, "若游戏画面出现异常或版本更新后可使用本工具清理过期的着色器(当大于500M时,建议清理) \n\n缓存大小:${((await SystemHelper.getDirLen(gameShaderCachePath ?? "", skipPath: [ "$gameShaderCachePath\\Crashes" ])) / 1024 / 1024).toStringAsFixed(4)} MB", @@ -207,10 +207,10 @@ class ToolsUIModel extends _$ToolsUIModel { return ToolsItemData( "photography_mode", - isEnable ? "关闭摄影模式" : "开启摄影模式", + isEnable ? "关闭摄影模式" : S.current.tools_action_open_photography_mode, isEnable ? "还原镜头摇晃效果。\n\n@拉邦那 Lapernum 提供参数信息。" - : "一键关闭游戏内镜头晃动以便于摄影操作。\n\n @拉邦那 Lapernum 提供参数信息。", + : "一键${S.current.action_close}游戏内镜头晃动以便于摄影操作。\n\n @拉邦那 Lapernum 提供参数信息。", const Icon(FontAwesomeIcons.camera, size: 24), onTap: () => _onChangePhotographyMode(context, isEnable), ); @@ -260,18 +260,18 @@ class ToolsUIModel extends _$ToolsUIModel { if (rsiLauncherInstalledPath == "") { if (!context.mounted) return; - showToast(context, "未找到 RSI 启动器,请尝试重新安装,或在设置中手动添加。"); + showToast(context, S.current.tools_action_info_rsi_launcher_not_found); } if (scInstalledPath == "") { if (!context.mounted) return; - showToast(context, "未找到星际公民游戏安装位置,请至少完成一次游戏启动操作 或在设置中手动添加。"); + showToast(context, S.current.tools_action_info_star_citizen_not_found); } } /// 重装EAC Future _reinstallEAC(BuildContext context) async { if (state.scInstalledPath.isEmpty) { - showToast(context, "该功能需要一个有效的游戏安装目录"); + showToast(context, S.current.tools_action_info_valid_game_directory_needed); return; } state = state.copyWith(working: true); @@ -302,7 +302,7 @@ class ToolsUIModel extends _$ToolsUIModel { } if (!context.mounted) return; showToast(context, - "已为您移除 EAC 文件,接下来将为您打开 RSI 启动器,请您前往 SETTINGS -> VERIFY 重装 EAC。"); + S.current.tools_action_info_eac_file_removed); _adminRSILauncher(context); } catch (e) { showToast(context, "出现错误:$e"); @@ -322,7 +322,7 @@ class ToolsUIModel extends _$ToolsUIModel { /// 管理员模式运行 RSI 启动器 Future _adminRSILauncher(BuildContext context) async { if (state.rsiLauncherInstalledPath == "") { - showToast(context, "未找到 RSI 启动器目录,请您尝试手动操作。"); + showToast(context, S.current.tools_action_info_rsi_launcher_directory_not_found); } SystemHelper.checkAndLaunchRSILauncher(state.rsiLauncherInstalledPath); } @@ -333,14 +333,14 @@ class ToolsUIModel extends _$ToolsUIModel { if (!await File(path!).exists()) { if (!context.mounted) return; showToast( - context, "日志文件不存在,请尝试进行一次游戏启动或游戏安装,并退出启动器,若无法解决问题,请尝试将启动器更新至最新版本!"); + context, S.current.tools_action_info_log_file_not_exist); return; } try { SystemHelper.killRSILauncher(); await File(path).delete(recursive: true); if (!context.mounted) return; - showToast(context, "清理完毕,请完成一次安装 / 游戏启动 操作。"); + showToast(context, S.current.tools_action_info_cleanup_complete); SystemHelper.checkAndLaunchRSILauncher(state.rsiLauncherInstalledPath); } catch (_) { if (!context.mounted) return; @@ -362,16 +362,16 @@ class ToolsUIModel extends _$ToolsUIModel { showDialog( context: context, builder: (context) => ContentDialog( - title: const Text('系统信息'), + title: Text(S.current.tools_action_info_system_info_title), content: Text(systemInfo), constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * .65, ), actions: [ FilledButton( - child: const Padding( - padding: EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8), - child: Text('关闭'), + child: Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8), + child: Text(S.current.action_close), ), onPressed: () => Navigator.pop(context), ), @@ -404,7 +404,7 @@ class ToolsUIModel extends _$ToolsUIModel { if ((await SystemHelper.getPID("\"RSI Launcher\"")).isNotEmpty) { if (!context.mounted) return; - showToast(context, "RSI启动器正在运行!请先关闭启动器再使用此功能!", + showToast(context, S.current.tools_action_info_rsi_launcher_running_warning, constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * .35)); return; @@ -413,7 +413,7 @@ class ToolsUIModel extends _$ToolsUIModel { if (!context.mounted) return; await showToast( context, - "P4k 是星际公民的核心游戏文件,高达 100GB+,盒子提供的离线下载是为了帮助一些p4k文件下载超级慢的用户 或用于修复官方启动器无法修复的 p4k 文件。" + "${S.current.tools_action_info_p4k_file_description_part1}" "\n\n接下来会弹窗询问您保存位置(可以选择星际公民文件夹也可以选择别处),下载完成后请确保 P4K 文件夹位于 LIVE 文件夹内,之后使用星际公民启动器校验更新即可。"); try { @@ -431,7 +431,7 @@ class ToolsUIModel extends _$ToolsUIModel { final t = HomeDownloaderUIModel.getTaskTypeAndName(value); if (t.key == "torrent" && t.value.contains("Data.p4k")) { if (!context.mounted) return; - showToast(context, "已经有一个p4k下载任务正在进行中,请前往下载管理器查看!"); + showToast(context, S.current.tools_action_info_p4k_download_in_progress); state = state.copyWith(working: false); return; } @@ -447,7 +447,7 @@ class ToolsUIModel extends _$ToolsUIModel { if (torrentUrl == "") { state = state.copyWith(working: false); if (!context.mounted) return; - showToast(context, "功能维护中,请稍后重试!"); + showToast(context, S.current.tools_action_info_function_under_maintenance); return; } @@ -496,7 +496,7 @@ class ToolsUIModel extends _$ToolsUIModel { Future _checkPhotographyStatus(BuildContext context, {bool? setMode}) async { final scInstalledPath = state.scInstalledPath; - const keys = ["AudioShakeStrength", "CameraSpringMovement", "ShakeScale"]; + final keys = ["AudioShakeStrength", "CameraSpringMovement", "ShakeScale"]; final attributesFile = File( "$scInstalledPath\\USER\\Client\\0\\Profiles\\default\\attributes.xml"); if (setMode == null) { @@ -522,7 +522,7 @@ class ToolsUIModel extends _$ToolsUIModel { } else { if (!await attributesFile.exists()) { if (!context.mounted) return false; - showToast(context, "配置文件不存在,请尝试运行一次游戏"); + showToast(context, S.current.tools_action_info_config_file_not_exist); return false; } final xmlFile = XmlDocument.parse(await attributesFile.readAsString()); @@ -564,4 +564,4 @@ class ToolsUIModel extends _$ToolsUIModel { context: context, builder: (BuildContext context) => const HostsBoosterDialogUI()); } -} +} \ No newline at end of file diff --git a/lib/ui/tools/tools_ui_model.freezed.dart b/lib/ui/tools/tools_ui_model.freezed.dart index 9cff683..983e82a 100644 --- a/lib/ui/tools/tools_ui_model.freezed.dart +++ b/lib/ui/tools/tools_ui_model.freezed.dart @@ -173,7 +173,7 @@ class __$$ToolsUIStateImplCopyWithImpl<$Res> /// @nodoc class _$ToolsUIStateImpl implements _ToolsUIState { - const _$ToolsUIStateImpl( + _$ToolsUIStateImpl( {this.working = false, this.scInstalledPath = "", this.rsiLauncherInstalledPath = "", @@ -270,7 +270,7 @@ class _$ToolsUIStateImpl implements _ToolsUIState { } abstract class _ToolsUIState implements ToolsUIState { - const factory _ToolsUIState( + factory _ToolsUIState( {final bool working, final String scInstalledPath, final String rsiLauncherInstalledPath, diff --git a/lib/ui/tools/tools_ui_model.g.dart b/lib/ui/tools/tools_ui_model.g.dart index 04f1e67..a831fae 100644 --- a/lib/ui/tools/tools_ui_model.g.dart +++ b/lib/ui/tools/tools_ui_model.g.dart @@ -6,7 +6,7 @@ part of 'tools_ui_model.dart'; // RiverpodGenerator // ************************************************************************** -String _$toolsUIModelHash() => r'4fb78bfe350d792cfdadd3314f4763097ea1b279'; +String _$toolsUIModelHash() => r'5568cfd422f98a1aff9b8cb9d522c84565fcc289'; /// See also [ToolsUIModel]. @ProviderFor(ToolsUIModel) diff --git a/lib/ui/webview/webview.dart b/lib/ui/webview/webview.dart index 8406608..709cb46 100644 --- a/lib/ui/webview/webview.dart +++ b/lib/ui/webview/webview.dart @@ -101,7 +101,10 @@ class WebViewModel { if (url.startsWith(org) || url.startsWith(citizens) || url.startsWith(organization)) { - replaceWords.add({"word": 'members', "replacement": '名成员'}); + replaceWords.add({ + "word": 'members', + "replacement": S.current.webview_localization_name_member + }); replaceWords.addAll(_getLocalizationResource("orgs")); } @@ -111,9 +114,21 @@ class WebViewModel { if (url.startsWith(referral)) { replaceWords.addAll([ - {"word": 'Total recruits: ', "replacement": '总邀请数:'}, - {"word": 'Prospects ', "replacement": '未完成的邀请'}, - {"word": 'Recruits', "replacement": '已完成的邀请'}, + { + "word": 'Total recruits: ', + "replacement": + S.current.webview_localization_total_invitations + }, + { + "word": 'Prospects ', + "replacement": + S.current.webview_localization_unfinished_invitations + }, + { + "word": 'Recruits', + "replacement": + S.current.webview_localization_finished_invitations + }, ]); } @@ -304,7 +319,9 @@ class WebViewModel { // send toast webview.evaluateJavaScript("SCTShowToast(\"请完成 Windows Hello 验证以填充密码\")"); // decrypt - if (await localAuth.authenticate(localizedReason: "请输入设备PIN以自动登录RSI账户") != + if (await localAuth.authenticate( + localizedReason: + S.current.webview_localization_enter_device_pin) != true) return; final kv = Win32Credentials.read("SCToolbox_RSI_Account_secret"); if (kv == null || kv.key != email) return; diff --git a/packages/sct_dev_tools/bin/auto_l10n.dart b/packages/sct_dev_tools/bin/auto_l10n.dart index dccca9f..f334144 100644 --- a/packages/sct_dev_tools/bin/auto_l10n.dart +++ b/packages/sct_dev_tools/bin/auto_l10n.dart @@ -41,9 +41,17 @@ class AutoL10nTools { // read all dart File final dir = Directory('lib/ui'); for (var entity in dir.listSync(recursive: true)) { - if (entity is File && entity.path.endsWith('.dart')) { + if (entity is File && + entity.path.endsWith('.dart') && + !(entity.path.endsWith(".g.dart") && + entity.path.endsWith(".freezed.dart"))) { print('Processing ${entity.path}...'); - _replaceDartFile(entity, jsonMap); + // sort map with value length + final newMap = Map.fromEntries( + jsonMap.entries.toList() + ..sort((a, b) => (b.value as String).length.compareTo((a.value as String).length)), + ); + _replaceDartFile(entity, newMap); } } } @@ -56,34 +64,51 @@ class AutoL10nTools { } void _replaceDartFile(File entity, jsonMap) { - final parseResult = parseFile( - path: entity.path, featureSet: FeatureSet.latestLanguageVersion()); - final unit = parseResult.unit; - final visitor = ReplaceAstVisitor(jsonMap); - unit.accept(visitor); - final output = visitor.buffer.toString(); - entity.writeAsStringSync(output); + for (var key in jsonMap.keys) { + if (key == "@@locale") continue; + final mapValue = jsonMap[key] as String; + if (mapValue.contains("{{") && mapValue.contains("}}")) { + print("skipping args value === $mapValue"); + continue; + } + // 使用 CheckContainsVisitor.visitStringLiteral 获取是否有匹配的值 ,返回 true false + final parseResult = parseFile( + path: entity.path, featureSet: FeatureSet.latestLanguageVersion()); + final unit = parseResult.unit; + final visitor = CheckContainsVisitor(mapValue); + unit.accept(visitor); + if (visitor.hasValue) { + // replaceDartFile with line + final lines = entity.readAsLinesSync(); + final newLines = []; + for (var line in lines) { + if (line.contains(mapValue) && !line.contains("\$")) { + line = line.replaceAll(mapValue, "\${S.current.$key}"); + } + newLines.add(line); + } + entity.writeAsStringSync(newLines.join("\n")); + } + } } } -class ReplaceAstVisitor extends GeneralizingAstVisitor { - final Map jsonMap; - final buffer = StringBuffer(); +class CheckContainsVisitor extends GeneralizingAstVisitor { + final String mapValue; - ReplaceAstVisitor(this.jsonMap); + CheckContainsVisitor(this.mapValue); + + bool hasValue = false; @override - visitSimpleStringLiteral(SimpleStringLiteral node) { - final value = node.value; - if (jsonMap.containsValue(value)) { - final key = jsonMap.keys.firstWhere((k) => jsonMap[k] == value); - buffer.write('S.current.$key'); - } else { - buffer.write(value); + visitStringLiteral(StringLiteral node) { + final value = node.stringValue ?? ""; + if (value == mapValue) { + print('Found->visitStringLiteral: $value'); + hasValue = true; } - return super.visitSimpleStringLiteral(node); + return super.visitStringLiteral(node); } - } class MyAstVisitor extends GeneralizingAstVisitor { diff --git a/packages/sct_dev_tools/bin/sct_dev_tools.dart b/packages/sct_dev_tools/bin/sct_dev_tools.dart index e90e28c..98901f6 100644 --- a/packages/sct_dev_tools/bin/sct_dev_tools.dart +++ b/packages/sct_dev_tools/bin/sct_dev_tools.dart @@ -4,7 +4,9 @@ void main(List args) { switch (args.elementAtOrNull(0)) { case "gen": return AutoL10nTools().genL10nFiles(); + case "replace": + return AutoL10nTools().replaceL10nFiles(); default: - throw Exception("cmd not found"); + throw Exception("cmd not found"); } } diff --git a/pubspec.yaml b/pubspec.yaml index 70a1abc..be4c5c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter flutter_riverpod: ^2.4.10 riverpod_annotation: ^2.3.4 flutter_hooks: ^0.20.5