diff --git a/lib/common/conf/binary_conf.dart b/lib/common/conf/binary_conf.dart index 13bb7a0..41a4aae 100644 --- a/lib/common/conf/binary_conf.dart +++ b/lib/common/conf/binary_conf.dart @@ -8,7 +8,7 @@ import 'package:starcitizen_doctor/common/utils/log.dart'; class BinaryModuleConf { static const _modules = { "aria2c": "0", - "unp4kc": "0", + "unp4kc": "1", }; static Future extractModule(List modules, String workingDir) async { diff --git a/lib/provider/unp4kc.dart b/lib/provider/unp4kc.dart index 5ba9da7..b5ce40e 100644 --- a/lib/provider/unp4kc.dart +++ b/lib/provider/unp4kc.dart @@ -29,6 +29,7 @@ class Unp4kcState with _$Unp4kcState { required String curPath, String? endMessage, MapEntry? tempOpenFile, + @Default("") String errorMessage, }) = _Unp4kcState; } @@ -72,6 +73,12 @@ class Unp4kCModel extends _$Unp4kCModel { break; case RsProcessStreamDataType.error: dPrint("[unp4kc] stderr: ${event.data}"); + if (state.errorMessage.isEmpty) { + state = state.copyWith(errorMessage: event.data); + } else { + state = state.copyWith( + errorMessage: "${state.errorMessage}\n${event.data}"); + } break; case RsProcessStreamDataType.exit: dPrint("[unp4kc] exit: ${event.data}"); diff --git a/lib/provider/unp4kc.freezed.dart b/lib/provider/unp4kc.freezed.dart index e4d1aa4..0e32078 100644 --- a/lib/provider/unp4kc.freezed.dart +++ b/lib/provider/unp4kc.freezed.dart @@ -24,6 +24,7 @@ mixin _$Unp4kcState { String? get endMessage => throw _privateConstructorUsedError; MapEntry? get tempOpenFile => throw _privateConstructorUsedError; + String get errorMessage => throw _privateConstructorUsedError; @JsonKey(ignore: true) $Unp4kcStateCopyWith get copyWith => @@ -42,7 +43,8 @@ abstract class $Unp4kcStateCopyWith<$Res> { MemoryFileSystem? fs, String curPath, String? endMessage, - MapEntry? tempOpenFile}); + MapEntry? tempOpenFile, + String errorMessage}); } /// @nodoc @@ -64,6 +66,7 @@ class _$Unp4kcStateCopyWithImpl<$Res, $Val extends Unp4kcState> Object? curPath = null, Object? endMessage = freezed, Object? tempOpenFile = freezed, + Object? errorMessage = null, }) { return _then(_value.copyWith( startUp: null == startUp @@ -90,6 +93,10 @@ class _$Unp4kcStateCopyWithImpl<$Res, $Val extends Unp4kcState> ? _value.tempOpenFile : tempOpenFile // ignore: cast_nullable_to_non_nullable as MapEntry?, + errorMessage: null == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String, ) as $Val); } } @@ -108,7 +115,8 @@ abstract class _$$Unp4kcStateImplCopyWith<$Res> MemoryFileSystem? fs, String curPath, String? endMessage, - MapEntry? tempOpenFile}); + MapEntry? tempOpenFile, + String errorMessage}); } /// @nodoc @@ -128,6 +136,7 @@ class __$$Unp4kcStateImplCopyWithImpl<$Res> Object? curPath = null, Object? endMessage = freezed, Object? tempOpenFile = freezed, + Object? errorMessage = null, }) { return _then(_$Unp4kcStateImpl( startUp: null == startUp @@ -154,6 +163,10 @@ class __$$Unp4kcStateImplCopyWithImpl<$Res> ? _value.tempOpenFile : tempOpenFile // ignore: cast_nullable_to_non_nullable as MapEntry?, + errorMessage: null == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String, )); } } @@ -167,7 +180,8 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState { this.fs, required this.curPath, this.endMessage, - this.tempOpenFile}) + this.tempOpenFile, + this.errorMessage = ""}) : _files = files; @override @@ -190,10 +204,13 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState { final String? endMessage; @override final MapEntry? tempOpenFile; + @override + @JsonKey() + final String errorMessage; @override String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'Unp4kcState(startUp: $startUp, files: $files, fs: $fs, curPath: $curPath, endMessage: $endMessage, tempOpenFile: $tempOpenFile)'; + return 'Unp4kcState(startUp: $startUp, files: $files, fs: $fs, curPath: $curPath, endMessage: $endMessage, tempOpenFile: $tempOpenFile, errorMessage: $errorMessage)'; } @override @@ -206,7 +223,8 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState { ..add(DiagnosticsProperty('fs', fs)) ..add(DiagnosticsProperty('curPath', curPath)) ..add(DiagnosticsProperty('endMessage', endMessage)) - ..add(DiagnosticsProperty('tempOpenFile', tempOpenFile)); + ..add(DiagnosticsProperty('tempOpenFile', tempOpenFile)) + ..add(DiagnosticsProperty('errorMessage', errorMessage)); } @override @@ -221,7 +239,9 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState { (identical(other.endMessage, endMessage) || other.endMessage == endMessage) && (identical(other.tempOpenFile, tempOpenFile) || - other.tempOpenFile == tempOpenFile)); + other.tempOpenFile == tempOpenFile) && + (identical(other.errorMessage, errorMessage) || + other.errorMessage == errorMessage)); } @override @@ -232,7 +252,8 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState { fs, curPath, endMessage, - tempOpenFile); + tempOpenFile, + errorMessage); @JsonKey(ignore: true) @override @@ -248,7 +269,8 @@ abstract class _Unp4kcState implements Unp4kcState { final MemoryFileSystem? fs, required final String curPath, final String? endMessage, - final MapEntry? tempOpenFile}) = _$Unp4kcStateImpl; + final MapEntry? tempOpenFile, + final String errorMessage}) = _$Unp4kcStateImpl; @override bool get startUp; @@ -263,6 +285,8 @@ abstract class _Unp4kcState implements Unp4kcState { @override MapEntry? get tempOpenFile; @override + String get errorMessage; + @override @JsonKey(ignore: true) _$$Unp4kcStateImplCopyWith<_$Unp4kcStateImpl> get copyWith => throw _privateConstructorUsedError; diff --git a/lib/provider/unp4kc.g.dart b/lib/provider/unp4kc.g.dart index ce7b999..2830286 100644 --- a/lib/provider/unp4kc.g.dart +++ b/lib/provider/unp4kc.g.dart @@ -6,7 +6,7 @@ part of 'unp4kc.dart'; // RiverpodGenerator // ************************************************************************** -String _$unp4kCModelHash() => r'be71e2f9c2060df5ed8f1b64cce993058320bac4'; +String _$unp4kCModelHash() => r'24f5043f687a5f652a0741b8e6f4a3855fca0101'; /// See also [Unp4kCModel]. @ProviderFor(Unp4kCModel) diff --git a/lib/ui/home/localization/advanced_localization_ui_model.g.dart b/lib/ui/home/localization/advanced_localization_ui_model.g.dart index 613adb8..c4d0015 100644 --- a/lib/ui/home/localization/advanced_localization_ui_model.g.dart +++ b/lib/ui/home/localization/advanced_localization_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'advanced_localization_ui_model.dart'; // ************************************************************************** String _$advancedLocalizationUIModelHash() => - r'acf91fc467108c3669d8ddd6fed3c24434be4ae8'; + r'9fbbeca3af90f992717710633bcf2cd0e1cb06eb'; /// See also [AdvancedLocalizationUIModel]. @ProviderFor(AdvancedLocalizationUIModel) diff --git a/lib/ui/tools/tools_ui_model.g.dart b/lib/ui/tools/tools_ui_model.g.dart index 42cc88e..367ae60 100644 --- a/lib/ui/tools/tools_ui_model.g.dart +++ b/lib/ui/tools/tools_ui_model.g.dart @@ -6,7 +6,7 @@ part of 'tools_ui_model.dart'; // RiverpodGenerator // ************************************************************************** -String _$toolsUIModelHash() => r'4c27a3df07cb000ac58b74b3da48d926d0b01ea8'; +String _$toolsUIModelHash() => r'bef6b6cf35ae13d7100fa8db85b7f6c04f244b27'; /// See also [ToolsUIModel]. @ProviderFor(ToolsUIModel) diff --git a/lib/ui/tools/unp4kc/unp4kc_ui.dart b/lib/ui/tools/unp4kc/unp4kc_ui.dart index a2e743a..c5091cf 100644 --- a/lib/ui/tools/unp4kc/unp4kc_ui.dart +++ b/lib/ui/tools/unp4kc/unp4kc_ui.dart @@ -6,6 +6,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:re_editor/re_editor.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart'; +import 'package:starcitizen_doctor/data/app_unp4k_p4k_item_data.dart'; import 'package:starcitizen_doctor/provider/unp4kc.dart'; import 'package:starcitizen_doctor/widgets/widgets.dart'; import 'package:super_sliver_list/super_sliver_list.dart'; @@ -22,232 +23,236 @@ class UnP4kcUI extends HookConsumerWidget { return makeDefaultPage(context, title: S.current.tools_unp4k_title(model.getGamePath()), useBodyContainer: false, - content: state.files == null - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded(child: makeLoading(context)), - if (state.endMessage != null) - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - "${state.endMessage}", - style: const TextStyle(fontSize: 12), - ), - ), - ], - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, + content: makeBody(context, state, model, files, paths)); + } + + Widget makeBody(BuildContext context, Unp4kcState state, Unp4kCModel model, + List? files, List paths) { + if (state.errorMessage.isNotEmpty) { + return Padding( + padding: const EdgeInsets.all(24), + child: Center( + child: Text(state.errorMessage), + ), + ); + } + return state.files == null + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: makeLoading(context)), + if (state.endMessage != null) + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + "${state.endMessage}", + style: const TextStyle(fontSize: 12), + ), + ), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + color: FluentTheme.of(context).cardColor.withOpacity(.06)), + height: 36, + padding: const EdgeInsets.only(left: 12, right: 12), + child: SuperListView.builder( + itemCount: paths.length - 1, + scrollDirection: Axis.horizontal, + itemBuilder: (BuildContext context, int index) { + var path = paths[index]; + if (path.isEmpty) { + path = "\\"; + } + final fullPath = + "${paths.sublist(0, index + 1).join("\\")}\\"; + return Row( + children: [ + IconButton( + icon: Text(path), + onPressed: () { + model.changeDir(fullPath, fullPath: true); + }, + ), + const Icon( + FluentIcons.chevron_right, + size: 12, + ), + ], + ); + }, + ), + ), + Expanded( + child: Row( children: [ Container( + width: MediaQuery.of(context).size.width * .3, decoration: BoxDecoration( - color: - FluentTheme.of(context).cardColor.withOpacity(.06)), - height: 36, - padding: const EdgeInsets.only(left: 12, right: 12), - child: SuperListView.builder( - itemCount: paths.length - 1, - scrollDirection: Axis.horizontal, - itemBuilder: (BuildContext context, int index) { - var path = paths[index]; - if (path.isEmpty) { - path = "\\"; - } - final fullPath = - "${paths.sublist(0, index + 1).join("\\")}\\"; - return Row( - children: [ - IconButton( - icon: Text(path), - onPressed: () { - model.changeDir(fullPath, fullPath: true); - }, - ), - const Icon( - FluentIcons.chevron_right, - size: 12, - ), - ], - ); - }, + color: FluentTheme.of(context).cardColor.withOpacity(.01), ), - ), - Expanded( - child: Row( - children: [ - Container( - width: MediaQuery.of(context).size.width * .3, - decoration: BoxDecoration( - color: FluentTheme.of(context) - .cardColor - .withOpacity(.01), - ), - child: SuperListView.builder( - padding: const EdgeInsets.only( - top: 6, bottom: 6, left: 3, right: 12), - itemBuilder: (BuildContext context, int index) { - final item = files![index]; - final fileName = item.name - ?.replaceAll(state.curPath.trim(), "") ?? + child: SuperListView.builder( + padding: const EdgeInsets.only( + top: 6, bottom: 6, left: 3, right: 12), + itemBuilder: (BuildContext context, int index) { + final item = files![index]; + final fileName = + item.name?.replaceAll(state.curPath.trim(), "") ?? "?"; - return Container( - margin: const EdgeInsets.only(top: 4, bottom: 4), - decoration: BoxDecoration( - color: FluentTheme.of(context) - .cardColor - .withOpacity(.05), - ), - child: IconButton( - onPressed: () { - if (item.isDirectory ?? false) { - model.changeDir(fileName); - } else { - model.openFile(item.name ?? ""); - } - }, - icon: Padding( - padding: - const EdgeInsets.only(left: 4, right: 4), - child: Row( - children: [ - if (item.isDirectory ?? false) - const Icon( - FluentIcons.folder_fill, - color: - Color.fromRGBO(255, 224, 138, 1), - ) - else if (fileName.endsWith(".xml")) - const Icon( - FluentIcons.file_code, - ) - else - const Icon( - FluentIcons.open_file, - ), - const SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + return Container( + margin: const EdgeInsets.only(top: 4, bottom: 4), + decoration: BoxDecoration( + color: FluentTheme.of(context) + .cardColor + .withOpacity(.05), + ), + child: IconButton( + onPressed: () { + if (item.isDirectory ?? false) { + model.changeDir(fileName); + } else { + model.openFile(item.name ?? ""); + } + }, + icon: Padding( + padding: const EdgeInsets.only(left: 4, right: 4), + child: Row( + children: [ + if (item.isDirectory ?? false) + const Icon( + FluentIcons.folder_fill, + color: Color.fromRGBO(255, 224, 138, 1), + ) + else if (fileName.endsWith(".xml")) + const Icon( + FluentIcons.file_code, + ) + else + const Icon( + FluentIcons.open_file, + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( children: [ - Row( - children: [ - Expanded( - child: Text( - fileName, - style: const TextStyle( - fontSize: 13), - textAlign: TextAlign.start, - ), - ), - ], - ), - if (!(item.isDirectory ?? - true)) ...[ - const SizedBox(height: 1), - Row( - children: [ - Text( - FileSize.getSize(item.size), - style: TextStyle( - fontSize: 10, - color: Colors.white - .withOpacity(.6)), - ), - const SizedBox(width: 12), - Text( - "${item.dateTime}", - style: TextStyle( - fontSize: 10, - color: Colors.white - .withOpacity(.6)), - ), - ], + Expanded( + child: Text( + fileName, + style: const TextStyle( + fontSize: 13), + textAlign: TextAlign.start, ), - ], + ), ], ), - ), - const SizedBox(width: 3), - Icon( - FluentIcons.chevron_right, - size: 14, - color: Colors.white.withOpacity(.6), - ) - ], - ), - ), - ), - ); - }, - itemCount: files?.length ?? 0, - ), - ), - Expanded( - child: Container( - child: state.tempOpenFile == null - ? Center( - child: - Text(S.current.tools_unp4k_view_file), - ) - : state.tempOpenFile?.key == "loading" - ? makeLoading(context) - : Padding( - padding: const EdgeInsets.all(12), - child: Column( - children: [ - if (state.tempOpenFile?.key == "text") - Expanded( - child: _TextTempWidget( - state.tempOpenFile?.value ?? - "")) - else - Expanded( - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(S.current - .tools_unp4k_msg_unknown_file_type( - state.tempOpenFile - ?.value ?? - "")), - const SizedBox(height: 32), - FilledButton( - child: Padding( - padding: - const EdgeInsets - .all(4), - child: Text(S.current - .action_open_folder), - ), - onPressed: () { - SystemHelper.openDir( - state.tempOpenFile - ?.value ?? - ""); - }) - ], + if (!(item.isDirectory ?? true)) ...[ + const SizedBox(height: 1), + Row( + children: [ + Text( + FileSize.getSize(item.size), + style: TextStyle( + fontSize: 10, + color: Colors.white + .withOpacity(.6)), ), - ), - ) + const SizedBox(width: 12), + Text( + "${item.dateTime}", + style: TextStyle( + fontSize: 10, + color: Colors.white + .withOpacity(.6)), + ), + ], + ), + ], ], ), ), - )) - ], - )), - if (state.endMessage != null) - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - "${state.endMessage}", - style: const TextStyle(fontSize: 12), - ), + const SizedBox(width: 3), + Icon( + FluentIcons.chevron_right, + size: 14, + color: Colors.white.withOpacity(.6), + ) + ], + ), + ), + ), + ); + }, + itemCount: files?.length ?? 0, ), + ), + Expanded( + child: Container( + child: state.tempOpenFile == null + ? Center( + child: Text(S.current.tools_unp4k_view_file), + ) + : state.tempOpenFile?.key == "loading" + ? makeLoading(context) + : Padding( + padding: const EdgeInsets.all(12), + child: Column( + children: [ + if (state.tempOpenFile?.key == "text") + Expanded( + child: _TextTempWidget( + state.tempOpenFile?.value ?? "")) + else + Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(S.current + .tools_unp4k_msg_unknown_file_type( + state.tempOpenFile + ?.value ?? + "")), + const SizedBox(height: 32), + FilledButton( + child: Padding( + padding: + const EdgeInsets.all(4), + child: Text(S.current + .action_open_folder), + ), + onPressed: () { + SystemHelper.openDir(state + .tempOpenFile + ?.value ?? + ""); + }) + ], + ), + ), + ) + ], + ), + ), + )) ], - )); + )), + if (state.endMessage != null) + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + "${state.endMessage}", + style: const TextStyle(fontSize: 12), + ), + ), + ], + ); } }