mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-02 20:13:51 +08:00
feat: desktop_multi_window Support
This commit is contained in:
parent
b18024a8ce
commit
f5f3e4753c
75
lib/app.dart
75
lib/app.dart
@ -58,45 +58,35 @@ GoRouter router(Ref ref) {
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const SplashUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const SplashUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/index',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const IndexUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const IndexUI()),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: "downloader",
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomeDownloaderUI())),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomeDownloaderUI())),
|
||||
GoRoute(
|
||||
path: 'game_doctor',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomeGameDoctorUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomeGameDoctorUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'performance',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomePerformanceUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomePerformanceUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'advanced_localization',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const AdvancedLocalizationUI()))
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const AdvancedLocalizationUI()))
|
||||
],
|
||||
),
|
||||
GoRoute(path: '/tools', builder: (_, __) => const SizedBox(), routes: [
|
||||
GoRoute(
|
||||
path: 'unp4kc',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const UnP4kcUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const UnP4kcUI()),
|
||||
),
|
||||
]),
|
||||
GoRoute(
|
||||
path: '/guide',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const GuideUI()))
|
||||
GoRoute(path: '/guide', pageBuilder: (context, state) => myPageBuilder(context, state, const GuideUI()))
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -218,11 +208,9 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
AppConf.setNetworkChannels(networkVersionData.gameChannels);
|
||||
checkActivityThemeColor(networkVersionData);
|
||||
if (ConstConf.isMSE) {
|
||||
dPrint(
|
||||
"lastVersion=${networkVersionData.mSELastVersion} ${networkVersionData.mSELastVersionCode}");
|
||||
dPrint("lastVersion=${networkVersionData.mSELastVersion} ${networkVersionData.mSELastVersionCode}");
|
||||
} else {
|
||||
dPrint(
|
||||
"lastVersion=${networkVersionData.lastVersion} ${networkVersionData.lastVersionCode}");
|
||||
dPrint("lastVersion=${networkVersionData.lastVersion} ${networkVersionData.lastVersionCode}");
|
||||
}
|
||||
state = state.copyWith(networkVersionData: networkVersionData);
|
||||
} catch (e) {
|
||||
@ -234,23 +222,18 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
if (state.networkVersionData == null) {
|
||||
if (!context.mounted) return false;
|
||||
await showToast(
|
||||
context,
|
||||
S.current.app_common_network_error(
|
||||
ConstConf.appVersionDate, checkUpdateError.toString()));
|
||||
context, S.current.app_common_network_error(ConstConf.appVersionDate, checkUpdateError.toString()));
|
||||
return false;
|
||||
}
|
||||
if (!Platform.isWindows) return false;
|
||||
final lastVersion = ConstConf.isMSE
|
||||
? state.networkVersionData?.mSELastVersionCode
|
||||
: state.networkVersionData?.lastVersionCode;
|
||||
final lastVersion =
|
||||
ConstConf.isMSE ? state.networkVersionData?.mSELastVersionCode : state.networkVersionData?.lastVersionCode;
|
||||
if ((lastVersion ?? 0) > ConstConf.appVersionCode) {
|
||||
// need update
|
||||
if (!context.mounted) return false;
|
||||
|
||||
final r = await showDialog(
|
||||
dismissWithEsc: false,
|
||||
context: context,
|
||||
builder: (context) => const UpgradeDialogUI());
|
||||
final r =
|
||||
await showDialog(dismissWithEsc: false, context: context, builder: (context) => const UpgradeDialogUI());
|
||||
|
||||
if (r != true) {
|
||||
if (!context.mounted) return false;
|
||||
@ -277,8 +260,8 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
|
||||
dPrint("now == $now start == $startTime end == $endTime");
|
||||
if (now < startTime) {
|
||||
_activityThemeColorTimer = Timer(Duration(milliseconds: startTime - now),
|
||||
() => checkActivityThemeColor(networkVersionData));
|
||||
_activityThemeColorTimer =
|
||||
Timer(Duration(milliseconds: startTime - now), () => checkActivityThemeColor(networkVersionData));
|
||||
dPrint("start Timer ....");
|
||||
} else if (now >= startTime && now <= endTime) {
|
||||
dPrint("update Color ....");
|
||||
@ -286,17 +269,15 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
final colorCfg = networkVersionData.activityColors;
|
||||
state = state.copyWith(
|
||||
themeConf: ThemeConf(
|
||||
backgroundColor: HexColor(colorCfg?.background ?? "#132431")
|
||||
.withValues(alpha: .75),
|
||||
menuColor:
|
||||
HexColor(colorCfg?.menu ?? "#132431").withValues(alpha: .95),
|
||||
backgroundColor: HexColor(colorCfg?.background ?? "#132431").withValues(alpha: .75),
|
||||
menuColor: HexColor(colorCfg?.menu ?? "#132431").withValues(alpha: .95),
|
||||
micaColor: HexColor(colorCfg?.mica ?? "#0A3142"),
|
||||
),
|
||||
);
|
||||
|
||||
// wait for end
|
||||
_activityThemeColorTimer = Timer(Duration(milliseconds: endTime - now),
|
||||
() => checkActivityThemeColor(networkVersionData));
|
||||
_activityThemeColorTimer =
|
||||
Timer(Duration(milliseconds: endTime - now), () => checkActivityThemeColor(networkVersionData));
|
||||
} else {
|
||||
dPrint("reset Color ....");
|
||||
state = state.copyWith(
|
||||
@ -317,9 +298,8 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
await appConfBox.put("app_locale", null);
|
||||
return;
|
||||
}
|
||||
final localeCode = value.countryCode != null
|
||||
? "${value.languageCode}_${value.countryCode ?? ""}"
|
||||
: value.languageCode;
|
||||
final localeCode =
|
||||
value.countryCode != null ? "${value.languageCode}_${value.countryCode ?? ""}" : value.languageCode;
|
||||
dPrint("changeLocale == $value localeCode=== $localeCode");
|
||||
await appConfBox.put("app_locale", localeCode);
|
||||
state = state.copyWith(appLocale: value);
|
||||
@ -329,8 +309,7 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
Future<String> _initAppDir() async {
|
||||
if (Platform.isWindows) {
|
||||
final userProfileDir = Platform.environment["USERPROFILE"];
|
||||
final applicationSupportDir =
|
||||
(await getApplicationSupportDirectory()).absolute.path;
|
||||
final applicationSupportDir = (await getApplicationSupportDirectory()).absolute.path;
|
||||
String? applicationBinaryModuleDir;
|
||||
try {
|
||||
await initDPrintFile(applicationSupportDir);
|
||||
@ -338,8 +317,7 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
dPrint("initDPrintFile Error: $e");
|
||||
}
|
||||
if (ConstConf.isMSE && userProfileDir != null) {
|
||||
applicationBinaryModuleDir =
|
||||
"$userProfileDir\\AppData\\Local\\Temp\\SCToolbox\\modules";
|
||||
applicationBinaryModuleDir = "$userProfileDir\\AppData\\Local\\Temp\\SCToolbox\\modules";
|
||||
} else {
|
||||
applicationBinaryModuleDir = "$applicationSupportDir\\modules";
|
||||
}
|
||||
@ -351,8 +329,7 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
);
|
||||
return applicationSupportDir;
|
||||
} else {
|
||||
final applicationSupportDir =
|
||||
(await getApplicationSupportDirectory()).absolute.path;
|
||||
final applicationSupportDir = (await getApplicationSupportDirectory()).absolute.path;
|
||||
final applicationBinaryModuleDir = "$applicationSupportDir/modules";
|
||||
dPrint("applicationSupportDir == $applicationSupportDir");
|
||||
dPrint("applicationBinaryModuleDir == $applicationBinaryModuleDir");
|
||||
|
@ -7,16 +7,14 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
|
||||
Future showToast(BuildContext context, String msg,
|
||||
{BoxConstraints? constraints, String? title}) async {
|
||||
Future showToast(BuildContext context, String msg, {BoxConstraints? constraints, String? title}) async {
|
||||
return showBaseDialog(context,
|
||||
title: title ?? S.current.app_common_tip,
|
||||
content: Text(msg),
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(S.current.app_common_tip_i_know),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
@ -25,11 +23,8 @@ Future showToast(BuildContext context, String msg,
|
||||
constraints: constraints);
|
||||
}
|
||||
|
||||
Future<bool> showConfirmDialogs(
|
||||
BuildContext context, String title, Widget content,
|
||||
{String confirm = "",
|
||||
String cancel = "",
|
||||
BoxConstraints? constraints}) async {
|
||||
Future<bool> showConfirmDialogs(BuildContext context, String title, Widget content,
|
||||
{String confirm = "", String cancel = "", BoxConstraints? constraints}) async {
|
||||
if (confirm.isEmpty) confirm = S.current.app_common_tip_confirm;
|
||||
if (cancel.isEmpty) cancel = S.current.app_common_tip_cancel;
|
||||
|
||||
@ -40,8 +35,7 @@ Future<bool> showConfirmDialogs(
|
||||
if (confirm.isNotEmpty)
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(confirm),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
@ -49,8 +43,7 @@ Future<bool> showConfirmDialogs(
|
||||
if (cancel.isNotEmpty)
|
||||
Button(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(cancel),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
@ -62,13 +55,15 @@ Future<bool> showConfirmDialogs(
|
||||
|
||||
Future<String?> showInputDialogs(BuildContext context,
|
||||
{required String title,
|
||||
required String content,
|
||||
BoxConstraints? constraints,
|
||||
String? initialValue,
|
||||
List<TextInputFormatter>? inputFormatters}) async {
|
||||
required String content,
|
||||
BoxConstraints? constraints,
|
||||
String? initialValue,
|
||||
List<TextInputFormatter>? inputFormatters}) async {
|
||||
String? userInput;
|
||||
constraints ??=
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .38);
|
||||
constraints ??= BoxConstraints(maxWidth: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width * .38);
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
title,
|
||||
@ -97,22 +92,20 @@ Future<String?> showInputDialogs(BuildContext context,
|
||||
}
|
||||
|
||||
Future showBaseDialog(BuildContext context,
|
||||
{required String title,
|
||||
required Widget content,
|
||||
List<Widget>? actions,
|
||||
BoxConstraints? constraints}) async {
|
||||
{required String title, required Widget content, List<Widget>? actions, BoxConstraints? constraints}) async {
|
||||
return await showDialog(
|
||||
context: context,
|
||||
builder: (context) => ContentDialog(
|
||||
title: Text(title),
|
||||
content: content,
|
||||
constraints: constraints ??
|
||||
const BoxConstraints(
|
||||
maxWidth: 512,
|
||||
maxHeight: 756.0,
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
builder: (context) =>
|
||||
ContentDialog(
|
||||
title: Text(title),
|
||||
content: content,
|
||||
constraints: constraints ??
|
||||
const BoxConstraints(
|
||||
maxWidth: 512,
|
||||
maxHeight: 756.0,
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -120,10 +113,8 @@ bool stringIsNotEmpty(String? s) {
|
||||
return s != null && (s.isNotEmpty);
|
||||
}
|
||||
|
||||
Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey,
|
||||
{double pixelRatio = 3.0}) async {
|
||||
RenderRepaintBoundary? boundary = repaintBoundaryKey.currentContext
|
||||
?.findRenderObject() as RenderRepaintBoundary?;
|
||||
Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey, {double pixelRatio = 3.0}) async {
|
||||
RenderRepaintBoundary? boundary = repaintBoundaryKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
|
||||
if (boundary == null) return null;
|
||||
|
||||
ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
|
||||
@ -133,11 +124,25 @@ Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey,
|
||||
return pngBytes;
|
||||
}
|
||||
|
||||
double roundDoubleTo(double value, double precision) =>
|
||||
(value * precision).round() / precision;
|
||||
double roundDoubleTo(double value, double precision) => (value * precision).round() / precision;
|
||||
|
||||
int getMinNumber(List<int> list) {
|
||||
if (list.isEmpty) return 0;
|
||||
list.sort((a, b) => a.compareTo(b));
|
||||
return list.first;
|
||||
}
|
||||
|
||||
String colorToHexCode(Color color, {ignoreTransparency = false}) {
|
||||
final colorValue = color.toARGB32();
|
||||
final colorAlpha = ((0xff000000 & colorValue) >> 24);
|
||||
final r = ((0x00ff0000 & colorValue) >> 16).toRadixString(16).padLeft(2, '0');
|
||||
final g = ((0x0000ff00 & colorValue) >> 8).toRadixString(16).padLeft(2, '0');
|
||||
final b = ((0x000000ff & colorValue) >> 0).toRadixString(16).padLeft(2, '0');
|
||||
final a = colorAlpha.toRadixString(16).padLeft(2, '0');
|
||||
|
||||
if (ignoreTransparency || colorAlpha == 255) {
|
||||
return '#$r$g$b';
|
||||
} else {
|
||||
return '#$a$r$g$b';
|
||||
}
|
||||
}
|
||||
|
108
lib/common/utils/multi_window_manager.dart
Normal file
108
lib/common/utils/multi_window_manager.dart
Normal file
@ -0,0 +1,108 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hexcolor/hexcolor.dart';
|
||||
import 'package:starcitizen_doctor/app.dart';
|
||||
import 'package:starcitizen_doctor/ui/tools/log_analyze_ui/log_analyze_ui.dart';
|
||||
|
||||
import 'base_utils.dart';
|
||||
|
||||
part 'multi_window_manager.freezed.dart';
|
||||
|
||||
part 'multi_window_manager.g.dart';
|
||||
|
||||
@freezed
|
||||
class MultiWindowAppState with _$MultiWindowAppState {
|
||||
const factory MultiWindowAppState({
|
||||
required String backgroundColor,
|
||||
required String menuColor,
|
||||
required String micaColor,
|
||||
String? languageCode,
|
||||
String? countryCode,
|
||||
}) = _MultiWindowAppState;
|
||||
|
||||
factory MultiWindowAppState.fromJson(Map<String, dynamic> json) => _$MultiWindowAppStateFromJson(json);
|
||||
}
|
||||
|
||||
class MultiWindowManager {
|
||||
static Future<void> launchSubWindow(String type, AppGlobalState appGlobalState) async {
|
||||
final window = await DesktopMultiWindow.createWindow(jsonEncode({
|
||||
'window_type': type,
|
||||
'app_state': _appStateToWindowState(appGlobalState).toJson(),
|
||||
}));
|
||||
window.setTitle("Log 分析器");
|
||||
await window.center();
|
||||
await window.show();
|
||||
// sendAppStateBroadcast(appGlobalState);
|
||||
}
|
||||
|
||||
static sendAppStateBroadcast(AppGlobalState appGlobalState) {
|
||||
DesktopMultiWindow.invokeMethod(
|
||||
0,
|
||||
'app_state_broadcast',
|
||||
_appStateToWindowState(appGlobalState).toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
static MultiWindowAppState _appStateToWindowState(AppGlobalState appGlobalState) {
|
||||
return MultiWindowAppState(
|
||||
backgroundColor: colorToHexCode(appGlobalState.themeConf.backgroundColor),
|
||||
menuColor: colorToHexCode(appGlobalState.themeConf.menuColor),
|
||||
micaColor: colorToHexCode(appGlobalState.themeConf.micaColor),
|
||||
languageCode: appGlobalState.appLocale?.languageCode,
|
||||
countryCode: appGlobalState.appLocale?.countryCode,
|
||||
);
|
||||
}
|
||||
|
||||
static void runSubWindowApp(List<String> args) {
|
||||
final argument = args[2].isEmpty ? const {} : jsonDecode(args[2]) as Map<String, dynamic>;
|
||||
Widget? windowWidget;
|
||||
switch (argument["window_type"]) {
|
||||
case "log_analyze":
|
||||
windowWidget = const ToolsLogAnalyzeDialogUI();
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unknown window type');
|
||||
}
|
||||
|
||||
final windowAppState = MultiWindowAppState.fromJson(argument['app_state'] ?? {});
|
||||
|
||||
return runApp(ProviderScope(
|
||||
child: FluentApp(
|
||||
title: "StarCitizenToolBox",
|
||||
restorationScopeId: "StarCitizenToolBox",
|
||||
themeMode: ThemeMode.dark,
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
FluentLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('en', 'US')],
|
||||
home: windowWidget,
|
||||
theme: FluentThemeData(
|
||||
brightness: Brightness.dark,
|
||||
fontFamily: "SourceHanSansCN-Regular",
|
||||
navigationPaneTheme: NavigationPaneThemeData(
|
||||
backgroundColor: HexColor(windowAppState.backgroundColor),
|
||||
),
|
||||
menuColor: HexColor(windowAppState.menuColor),
|
||||
micaBackgroundColor: HexColor(windowAppState.micaColor),
|
||||
buttonTheme: ButtonThemeData(
|
||||
defaultButtonStyle: ButtonStyle(
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
side: BorderSide(color: Colors.white.withValues(alpha: .01)))),
|
||||
))),
|
||||
locale: windowAppState.languageCode != null
|
||||
? Locale(windowAppState.languageCode!, windowAppState.countryCode)
|
||||
: null,
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
255
lib/common/utils/multi_window_manager.freezed.dart
Normal file
255
lib/common/utils/multi_window_manager.freezed.dart
Normal file
@ -0,0 +1,255 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'multi_window_manager.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
MultiWindowAppState _$MultiWindowAppStateFromJson(Map<String, dynamic> json) {
|
||||
return _MultiWindowAppState.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MultiWindowAppState {
|
||||
String get backgroundColor => throw _privateConstructorUsedError;
|
||||
String get menuColor => throw _privateConstructorUsedError;
|
||||
String get micaColor => throw _privateConstructorUsedError;
|
||||
String? get languageCode => throw _privateConstructorUsedError;
|
||||
String? get countryCode => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this MultiWindowAppState to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$MultiWindowAppStateCopyWith<MultiWindowAppState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MultiWindowAppStateCopyWith<$Res> {
|
||||
factory $MultiWindowAppStateCopyWith(
|
||||
MultiWindowAppState value, $Res Function(MultiWindowAppState) then) =
|
||||
_$MultiWindowAppStateCopyWithImpl<$Res, MultiWindowAppState>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{String backgroundColor,
|
||||
String menuColor,
|
||||
String micaColor,
|
||||
String? languageCode,
|
||||
String? countryCode});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MultiWindowAppStateCopyWithImpl<$Res, $Val extends MultiWindowAppState>
|
||||
implements $MultiWindowAppStateCopyWith<$Res> {
|
||||
_$MultiWindowAppStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? backgroundColor = null,
|
||||
Object? menuColor = null,
|
||||
Object? micaColor = null,
|
||||
Object? languageCode = freezed,
|
||||
Object? countryCode = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
backgroundColor: null == backgroundColor
|
||||
? _value.backgroundColor
|
||||
: backgroundColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
menuColor: null == menuColor
|
||||
? _value.menuColor
|
||||
: menuColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
micaColor: null == micaColor
|
||||
? _value.micaColor
|
||||
: micaColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
languageCode: freezed == languageCode
|
||||
? _value.languageCode
|
||||
: languageCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
countryCode: freezed == countryCode
|
||||
? _value.countryCode
|
||||
: countryCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MultiWindowAppStateImplCopyWith<$Res>
|
||||
implements $MultiWindowAppStateCopyWith<$Res> {
|
||||
factory _$$MultiWindowAppStateImplCopyWith(_$MultiWindowAppStateImpl value,
|
||||
$Res Function(_$MultiWindowAppStateImpl) then) =
|
||||
__$$MultiWindowAppStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{String backgroundColor,
|
||||
String menuColor,
|
||||
String micaColor,
|
||||
String? languageCode,
|
||||
String? countryCode});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MultiWindowAppStateImplCopyWithImpl<$Res>
|
||||
extends _$MultiWindowAppStateCopyWithImpl<$Res, _$MultiWindowAppStateImpl>
|
||||
implements _$$MultiWindowAppStateImplCopyWith<$Res> {
|
||||
__$$MultiWindowAppStateImplCopyWithImpl(_$MultiWindowAppStateImpl _value,
|
||||
$Res Function(_$MultiWindowAppStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? backgroundColor = null,
|
||||
Object? menuColor = null,
|
||||
Object? micaColor = null,
|
||||
Object? languageCode = freezed,
|
||||
Object? countryCode = freezed,
|
||||
}) {
|
||||
return _then(_$MultiWindowAppStateImpl(
|
||||
backgroundColor: null == backgroundColor
|
||||
? _value.backgroundColor
|
||||
: backgroundColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
menuColor: null == menuColor
|
||||
? _value.menuColor
|
||||
: menuColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
micaColor: null == micaColor
|
||||
? _value.micaColor
|
||||
: micaColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
languageCode: freezed == languageCode
|
||||
? _value.languageCode
|
||||
: languageCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
countryCode: freezed == countryCode
|
||||
? _value.countryCode
|
||||
: countryCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MultiWindowAppStateImpl implements _MultiWindowAppState {
|
||||
const _$MultiWindowAppStateImpl(
|
||||
{required this.backgroundColor,
|
||||
required this.menuColor,
|
||||
required this.micaColor,
|
||||
this.languageCode,
|
||||
this.countryCode});
|
||||
|
||||
factory _$MultiWindowAppStateImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MultiWindowAppStateImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String backgroundColor;
|
||||
@override
|
||||
final String menuColor;
|
||||
@override
|
||||
final String micaColor;
|
||||
@override
|
||||
final String? languageCode;
|
||||
@override
|
||||
final String? countryCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MultiWindowAppState(backgroundColor: $backgroundColor, menuColor: $menuColor, micaColor: $micaColor, languageCode: $languageCode, countryCode: $countryCode)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MultiWindowAppStateImpl &&
|
||||
(identical(other.backgroundColor, backgroundColor) ||
|
||||
other.backgroundColor == backgroundColor) &&
|
||||
(identical(other.menuColor, menuColor) ||
|
||||
other.menuColor == menuColor) &&
|
||||
(identical(other.micaColor, micaColor) ||
|
||||
other.micaColor == micaColor) &&
|
||||
(identical(other.languageCode, languageCode) ||
|
||||
other.languageCode == languageCode) &&
|
||||
(identical(other.countryCode, countryCode) ||
|
||||
other.countryCode == countryCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, backgroundColor, menuColor,
|
||||
micaColor, languageCode, countryCode);
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MultiWindowAppStateImplCopyWith<_$MultiWindowAppStateImpl> get copyWith =>
|
||||
__$$MultiWindowAppStateImplCopyWithImpl<_$MultiWindowAppStateImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MultiWindowAppStateImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MultiWindowAppState implements MultiWindowAppState {
|
||||
const factory _MultiWindowAppState(
|
||||
{required final String backgroundColor,
|
||||
required final String menuColor,
|
||||
required final String micaColor,
|
||||
final String? languageCode,
|
||||
final String? countryCode}) = _$MultiWindowAppStateImpl;
|
||||
|
||||
factory _MultiWindowAppState.fromJson(Map<String, dynamic> json) =
|
||||
_$MultiWindowAppStateImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get backgroundColor;
|
||||
@override
|
||||
String get menuColor;
|
||||
@override
|
||||
String get micaColor;
|
||||
@override
|
||||
String? get languageCode;
|
||||
@override
|
||||
String? get countryCode;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$MultiWindowAppStateImplCopyWith<_$MultiWindowAppStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
27
lib/common/utils/multi_window_manager.g.dart
Normal file
27
lib/common/utils/multi_window_manager.g.dart
Normal file
@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'multi_window_manager.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$MultiWindowAppStateImpl _$$MultiWindowAppStateImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MultiWindowAppStateImpl(
|
||||
backgroundColor: json['backgroundColor'] as String,
|
||||
menuColor: json['menuColor'] as String,
|
||||
micaColor: json['micaColor'] as String,
|
||||
languageCode: json['languageCode'] as String?,
|
||||
countryCode: json['countryCode'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MultiWindowAppStateImplToJson(
|
||||
_$MultiWindowAppStateImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'backgroundColor': instance.backgroundColor,
|
||||
'menuColor': instance.menuColor,
|
||||
'micaColor': instance.micaColor,
|
||||
'languageCode': instance.languageCode,
|
||||
'countryCode': instance.countryCode,
|
||||
};
|
@ -7,6 +7,7 @@ import 'package:window_manager/window_manager.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'common/utils/multi_window_manager.dart';
|
||||
|
||||
void main(List<String> args) async {
|
||||
// webview window
|
||||
@ -14,6 +15,10 @@ void main(List<String> args) async {
|
||||
backgroundColor: const Color.fromRGBO(19, 36, 49, 1), builder: _defaultWebviewTitleBar)) {
|
||||
return;
|
||||
}
|
||||
if (args.firstOrNull == 'multi_window') {
|
||||
MultiWindowManager.runSubWindowApp(args);
|
||||
return;
|
||||
}
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await _initWindow();
|
||||
// run app
|
||||
|
12
lib/ui/tools/log_analyze_ui/log_analyze_provider.dart
Normal file
12
lib/ui/tools/log_analyze_ui/log_analyze_provider.dart
Normal file
@ -0,0 +1,12 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'log_analyze_provider.g.dart';
|
||||
|
||||
|
||||
@riverpod
|
||||
class ToolsLogAnalyze extends _$ToolsLogAnalyze {
|
||||
@override
|
||||
void build() async {
|
||||
return;
|
||||
}
|
||||
}
|
26
lib/ui/tools/log_analyze_ui/log_analyze_provider.g.dart
Normal file
26
lib/ui/tools/log_analyze_ui/log_analyze_provider.g.dart
Normal file
@ -0,0 +1,26 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'log_analyze_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$toolsLogAnalyzeHash() => r'a31922fe5ee020b06e8d494486c39bdd261af34c';
|
||||
|
||||
/// See also [ToolsLogAnalyze].
|
||||
@ProviderFor(ToolsLogAnalyze)
|
||||
final toolsLogAnalyzeProvider =
|
||||
AutoDisposeNotifierProvider<ToolsLogAnalyze, void>.internal(
|
||||
ToolsLogAnalyze.new,
|
||||
name: r'toolsLogAnalyzeProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$toolsLogAnalyzeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$ToolsLogAnalyze = AutoDisposeNotifier<void>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
18
lib/ui/tools/log_analyze_ui/log_analyze_ui.dart
Normal file
18
lib/ui/tools/log_analyze_ui/log_analyze_ui.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
class ToolsLogAnalyzeDialogUI extends HookConsumerWidget {
|
||||
const ToolsLogAnalyzeDialogUI({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return ScaffoldPage(
|
||||
header: const PageHeader(
|
||||
title: Text("Log 分析器"),
|
||||
),
|
||||
content: Column(
|
||||
children: [],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ 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/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/multi_window_manager.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/provider/aria2c.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/downloader/home_downloader_ui_model.dart';
|
||||
@ -90,6 +91,13 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
const Icon(FluentIcons.virtual_network, size: 24),
|
||||
onTap: () => _doHostsBooster(context),
|
||||
),
|
||||
ToolsItemData(
|
||||
"log_analyze",
|
||||
"log 分析器",
|
||||
"分析您的游玩记录 (登录、死亡、击杀 等信息)",
|
||||
Icon(FluentIcons.analytics_logo),
|
||||
onTap: () => _showLogAnalyze(context),
|
||||
),
|
||||
ToolsItemData(
|
||||
"rsilauncher_enhance_mod",
|
||||
S.current.tools_rsi_launcher_enhance_title,
|
||||
@ -167,9 +175,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
ToolsItemData(
|
||||
"remove_nvme_settings",
|
||||
S.current.tools_action_remove_nvme_registry_patch,
|
||||
S.current.tools_action_info_nvme_patch_issue(nvmePatchStatus
|
||||
? S.current.localization_info_installed
|
||||
: S.current.tools_action_info_not_installed),
|
||||
S.current.tools_action_info_nvme_patch_issue(
|
||||
nvmePatchStatus ? S.current.localization_info_installed : S.current.tools_action_info_not_installed),
|
||||
const Icon(FluentIcons.hard_drive, size: 24),
|
||||
onTap: nvmePatchStatus
|
||||
? () async {
|
||||
@ -177,8 +184,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
await SystemHelper.doRemoveNvmePath();
|
||||
state = state.copyWith(working: false);
|
||||
if (!context.mounted) return;
|
||||
showToast(context,
|
||||
S.current.tools_action_info_removed_restart_effective);
|
||||
showToast(context, S.current.tools_action_info_removed_restart_effective);
|
||||
loadToolsCard(context, skipPathScan: true);
|
||||
}
|
||||
: null,
|
||||
@ -194,8 +200,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
final r = await SystemHelper.addNvmePatch();
|
||||
if (r == "") {
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_fix_success_restart);
|
||||
showToast(context, S.current.tools_action_info_fix_success_restart);
|
||||
} else {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.doctor_action_result_fix_fail(r));
|
||||
@ -209,11 +214,11 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
Future<ToolsItemData> _addShaderCard(BuildContext context) async {
|
||||
final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath();
|
||||
final shaderSize = ((await SystemHelper.getDirLen(gameShaderCachePath ?? "",
|
||||
skipPath: ["$gameShaderCachePath\\Crashes"])) /
|
||||
1024 /
|
||||
1024)
|
||||
.toStringAsFixed(4);
|
||||
final shaderSize =
|
||||
((await SystemHelper.getDirLen(gameShaderCachePath ?? "", skipPath: ["$gameShaderCachePath\\Crashes"])) /
|
||||
1024 /
|
||||
1024)
|
||||
.toStringAsFixed(4);
|
||||
return ToolsItemData(
|
||||
"clean_shaders",
|
||||
S.current.tools_action_clear_shader_cache,
|
||||
@ -229,12 +234,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
return ToolsItemData(
|
||||
"photography_mode",
|
||||
isEnable
|
||||
? S.current.tools_action_close_photography_mode
|
||||
: S.current.tools_action_open_photography_mode,
|
||||
isEnable
|
||||
? S.current.tools_action_info_restore_lens_shake
|
||||
: S.current.tools_action_info_one_key_close_lens_shake,
|
||||
isEnable ? S.current.tools_action_close_photography_mode : S.current.tools_action_open_photography_mode,
|
||||
isEnable ? S.current.tools_action_info_restore_lens_shake : S.current.tools_action_info_one_key_close_lens_shake,
|
||||
const Icon(FontAwesomeIcons.camera, size: 24),
|
||||
onTap: () => _onChangePhotographyMode(context, isEnable),
|
||||
);
|
||||
@ -245,8 +246,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
/// -----------------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------------
|
||||
|
||||
Future<void> reScanPath(BuildContext context,
|
||||
{bool checkActive = false, bool skipToast = false}) async {
|
||||
Future<void> reScanPath(BuildContext context, {bool checkActive = false, bool skipToast = false}) async {
|
||||
var scInstallPaths = <String>[];
|
||||
var rsiLauncherInstallPaths = <String>[];
|
||||
var scInstalledPath = "";
|
||||
@ -298,8 +298,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
/// 重装EAC
|
||||
Future<void> _reinstallEAC(BuildContext context) async {
|
||||
if (state.scInstalledPath.isEmpty) {
|
||||
showToast(
|
||||
context, S.current.tools_action_info_valid_game_directory_needed);
|
||||
showToast(context, S.current.tools_action_info_valid_game_directory_needed);
|
||||
return;
|
||||
}
|
||||
state = state.copyWith(working: true);
|
||||
@ -312,8 +311,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
final Map eacJson = json.decode(eacJsonData);
|
||||
final eacID = eacJson["productid"];
|
||||
if (eacID != null) {
|
||||
final eacCacheDir =
|
||||
Directory("${envVars["appdata"]}\\EasyAntiCheat\\$eacID");
|
||||
final eacCacheDir = Directory("${envVars["appdata"]}\\EasyAntiCheat\\$eacID");
|
||||
if (await eacCacheDir.exists()) {
|
||||
await eacCacheDir.delete(recursive: true);
|
||||
}
|
||||
@ -323,8 +321,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
if (await dir.exists()) {
|
||||
await dir.delete(recursive: true);
|
||||
}
|
||||
final eacLauncher =
|
||||
File("${state.scInstalledPath}\\StarCitizen_Launcher.exe");
|
||||
final eacLauncher = File("${state.scInstalledPath}\\StarCitizen_Launcher.exe");
|
||||
if (await eacLauncher.exists()) {
|
||||
await eacLauncher.delete(recursive: true);
|
||||
}
|
||||
@ -350,8 +347,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
/// 管理员模式运行 RSI 启动器
|
||||
Future _adminRSILauncher(BuildContext context) async {
|
||||
if (state.rsiLauncherInstalledPath == "") {
|
||||
showToast(context,
|
||||
S.current.tools_action_info_rsi_launcher_directory_not_found);
|
||||
showToast(context, S.current.tools_action_info_rsi_launcher_directory_not_found);
|
||||
}
|
||||
SystemHelper.checkAndLaunchRSILauncher(state.rsiLauncherInstalledPath);
|
||||
}
|
||||
@ -375,8 +371,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(S.current.action_close),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
@ -390,8 +385,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
Future<void> _cleanShaderCache(BuildContext context) async {
|
||||
state = state.copyWith(working: true);
|
||||
final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath();
|
||||
final l =
|
||||
await Directory(gameShaderCachePath!).list(recursive: false).toList();
|
||||
final l = await Directory(gameShaderCachePath!).list(recursive: false).toList();
|
||||
for (var value in l) {
|
||||
if (value is Directory) {
|
||||
if (!value.absolute.path.contains("Crashes")) {
|
||||
@ -410,10 +404,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
if ((await SystemHelper.getPID("\"RSI Launcher\"")).isNotEmpty) {
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
showToast(context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -427,20 +419,15 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
try {
|
||||
state = state.copyWith(working: true);
|
||||
final aria2cManager = ref.read(aria2cModelProvider.notifier);
|
||||
await aria2cManager
|
||||
.launchDaemon(appGlobalState.applicationBinaryModuleDir!);
|
||||
await aria2cManager.launchDaemon(appGlobalState.applicationBinaryModuleDir!);
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c!;
|
||||
|
||||
// check download task list
|
||||
for (var value in [
|
||||
...await aria2c.tellActive(),
|
||||
...await aria2c.tellWaiting(0, 100000)
|
||||
]) {
|
||||
for (var value in [...await aria2c.tellActive(), ...await aria2c.tellWaiting(0, 100000)]) {
|
||||
final t = HomeDownloaderUIModel.getTaskTypeAndName(value);
|
||||
if (t.key == "torrent" && t.value.contains("Data.p4k")) {
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_p4k_download_in_progress);
|
||||
showToast(context, S.current.tools_action_info_p4k_download_in_progress);
|
||||
state = state.copyWith(working: false);
|
||||
return;
|
||||
}
|
||||
@ -449,15 +436,12 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
if (torrentUrl == "") {
|
||||
state = state.copyWith(working: false);
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_function_under_maintenance);
|
||||
showToast(context, S.current.tools_action_info_function_under_maintenance);
|
||||
return;
|
||||
}
|
||||
|
||||
final userSelect = await FilePicker.platform.saveFile(
|
||||
initialDirectory: savePath,
|
||||
fileName: fileName,
|
||||
lockParentWindow: true);
|
||||
final userSelect =
|
||||
await FilePicker.platform.saveFile(initialDirectory: savePath, fileName: fileName, lockParentWindow: true);
|
||||
if (userSelect == null) {
|
||||
state = state.copyWith(working: false);
|
||||
return;
|
||||
@ -478,8 +462,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
}
|
||||
final b64Str = base64Encode(btData.data!);
|
||||
|
||||
final gid =
|
||||
await aria2c.addTorrent(b64Str, extraParams: {"dir": savePath});
|
||||
final gid = await aria2c.addTorrent(b64Str, extraParams: {"dir": savePath});
|
||||
state = state.copyWith(working: false);
|
||||
dPrint("Aria2cManager.aria2c.addUri resp === $gid");
|
||||
await aria2c.saveSession();
|
||||
@ -497,24 +480,19 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
launchUrlString("https://support.citizenwiki.cn/d/8");
|
||||
}
|
||||
|
||||
Future<bool> _checkPhotographyStatus(BuildContext context,
|
||||
{bool? setMode}) async {
|
||||
Future<bool> _checkPhotographyStatus(BuildContext context, {bool? setMode}) async {
|
||||
final scInstalledPath = state.scInstalledPath;
|
||||
final keys = ["AudioShakeStrength", "CameraSpringMovement", "ShakeScale"];
|
||||
final attributesFile = File(
|
||||
"$scInstalledPath\\USER\\Client\\0\\Profiles\\default\\attributes.xml");
|
||||
final attributesFile = File("$scInstalledPath\\USER\\Client\\0\\Profiles\\default\\attributes.xml");
|
||||
if (setMode == null) {
|
||||
bool isEnable = false;
|
||||
if (scInstalledPath.isNotEmpty) {
|
||||
if (await attributesFile.exists()) {
|
||||
final xmlFile =
|
||||
XmlDocument.parse(await attributesFile.readAsString());
|
||||
final xmlFile = XmlDocument.parse(await attributesFile.readAsString());
|
||||
isEnable = true;
|
||||
for (var k in keys) {
|
||||
if (!isEnable) break;
|
||||
final e = xmlFile.rootElement.children
|
||||
.where((element) => element.getAttribute("name") == k)
|
||||
.firstOrNull;
|
||||
final e = xmlFile.rootElement.children.where((element) => element.getAttribute("name") == k).firstOrNull;
|
||||
if (e != null && e.getAttribute("value") == "0") {
|
||||
} else {
|
||||
isEnable = false;
|
||||
@ -531,8 +509,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
}
|
||||
final xmlFile = XmlDocument.parse(await attributesFile.readAsString());
|
||||
// clear all
|
||||
xmlFile.rootElement.children.removeWhere(
|
||||
(element) => keys.contains(element.getAttribute("name")));
|
||||
xmlFile.rootElement.children.removeWhere((element) => keys.contains(element.getAttribute("name")));
|
||||
if (setMode) {
|
||||
for (var element in keys) {
|
||||
XmlElement newNode = XmlElement(XmlName('Attr'), [
|
||||
@ -550,8 +527,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
}
|
||||
|
||||
_onChangePhotographyMode(BuildContext context, bool isEnable) async {
|
||||
_checkPhotographyStatus(context, setMode: !isEnable)
|
||||
.unwrap(context: context);
|
||||
_checkPhotographyStatus(context, setMode: !isEnable).unwrap(context: context);
|
||||
loadToolsCard(context, skipPathScan: true);
|
||||
}
|
||||
|
||||
@ -564,23 +540,18 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
}
|
||||
|
||||
_doHostsBooster(BuildContext context) async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => const HostsBoosterDialogUI());
|
||||
showDialog(context: context, builder: (BuildContext context) => const HostsBoosterDialogUI());
|
||||
}
|
||||
|
||||
_unp4kc(BuildContext context) async {
|
||||
context.push("/tools/unp4kc");
|
||||
}
|
||||
|
||||
static rsiEnhance(BuildContext context,
|
||||
{bool showNotGameInstallMsg = false}) async {
|
||||
static rsiEnhance(BuildContext context, {bool showNotGameInstallMsg = false}) async {
|
||||
if ((await SystemHelper.getPID("\"RSI Launcher\"")).isNotEmpty) {
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
showToast(context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
@ -590,4 +561,13 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
showNotGameInstallMsg: showNotGameInstallMsg,
|
||||
));
|
||||
}
|
||||
|
||||
_showLogAnalyze(BuildContext context) async {
|
||||
if (state.scInstalledPath.isEmpty) {
|
||||
showToast(context, S.current.tools_action_info_valid_game_directory_needed);
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
await MultiWindowManager.launchSubWindow("log_analyze", appGlobalState);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ part of 'tools_ui_model.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$toolsUIModelHash() => r'ba4d824a61e83b496dbff4d7b5f2e29bd2ed4904';
|
||||
String _$toolsUIModelHash() => r'af6e6de30c191a7c9a4e2a1c96a688fba6ee086c';
|
||||
|
||||
/// See also [ToolsUIModel].
|
||||
@ProviderFor(ToolsUIModel)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <desktop_multi_window/desktop_multi_window_plugin.h>
|
||||
#include <desktop_webview_window/desktop_webview_window_plugin.h>
|
||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||
@ -13,6 +14,9 @@
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) desktop_multi_window_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopMultiWindowPlugin");
|
||||
desktop_multi_window_plugin_register_with_registrar(desktop_multi_window_registrar);
|
||||
g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin");
|
||||
desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
desktop_multi_window
|
||||
desktop_webview_window
|
||||
flutter_acrylic
|
||||
screen_retriever_linux
|
||||
|
@ -5,6 +5,7 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import desktop_multi_window
|
||||
import desktop_webview_window
|
||||
import device_info_plus
|
||||
import file_picker
|
||||
@ -15,6 +16,7 @@ import url_launcher_macos
|
||||
import window_manager
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FlutterMultiWindowPlugin.register(with: registry.registrar(forPlugin: "FlutterMultiWindowPlugin"))
|
||||
DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||
|
@ -66,6 +66,7 @@ dependencies:
|
||||
re_highlight: ^0.0.3
|
||||
shelf: ^1.4.1
|
||||
qr_flutter: ^4.1.0
|
||||
desktop_multi_window: ^0.2.1
|
||||
dependency_overrides:
|
||||
http: ^1.1.2
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <desktop_multi_window/desktop_multi_window_plugin.h>
|
||||
#include <desktop_webview_window/desktop_webview_window_plugin.h>
|
||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
|
||||
@ -13,6 +14,8 @@
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
DesktopMultiWindowPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("DesktopMultiWindowPlugin"));
|
||||
DesktopWebviewWindowPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin"));
|
||||
FlutterAcrylicPluginRegisterWithRegistrar(
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
desktop_multi_window
|
||||
desktop_webview_window
|
||||
flutter_acrylic
|
||||
screen_retriever_windows
|
||||
|
Loading…
x
Reference in New Issue
Block a user