mirror of
https://mirror.ghproxy.com/https://github.com/StarCitizenToolBox/app.git
synced 2024-12-23 06:33:43 +08:00
feat:重新实现汉化更新
This commit is contained in:
parent
d54a84698c
commit
1c73217ea7
@ -15,6 +15,7 @@ import 'dialogs/home_countdown_dialog_ui.dart';
|
|||||||
import 'dialogs/home_md_content_dialog_ui.dart';
|
import 'dialogs/home_md_content_dialog_ui.dart';
|
||||||
import 'home_ui_model.dart';
|
import 'home_ui_model.dart';
|
||||||
import 'localization/localization_dialog_ui.dart';
|
import 'localization/localization_dialog_ui.dart';
|
||||||
|
import 'localization/localization_ui_model.dart';
|
||||||
|
|
||||||
class HomeUI extends HookConsumerWidget {
|
class HomeUI extends HookConsumerWidget {
|
||||||
const HomeUI({super.key});
|
const HomeUI({super.key});
|
||||||
@ -23,6 +24,7 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final homeState = ref.watch(homeUIModelProvider);
|
final homeState = ref.watch(homeUIModelProvider);
|
||||||
final model = ref.watch(homeUIModelProvider.notifier);
|
final model = ref.watch(homeUIModelProvider.notifier);
|
||||||
|
ref.watch(localizationUIModelProvider);
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
@ -48,7 +50,7 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
],
|
],
|
||||||
...makeIndex(context, model, homeState)
|
...makeIndex(context, model, homeState, ref)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -75,8 +77,8 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> makeIndex(
|
List<Widget> makeIndex(BuildContext context, HomeUIModel model,
|
||||||
BuildContext context, HomeUIModel model, HomeUIModelState homeState) {
|
HomeUIModelState homeState, WidgetRef ref) {
|
||||||
const double width = 280;
|
const double width = 280;
|
||||||
return [
|
return [
|
||||||
Stack(
|
Stack(
|
||||||
@ -176,7 +178,7 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(homeState.lastScreenInfo, maxLines: 1),
|
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);
|
return const FaIcon(FontAwesomeIcons.rss, size: 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget makeIndexActionLists(
|
Widget makeIndexActionLists(BuildContext context, HomeUIModel model,
|
||||||
BuildContext context, HomeUIModel model, HomeUIModelState homeState) {
|
HomeUIModelState homeState, WidgetRef ref) {
|
||||||
final items = [
|
final items = [
|
||||||
_HomeItemData("game_doctor", "一键诊断", "一键诊断星际公民常见问题",
|
_HomeItemData("game_doctor", "一键诊断", "一键诊断星际公民常见问题",
|
||||||
FluentIcons.auto_deploy_settings),
|
FluentIcons.auto_deploy_settings),
|
||||||
@ -447,7 +449,7 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = items.elementAt(index);
|
final item = items.elementAt(index);
|
||||||
return HoverButton(
|
return HoverButton(
|
||||||
onPressed: () => _onMenuTap(context, item.key, homeState),
|
onPressed: () => _onMenuTap(context, item.key, homeState, ref),
|
||||||
builder: (BuildContext context, Set<ButtonStates> states) {
|
builder: (BuildContext context, Set<ButtonStates> states) {
|
||||||
return Container(
|
return Container(
|
||||||
width: 300,
|
width: 300,
|
||||||
@ -749,8 +751,8 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
context: context, builder: (context) => const HomeCountdownDialogUI());
|
context: context, builder: (context) => const HomeCountdownDialogUI());
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMenuTap(
|
_onMenuTap(BuildContext context, String key, HomeUIModelState homeState,
|
||||||
BuildContext context, String key, HomeUIModelState homeState) async {
|
WidgetRef ref) async {
|
||||||
const String gameInstallReqInfo =
|
const String gameInstallReqInfo =
|
||||||
"该功能需要一个有效的安装位置\n\n如果您的游戏未下载完成,请等待下载完毕后使用此功能。\n\n如果您的游戏已下载完毕但未识别,请启动一次游戏后重新打开盒子 或 在设置选项中手动设置安装位置。";
|
"该功能需要一个有效的安装位置\n\n如果您的游戏未下载完成,请等待下载完毕后使用此功能。\n\n如果您的游戏已下载完毕但未识别,请启动一次游戏后重新打开盒子 或 在设置选项中手动设置安装位置。";
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@ -759,10 +761,13 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
showToast(context, gameInstallReqInfo);
|
showToast(context, gameInstallReqInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
final model = ref.watch(homeUIModelProvider.notifier);
|
||||||
|
model.checkLocalizationUpdate();
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
dismissWithEsc: false,
|
dismissWithEsc: false,
|
||||||
builder: (BuildContext context) => const LocalizationDialogUI());
|
builder: (BuildContext context) => const LocalizationDialogUI());
|
||||||
|
model.checkLocalizationUpdate(skipReload: true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
context.push("/index/$key");
|
context.push("/index/$key");
|
||||||
|
@ -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/log_helper.dart';
|
||||||
import 'package:starcitizen_doctor/common/helper/system_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/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/base_utils.dart';
|
||||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||||
import 'package:starcitizen_doctor/common/utils/provider.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:url_launcher/url_launcher_string.dart';
|
||||||
import 'package:html/parser.dart' as html;
|
import 'package:html/parser.dart' as html;
|
||||||
import 'package:html/dom.dart' as html_dom;
|
import 'package:html/dom.dart' as html_dom;
|
||||||
|
import 'package:windows_ui/windows_ui.dart';
|
||||||
|
|
||||||
import '../webview/webview.dart';
|
import '../webview/webview.dart';
|
||||||
|
import 'localization/localization_ui_model.dart';
|
||||||
|
|
||||||
part 'home_ui_model.freezed.dart';
|
part 'home_ui_model.freezed.dart';
|
||||||
|
|
||||||
@ -199,7 +202,7 @@ class HomeUIModel extends _$HomeUIModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
_appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
|
_appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
|
||||||
_checkLocalizationUpdate();
|
checkLocalizationUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
@ -237,7 +240,7 @@ class HomeUIModel extends _$HomeUIModel {
|
|||||||
dPrint(e);
|
dPrint(e);
|
||||||
}
|
}
|
||||||
// check Localization update
|
// check Localization update
|
||||||
_checkLocalizationUpdate();
|
checkLocalizationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateSCServerStatus() async {
|
Future<void> _updateSCServerStatus() async {
|
||||||
@ -262,7 +265,41 @@ class HomeUIModel extends _$HomeUIModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkLocalizationUpdate() {}
|
Future<void> checkLocalizationUpdate({bool skipReload = false}) async {
|
||||||
|
dPrint("_checkLocalizationUpdate");
|
||||||
|
final updates = await (ref.read(localizationUIModelProvider.notifier))
|
||||||
|
.checkLangUpdate(skipReload: skipReload)
|
||||||
|
.unwrap<List<String>>();
|
||||||
|
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
|
// ignore: avoid_build_context_in_providers
|
||||||
launchRSI(BuildContext context) async {
|
launchRSI(BuildContext context) async {
|
||||||
|
@ -9,6 +9,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||||
import 'package:starcitizen_doctor/api/api.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/conf/url_conf.dart';
|
||||||
import 'package:starcitizen_doctor/common/helper/system_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/io/rs_http.dart';
|
||||||
@ -64,7 +65,10 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
_init() async {
|
Future<void> _init() async {
|
||||||
|
if (_scInstallPath == "not_install") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!_customizeDir.existsSync()) {
|
if (!_customizeDir.existsSync()) {
|
||||||
await _customizeDir.create(recursive: true);
|
await _customizeDir.create(recursive: true);
|
||||||
}
|
}
|
||||||
@ -75,24 +79,37 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
_customizeDirListenSub?.cancel();
|
_customizeDirListenSub?.cancel();
|
||||||
_customizeDirListenSub = null;
|
_customizeDirListenSub = null;
|
||||||
});
|
});
|
||||||
_loadData();
|
await _loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadData() async {
|
final Map<String, Map<String, ScLocalizationData>>
|
||||||
|
_allVersionLocalizationData = {};
|
||||||
|
|
||||||
|
Future<void> _loadData() async {
|
||||||
|
_allVersionLocalizationData.clear();
|
||||||
await _updateStatus();
|
await _updateStatus();
|
||||||
_scanCustomizeDir();
|
_scanCustomizeDir();
|
||||||
final l = await Api.getScLocalizationData(state.selectedLanguage!).unwrap();
|
for (var lang in languageSupport.keys) {
|
||||||
if (l != null) {
|
final l = await Api.getScLocalizationData(lang).unwrap();
|
||||||
final apiLocalizationData = <String, ScLocalizationData>{};
|
if (l != null) {
|
||||||
for (var element in l) {
|
if (lang == state.selectedLanguage) {
|
||||||
final isPTU = !_scInstallPath.contains("LIVE");
|
final apiLocalizationData = <String, ScLocalizationData>{};
|
||||||
if (isPTU && element.gameChannel == "PTU") {
|
for (var element in l) {
|
||||||
apiLocalizationData[element.versionName ?? ""] = element;
|
final isPTU = !_scInstallPath.contains("LIVE");
|
||||||
} else if (!isPTU && element.gameChannel == "PU") {
|
if (isPTU && element.gameChannel == "PTU") {
|
||||||
apiLocalizationData[element.versionName ?? ""] = element;
|
apiLocalizationData[element.versionName ?? ""] = element;
|
||||||
|
} else if (!isPTU && element.gameChannel == "PU") {
|
||||||
|
apiLocalizationData[element.versionName ?? ""] = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = state.copyWith(apiLocalizationData: apiLocalizationData);
|
||||||
}
|
}
|
||||||
|
final map = <String, ScLocalizationData>{};
|
||||||
|
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 "自定义文件";
|
return "自定义文件";
|
||||||
}
|
}
|
||||||
|
|
||||||
Future checkLangUpdate() async {
|
Future<List<String>> 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<String> 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user