feat: update

This commit is contained in:
xkeyC 2025-12-20 17:31:36 +08:00
parent 6d2bb89c64
commit 79cc157e04
10 changed files with 95 additions and 38 deletions

View File

@ -16,9 +16,6 @@ import 'package:starcitizen_doctor/ui/guide/guide_ui.dart';
import 'package:starcitizen_doctor/ui/home/performance/performance_ui.dart'; import 'package:starcitizen_doctor/ui/home/performance/performance_ui.dart';
import 'package:starcitizen_doctor/ui/splash_ui.dart'; import 'package:starcitizen_doctor/ui/splash_ui.dart';
import 'package:starcitizen_doctor/widgets/widgets.dart'; import 'package:starcitizen_doctor/widgets/widgets.dart';
import 'package:uuid/uuid.dart';
import 'api/analytics.dart';
import 'api/api.dart'; import 'api/api.dart';
import 'common/conf/url_conf.dart'; import 'common/conf/url_conf.dart';
import 'common/helper/system_helper.dart'; import 'common/helper/system_helper.dart';

View File

@ -1883,7 +1883,7 @@ class MessageLookup extends MessageLookupByLibrary {
), ),
"yearly_report_play_time_value": m89, "yearly_report_play_time_value": m89,
"yearly_report_powered_by": MessageLookupByLibrary.simpleMessage( "yearly_report_powered_by": MessageLookupByLibrary.simpleMessage(
"Presented by SCToolbox", "Presented by SCToolbox | github.com/StarCitizenToolBox/app",
), ),
"yearly_report_session_average": MessageLookupByLibrary.simpleMessage( "yearly_report_session_average": MessageLookupByLibrary.simpleMessage(
"Average", "Average",

View File

@ -1693,7 +1693,7 @@ class MessageLookup extends MessageLookupByLibrary {
"yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("時間"), "yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("時間"),
"yearly_report_play_time_value": m89, "yearly_report_play_time_value": m89,
"yearly_report_powered_by": MessageLookupByLibrary.simpleMessage( "yearly_report_powered_by": MessageLookupByLibrary.simpleMessage(
"SCToolbox 提供", "SCToolbox 提供 | github.com/StarCitizenToolBox/app",
), ),
"yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"), "yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"),
"yearly_report_session_date": m90, "yearly_report_session_date": m90,

View File

@ -1897,7 +1897,7 @@ class MessageLookup extends MessageLookupByLibrary {
), ),
"yearly_report_play_time_value": m89, "yearly_report_play_time_value": m89,
"yearly_report_powered_by": MessageLookupByLibrary.simpleMessage( "yearly_report_powered_by": MessageLookupByLibrary.simpleMessage(
"Представлено SCToolbox", "Представлено SCToolbox | github.com/StarCitizenToolBox/app",
), ),
"yearly_report_session_average": MessageLookupByLibrary.simpleMessage( "yearly_report_session_average": MessageLookupByLibrary.simpleMessage(
"Среднее", "Среднее",

View File

@ -1621,7 +1621,7 @@ class MessageLookup extends MessageLookupByLibrary {
"yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("小时"), "yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("小时"),
"yearly_report_play_time_value": m89, "yearly_report_play_time_value": m89,
"yearly_report_powered_by": MessageLookupByLibrary.simpleMessage( "yearly_report_powered_by": MessageLookupByLibrary.simpleMessage(
"由 SC 汉化盒子为您呈现", "由 SC 汉化盒子为您呈现 | github.com/StarCitizenToolBox/app",
), ),
"yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"), "yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"),
"yearly_report_session_date": m90, "yearly_report_session_date": m90,

View File

@ -1624,7 +1624,7 @@ class MessageLookup extends MessageLookupByLibrary {
"yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("小時"), "yearly_report_play_time_unit": MessageLookupByLibrary.simpleMessage("小時"),
"yearly_report_play_time_value": m89, "yearly_report_play_time_value": m89,
"yearly_report_powered_by": MessageLookupByLibrary.simpleMessage( "yearly_report_powered_by": MessageLookupByLibrary.simpleMessage(
"由 SC工具箱為您呈現", "由 SC工具箱為您呈現 | github.com/StarCitizenToolBox/app",
), ),
"yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"), "yearly_report_session_average": MessageLookupByLibrary.simpleMessage("平均"),
"yearly_report_session_date": m90, "yearly_report_session_date": m90,

View File

@ -6812,10 +6812,10 @@ class S {
); );
} }
/// `Presented by SCToolbox` /// `Presented by SCToolbox | github.com/StarCitizenToolBox/app`
String get yearly_report_powered_by { String get yearly_report_powered_by {
return Intl.message( return Intl.message(
'Presented by SCToolbox', 'Presented by SCToolbox | github.com/StarCitizenToolBox/app',
name: 'yearly_report_powered_by', name: 'yearly_report_powered_by',
desc: '', desc: '',
args: [], args: [],

View File

@ -7,6 +7,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:starcitizen_doctor/app.dart'; import 'package:starcitizen_doctor/app.dart';
import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/widgets/widgets.dart'; import 'package:starcitizen_doctor/widgets/widgets.dart';
import 'package:web/web.dart' as web; import 'package:web/web.dart' as web;
@ -65,6 +66,12 @@ class YearlyReportEntryUIRoute extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final globalState = ref.watch(appGlobalModelProvider); final globalState = ref.watch(appGlobalModelProvider);
// initApp
useEffect(() {
ref.read(appGlobalModelProvider.notifier).initApp();
return null;
}, const []);
// 使 index_ui.dart // 使 index_ui.dart
return Container( return Container(
color: const Color(0xFF0a0a12), // color: const Color(0xFF0a0a12), //
@ -94,25 +101,16 @@ class YearlyReportEntryUIRoute extends HookConsumerWidget {
}, },
), ),
), ),
//
Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.black.withValues(alpha: .6), Colors.black.withValues(alpha: .75)],
),
),
),
// //
Center( Center(
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 1440, maxHeight: 920), constraints: const BoxConstraints(maxWidth: 1440, maxHeight: 920),
child: ClipRRect( child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(12)), borderRadius: const BorderRadius.all(Radius.circular(12)),
child: BlurOvalWidget(child: const YearlyReportEntryUI()), child: BlurOvalWidget(
blurColor: Colors.black.withValues(alpha: .65),
child: const YearlyReportEntryUI(),
),
), ),
), ),
), ),
@ -304,27 +302,31 @@ class YearlyReportEntryUI extends HookConsumerWidget {
loadingProgress.value = 0; loadingProgress.value = 0;
errorMessage.value = null; errorMessage.value = null;
dPrint('[YearlyReport] Starting to read log files from directory...');
final contents = await _readLogFilesFromDirectory(loadingMessage, loadingProgress); final contents = await _readLogFilesFromDirectory(loadingMessage, loadingProgress);
if (contents.isEmpty) { if (contents.isEmpty) {
dPrint('[YearlyReport] No log files found');
errorMessage.value = S.current.yearly_report_web_no_logs_found; errorMessage.value = S.current.yearly_report_web_no_logs_found;
isLoading.value = false; isLoading.value = false;
return; return;
} }
dPrint('[YearlyReport] Successfully read ${contents.length} log files');
logContents.value = contents; logContents.value = contents;
} catch (e) { } catch (e, stackTrace) {
errorMessage.value = e.toString(); dPrint('[YearlyReport] Error reading directory: $e');
dPrint('[YearlyReport] Stack trace: $stackTrace');
errorMessage.value = 'Error: $e\n\nStack trace:\n$stackTrace';
isLoading.value = false; isLoading.value = false;
} }
} }
bool _isDirectoryPickerSupported() { bool _isDirectoryPickerSupported() {
try { // WASM/Web true
return true; // js_interop @JS 使
} catch (_) { dPrint('[YearlyReport] Assuming showDirectoryPicker API is available (will handle error if not)');
return false; return true;
}
} }
Future<List<String>> _readLogFilesFromDirectory( Future<List<String>> _readLogFilesFromDirectory(
@ -334,18 +336,26 @@ class YearlyReportEntryUI extends HookConsumerWidget {
final logContents = <String>[]; final logContents = <String>[];
try { try {
dPrint('[YearlyReport] Calling showDirectoryPicker...');
final dirHandle = await _showDirectoryPickerWrapper(); final dirHandle = await _showDirectoryPickerWrapper();
if (dirHandle == null) return []; if (dirHandle == null) {
dPrint('[YearlyReport] User cancelled directory picker');
return [];
}
dPrint('[YearlyReport] Got directory handle');
final dirHandleJS = FileSystemDirectoryHandleJS(dirHandle); final dirHandleJS = FileSystemDirectoryHandleJS(dirHandle);
// LIVE // LIVE
FileSystemDirectoryHandleJS? liveHandle; FileSystemDirectoryHandleJS? liveHandle;
try { try {
dPrint('[YearlyReport] Trying to get LIVE directory...');
final livePromise = dirHandleJS.getDirectoryHandle('LIVE'.toJS); final livePromise = dirHandleJS.getDirectoryHandle('LIVE'.toJS);
final liveResult = await livePromise.toDart; final liveResult = await livePromise.toDart;
liveHandle = FileSystemDirectoryHandleJS(liveResult); liveHandle = FileSystemDirectoryHandleJS(liveResult);
} catch (_) { dPrint('[YearlyReport] Found LIVE directory');
} catch (e) {
dPrint('[YearlyReport] LIVE directory not found, using selected directory: $e');
liveHandle = dirHandleJS; liveHandle = dirHandleJS;
} }
@ -354,18 +364,29 @@ class YearlyReportEntryUI extends HookConsumerWidget {
// Game.log // Game.log
try { try {
dPrint('[YearlyReport] Trying to get Game.log...');
final gameLogPromise = liveHandle.getFileHandle('Game.log'.toJS); final gameLogPromise = liveHandle.getFileHandle('Game.log'.toJS);
final gameLogResult = await gameLogPromise.toDart; final gameLogResult = await gameLogPromise.toDart;
filesToRead.add(FileSystemFileHandleJS(gameLogResult)); filesToRead.add(FileSystemFileHandleJS(gameLogResult));
} catch (_) {} dPrint('[YearlyReport] Found Game.log');
} catch (e) {
dPrint('[YearlyReport] Game.log not found: $e');
}
// logbackups // logbackups
try { try {
dPrint('[YearlyReport] Trying to get logbackups directory...');
final logbackupsPromise = liveHandle.getDirectoryHandle('logbackups'.toJS); final logbackupsPromise = liveHandle.getDirectoryHandle('logbackups'.toJS);
final logbackupsResult = await logbackupsPromise.toDart; final logbackupsResult = await logbackupsPromise.toDart;
final logbackupsHandle = FileSystemDirectoryHandleJS(logbackupsResult); final logbackupsHandle = FileSystemDirectoryHandleJS(logbackupsResult);
dPrint('[YearlyReport] Found logbackups directory');
await _collectLogbackupsFiles(logbackupsHandle, filesToRead); await _collectLogbackupsFiles(logbackupsHandle, filesToRead);
} catch (_) {} dPrint('[YearlyReport] Collected ${filesToRead.length} files from logbackups');
} catch (e) {
dPrint('[YearlyReport] logbackups directory not found: $e');
}
dPrint('[YearlyReport] Total files to read: ${filesToRead.length}');
// //
for (var i = 0; i < filesToRead.length; i++) { for (var i = 0; i < filesToRead.length; i++) {
@ -380,12 +401,18 @@ class YearlyReportEntryUI extends HookConsumerWidget {
final content = await _readFileContent(fileHandle); final content = await _readFileContent(fileHandle);
if (content.isNotEmpty) { if (content.isNotEmpty) {
logContents.add(content); logContents.add(content);
dPrint('[YearlyReport] Read file: $fileName (${content.length} chars)');
} }
} catch (_) {} } catch (e) {
dPrint('[YearlyReport] Error reading file $fileName: $e');
}
} }
loadingProgress.value = 1.0; loadingProgress.value = 1.0;
} catch (e) { dPrint('[YearlyReport] Finished reading files, total: ${logContents.length}');
} catch (e, stackTrace) {
dPrint('[YearlyReport] Error in _readLogFilesFromDirectory: $e');
dPrint('[YearlyReport] Stack trace: $stackTrace');
rethrow; rethrow;
} }
@ -416,18 +443,30 @@ class YearlyReportEntryUI extends HookConsumerWidget {
filesToRead.add(handleJS); filesToRead.add(handleJS);
} }
} }
} catch (e) {} } catch (e) {
dPrint('[YearlyReport] Error collecting logbackups files: $e');
}
} }
Future<JSObject?> _showDirectoryPickerWrapper() async { Future<JSObject?> _showDirectoryPickerWrapper() async {
try { try {
dPrint('[YearlyReport] Calling _showDirectoryPicker JS function...');
final promise = _showDirectoryPicker(); final promise = _showDirectoryPicker();
dPrint('[YearlyReport] Got promise, awaiting result...');
final result = await promise.toDart; final result = await promise.toDart;
dPrint('[YearlyReport] Got result from showDirectoryPicker');
return result; return result;
} catch (e) { } catch (e, stackTrace) {
dPrint('[YearlyReport] Error in _showDirectoryPickerWrapper: $e');
dPrint('[YearlyReport] Stack trace: $stackTrace');
if (e.toString().contains('AbortError')) { if (e.toString().contains('AbortError')) {
dPrint('[YearlyReport] User aborted the picker');
return null; return null;
} }
// API
if (e.toString().contains('TypeError') || e.toString().contains('undefined')) {
throw Exception('${S.current.yearly_report_web_browser_not_supported}\n\nTechnical details: $e');
}
rethrow; rethrow;
} }
} }

View File

@ -1243,6 +1243,26 @@ class _SummaryPage extends StatelessWidget {
style: TextStyle(fontSize: 16, color: Colors.white.withValues(alpha: .6)), style: TextStyle(fontSize: 16, color: Colors.white.withValues(alpha: .6)),
), ),
), ),
const SizedBox(height: 32),
FadeInUp(
delay: const Duration(milliseconds: 900),
child: Button(
onPressed: () {
launchUrlString("https://github.com/StarCitizenToolBox/app");
},
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(FontAwesomeIcons.github),
const SizedBox(width: 12),
Text(S.current.support_dev_github_star_button),
],
),
),
),
),
], ],
), ),
); );

View File

@ -6,6 +6,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:starcitizen_doctor/common/helper/yearly_report_analyzer.dart'; import 'package:starcitizen_doctor/common/helper/yearly_report_analyzer.dart';
import 'package:starcitizen_doctor/widgets/widgets.dart'; import 'package:starcitizen_doctor/widgets/widgets.dart';
import 'package:url_launcher/url_launcher_string.dart';
part 'yearly_report_pages.dart'; part 'yearly_report_pages.dart';