mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-29 04:35:38 +08:00
feat:riverpod 迁移 HomeUI
This commit is contained in:
246
lib/ui/home/home_ui_model.dart
Normal file
246
lib/ui/home/home_ui_model.dart
Normal file
@ -0,0 +1,246 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_rss/domain/rss_item.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive/hive.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/api/rss.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/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/base_utils.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/app_placard_data.dart';
|
||||
import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart';
|
||||
import 'package:starcitizen_doctor/data/countdown_festival_item_data.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:html/parser.dart' as html;
|
||||
import 'package:html/dom.dart' as html_dom;
|
||||
|
||||
part 'home_ui_model.freezed.dart';
|
||||
|
||||
part 'home_ui_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class HomeUIModelState with _$HomeUIModelState {
|
||||
factory HomeUIModelState({
|
||||
AppPlacardData? appPlacardData,
|
||||
@Default(false) bool isFixing,
|
||||
@Default("") String isFixingString,
|
||||
String? scInstalledPath,
|
||||
@Default([]) List<String> scInstallPaths,
|
||||
AppWebLocalizationVersionsData? webLocalizationVersionsData,
|
||||
@Default(false) bool isCurGameRunning,
|
||||
@Default("") String lastScreenInfo,
|
||||
List<RssItem>? rssVideoItems,
|
||||
List<RssItem>? rssTextItems,
|
||||
MapEntry<String, bool>? localizationUpdateInfo,
|
||||
List? scServerStatus,
|
||||
List<CountdownFestivalItemData>? countdownFestivalListData,
|
||||
}) = _HomeUIModelState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class HomeUIModel extends _$HomeUIModel {
|
||||
@override
|
||||
HomeUIModelState build() {
|
||||
state = HomeUIModelState();
|
||||
_init();
|
||||
_loadData();
|
||||
return state;
|
||||
}
|
||||
|
||||
closePlacard() async {
|
||||
final box = await Hive.openBox("app_conf");
|
||||
await box.put("close_placard", state.appPlacardData?.version);
|
||||
state = state.copyWith(appPlacardData: null);
|
||||
}
|
||||
|
||||
Future<void> reScanPath() async {
|
||||
state = state.copyWith(
|
||||
scInstalledPath: "not_install", lastScreenInfo: "正在扫描 ...");
|
||||
try {
|
||||
final listData = await SCLoggerHelper.getLauncherLogList();
|
||||
if (listData == null) {
|
||||
state = state.copyWith(scInstalledPath: "not_install");
|
||||
return;
|
||||
}
|
||||
final scInstallPaths = await SCLoggerHelper.getGameInstallPath(listData,
|
||||
withVersion: ["LIVE", "PTU", "EPTU"], checkExists: true);
|
||||
String? scInstalledPath;
|
||||
if (scInstallPaths.isNotEmpty) {
|
||||
scInstalledPath = scInstallPaths.first;
|
||||
}
|
||||
final lastScreenInfo = "扫描完毕,共找到 ${scInstallPaths.length} 个有效安装目录";
|
||||
state = state.copyWith(
|
||||
scInstalledPath: scInstalledPath,
|
||||
scInstallPaths: scInstallPaths,
|
||||
lastScreenInfo: lastScreenInfo);
|
||||
} catch (e) {
|
||||
state = state.copyWith(
|
||||
scInstalledPath: "not_install", lastScreenInfo: "解析 log 文件失败!");
|
||||
AnalyticsApi.touch("error_launchLogs");
|
||||
// showToast(context!,
|
||||
// "解析 log 文件失败! \n请关闭游戏,退出RSI启动器后重试,若仍有问题,请使用工具箱中的 RSI Launcher log 修复。");
|
||||
}
|
||||
}
|
||||
|
||||
String getRssImage(RssItem item) {
|
||||
final h = html.parse(item.description ?? "");
|
||||
if (h.body == null) return "";
|
||||
for (var node in h.body!.nodes) {
|
||||
if (node is html_dom.Element) {
|
||||
if (node.localName == "img") {
|
||||
return node.attributes["src"]?.trim() ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
String handleTitle(String? title) {
|
||||
if (title == null) return "";
|
||||
title = title.replaceAll("【", "[ ");
|
||||
title = title.replaceAll("】", " ] ");
|
||||
return title;
|
||||
}
|
||||
|
||||
onMenuTap(String key) {}
|
||||
|
||||
void goWebView(String webTitle, String webURL,
|
||||
{required bool useLocalization}) {}
|
||||
|
||||
bool isRSIServerStatusOK(Map map) {
|
||||
return (map["status"] == "ok" || map["status"] == "operational");
|
||||
}
|
||||
|
||||
Timer? _serverUpdateTimer;
|
||||
Timer? _appUpdateTimer;
|
||||
|
||||
void _init() {
|
||||
reScanPath();
|
||||
_serverUpdateTimer = Timer.periodic(
|
||||
const Duration(minutes: 10),
|
||||
(timer) {
|
||||
_updateSCServerStatus();
|
||||
},
|
||||
);
|
||||
|
||||
_appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
|
||||
_checkLocalizationUpdate();
|
||||
});
|
||||
|
||||
ref.onDispose(() {
|
||||
_serverUpdateTimer?.cancel();
|
||||
_serverUpdateTimer = null;
|
||||
_appUpdateTimer?.cancel();
|
||||
_appUpdateTimer = null;
|
||||
});
|
||||
}
|
||||
|
||||
void _loadData() async {
|
||||
if (appGlobalState.networkVersionData == null) return;
|
||||
try {
|
||||
final r = await Api.getAppPlacard();
|
||||
final box = await Hive.openBox("app_conf");
|
||||
final version = box.get("close_placard", defaultValue: "");
|
||||
if (r.enable == true) {
|
||||
if (r.alwaysShow != true && version == r.version) {
|
||||
} else {
|
||||
state = state.copyWith(appPlacardData: r);
|
||||
}
|
||||
}
|
||||
|
||||
final appWebLocalizationVersionsData =
|
||||
AppWebLocalizationVersionsData.fromJson(json.decode(
|
||||
(await RSHttp.getText(
|
||||
"${URLConf.webTranslateHomeUrl}/versions.json"))));
|
||||
final countdownFestivalListData = await Api.getFestivalCountdownList();
|
||||
state = state.copyWith(
|
||||
webLocalizationVersionsData: appWebLocalizationVersionsData,
|
||||
countdownFestivalListData: countdownFestivalListData);
|
||||
_updateSCServerStatus();
|
||||
_loadRRS();
|
||||
} catch (e) {
|
||||
dPrint(e);
|
||||
}
|
||||
// check Localization update
|
||||
_checkLocalizationUpdate();
|
||||
}
|
||||
|
||||
Future<void> _updateSCServerStatus() async {
|
||||
try {
|
||||
final s = await Api.getScServerStatus();
|
||||
dPrint("updateSCServerStatus===$s");
|
||||
state = state.copyWith(scServerStatus: s);
|
||||
} catch (e) {
|
||||
dPrint(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future _loadRRS() async {
|
||||
try {
|
||||
state = state.copyWith(
|
||||
rssVideoItems: await RSSApi.getRssVideo(),
|
||||
rssTextItems: await RSSApi.getRssText());
|
||||
dPrint("RSS update Success !");
|
||||
} catch (e) {
|
||||
dPrint("_loadRRS Error:$e");
|
||||
}
|
||||
}
|
||||
|
||||
void _checkLocalizationUpdate() {}
|
||||
|
||||
// ignore: avoid_build_context_in_providers
|
||||
launchRSI(BuildContext context) async {
|
||||
if (state.scInstalledPath == "not_install") {
|
||||
showToast(context, "该功能需要一个有效的安装位置");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConstConf.isMSE) {
|
||||
if (state.isCurGameRunning) {
|
||||
await Process.run(
|
||||
SystemHelper.powershellPath, ["ps \"StarCitizen\" | kill"]);
|
||||
return;
|
||||
}
|
||||
AnalyticsApi.touch("gameLaunch");
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// dismissWithEsc: false,
|
||||
// builder: (context) {
|
||||
// return BaseUIContainer(
|
||||
// uiCreate: () => LoginDialog(),
|
||||
// modelCreate: () => LoginDialogModel(scInstalledPath, this));
|
||||
// });
|
||||
} else {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
"一键启动功能提示",
|
||||
const Text("为确保账户安全,一键启动功能已在开发版中禁用,我们将在微软商店版本中提供此功能。"
|
||||
"\n\n微软商店版由微软提供可靠的分发下载与数字签名,可有效防止软件被恶意篡改。\n\n提示:您无需使用盒子启动游戏也可使用汉化。"),
|
||||
confirm: "安装微软商店版本",
|
||||
cancel: "取消");
|
||||
if (ok == true) {
|
||||
await launchUrlString(
|
||||
"https://apps.microsoft.com/detail/9NF3SWFWNKL1?launch=true");
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onChangeInstallPath(String? value) {
|
||||
if (value == null) return;
|
||||
state = state.copyWith(scInstalledPath: value);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user