mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-02-12 18:20:24 +00:00
feat: unp4k data forge support
This commit is contained in:
323
lib/provider/dcb_viewer.dart
Normal file
323
lib/provider/dcb_viewer.dart
Normal file
@@ -0,0 +1,323 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/unp4k_api.dart' as unp4k_api;
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/data/dcb_data.dart';
|
||||
|
||||
part 'dcb_viewer.freezed.dart';
|
||||
|
||||
part 'dcb_viewer.g.dart';
|
||||
|
||||
/// DCB 查看器视图模式
|
||||
enum DcbViewMode {
|
||||
/// 普通列表浏览模式
|
||||
browse,
|
||||
|
||||
/// 全文搜索结果模式
|
||||
searchResults,
|
||||
}
|
||||
|
||||
/// DCB 查看器输入源类型
|
||||
enum DcbSourceType {
|
||||
/// 未初始化
|
||||
none,
|
||||
|
||||
/// 从文件路径加载
|
||||
filePath,
|
||||
|
||||
/// 从 P4K 内存数据加载
|
||||
p4kMemory,
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DcbViewerState with _$DcbViewerState {
|
||||
const factory DcbViewerState({
|
||||
/// 是否正在加载
|
||||
@Default(true) bool isLoading,
|
||||
|
||||
/// 加载/错误消息
|
||||
@Default('') String message,
|
||||
|
||||
/// 错误消息
|
||||
String? errorMessage,
|
||||
|
||||
/// DCB 文件路径(用于显示标题)
|
||||
@Default('') String dcbFilePath,
|
||||
|
||||
/// 数据源类型
|
||||
@Default(DcbSourceType.none) DcbSourceType sourceType,
|
||||
|
||||
/// 所有记录列表
|
||||
@Default([]) List<DcbRecordData> allRecords,
|
||||
|
||||
/// 当前过滤后的记录列表(用于列表搜索)
|
||||
@Default([]) List<DcbRecordData> filteredRecords,
|
||||
|
||||
/// 当前选中的记录路径
|
||||
String? selectedRecordPath,
|
||||
|
||||
/// 当前显示的 XML 内容
|
||||
@Default('') String currentXml,
|
||||
|
||||
/// 列表搜索查询
|
||||
@Default('') String listSearchQuery,
|
||||
|
||||
/// 全文搜索查询
|
||||
@Default('') String fullTextSearchQuery,
|
||||
|
||||
/// 当前视图模式
|
||||
@Default(DcbViewMode.browse) DcbViewMode viewMode,
|
||||
|
||||
/// 全文搜索结果
|
||||
@Default([]) List<DcbSearchResultData> searchResults,
|
||||
|
||||
/// 是否正在搜索
|
||||
@Default(false) bool isSearching,
|
||||
|
||||
/// 是否正在加载 XML
|
||||
@Default(false) bool isLoadingXml,
|
||||
|
||||
/// 是否正在导出
|
||||
@Default(false) bool isExporting,
|
||||
|
||||
/// 是否需要选择文件
|
||||
@Default(false) bool needSelectFile,
|
||||
}) = _DcbViewerState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class DcbViewerModel extends _$DcbViewerModel {
|
||||
@override
|
||||
DcbViewerState build() {
|
||||
ref.onDispose(() async {
|
||||
try {
|
||||
await unp4k_api.dcbClose();
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] close error: $e');
|
||||
}
|
||||
});
|
||||
return const DcbViewerState(isLoading: false, needSelectFile: true);
|
||||
}
|
||||
|
||||
/// 从磁盘文件路径加载 DCB
|
||||
Future<void> initFromFilePath(String filePath) async {
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
message: S.current.dcb_viewer_loading,
|
||||
dcbFilePath: filePath,
|
||||
sourceType: DcbSourceType.filePath,
|
||||
needSelectFile: false,
|
||||
errorMessage: null,
|
||||
);
|
||||
|
||||
try {
|
||||
final file = File(filePath);
|
||||
if (!await file.exists()) {
|
||||
state = state.copyWith(isLoading: false, errorMessage: 'File not found: $filePath');
|
||||
return;
|
||||
}
|
||||
|
||||
final data = await file.readAsBytes();
|
||||
await _loadDcbData(data, filePath);
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] init from file error: $e');
|
||||
state = state.copyWith(isLoading: false, errorMessage: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/// 从 P4K 文件中提取并加载 DCB (Data/Game2.dcb)
|
||||
Future<void> initFromP4kFile(String p4kPath) async {
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
message: S.current.dcb_viewer_loading,
|
||||
dcbFilePath: 'Data/Game2.dcb',
|
||||
sourceType: DcbSourceType.p4kMemory,
|
||||
needSelectFile: false,
|
||||
errorMessage: null,
|
||||
);
|
||||
|
||||
try {
|
||||
// 打开 P4K 文件
|
||||
state = state.copyWith(message: S.current.tools_unp4k_msg_reading);
|
||||
await unp4k_api.p4KOpen(p4KPath: p4kPath);
|
||||
|
||||
// 提取 DCB 文件到内存
|
||||
state = state.copyWith(message: S.current.dcb_viewer_loading);
|
||||
final data = await unp4k_api.p4KExtractToMemory(filePath: '\\Data\\Game2.dcb');
|
||||
|
||||
// 关闭 P4K(已完成提取)
|
||||
await unp4k_api.p4KClose();
|
||||
|
||||
// 将数据写入临时文件并加载
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final tempPath = '${tempDir.path}/SCToolbox_dcb/Game2.dcb';
|
||||
final tempFile = File(tempPath);
|
||||
await tempFile.parent.create(recursive: true);
|
||||
await tempFile.writeAsBytes(data);
|
||||
|
||||
state = state.copyWith(dcbFilePath: tempPath);
|
||||
await _loadDcbData(Uint8List.fromList(data), tempPath);
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] init from P4K error: $e');
|
||||
// 确保关闭 P4K
|
||||
try {
|
||||
await unp4k_api.p4KClose();
|
||||
} catch (_) {}
|
||||
state = state.copyWith(isLoading: false, errorMessage: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/// 从内存数据初始化 DCB 查看器
|
||||
Future<void> initFromData(Uint8List data, String filePath) async {
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
message: S.current.dcb_viewer_loading,
|
||||
dcbFilePath: filePath,
|
||||
sourceType: DcbSourceType.p4kMemory,
|
||||
needSelectFile: false,
|
||||
errorMessage: null,
|
||||
);
|
||||
|
||||
await _loadDcbData(data, filePath);
|
||||
}
|
||||
|
||||
/// 内部方法:加载 DCB 数据
|
||||
Future<void> _loadDcbData(Uint8List data, String filePath) async {
|
||||
try {
|
||||
// 检查是否为 DCB 格式
|
||||
final isDataforge = await unp4k_api.dcbIsDataforge(data: data);
|
||||
if (!isDataforge) {
|
||||
state = state.copyWith(isLoading: false, errorMessage: S.current.dcb_viewer_error_not_dcb);
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析 DCB 文件
|
||||
state = state.copyWith(message: S.current.dcb_viewer_parsing);
|
||||
await unp4k_api.dcbOpen(data: data);
|
||||
|
||||
// 获取记录列表
|
||||
state = state.copyWith(message: S.current.dcb_viewer_loading_records);
|
||||
final apiRecords = await unp4k_api.dcbGetRecordList();
|
||||
|
||||
// 转换为本地数据类型
|
||||
final records = apiRecords.map((r) => DcbRecordData(path: r.path, index: r.index.toInt())).toList();
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
message: S.current.dcb_viewer_loaded_records(records.length),
|
||||
allRecords: records,
|
||||
filteredRecords: records,
|
||||
);
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] load data error: $e');
|
||||
state = state.copyWith(isLoading: false, errorMessage: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/// 选择一条记录并加载其 XML
|
||||
Future<void> selectRecord(DcbRecordData record) async {
|
||||
if (state.selectedRecordPath == record.path) return;
|
||||
|
||||
state = state.copyWith(selectedRecordPath: record.path, isLoadingXml: true, currentXml: '');
|
||||
|
||||
try {
|
||||
final xml = await unp4k_api.dcbRecordToXml(path: record.path);
|
||||
state = state.copyWith(isLoadingXml: false, currentXml: xml);
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] load xml error: $e');
|
||||
state = state.copyWith(isLoadingXml: false, currentXml: '<!-- Error loading XML: $e -->');
|
||||
}
|
||||
}
|
||||
|
||||
/// 列表搜索(过滤路径)
|
||||
void searchList(String query) {
|
||||
state = state.copyWith(listSearchQuery: query);
|
||||
|
||||
if (query.isEmpty) {
|
||||
state = state.copyWith(filteredRecords: state.allRecords);
|
||||
return;
|
||||
}
|
||||
|
||||
final queryLower = query.toLowerCase();
|
||||
final filtered = state.allRecords.where((record) {
|
||||
return record.path.toLowerCase().contains(queryLower);
|
||||
}).toList();
|
||||
|
||||
state = state.copyWith(filteredRecords: filtered);
|
||||
}
|
||||
|
||||
/// 全文搜索
|
||||
Future<void> searchFullText(String query) async {
|
||||
if (query.isEmpty) {
|
||||
// 退出搜索模式
|
||||
state = state.copyWith(viewMode: DcbViewMode.browse, fullTextSearchQuery: '', searchResults: []);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(isSearching: true, fullTextSearchQuery: query, viewMode: DcbViewMode.searchResults);
|
||||
|
||||
try {
|
||||
final apiResults = await unp4k_api.dcbSearchAll(query: query, maxResults: BigInt.from(500));
|
||||
|
||||
// 转换为本地数据类型
|
||||
final results = apiResults.map((r) {
|
||||
return DcbSearchResultData(
|
||||
path: r.path,
|
||||
index: r.index.toInt(),
|
||||
matches: r.matches
|
||||
.map((m) => DcbSearchMatchData(lineNumber: m.lineNumber.toInt(), lineContent: m.lineContent))
|
||||
.toList(),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
state = state.copyWith(
|
||||
isSearching: false,
|
||||
searchResults: results,
|
||||
message: S.current.dcb_viewer_search_results(results.length),
|
||||
);
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] search error: $e');
|
||||
state = state.copyWith(isSearching: false, message: 'Search error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// 从搜索结果选择记录
|
||||
Future<void> selectFromSearchResult(DcbSearchResultData result) async {
|
||||
final record = DcbRecordData(path: result.path, index: result.index);
|
||||
await selectRecord(record);
|
||||
}
|
||||
|
||||
/// 退出搜索模式
|
||||
void exitSearchMode() {
|
||||
state = state.copyWith(
|
||||
viewMode: DcbViewMode.browse,
|
||||
fullTextSearchQuery: '',
|
||||
searchResults: [],
|
||||
message: S.current.dcb_viewer_loaded_records(state.allRecords.length),
|
||||
);
|
||||
}
|
||||
|
||||
/// 导出 DCB(合并或分离模式)
|
||||
Future<String?> exportToDisk(String outputPath, bool merge) async {
|
||||
state = state.copyWith(isExporting: true);
|
||||
|
||||
try {
|
||||
await unp4k_api.dcbExportToDisk(outputPath: outputPath, merge: merge, dcbPath: state.dcbFilePath);
|
||||
state = state.copyWith(isExporting: false);
|
||||
return null; // 成功
|
||||
} catch (e) {
|
||||
dPrint('[DCB Viewer] export error: $e');
|
||||
state = state.copyWith(isExporting: false);
|
||||
return e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// 重置状态,回到选择文件界面
|
||||
void reset() {
|
||||
state = const DcbViewerState(isLoading: false, needSelectFile: true);
|
||||
}
|
||||
}
|
||||
374
lib/provider/dcb_viewer.freezed.dart
Normal file
374
lib/provider/dcb_viewer.freezed.dart
Normal file
@@ -0,0 +1,374 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// 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 'dcb_viewer.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DcbViewerState {
|
||||
|
||||
/// 是否正在加载
|
||||
bool get isLoading;/// 加载/错误消息
|
||||
String get message;/// 错误消息
|
||||
String? get errorMessage;/// DCB 文件路径(用于显示标题)
|
||||
String get dcbFilePath;/// 数据源类型
|
||||
DcbSourceType get sourceType;/// 所有记录列表
|
||||
List<DcbRecordData> get allRecords;/// 当前过滤后的记录列表(用于列表搜索)
|
||||
List<DcbRecordData> get filteredRecords;/// 当前选中的记录路径
|
||||
String? get selectedRecordPath;/// 当前显示的 XML 内容
|
||||
String get currentXml;/// 列表搜索查询
|
||||
String get listSearchQuery;/// 全文搜索查询
|
||||
String get fullTextSearchQuery;/// 当前视图模式
|
||||
DcbViewMode get viewMode;/// 全文搜索结果
|
||||
List<DcbSearchResultData> get searchResults;/// 是否正在搜索
|
||||
bool get isSearching;/// 是否正在加载 XML
|
||||
bool get isLoadingXml;/// 是否正在导出
|
||||
bool get isExporting;/// 是否需要选择文件
|
||||
bool get needSelectFile;
|
||||
/// Create a copy of DcbViewerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DcbViewerStateCopyWith<DcbViewerState> get copyWith => _$DcbViewerStateCopyWithImpl<DcbViewerState>(this as DcbViewerState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DcbViewerState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.message, message) || other.message == message)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.dcbFilePath, dcbFilePath) || other.dcbFilePath == dcbFilePath)&&(identical(other.sourceType, sourceType) || other.sourceType == sourceType)&&const DeepCollectionEquality().equals(other.allRecords, allRecords)&&const DeepCollectionEquality().equals(other.filteredRecords, filteredRecords)&&(identical(other.selectedRecordPath, selectedRecordPath) || other.selectedRecordPath == selectedRecordPath)&&(identical(other.currentXml, currentXml) || other.currentXml == currentXml)&&(identical(other.listSearchQuery, listSearchQuery) || other.listSearchQuery == listSearchQuery)&&(identical(other.fullTextSearchQuery, fullTextSearchQuery) || other.fullTextSearchQuery == fullTextSearchQuery)&&(identical(other.viewMode, viewMode) || other.viewMode == viewMode)&&const DeepCollectionEquality().equals(other.searchResults, searchResults)&&(identical(other.isSearching, isSearching) || other.isSearching == isSearching)&&(identical(other.isLoadingXml, isLoadingXml) || other.isLoadingXml == isLoadingXml)&&(identical(other.isExporting, isExporting) || other.isExporting == isExporting)&&(identical(other.needSelectFile, needSelectFile) || other.needSelectFile == needSelectFile));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,message,errorMessage,dcbFilePath,sourceType,const DeepCollectionEquality().hash(allRecords),const DeepCollectionEquality().hash(filteredRecords),selectedRecordPath,currentXml,listSearchQuery,fullTextSearchQuery,viewMode,const DeepCollectionEquality().hash(searchResults),isSearching,isLoadingXml,isExporting,needSelectFile);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DcbViewerState(isLoading: $isLoading, message: $message, errorMessage: $errorMessage, dcbFilePath: $dcbFilePath, sourceType: $sourceType, allRecords: $allRecords, filteredRecords: $filteredRecords, selectedRecordPath: $selectedRecordPath, currentXml: $currentXml, listSearchQuery: $listSearchQuery, fullTextSearchQuery: $fullTextSearchQuery, viewMode: $viewMode, searchResults: $searchResults, isSearching: $isSearching, isLoadingXml: $isLoadingXml, isExporting: $isExporting, needSelectFile: $needSelectFile)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DcbViewerStateCopyWith<$Res> {
|
||||
factory $DcbViewerStateCopyWith(DcbViewerState value, $Res Function(DcbViewerState) _then) = _$DcbViewerStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isLoading, String message, String? errorMessage, String dcbFilePath, DcbSourceType sourceType, List<DcbRecordData> allRecords, List<DcbRecordData> filteredRecords, String? selectedRecordPath, String currentXml, String listSearchQuery, String fullTextSearchQuery, DcbViewMode viewMode, List<DcbSearchResultData> searchResults, bool isSearching, bool isLoadingXml, bool isExporting, bool needSelectFile
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DcbViewerStateCopyWithImpl<$Res>
|
||||
implements $DcbViewerStateCopyWith<$Res> {
|
||||
_$DcbViewerStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DcbViewerState _self;
|
||||
final $Res Function(DcbViewerState) _then;
|
||||
|
||||
/// Create a copy of DcbViewerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? message = null,Object? errorMessage = freezed,Object? dcbFilePath = null,Object? sourceType = null,Object? allRecords = null,Object? filteredRecords = null,Object? selectedRecordPath = freezed,Object? currentXml = null,Object? listSearchQuery = null,Object? fullTextSearchQuery = null,Object? viewMode = null,Object? searchResults = null,Object? isSearching = null,Object? isLoadingXml = null,Object? isExporting = null,Object? needSelectFile = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,dcbFilePath: null == dcbFilePath ? _self.dcbFilePath : dcbFilePath // ignore: cast_nullable_to_non_nullable
|
||||
as String,sourceType: null == sourceType ? _self.sourceType : sourceType // ignore: cast_nullable_to_non_nullable
|
||||
as DcbSourceType,allRecords: null == allRecords ? _self.allRecords : allRecords // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbRecordData>,filteredRecords: null == filteredRecords ? _self.filteredRecords : filteredRecords // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbRecordData>,selectedRecordPath: freezed == selectedRecordPath ? _self.selectedRecordPath : selectedRecordPath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,currentXml: null == currentXml ? _self.currentXml : currentXml // ignore: cast_nullable_to_non_nullable
|
||||
as String,listSearchQuery: null == listSearchQuery ? _self.listSearchQuery : listSearchQuery // ignore: cast_nullable_to_non_nullable
|
||||
as String,fullTextSearchQuery: null == fullTextSearchQuery ? _self.fullTextSearchQuery : fullTextSearchQuery // ignore: cast_nullable_to_non_nullable
|
||||
as String,viewMode: null == viewMode ? _self.viewMode : viewMode // ignore: cast_nullable_to_non_nullable
|
||||
as DcbViewMode,searchResults: null == searchResults ? _self.searchResults : searchResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbSearchResultData>,isSearching: null == isSearching ? _self.isSearching : isSearching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoadingXml: null == isLoadingXml ? _self.isLoadingXml : isLoadingXml // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isExporting: null == isExporting ? _self.isExporting : isExporting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,needSelectFile: null == needSelectFile ? _self.needSelectFile : needSelectFile // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DcbViewerState].
|
||||
extension DcbViewerStatePatterns on DcbViewerState {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DcbViewerState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DcbViewerState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DcbViewerState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isLoading, String message, String? errorMessage, String dcbFilePath, DcbSourceType sourceType, List<DcbRecordData> allRecords, List<DcbRecordData> filteredRecords, String? selectedRecordPath, String currentXml, String listSearchQuery, String fullTextSearchQuery, DcbViewMode viewMode, List<DcbSearchResultData> searchResults, bool isSearching, bool isLoadingXml, bool isExporting, bool needSelectFile)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState() when $default != null:
|
||||
return $default(_that.isLoading,_that.message,_that.errorMessage,_that.dcbFilePath,_that.sourceType,_that.allRecords,_that.filteredRecords,_that.selectedRecordPath,_that.currentXml,_that.listSearchQuery,_that.fullTextSearchQuery,_that.viewMode,_that.searchResults,_that.isSearching,_that.isLoadingXml,_that.isExporting,_that.needSelectFile);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isLoading, String message, String? errorMessage, String dcbFilePath, DcbSourceType sourceType, List<DcbRecordData> allRecords, List<DcbRecordData> filteredRecords, String? selectedRecordPath, String currentXml, String listSearchQuery, String fullTextSearchQuery, DcbViewMode viewMode, List<DcbSearchResultData> searchResults, bool isSearching, bool isLoadingXml, bool isExporting, bool needSelectFile) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState():
|
||||
return $default(_that.isLoading,_that.message,_that.errorMessage,_that.dcbFilePath,_that.sourceType,_that.allRecords,_that.filteredRecords,_that.selectedRecordPath,_that.currentXml,_that.listSearchQuery,_that.fullTextSearchQuery,_that.viewMode,_that.searchResults,_that.isSearching,_that.isLoadingXml,_that.isExporting,_that.needSelectFile);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isLoading, String message, String? errorMessage, String dcbFilePath, DcbSourceType sourceType, List<DcbRecordData> allRecords, List<DcbRecordData> filteredRecords, String? selectedRecordPath, String currentXml, String listSearchQuery, String fullTextSearchQuery, DcbViewMode viewMode, List<DcbSearchResultData> searchResults, bool isSearching, bool isLoadingXml, bool isExporting, bool needSelectFile)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DcbViewerState() when $default != null:
|
||||
return $default(_that.isLoading,_that.message,_that.errorMessage,_that.dcbFilePath,_that.sourceType,_that.allRecords,_that.filteredRecords,_that.selectedRecordPath,_that.currentXml,_that.listSearchQuery,_that.fullTextSearchQuery,_that.viewMode,_that.searchResults,_that.isSearching,_that.isLoadingXml,_that.isExporting,_that.needSelectFile);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DcbViewerState implements DcbViewerState {
|
||||
const _DcbViewerState({this.isLoading = true, this.message = '', this.errorMessage, this.dcbFilePath = '', this.sourceType = DcbSourceType.none, final List<DcbRecordData> allRecords = const [], final List<DcbRecordData> filteredRecords = const [], this.selectedRecordPath, this.currentXml = '', this.listSearchQuery = '', this.fullTextSearchQuery = '', this.viewMode = DcbViewMode.browse, final List<DcbSearchResultData> searchResults = const [], this.isSearching = false, this.isLoadingXml = false, this.isExporting = false, this.needSelectFile = false}): _allRecords = allRecords,_filteredRecords = filteredRecords,_searchResults = searchResults;
|
||||
|
||||
|
||||
/// 是否正在加载
|
||||
@override@JsonKey() final bool isLoading;
|
||||
/// 加载/错误消息
|
||||
@override@JsonKey() final String message;
|
||||
/// 错误消息
|
||||
@override final String? errorMessage;
|
||||
/// DCB 文件路径(用于显示标题)
|
||||
@override@JsonKey() final String dcbFilePath;
|
||||
/// 数据源类型
|
||||
@override@JsonKey() final DcbSourceType sourceType;
|
||||
/// 所有记录列表
|
||||
final List<DcbRecordData> _allRecords;
|
||||
/// 所有记录列表
|
||||
@override@JsonKey() List<DcbRecordData> get allRecords {
|
||||
if (_allRecords is EqualUnmodifiableListView) return _allRecords;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_allRecords);
|
||||
}
|
||||
|
||||
/// 当前过滤后的记录列表(用于列表搜索)
|
||||
final List<DcbRecordData> _filteredRecords;
|
||||
/// 当前过滤后的记录列表(用于列表搜索)
|
||||
@override@JsonKey() List<DcbRecordData> get filteredRecords {
|
||||
if (_filteredRecords is EqualUnmodifiableListView) return _filteredRecords;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_filteredRecords);
|
||||
}
|
||||
|
||||
/// 当前选中的记录路径
|
||||
@override final String? selectedRecordPath;
|
||||
/// 当前显示的 XML 内容
|
||||
@override@JsonKey() final String currentXml;
|
||||
/// 列表搜索查询
|
||||
@override@JsonKey() final String listSearchQuery;
|
||||
/// 全文搜索查询
|
||||
@override@JsonKey() final String fullTextSearchQuery;
|
||||
/// 当前视图模式
|
||||
@override@JsonKey() final DcbViewMode viewMode;
|
||||
/// 全文搜索结果
|
||||
final List<DcbSearchResultData> _searchResults;
|
||||
/// 全文搜索结果
|
||||
@override@JsonKey() List<DcbSearchResultData> get searchResults {
|
||||
if (_searchResults is EqualUnmodifiableListView) return _searchResults;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_searchResults);
|
||||
}
|
||||
|
||||
/// 是否正在搜索
|
||||
@override@JsonKey() final bool isSearching;
|
||||
/// 是否正在加载 XML
|
||||
@override@JsonKey() final bool isLoadingXml;
|
||||
/// 是否正在导出
|
||||
@override@JsonKey() final bool isExporting;
|
||||
/// 是否需要选择文件
|
||||
@override@JsonKey() final bool needSelectFile;
|
||||
|
||||
/// Create a copy of DcbViewerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DcbViewerStateCopyWith<_DcbViewerState> get copyWith => __$DcbViewerStateCopyWithImpl<_DcbViewerState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DcbViewerState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.message, message) || other.message == message)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.dcbFilePath, dcbFilePath) || other.dcbFilePath == dcbFilePath)&&(identical(other.sourceType, sourceType) || other.sourceType == sourceType)&&const DeepCollectionEquality().equals(other._allRecords, _allRecords)&&const DeepCollectionEquality().equals(other._filteredRecords, _filteredRecords)&&(identical(other.selectedRecordPath, selectedRecordPath) || other.selectedRecordPath == selectedRecordPath)&&(identical(other.currentXml, currentXml) || other.currentXml == currentXml)&&(identical(other.listSearchQuery, listSearchQuery) || other.listSearchQuery == listSearchQuery)&&(identical(other.fullTextSearchQuery, fullTextSearchQuery) || other.fullTextSearchQuery == fullTextSearchQuery)&&(identical(other.viewMode, viewMode) || other.viewMode == viewMode)&&const DeepCollectionEquality().equals(other._searchResults, _searchResults)&&(identical(other.isSearching, isSearching) || other.isSearching == isSearching)&&(identical(other.isLoadingXml, isLoadingXml) || other.isLoadingXml == isLoadingXml)&&(identical(other.isExporting, isExporting) || other.isExporting == isExporting)&&(identical(other.needSelectFile, needSelectFile) || other.needSelectFile == needSelectFile));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,message,errorMessage,dcbFilePath,sourceType,const DeepCollectionEquality().hash(_allRecords),const DeepCollectionEquality().hash(_filteredRecords),selectedRecordPath,currentXml,listSearchQuery,fullTextSearchQuery,viewMode,const DeepCollectionEquality().hash(_searchResults),isSearching,isLoadingXml,isExporting,needSelectFile);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DcbViewerState(isLoading: $isLoading, message: $message, errorMessage: $errorMessage, dcbFilePath: $dcbFilePath, sourceType: $sourceType, allRecords: $allRecords, filteredRecords: $filteredRecords, selectedRecordPath: $selectedRecordPath, currentXml: $currentXml, listSearchQuery: $listSearchQuery, fullTextSearchQuery: $fullTextSearchQuery, viewMode: $viewMode, searchResults: $searchResults, isSearching: $isSearching, isLoadingXml: $isLoadingXml, isExporting: $isExporting, needSelectFile: $needSelectFile)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DcbViewerStateCopyWith<$Res> implements $DcbViewerStateCopyWith<$Res> {
|
||||
factory _$DcbViewerStateCopyWith(_DcbViewerState value, $Res Function(_DcbViewerState) _then) = __$DcbViewerStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isLoading, String message, String? errorMessage, String dcbFilePath, DcbSourceType sourceType, List<DcbRecordData> allRecords, List<DcbRecordData> filteredRecords, String? selectedRecordPath, String currentXml, String listSearchQuery, String fullTextSearchQuery, DcbViewMode viewMode, List<DcbSearchResultData> searchResults, bool isSearching, bool isLoadingXml, bool isExporting, bool needSelectFile
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DcbViewerStateCopyWithImpl<$Res>
|
||||
implements _$DcbViewerStateCopyWith<$Res> {
|
||||
__$DcbViewerStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DcbViewerState _self;
|
||||
final $Res Function(_DcbViewerState) _then;
|
||||
|
||||
/// Create a copy of DcbViewerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? message = null,Object? errorMessage = freezed,Object? dcbFilePath = null,Object? sourceType = null,Object? allRecords = null,Object? filteredRecords = null,Object? selectedRecordPath = freezed,Object? currentXml = null,Object? listSearchQuery = null,Object? fullTextSearchQuery = null,Object? viewMode = null,Object? searchResults = null,Object? isSearching = null,Object? isLoadingXml = null,Object? isExporting = null,Object? needSelectFile = null,}) {
|
||||
return _then(_DcbViewerState(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,dcbFilePath: null == dcbFilePath ? _self.dcbFilePath : dcbFilePath // ignore: cast_nullable_to_non_nullable
|
||||
as String,sourceType: null == sourceType ? _self.sourceType : sourceType // ignore: cast_nullable_to_non_nullable
|
||||
as DcbSourceType,allRecords: null == allRecords ? _self._allRecords : allRecords // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbRecordData>,filteredRecords: null == filteredRecords ? _self._filteredRecords : filteredRecords // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbRecordData>,selectedRecordPath: freezed == selectedRecordPath ? _self.selectedRecordPath : selectedRecordPath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,currentXml: null == currentXml ? _self.currentXml : currentXml // ignore: cast_nullable_to_non_nullable
|
||||
as String,listSearchQuery: null == listSearchQuery ? _self.listSearchQuery : listSearchQuery // ignore: cast_nullable_to_non_nullable
|
||||
as String,fullTextSearchQuery: null == fullTextSearchQuery ? _self.fullTextSearchQuery : fullTextSearchQuery // ignore: cast_nullable_to_non_nullable
|
||||
as String,viewMode: null == viewMode ? _self.viewMode : viewMode // ignore: cast_nullable_to_non_nullable
|
||||
as DcbViewMode,searchResults: null == searchResults ? _self._searchResults : searchResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<DcbSearchResultData>,isSearching: null == isSearching ? _self.isSearching : isSearching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoadingXml: null == isLoadingXml ? _self.isLoadingXml : isLoadingXml // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isExporting: null == isExporting ? _self.isExporting : isExporting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,needSelectFile: null == needSelectFile ? _self.needSelectFile : needSelectFile // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
63
lib/provider/dcb_viewer.g.dart
Normal file
63
lib/provider/dcb_viewer.g.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'dcb_viewer.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(DcbViewerModel)
|
||||
const dcbViewerModelProvider = DcbViewerModelProvider._();
|
||||
|
||||
final class DcbViewerModelProvider
|
||||
extends $NotifierProvider<DcbViewerModel, DcbViewerState> {
|
||||
const DcbViewerModelProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'dcbViewerModelProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$dcbViewerModelHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
DcbViewerModel create() => DcbViewerModel();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(DcbViewerState value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<DcbViewerState>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$dcbViewerModelHash() => r'94c3542282f64917efadbe14a0ee4967220bec77';
|
||||
|
||||
abstract class _$DcbViewerModel extends $Notifier<DcbViewerState> {
|
||||
DcbViewerState build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<DcbViewerState, DcbViewerState>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<DcbViewerState, DcbViewerState>,
|
||||
DcbViewerState,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
// ignore_for_file: avoid_build_context_in_providers
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||
@@ -378,17 +381,18 @@ class Unp4kCModel extends _$Unp4kCModel {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> openFile(String filePath) async {
|
||||
Future<void> openFile(String filePath, {BuildContext? context}) async {
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final tempPath = "${tempDir.absolute.path}\\SCToolbox_unp4kc\\${SCLoggerHelper.getGameChannelID(getGamePath())}\\";
|
||||
state = state.copyWith(
|
||||
tempOpenFile: const MapEntry("loading", ""),
|
||||
endMessage: S.current.tools_unp4k_msg_open_file(filePath),
|
||||
);
|
||||
await extractFile(filePath, tempPath, mode: "extract_open");
|
||||
// ignore: use_build_context_synchronously
|
||||
await extractFile(filePath, tempPath, mode: "extract_open", context: context);
|
||||
}
|
||||
|
||||
Future<void> extractFile(String filePath, String outputPath, {String mode = "extract"}) async {
|
||||
Future<void> extractFile(String filePath, String outputPath, {String mode = "extract", BuildContext? context}) async {
|
||||
try {
|
||||
// remove first \\
|
||||
if (filePath.startsWith("\\")) {
|
||||
@@ -402,6 +406,16 @@ class Unp4kCModel extends _$Unp4kCModel {
|
||||
await unp4k_api.p4KExtractToDisk(filePath: filePath, outputPath: outputPath);
|
||||
|
||||
if (mode == "extract_open") {
|
||||
if (context != null && filePath.toLowerCase().endsWith(".dcb")) {
|
||||
// 关闭 loading 状态
|
||||
state = state.copyWith(tempOpenFile: null, endMessage: S.current.tools_unp4k_msg_open_file(filePath));
|
||||
// 跳转至 DCBViewer
|
||||
if (context.mounted) {
|
||||
context.push("/tools/dcb_viewer", extra: {"path": fullOutputPath});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
const textExt = [".txt", ".xml", ".json", ".lua", ".cfg", ".ini", ".mtl"];
|
||||
const imgExt = [".png"];
|
||||
String openType = "unknown";
|
||||
|
||||
@@ -12,7 +12,7 @@ part of 'unp4kc.dart';
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$Unp4kcState implements DiagnosticableTreeMixin {
|
||||
mixin _$Unp4kcState {
|
||||
|
||||
bool get startUp; Map<String, AppUnp4kP4kItemData>? get files; MemoryFileSystem? get fs; String get curPath; String? get endMessage; MapEntry<String, String>? get tempOpenFile; String get errorMessage; String get searchQuery; bool get isSearching;/// 搜索结果的虚拟文件系统(支持分级展示)
|
||||
MemoryFileSystem? get searchFs;/// 搜索匹配的文件路径集合
|
||||
@@ -26,12 +26,6 @@ mixin _$Unp4kcState implements DiagnosticableTreeMixin {
|
||||
$Unp4kcStateCopyWith<Unp4kcState> get copyWith => _$Unp4kcStateCopyWithImpl<Unp4kcState>(this as Unp4kcState, _$identity);
|
||||
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'Unp4kcState'))
|
||||
..add(DiagnosticsProperty('startUp', startUp))..add(DiagnosticsProperty('files', files))..add(DiagnosticsProperty('fs', fs))..add(DiagnosticsProperty('curPath', curPath))..add(DiagnosticsProperty('endMessage', endMessage))..add(DiagnosticsProperty('tempOpenFile', tempOpenFile))..add(DiagnosticsProperty('errorMessage', errorMessage))..add(DiagnosticsProperty('searchQuery', searchQuery))..add(DiagnosticsProperty('isSearching', isSearching))..add(DiagnosticsProperty('searchFs', searchFs))..add(DiagnosticsProperty('searchMatchedFiles', searchMatchedFiles))..add(DiagnosticsProperty('sortType', sortType))..add(DiagnosticsProperty('isMultiSelectMode', isMultiSelectMode))..add(DiagnosticsProperty('selectedItems', selectedItems));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
@@ -43,7 +37,7 @@ bool operator ==(Object other) {
|
||||
int get hashCode => Object.hash(runtimeType,startUp,const DeepCollectionEquality().hash(files),fs,curPath,endMessage,tempOpenFile,errorMessage,searchQuery,isSearching,searchFs,const DeepCollectionEquality().hash(searchMatchedFiles),sortType,isMultiSelectMode,const DeepCollectionEquality().hash(selectedItems));
|
||||
|
||||
@override
|
||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||
String toString() {
|
||||
return 'Unp4kcState(startUp: $startUp, files: $files, fs: $fs, curPath: $curPath, endMessage: $endMessage, tempOpenFile: $tempOpenFile, errorMessage: $errorMessage, searchQuery: $searchQuery, isSearching: $isSearching, searchFs: $searchFs, searchMatchedFiles: $searchMatchedFiles, sortType: $sortType, isMultiSelectMode: $isMultiSelectMode, selectedItems: $selectedItems)';
|
||||
}
|
||||
|
||||
@@ -228,7 +222,7 @@ return $default(_that.startUp,_that.files,_that.fs,_that.curPath,_that.endMessag
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Unp4kcState with DiagnosticableTreeMixin implements Unp4kcState {
|
||||
class _Unp4kcState implements Unp4kcState {
|
||||
const _Unp4kcState({required this.startUp, final Map<String, AppUnp4kP4kItemData>? files, this.fs, required this.curPath, this.endMessage, this.tempOpenFile, this.errorMessage = "", this.searchQuery = "", this.isSearching = false, this.searchFs, final Set<String>? searchMatchedFiles, this.sortType = Unp4kSortType.defaultSort, this.isMultiSelectMode = false, final Set<String> selectedItems = const {}}): _files = files,_searchMatchedFiles = searchMatchedFiles,_selectedItems = selectedItems;
|
||||
|
||||
|
||||
@@ -282,12 +276,6 @@ class _Unp4kcState with DiagnosticableTreeMixin implements Unp4kcState {
|
||||
_$Unp4kcStateCopyWith<_Unp4kcState> get copyWith => __$Unp4kcStateCopyWithImpl<_Unp4kcState>(this, _$identity);
|
||||
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'Unp4kcState'))
|
||||
..add(DiagnosticsProperty('startUp', startUp))..add(DiagnosticsProperty('files', files))..add(DiagnosticsProperty('fs', fs))..add(DiagnosticsProperty('curPath', curPath))..add(DiagnosticsProperty('endMessage', endMessage))..add(DiagnosticsProperty('tempOpenFile', tempOpenFile))..add(DiagnosticsProperty('errorMessage', errorMessage))..add(DiagnosticsProperty('searchQuery', searchQuery))..add(DiagnosticsProperty('isSearching', isSearching))..add(DiagnosticsProperty('searchFs', searchFs))..add(DiagnosticsProperty('searchMatchedFiles', searchMatchedFiles))..add(DiagnosticsProperty('sortType', sortType))..add(DiagnosticsProperty('isMultiSelectMode', isMultiSelectMode))..add(DiagnosticsProperty('selectedItems', selectedItems));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
@@ -299,7 +287,7 @@ bool operator ==(Object other) {
|
||||
int get hashCode => Object.hash(runtimeType,startUp,const DeepCollectionEquality().hash(_files),fs,curPath,endMessage,tempOpenFile,errorMessage,searchQuery,isSearching,searchFs,const DeepCollectionEquality().hash(_searchMatchedFiles),sortType,isMultiSelectMode,const DeepCollectionEquality().hash(_selectedItems));
|
||||
|
||||
@override
|
||||
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||
String toString() {
|
||||
return 'Unp4kcState(startUp: $startUp, files: $files, fs: $fs, curPath: $curPath, endMessage: $endMessage, tempOpenFile: $tempOpenFile, errorMessage: $errorMessage, searchQuery: $searchQuery, isSearching: $isSearching, searchFs: $searchFs, searchMatchedFiles: $searchMatchedFiles, sortType: $sortType, isMultiSelectMode: $isMultiSelectMode, selectedItems: $selectedItems)';
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ final class Unp4kCModelProvider
|
||||
}
|
||||
}
|
||||
|
||||
String _$unp4kCModelHash() => r'72ee23ad9864cdfb73a588ea1a0509b083e7dee8';
|
||||
String _$unp4kCModelHash() => r'68c24d50113e9e734ae8d277f65999bbef05dc05';
|
||||
|
||||
abstract class _$Unp4kCModel extends $Notifier<Unp4kcState> {
|
||||
Unp4kcState build();
|
||||
|
||||
Reference in New Issue
Block a user