mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-28 09:04:45 +08:00
feat: AdvancedLocalization Init
This commit is contained in:
@ -28,6 +28,7 @@ import 'data/app_version_data.dart';
|
||||
import 'generated/no_l10n_strings.dart';
|
||||
import 'ui/home/downloader/home_downloader_ui.dart';
|
||||
import 'ui/home/game_doctor/game_doctor_ui.dart';
|
||||
import 'ui/home/localization/advanced_localization_ui.dart';
|
||||
import 'ui/index_ui.dart';
|
||||
import 'ui/settings/upgrade_dialog.dart';
|
||||
import 'ui/tools/unp4kc/unp4kc_ui.dart';
|
||||
@ -77,6 +78,10 @@ GoRouter router(RouterRef ref) {
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomePerformanceUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'advanced_localization',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const AdvancedLocalizationUI()))
|
||||
],
|
||||
),
|
||||
GoRoute(path: '/tools', builder: (_, __) => const SizedBox(), routes: [
|
||||
|
@ -6,7 +6,7 @@ part of 'app.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$routerHash() => r'7ce5ef6a7a4f6f604a457dd050e04ee594c4760a';
|
||||
String _$routerHash() => r'4fb9802d06347972b530f17ea7d66724a6ded997';
|
||||
|
||||
/// See also [router].
|
||||
@ProviderFor(router)
|
||||
@ -20,7 +20,7 @@ final routerProvider = AutoDisposeProvider<GoRouter>.internal(
|
||||
);
|
||||
|
||||
typedef RouterRef = AutoDisposeProviderRef<GoRouter>;
|
||||
String _$appGlobalModelHash() => r'11a172d5fb19ad6566f1025354c8f8d91fe85a84';
|
||||
String _$appGlobalModelHash() => r'9dccbb898714695ef8b640a5b5dfb361783a0f45';
|
||||
|
||||
/// See also [AppGlobalModel].
|
||||
@ProviderFor(AppGlobalModel)
|
||||
|
@ -11,6 +11,7 @@ File? _logFile;
|
||||
void dPrint(src) async {
|
||||
if (kDebugMode) {
|
||||
print(src);
|
||||
return;
|
||||
}
|
||||
await _logLock.synchronized(() async {
|
||||
try {
|
||||
|
59
lib/data/app_advanced_localization_data.dart
Normal file
59
lib/data/app_advanced_localization_data.dart
Normal file
@ -0,0 +1,59 @@
|
||||
class AppAdvancedLocalizationData {
|
||||
AppAdvancedLocalizationData({
|
||||
this.classKeys,
|
||||
});
|
||||
|
||||
AppAdvancedLocalizationData.fromJson(dynamic json) {
|
||||
if (json['class_keys'] != null) {
|
||||
classKeys = [];
|
||||
json['class_keys'].forEach((v) {
|
||||
classKeys?.add(AppAdvancedLocalizationClassKeysData.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
List<AppAdvancedLocalizationClassKeysData>? classKeys;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
if (classKeys != null) {
|
||||
map['class_keys'] = classKeys?.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class AppAdvancedLocalizationClassKeysData {
|
||||
AppAdvancedLocalizationClassKeysData({
|
||||
this.id,
|
||||
this.className,
|
||||
this.keys,
|
||||
});
|
||||
|
||||
AppAdvancedLocalizationClassKeysData.fromJson(dynamic json) {
|
||||
id = json['id'];
|
||||
className = json['class_name'];
|
||||
keys = json['keys'] != null ? json['keys'].cast<String>() : [];
|
||||
}
|
||||
|
||||
String? id;
|
||||
String? className;
|
||||
List<String>? keys;
|
||||
Map<String, String> valuesMap = {};
|
||||
AppAdvancedLocalizationClassKeysDataMode mode =
|
||||
AppAdvancedLocalizationClassKeysDataMode.localization;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['id'] = id;
|
||||
map['class_name'] = className;
|
||||
map['keys'] = keys;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
enum AppAdvancedLocalizationClassKeysDataMode {
|
||||
unLocalization,
|
||||
localization,
|
||||
mixed,
|
||||
}
|
@ -6,7 +6,7 @@ part of 'unp4kc.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$unp4kCModelHash() => r'69117c5857797683e2d080da9238bfecc5948898';
|
||||
String _$unp4kCModelHash() => r'3b2325c72dcb47bf9207625b0a1d2a611f911b6f';
|
||||
|
||||
/// See also [Unp4kCModel].
|
||||
@ProviderFor(Unp4kCModel)
|
||||
|
102
lib/ui/home/localization/advanced_localization_ui.dart
Normal file
102
lib/ui/home/localization/advanced_localization_ui.dart
Normal file
@ -0,0 +1,102 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/localization/advanced_localization_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
|
||||
class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
const AdvancedLocalizationUI({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final state = ref.watch(advancedLocalizationUIModelProvider);
|
||||
final homeUIState = ref.watch(homeUIModelProvider);
|
||||
return makeDefaultPage(
|
||||
title: "高级汉化 -> ${homeUIState.scInstalledPath}",
|
||||
context,
|
||||
content: state.workingText.isNotEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const ProgressRing(),
|
||||
const SizedBox(height: 12),
|
||||
Text(state.workingText),
|
||||
],
|
||||
),
|
||||
)
|
||||
: _makeBody(context, homeUIState, state, ref));
|
||||
}
|
||||
|
||||
Widget _makeBody(BuildContext context, HomeUIModelState homeUIState,
|
||||
AdvancedLocalizationUIState state, WidgetRef ref) {
|
||||
return AlignedGridView.count(
|
||||
crossAxisCount: 3,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
padding: const EdgeInsets.all(12),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = state.classMap!.values.elementAt(index);
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(.05),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${item.className}",
|
||||
style: const TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
Text(
|
||||
"${item.valuesMap.length}",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withOpacity(.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 6, bottom: 12),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 1,
|
||||
color: Colors.white.withOpacity(.1),
|
||||
),
|
||||
SizedBox(
|
||||
height: 160,
|
||||
child: SuperListView.builder(
|
||||
itemCount: item.valuesMap.length,
|
||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final itemKey = item.valuesMap.keys.elementAt(index);
|
||||
return Text(
|
||||
"${item.valuesMap[itemKey]}",
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: state.classMap?.length ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
170
lib/ui/home/localization/advanced_localization_ui_model.dart
Normal file
170
lib/ui/home/localization/advanced_localization_ui_model.dart
Normal file
@ -0,0 +1,170 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/app_advanced_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/provider/unp4kc.dart';
|
||||
|
||||
import '../home_ui_model.dart';
|
||||
import 'localization_ui_model.dart';
|
||||
|
||||
part 'advanced_localization_ui_model.g.dart';
|
||||
|
||||
part 'advanced_localization_ui_model.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class AdvancedLocalizationUIState with _$AdvancedLocalizationUIState {
|
||||
factory AdvancedLocalizationUIState({
|
||||
@Default("") String workingText,
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
String? p4kGlobalIni,
|
||||
String? serverGlobalIni,
|
||||
}) = _AdvancedLocalizationUIState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
@override
|
||||
AdvancedLocalizationUIState build() {
|
||||
final localizationUIState = ref.read(localizationUIModelProvider);
|
||||
final localizationUIModel = ref.read(localizationUIModelProvider.notifier);
|
||||
state = AdvancedLocalizationUIState(classMap: {});
|
||||
_init(localizationUIState, localizationUIModel);
|
||||
return state;
|
||||
}
|
||||
|
||||
Future<void> _init(LocalizationUIState localizationUIState,
|
||||
LocalizationUIModel localizationUIModel) async {
|
||||
final (p4kGlobalIni, serverGlobalIni) =
|
||||
await _readIni(localizationUIState, localizationUIModel);
|
||||
final ald = await _readClassJson();
|
||||
if (ald.classKeys == null) return;
|
||||
state = state.copyWith(workingText: "正在分类 ...");
|
||||
final m = await compute(_doClassIni, (ald, p4kGlobalIni, serverGlobalIni));
|
||||
state = state.copyWith(
|
||||
workingText: "",
|
||||
p4kGlobalIni: p4kGlobalIni,
|
||||
serverGlobalIni: serverGlobalIni,
|
||||
classMap: m);
|
||||
}
|
||||
|
||||
static Map<String, AppAdvancedLocalizationClassKeysData> _doClassIni(
|
||||
(
|
||||
AppAdvancedLocalizationData ald,
|
||||
String p4kGlobalIni,
|
||||
String serverGlobalIni
|
||||
) v,
|
||||
) {
|
||||
final (
|
||||
AppAdvancedLocalizationData ald,
|
||||
String p4kGlobalIni,
|
||||
String serverGlobalIni,
|
||||
) = v;
|
||||
final unLocalization = AppAdvancedLocalizationClassKeysData(
|
||||
id: "un_localization",
|
||||
className: "未汉化",
|
||||
keys: [],
|
||||
);
|
||||
final unClass = AppAdvancedLocalizationClassKeysData(
|
||||
id: "un_class",
|
||||
className: "未分类",
|
||||
keys: [],
|
||||
);
|
||||
final classMap = <String, AppAdvancedLocalizationClassKeysData>{
|
||||
for (final keys in ald.classKeys!) keys.id ?? "": keys,
|
||||
};
|
||||
|
||||
final p4kIniMap = readIniAsMap(p4kGlobalIni);
|
||||
final serverIniMap = readIniAsMap(serverGlobalIni);
|
||||
|
||||
var regexList = classMap.values
|
||||
.expand((c) => c.keys!.map((k) => MapEntry(c, RegExp(k))))
|
||||
.toList();
|
||||
|
||||
iniKeysLoop:
|
||||
for (var p4kIniKey in p4kIniMap.keys) {
|
||||
final serverValue = serverIniMap[p4kIniKey];
|
||||
if (serverValue == null) {
|
||||
unLocalization.valuesMap[p4kIniKey] = p4kIniMap[p4kIniKey] ?? "";
|
||||
continue iniKeysLoop;
|
||||
} else {
|
||||
for (var item in regexList) {
|
||||
if (item.value.hasMatch(p4kIniKey)) {
|
||||
item.key.valuesMap[p4kIniKey] = serverValue;
|
||||
serverIniMap.remove(p4kIniKey);
|
||||
continue iniKeysLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unLocalization.valuesMap.isNotEmpty) {
|
||||
classMap[unLocalization.id!] = unLocalization;
|
||||
}
|
||||
if (serverIniMap.isNotEmpty) {
|
||||
for (var element in serverIniMap.keys) {
|
||||
unClass.valuesMap[element] = serverIniMap[element] ?? "";
|
||||
}
|
||||
classMap[unClass.id!] = unClass;
|
||||
}
|
||||
return classMap;
|
||||
}
|
||||
|
||||
static Map<String, String> readIniAsMap(String iniString) {
|
||||
final iniMap = <String, String>{};
|
||||
for (final line in iniString.split("\n")) {
|
||||
final index = line.indexOf("=");
|
||||
if (index == -1) continue;
|
||||
final key = line.substring(0, index).trim();
|
||||
final value = line.substring(index + 1).trim();
|
||||
iniMap[key] = value;
|
||||
}
|
||||
return iniMap;
|
||||
}
|
||||
|
||||
Future<AppAdvancedLocalizationData> _readClassJson() async {
|
||||
final s = await rootBundle.loadString("assets/advanced_localization.json");
|
||||
return AppAdvancedLocalizationData.fromJson(json.decode(s));
|
||||
}
|
||||
|
||||
Future<(String, String)> _readIni(LocalizationUIState localizationUIState,
|
||||
LocalizationUIModel localizationUIModel) async {
|
||||
final homeUIState = ref.read(homeUIModelProvider);
|
||||
final gameDir = homeUIState.scInstalledPath;
|
||||
if (gameDir == null) return ("", "");
|
||||
state = state.copyWith(workingText: "读取 p4k 文件 ...");
|
||||
final p4kGlobalIni = await readEnglishInI(gameDir);
|
||||
dPrint("read p4kGlobalIni => ${p4kGlobalIni.length}");
|
||||
state = state.copyWith(workingText: "获取汉化文本 ...");
|
||||
final apiLocalizationData =
|
||||
localizationUIState.apiLocalizationData?.values.firstOrNull;
|
||||
if (apiLocalizationData == null) return ("", "");
|
||||
final file = File(
|
||||
"${localizationUIModel.getDownloadDir().absolute.path}\\${apiLocalizationData.versionName}.sclang");
|
||||
if (!await file.exists()) {
|
||||
await localizationUIModel.downloadLocalizationFile(
|
||||
file, apiLocalizationData);
|
||||
}
|
||||
final serverGlobalIni =
|
||||
(await compute(LocalizationUIModel.readArchive, file.absolute.path))
|
||||
.toString();
|
||||
dPrint("read serverGlobalIni => ${serverGlobalIni.length}");
|
||||
return (p4kGlobalIni, serverGlobalIni);
|
||||
}
|
||||
|
||||
Future<String> readEnglishInI(String gameDir) async {
|
||||
final data = await Unp4kCModel.unp4kTools(
|
||||
appGlobalState.applicationBinaryModuleDir!, [
|
||||
"extract_memory",
|
||||
"$gameDir\\Data.p4k",
|
||||
"Data\\Localization\\english\\global.ini"
|
||||
]);
|
||||
final iniData = String.fromCharCodes(data);
|
||||
return iniData;
|
||||
}
|
||||
}
|
@ -0,0 +1,236 @@
|
||||
// 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 'advanced_localization_ui_model.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');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AdvancedLocalizationUIState {
|
||||
String get workingText => throw _privateConstructorUsedError;
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? get classMap =>
|
||||
throw _privateConstructorUsedError;
|
||||
String? get p4kGlobalIni => throw _privateConstructorUsedError;
|
||||
String? get serverGlobalIni => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$AdvancedLocalizationUIStateCopyWith<AdvancedLocalizationUIState>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $AdvancedLocalizationUIStateCopyWith<$Res> {
|
||||
factory $AdvancedLocalizationUIStateCopyWith(
|
||||
AdvancedLocalizationUIState value,
|
||||
$Res Function(AdvancedLocalizationUIState) then) =
|
||||
_$AdvancedLocalizationUIStateCopyWithImpl<$Res,
|
||||
AdvancedLocalizationUIState>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{String workingText,
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
String? p4kGlobalIni,
|
||||
String? serverGlobalIni});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$AdvancedLocalizationUIStateCopyWithImpl<$Res,
|
||||
$Val extends AdvancedLocalizationUIState>
|
||||
implements $AdvancedLocalizationUIStateCopyWith<$Res> {
|
||||
_$AdvancedLocalizationUIStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? workingText = null,
|
||||
Object? classMap = freezed,
|
||||
Object? p4kGlobalIni = freezed,
|
||||
Object? serverGlobalIni = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
workingText: null == workingText
|
||||
? _value.workingText
|
||||
: workingText // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
classMap: freezed == classMap
|
||||
? _value.classMap
|
||||
: classMap // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, AppAdvancedLocalizationClassKeysData>?,
|
||||
p4kGlobalIni: freezed == p4kGlobalIni
|
||||
? _value.p4kGlobalIni
|
||||
: p4kGlobalIni // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
serverGlobalIni: freezed == serverGlobalIni
|
||||
? _value.serverGlobalIni
|
||||
: serverGlobalIni // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$AdvancedLocalizationUIStateImplCopyWith<$Res>
|
||||
implements $AdvancedLocalizationUIStateCopyWith<$Res> {
|
||||
factory _$$AdvancedLocalizationUIStateImplCopyWith(
|
||||
_$AdvancedLocalizationUIStateImpl value,
|
||||
$Res Function(_$AdvancedLocalizationUIStateImpl) then) =
|
||||
__$$AdvancedLocalizationUIStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{String workingText,
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
String? p4kGlobalIni,
|
||||
String? serverGlobalIni});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$AdvancedLocalizationUIStateImplCopyWithImpl<$Res>
|
||||
extends _$AdvancedLocalizationUIStateCopyWithImpl<$Res,
|
||||
_$AdvancedLocalizationUIStateImpl>
|
||||
implements _$$AdvancedLocalizationUIStateImplCopyWith<$Res> {
|
||||
__$$AdvancedLocalizationUIStateImplCopyWithImpl(
|
||||
_$AdvancedLocalizationUIStateImpl _value,
|
||||
$Res Function(_$AdvancedLocalizationUIStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? workingText = null,
|
||||
Object? classMap = freezed,
|
||||
Object? p4kGlobalIni = freezed,
|
||||
Object? serverGlobalIni = freezed,
|
||||
}) {
|
||||
return _then(_$AdvancedLocalizationUIStateImpl(
|
||||
workingText: null == workingText
|
||||
? _value.workingText
|
||||
: workingText // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
classMap: freezed == classMap
|
||||
? _value._classMap
|
||||
: classMap // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, AppAdvancedLocalizationClassKeysData>?,
|
||||
p4kGlobalIni: freezed == p4kGlobalIni
|
||||
? _value.p4kGlobalIni
|
||||
: p4kGlobalIni // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
serverGlobalIni: freezed == serverGlobalIni
|
||||
? _value.serverGlobalIni
|
||||
: serverGlobalIni // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$AdvancedLocalizationUIStateImpl
|
||||
with DiagnosticableTreeMixin
|
||||
implements _AdvancedLocalizationUIState {
|
||||
_$AdvancedLocalizationUIStateImpl(
|
||||
{this.workingText = "",
|
||||
final Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
this.p4kGlobalIni,
|
||||
this.serverGlobalIni})
|
||||
: _classMap = classMap;
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final String workingText;
|
||||
final Map<String, AppAdvancedLocalizationClassKeysData>? _classMap;
|
||||
@override
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? get classMap {
|
||||
final value = _classMap;
|
||||
if (value == null) return null;
|
||||
if (_classMap is EqualUnmodifiableMapView) return _classMap;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
final String? p4kGlobalIni;
|
||||
@override
|
||||
final String? serverGlobalIni;
|
||||
|
||||
@override
|
||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||
return 'AdvancedLocalizationUIState(workingText: $workingText, classMap: $classMap, p4kGlobalIni: $p4kGlobalIni, serverGlobalIni: $serverGlobalIni)';
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'AdvancedLocalizationUIState'))
|
||||
..add(DiagnosticsProperty('workingText', workingText))
|
||||
..add(DiagnosticsProperty('classMap', classMap))
|
||||
..add(DiagnosticsProperty('p4kGlobalIni', p4kGlobalIni))
|
||||
..add(DiagnosticsProperty('serverGlobalIni', serverGlobalIni));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$AdvancedLocalizationUIStateImpl &&
|
||||
(identical(other.workingText, workingText) ||
|
||||
other.workingText == workingText) &&
|
||||
const DeepCollectionEquality().equals(other._classMap, _classMap) &&
|
||||
(identical(other.p4kGlobalIni, p4kGlobalIni) ||
|
||||
other.p4kGlobalIni == p4kGlobalIni) &&
|
||||
(identical(other.serverGlobalIni, serverGlobalIni) ||
|
||||
other.serverGlobalIni == serverGlobalIni));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
workingText,
|
||||
const DeepCollectionEquality().hash(_classMap),
|
||||
p4kGlobalIni,
|
||||
serverGlobalIni);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$AdvancedLocalizationUIStateImplCopyWith<_$AdvancedLocalizationUIStateImpl>
|
||||
get copyWith => __$$AdvancedLocalizationUIStateImplCopyWithImpl<
|
||||
_$AdvancedLocalizationUIStateImpl>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _AdvancedLocalizationUIState
|
||||
implements AdvancedLocalizationUIState {
|
||||
factory _AdvancedLocalizationUIState(
|
||||
{final String workingText,
|
||||
final Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
final String? p4kGlobalIni,
|
||||
final String? serverGlobalIni}) = _$AdvancedLocalizationUIStateImpl;
|
||||
|
||||
@override
|
||||
String get workingText;
|
||||
@override
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? get classMap;
|
||||
@override
|
||||
String? get p4kGlobalIni;
|
||||
@override
|
||||
String? get serverGlobalIni;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$AdvancedLocalizationUIStateImplCopyWith<_$AdvancedLocalizationUIStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'advanced_localization_ui_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$advancedLocalizationUIModelHash() =>
|
||||
r'2bb7dfc3cd8d45ecf5056083627136ad5cb7a285';
|
||||
|
||||
/// See also [AdvancedLocalizationUIModel].
|
||||
@ProviderFor(AdvancedLocalizationUIModel)
|
||||
final advancedLocalizationUIModelProvider = AutoDisposeNotifierProvider<
|
||||
AdvancedLocalizationUIModel, AdvancedLocalizationUIState>.internal(
|
||||
AdvancedLocalizationUIModel.new,
|
||||
name: r'advancedLocalizationUIModelProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$advancedLocalizationUIModelHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$AdvancedLocalizationUIModel
|
||||
= AutoDisposeNotifier<AdvancedLocalizationUIState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
@ -2,6 +2,7 @@ import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:flutter_tilt/flutter_tilt.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/ui/tools/tools_ui_model.dart';
|
||||
@ -145,7 +146,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
],
|
||||
context,
|
||||
gridViewMode: true),
|
||||
makeToolsListContainer(context, model),
|
||||
makeToolsListContainer(context, model, state),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -445,8 +446,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
Widget makeToolsListContainer(
|
||||
BuildContext context, LocalizationUIModel model) {
|
||||
Widget makeToolsListContainer(BuildContext context, LocalizationUIModel model,
|
||||
LocalizationUIState state) {
|
||||
final toolsMenu = {
|
||||
"launcher_mod": (
|
||||
const Icon(FluentIcons.c_plus_plus, size: 24),
|
||||
@ -462,21 +463,29 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
),
|
||||
};
|
||||
|
||||
final enableTap = state.workingVersion.isEmpty;
|
||||
|
||||
return makeListContainer(
|
||||
"汉化工具",
|
||||
[
|
||||
for (final item in toolsMenu.entries)
|
||||
Tilt(
|
||||
disable: !enableTap,
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
switch (item.key) {
|
||||
case "launcher_mod":
|
||||
ToolsUIModel.rsiEnhance(context);
|
||||
break;
|
||||
}
|
||||
},
|
||||
onTap: enableTap
|
||||
? () async {
|
||||
switch (item.key) {
|
||||
case "launcher_mod":
|
||||
ToolsUIModel.rsiEnhance(context);
|
||||
break;
|
||||
case "advanced":
|
||||
context.push("/index/advanced_localization");
|
||||
break;
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
|
@ -17,7 +17,6 @@ import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/generated/no_l10n_strings.dart';
|
||||
import 'package:starcitizen_doctor/provider/unp4kc.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@ -48,6 +47,8 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
Directory get _downloadDir =>
|
||||
Directory("${appGlobalState.applicationSupportDir}\\Localizations");
|
||||
|
||||
Directory getDownloadDir() => _downloadDir;
|
||||
|
||||
Directory get _scDataDir =>
|
||||
Directory("${ref.read(homeUIModelProvider).scInstalledPath}\\data");
|
||||
|
||||
@ -79,17 +80,6 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
await _loadData();
|
||||
}
|
||||
|
||||
readEnglishInI() async {
|
||||
final data = await Unp4kCModel.unp4kTools(
|
||||
appGlobalState.applicationBinaryModuleDir!, [
|
||||
"extract_memory",
|
||||
"$_scInstallPath\\Data.p4k",
|
||||
"Data\\Localization\\english\\global.ini"
|
||||
]);
|
||||
final iniData = String.fromCharCodes(data);
|
||||
dPrint("read english ini => ${iniData.length}");
|
||||
}
|
||||
|
||||
final Map<String, Map<String, ScLocalizationData>>
|
||||
_allVersionLocalizationData = {};
|
||||
|
||||
@ -268,27 +258,20 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
BuildContext context, ScLocalizationData value) {
|
||||
return () async {
|
||||
AnalyticsApi.touch("install_localization");
|
||||
final downloadUrl =
|
||||
"${URLConf.gitlabLocalizationUrl}/archive/${value.versionName}.tar.gz";
|
||||
|
||||
final savePath =
|
||||
File("${_downloadDir.absolute.path}\\${value.versionName}.sclang");
|
||||
try {
|
||||
state = state.copyWith(workingVersion: value.versionName!);
|
||||
if (!await savePath.exists()) {
|
||||
// download
|
||||
dPrint("downloading file to $savePath");
|
||||
final r = await RSHttp.get(downloadUrl);
|
||||
if (r.statusCode == 200 && r.data != null) {
|
||||
await savePath.writeAsBytes(r.data!);
|
||||
} else {
|
||||
throw "statusCode Error : ${r.statusCode}";
|
||||
}
|
||||
await downloadLocalizationFile(savePath, value);
|
||||
} else {
|
||||
dPrint("use cache $savePath");
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
// check file
|
||||
final globalIni = await compute(_readArchive, savePath.absolute.path);
|
||||
final globalIni = await compute(readArchive, savePath.absolute.path);
|
||||
if (globalIni.isEmpty) {
|
||||
throw S.current.localization_info_corrupted_file;
|
||||
}
|
||||
@ -303,7 +286,20 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
};
|
||||
}
|
||||
|
||||
static StringBuffer _readArchive(String savePath) {
|
||||
Future<void> downloadLocalizationFile(
|
||||
File savePath, ScLocalizationData value) async {
|
||||
dPrint("downloading file to $savePath");
|
||||
final downloadUrl =
|
||||
"${URLConf.gitlabLocalizationUrl}/archive/${value.versionName}.tar.gz";
|
||||
final r = await RSHttp.get(downloadUrl);
|
||||
if (r.statusCode == 200 && r.data != null) {
|
||||
await savePath.writeAsBytes(r.data!);
|
||||
} else {
|
||||
throw "statusCode Error : ${r.statusCode}";
|
||||
}
|
||||
}
|
||||
|
||||
static StringBuffer readArchive(String savePath) {
|
||||
final inputStream = InputFileStream(savePath);
|
||||
final archive =
|
||||
TarDecoder().decodeBytes(GZipDecoder().decodeBuffer(inputStream));
|
||||
|
@ -7,7 +7,7 @@ part of 'localization_ui_model.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$localizationUIModelHash() =>
|
||||
r'a4e33b337db587ad3e766450d9bd8ac4aa7b4c49';
|
||||
r'ed47da78fdc6adac904a17909f111640ac84563e';
|
||||
|
||||
/// See also [LocalizationUIModel].
|
||||
@ProviderFor(LocalizationUIModel)
|
||||
|
@ -6,7 +6,7 @@ part of 'tools_ui_model.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$toolsUIModelHash() => r'6cf170210fa7a7c2c63bde9d0920c64a20a81263';
|
||||
String _$toolsUIModelHash() => r'4c27a3df07cb000ac58b74b3da48d926d0b01ea8';
|
||||
|
||||
/// See also [ToolsUIModel].
|
||||
@ProviderFor(ToolsUIModel)
|
||||
|
Reference in New Issue
Block a user