From 1c73217ea734303452896039a8166be6aff8d1ab Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Sun, 10 Mar 2024 21:25:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E9=87=8D=E6=96=B0=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=B1=89=E5=8C=96=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ui/home/home_ui.dart | 23 +++-- lib/ui/home/home_ui_model.dart | 43 +++++++++- .../localization/localization_ui_model.dart | 84 +++++++++++++++---- 3 files changed, 124 insertions(+), 26 deletions(-) diff --git a/lib/ui/home/home_ui.dart b/lib/ui/home/home_ui.dart index f55b4b1..9935c2a 100644 --- a/lib/ui/home/home_ui.dart +++ b/lib/ui/home/home_ui.dart @@ -15,6 +15,7 @@ import 'dialogs/home_countdown_dialog_ui.dart'; import 'dialogs/home_md_content_dialog_ui.dart'; import 'home_ui_model.dart'; import 'localization/localization_dialog_ui.dart'; +import 'localization/localization_ui_model.dart'; class HomeUI extends HookConsumerWidget { const HomeUI({super.key}); @@ -23,6 +24,7 @@ class HomeUI extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final homeState = ref.watch(homeUIModelProvider); final model = ref.watch(homeUIModelProvider.notifier); + ref.watch(localizationUIModelProvider); return Stack( children: [ Center( @@ -48,7 +50,7 @@ class HomeUI extends HookConsumerWidget { ), const SizedBox(height: 6), ], - ...makeIndex(context, model, homeState) + ...makeIndex(context, model, homeState, ref) ], ), ), @@ -75,8 +77,8 @@ class HomeUI extends HookConsumerWidget { ); } - List makeIndex( - BuildContext context, HomeUIModel model, HomeUIModelState homeState) { + List makeIndex(BuildContext context, HomeUIModel model, + HomeUIModelState homeState, WidgetRef ref) { const double width = 280; return [ Stack( @@ -176,7 +178,7 @@ class HomeUI extends HookConsumerWidget { ), const SizedBox(height: 8), Text(homeState.lastScreenInfo, maxLines: 1), - makeIndexActionLists(context, model, homeState), + makeIndexActionLists(context, model, homeState, ref), ]; } @@ -426,8 +428,8 @@ class HomeUI extends HookConsumerWidget { return const FaIcon(FontAwesomeIcons.rss, size: 14); } - Widget makeIndexActionLists( - BuildContext context, HomeUIModel model, HomeUIModelState homeState) { + Widget makeIndexActionLists(BuildContext context, HomeUIModel model, + HomeUIModelState homeState, WidgetRef ref) { final items = [ _HomeItemData("game_doctor", "一键诊断", "一键诊断星际公民常见问题", FluentIcons.auto_deploy_settings), @@ -447,7 +449,7 @@ class HomeUI extends HookConsumerWidget { itemBuilder: (context, index) { final item = items.elementAt(index); return HoverButton( - onPressed: () => _onMenuTap(context, item.key, homeState), + onPressed: () => _onMenuTap(context, item.key, homeState, ref), builder: (BuildContext context, Set states) { return Container( width: 300, @@ -749,8 +751,8 @@ class HomeUI extends HookConsumerWidget { context: context, builder: (context) => const HomeCountdownDialogUI()); } - _onMenuTap( - BuildContext context, String key, HomeUIModelState homeState) async { + _onMenuTap(BuildContext context, String key, HomeUIModelState homeState, + WidgetRef ref) async { const String gameInstallReqInfo = "该功能需要一个有效的安装位置\n\n如果您的游戏未下载完成,请等待下载完毕后使用此功能。\n\n如果您的游戏已下载完毕但未识别,请启动一次游戏后重新打开盒子 或 在设置选项中手动设置安装位置。"; switch (key) { @@ -759,10 +761,13 @@ class HomeUI extends HookConsumerWidget { showToast(context, gameInstallReqInfo); break; } + final model = ref.watch(homeUIModelProvider.notifier); + model.checkLocalizationUpdate(); await showDialog( context: context, dismissWithEsc: false, builder: (BuildContext context) => const LocalizationDialogUI()); + model.checkLocalizationUpdate(skipReload: true); break; default: context.push("/index/$key"); diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index a2a1d14..6fc8764 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -16,6 +16,7 @@ import 'package:starcitizen_doctor/common/conf/url_conf.dart'; import 'package:starcitizen_doctor/common/helper/log_helper.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart'; import 'package:starcitizen_doctor/common/io/rs_http.dart'; +import 'package:starcitizen_doctor/common/utils/async.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart'; import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/utils/provider.dart'; @@ -26,8 +27,10 @@ import 'package:starcitizen_doctor/ui/home/dialogs/home_game_login_dialog_ui.dar import 'package:url_launcher/url_launcher_string.dart'; import 'package:html/parser.dart' as html; import 'package:html/dom.dart' as html_dom; +import 'package:windows_ui/windows_ui.dart'; import '../webview/webview.dart'; +import 'localization/localization_ui_model.dart'; part 'home_ui_model.freezed.dart'; @@ -199,7 +202,7 @@ class HomeUIModel extends _$HomeUIModel { ); _appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) { - _checkLocalizationUpdate(); + checkLocalizationUpdate(); }); ref.onDispose(() { @@ -237,7 +240,7 @@ class HomeUIModel extends _$HomeUIModel { dPrint(e); } // check Localization update - _checkLocalizationUpdate(); + checkLocalizationUpdate(); } Future _updateSCServerStatus() async { @@ -262,7 +265,41 @@ class HomeUIModel extends _$HomeUIModel { } } - void _checkLocalizationUpdate() {} + Future checkLocalizationUpdate({bool skipReload = false}) async { + dPrint("_checkLocalizationUpdate"); + final updates = await (ref.read(localizationUIModelProvider.notifier)) + .checkLangUpdate(skipReload: skipReload) + .unwrap>(); + if (updates == null || updates.isEmpty) { + state = state.copyWith(localizationUpdateInfo: null); + return; + } + state = + state.copyWith(localizationUpdateInfo: MapEntry(updates.first, true)); + if (_appUpdateTimer != null) { + _appUpdateTimer?.cancel(); + _appUpdateTimer = null; + // 发送通知 + final toastNotifier = + ToastNotificationManager.createToastNotifierWithId("SC汉化盒子"); + if (toastNotifier != null) { + final toastContent = ToastNotificationManager.getTemplateContent( + ToastTemplateType.toastText02); + if (toastContent != null) { + final xmlNodeList = toastContent.getElementsByTagName('text'); + const title = '汉化有新版本!'; + final content = '您在 ${updates.first} 安装的汉化有新版本啦!'; + xmlNodeList.item(0)?.appendChild(toastContent.createTextNode(title)); + xmlNodeList + .item(1) + ?.appendChild(toastContent.createTextNode(content)); + final toastNotification = + ToastNotification.createToastNotification(toastContent); + toastNotifier.show(toastNotification); + } + } + } + } // ignore: avoid_build_context_in_providers launchRSI(BuildContext context) async { diff --git a/lib/ui/home/localization/localization_ui_model.dart b/lib/ui/home/localization/localization_ui_model.dart index 4d2281e..d6a40f8 100644 --- a/lib/ui/home/localization/localization_ui_model.dart +++ b/lib/ui/home/localization/localization_ui_model.dart @@ -9,6 +9,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:starcitizen_doctor/api/analytics.dart'; import 'package:starcitizen_doctor/api/api.dart'; +import 'package:starcitizen_doctor/common/conf/const_conf.dart'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart'; import 'package:starcitizen_doctor/common/io/rs_http.dart'; @@ -64,7 +65,10 @@ class LocalizationUIModel extends _$LocalizationUIModel { return state; } - _init() async { + Future _init() async { + if (_scInstallPath == "not_install") { + return; + } if (!_customizeDir.existsSync()) { await _customizeDir.create(recursive: true); } @@ -75,24 +79,37 @@ class LocalizationUIModel extends _$LocalizationUIModel { _customizeDirListenSub?.cancel(); _customizeDirListenSub = null; }); - _loadData(); + await _loadData(); } - _loadData() async { + final Map> + _allVersionLocalizationData = {}; + + Future _loadData() async { + _allVersionLocalizationData.clear(); await _updateStatus(); _scanCustomizeDir(); - final l = await Api.getScLocalizationData(state.selectedLanguage!).unwrap(); - if (l != null) { - final apiLocalizationData = {}; - for (var element in l) { - final isPTU = !_scInstallPath.contains("LIVE"); - if (isPTU && element.gameChannel == "PTU") { - apiLocalizationData[element.versionName ?? ""] = element; - } else if (!isPTU && element.gameChannel == "PU") { - apiLocalizationData[element.versionName ?? ""] = element; + for (var lang in languageSupport.keys) { + final l = await Api.getScLocalizationData(lang).unwrap(); + if (l != null) { + if (lang == state.selectedLanguage) { + final apiLocalizationData = {}; + for (var element in l) { + final isPTU = !_scInstallPath.contains("LIVE"); + if (isPTU && element.gameChannel == "PTU") { + apiLocalizationData[element.versionName ?? ""] = element; + } else if (!isPTU && element.gameChannel == "PU") { + apiLocalizationData[element.versionName ?? ""] = element; + } + } + state = state.copyWith(apiLocalizationData: apiLocalizationData); } + final map = {}; + for (var element in l) { + map[element.versionName ?? ""] = element; + } + _allVersionLocalizationData[lang] = map; } - state = state.copyWith(apiLocalizationData: apiLocalizationData); } } @@ -368,7 +385,46 @@ class LocalizationUIModel extends _$LocalizationUIModel { return "自定义文件"; } - Future checkLangUpdate() async { + Future> checkLangUpdate({bool skipReload = false}) async { + if (_scInstallPath == "not_install") { + return []; + } + if (!skipReload || (state.apiLocalizationData?.isEmpty ?? true)) { + await _init(); + } + final homeState = ref.read(homeUIModelProvider); + if (homeState.scInstallPaths.isEmpty) return []; + + List updates = []; + + for (var scInstallPath in homeState.scInstallPaths) { + // 读取游戏安装文件夹 + final scDataDir = Directory("$scInstallPath\\data\\Localization"); + // 扫描目录确认已安装的语言 + final dirList = await scDataDir.list().toList(); + for (var element in dirList) { + for (var lang in languageSupport.keys) { + if (element.path.contains(lang)) { + final installedVersion = + await _getInstalledIniVersion("${element.path}\\global.ini"); + final curData = _allVersionLocalizationData[lang]; + dPrint("check Localization update $scInstallPath"); + if (!(curData?.keys.contains(installedVersion) ?? false)) { + // has update + for (var channel in ConstConf.gameChannels) { + if (scInstallPath.contains(channel)) { + dPrint("check Localization update: has update -> $channel"); + updates.add(channel); + } + } + } else { + dPrint("check Localization update: up to date"); + } + } + } + } + } + return updates; } }