feat: 高级汉化

This commit is contained in:
2024-05-05 14:59:07 +08:00
parent 0bb0f7deb4
commit f392463a84
12 changed files with 649 additions and 254 deletions

View File

@ -1,6 +1,12 @@
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:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:re_editor/re_editor.dart';
import 'package:re_highlight/languages/ini.dart';
import 'package:re_highlight/styles/vs2015.dart';
import 'package:starcitizen_doctor/data/app_advanced_localization_data.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';
@ -12,6 +18,7 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(advancedLocalizationUIModelProvider);
final model = ref.read(advancedLocalizationUIModelProvider.notifier);
final homeUIState = ref.watch(homeUIModelProvider);
return makeDefaultPage(
title: "高级汉化 -> ${homeUIState.scInstalledPath}",
@ -27,20 +34,51 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
],
),
)
: _makeBody(context, homeUIState, state, ref));
: Column(
children: [
Row(
children: [
const SizedBox(width: 12),
Expanded(
child: Text(
'已加载汉化版本:${state.apiLocalizationData?.versionName}')),
Text('汉化文本行数:${state.serverGlobalIniLines}'
' P4K文本行数${state.p4kGlobalIniLines}'),
const SizedBox(width: 32),
Button(
child: const Padding(
padding: EdgeInsets.only(
left: 12, right: 12, top: 4, bottom: 4),
child: Text("安装汉化"),
),
onPressed: () async {
await model.doInstall().unwrap(context: context);
}),
const SizedBox(width: 12),
],
),
Expanded(
child:
_makeBody(context, homeUIState, state, ref, model)),
],
));
}
Widget _makeBody(BuildContext context, HomeUIModelState homeUIState,
AdvancedLocalizationUIState state, WidgetRef ref) {
Widget _makeBody(
BuildContext context,
HomeUIModelState homeUIState,
AdvancedLocalizationUIState state,
WidgetRef ref,
AdvancedLocalizationUIModel model) {
return AlignedGridView.count(
crossAxisCount: 3,
crossAxisCount: 4,
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),
padding: const EdgeInsets.only(top: 6, bottom: 12),
decoration: BoxDecoration(
color: Colors.white.withOpacity(.05),
borderRadius: BorderRadius.circular(4),
@ -48,24 +86,35 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
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),
IconButton(
onPressed:
item.isWorking ? null : () => _showContent(context, item),
icon: 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),
textAlign: TextAlign.start,
)),
Text(
"${item.valuesMap.length}",
style: TextStyle(
fontSize: 14,
color: Colors.white.withOpacity(.6),
),
),
),
],
const SizedBox(width: 6),
Icon(
FluentIcons.chevron_right,
color: Colors.white.withOpacity(.6),
size: 16,
),
],
),
),
),
Container(
@ -74,24 +123,59 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
height: 1,
color: Colors.white.withOpacity(.1),
),
SizedBox(
height: 160,
child: SuperListView.builder(
itemCount: item.valuesMap.length,
if (item.isWorking)
Column(
children: [
makeLoading(context),
const SizedBox(height: 6),
const Text("正在重新生成文本..."),
],
)
else ...[
Padding(
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,
child: Row(
children: [
const Expanded(child: Text("模式")),
ComboBox(
value: item.mode,
items: [
for (final type
in AppAdvancedLocalizationClassKeysDataMode
.values)
ComboBoxItem(
value: type,
child: Text(state.typeNames[type] ?? "-"),
),
],
onChanged: item.lockMod
? null
: (v) => model.onChangeMod(item,
v as AppAdvancedLocalizationClassKeysDataMode),
),
);
},
],
),
),
),
const SizedBox(height: 6),
SizedBox(
height: 180,
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,
),
);
},
),
),
],
],
),
);
@ -99,4 +183,73 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
itemCount: state.classMap?.length ?? 0,
);
}
_showContent(
BuildContext context, AppAdvancedLocalizationClassKeysData item) {
showDialog(
context: context,
builder: (BuildContext context) {
return HookConsumer(
builder: (BuildContext context, WidgetRef ref, Widget? child) {
final textData = useState("");
loadData() async {
final v = StringBuffer("");
for (var element in item.valuesMap.entries) {
v.write("${element.key}=${element.value}\n");
await Future.delayed(Duration.zero);
}
textData.value = v.toString();
}
useEffect(() {
loadData();
return null;
}, const []);
return ContentDialog(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * .8,
),
title: Row(
children: [
IconButton(
icon: const Icon(
FluentIcons.back,
size: 22,
),
onPressed: () => context.pop()),
const SizedBox(
width: 24,
),
Text("预览:${item.className}"),
],
),
content: textData.value.isEmpty
? makeLoading(context)
: Container(
decoration: BoxDecoration(
color: FluentTheme.of(context).cardColor,
borderRadius: BorderRadius.circular(7),
),
child: CodeEditor(
readOnly: true,
controller:
CodeLineEditingController.fromText(textData.value),
style: CodeEditorStyle(
codeTheme: CodeHighlightTheme(
languages: {
'ini': CodeHighlightThemeMode(mode: langIni)
},
theme: vs2015Theme,
),
),
),
),
);
},
);
},
);
}
}

View File

@ -9,6 +9,7 @@ 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/data/sc_localization_data.dart';
import 'package:starcitizen_doctor/provider/unp4kc.dart';
import '../home_ui_model.dart';
@ -25,9 +26,21 @@ class AdvancedLocalizationUIState with _$AdvancedLocalizationUIState {
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
String? p4kGlobalIni,
String? serverGlobalIni,
ScLocalizationData? apiLocalizationData,
@Default(0) int p4kGlobalIniLines,
@Default(0) int serverGlobalIniLines,
}) = _AdvancedLocalizationUIState;
}
extension AdvancedLocalizationUIStateEx on AdvancedLocalizationUIState {
Map<AppAdvancedLocalizationClassKeysDataMode, String> get typeNames => {
AppAdvancedLocalizationClassKeysDataMode.localization: "汉化",
AppAdvancedLocalizationClassKeysDataMode.unLocalization: "英文原文",
AppAdvancedLocalizationClassKeysDataMode.mixed: "双语",
AppAdvancedLocalizationClassKeysDataMode.mixedNewline: "双语(换行)",
};
}
@riverpod
class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
@override
@ -47,10 +60,14 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
if (ald.classKeys == null) return;
state = state.copyWith(workingText: "正在分类 ...");
final m = await compute(_doClassIni, (ald, p4kGlobalIni, serverGlobalIni));
final p4kGlobalIniLines = p4kGlobalIni.split("\n").length;
final serverGlobalIniLines = serverGlobalIni.split("\n").length;
state = state.copyWith(
workingText: "",
p4kGlobalIni: p4kGlobalIni,
serverGlobalIni: serverGlobalIni,
p4kGlobalIniLines: p4kGlobalIniLines,
serverGlobalIniLines: serverGlobalIniLines,
classMap: m);
}
@ -70,10 +87,12 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
id: "un_localization",
className: "未汉化",
keys: [],
);
)
..mode = AppAdvancedLocalizationClassKeysDataMode.unLocalization
..lockMod = true;
final unClass = AppAdvancedLocalizationClassKeysData(
id: "un_class",
className: "未分类",
className: "其他",
keys: [],
);
final classMap = <String, AppAdvancedLocalizationClassKeysData>{
@ -84,18 +103,22 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
final serverIniMap = readIniAsMap(serverGlobalIni);
var regexList = classMap.values
.expand((c) => c.keys!.map((k) => MapEntry(c, RegExp(k))))
.expand((c) =>
c.keys!.map((k) => MapEntry(c, RegExp(k, caseSensitive: false))))
.toList();
iniKeysLoop:
for (var p4kIniKey in p4kIniMap.keys) {
final serverValue = serverIniMap[p4kIniKey];
if (serverValue == null) {
unLocalization.valuesMap[p4kIniKey] = p4kIniMap[p4kIniKey] ?? "";
if (serverValue == null || serverValue.trim().isEmpty) {
final p4kValue = p4kIniMap[p4kIniKey] ?? "";
if (p4kValue.trim().isNotEmpty) {
unLocalization.valuesMap[p4kIniKey] = p4kValue;
}
continue iniKeysLoop;
} else {
for (var item in regexList) {
if (item.value.hasMatch(p4kIniKey)) {
if (p4kIniKey.startsWith(item.value)) {
item.key.valuesMap[p4kIniKey] = serverValue;
serverIniMap.remove(p4kIniKey);
continue iniKeysLoop;
@ -103,15 +126,15 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
}
}
}
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;
}
if (unLocalization.valuesMap.isNotEmpty) {
classMap[unLocalization.id!] = unLocalization;
}
return classMap;
}
@ -150,6 +173,7 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
await localizationUIModel.downloadLocalizationFile(
file, apiLocalizationData);
}
state = state.copyWith(apiLocalizationData: apiLocalizationData);
final serverGlobalIni =
(await compute(LocalizationUIModel.readArchive, file.absolute.path))
.toString();
@ -158,13 +182,80 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
}
Future<String> readEnglishInI(String gameDir) async {
final data = await Unp4kCModel.unp4kTools(
var data = await Unp4kCModel.unp4kTools(
appGlobalState.applicationBinaryModuleDir!, [
"extract_memory",
"$gameDir\\Data.p4k",
"Data\\Localization\\english\\global.ini"
]);
// remove bom
if (data.length > 3 &&
data[0] == 0xEF &&
data[1] == 0xBB &&
data[2] == 0xBF) {
data = data.sublist(3);
}
final iniData = String.fromCharCodes(data);
return iniData;
}
onChangeMod(AppAdvancedLocalizationClassKeysData item,
AppAdvancedLocalizationClassKeysDataMode mode) async {
if (item.lockMod) return;
item.mode = mode;
item.isWorking = true;
final classMap =
Map<String, AppAdvancedLocalizationClassKeysData>.from(state.classMap!);
classMap[item.id!] = item;
state = state.copyWith(classMap: classMap);
final p4kIniMap = readIniAsMap(state.p4kGlobalIni!);
final serverIniMap = readIniAsMap(state.serverGlobalIni!);
final newValuesMap = <String, String>{};
for (var kv in item.valuesMap.entries) {
switch (mode) {
case AppAdvancedLocalizationClassKeysDataMode.localization:
newValuesMap[kv.key] = serverIniMap[kv.key] ?? "";
break;
case AppAdvancedLocalizationClassKeysDataMode.unLocalization:
newValuesMap[kv.key] = p4kIniMap[kv.key] ?? "";
break;
case AppAdvancedLocalizationClassKeysDataMode.mixed:
newValuesMap[kv.key] =
"${serverIniMap[kv.key]} [${p4kIniMap[kv.key]}]";
break;
case AppAdvancedLocalizationClassKeysDataMode.mixedNewline:
newValuesMap[kv.key] =
"${serverIniMap[kv.key]}\\n${p4kIniMap[kv.key]}";
break;
}
await Future.delayed(Duration.zero);
}
item.valuesMap = newValuesMap;
item.isWorking = false;
classMap[item.id!] = item;
state = state.copyWith(classMap: classMap);
}
Future<bool> doInstall() async {
state = state.copyWith(workingText: "生成汉化文件...");
final classMap = state.classMap!;
final globalIni = StringBuffer();
for (var item in classMap.values) {
for (var kv in item.valuesMap.entries) {
globalIni.write("${kv.key}=${kv.value}\n");
await Future.delayed(Duration.zero);
}
}
state = state.copyWith(workingText: "安装汉化文件...");
final localizationUIModel = ref.read(localizationUIModelProvider.notifier);
await localizationUIModel.installFormString(
globalIni, state.apiLocalizationData?.versionName ?? "-",
advanced: true);
state = state.copyWith(workingText: "");
return true;
}
}

View File

@ -21,6 +21,10 @@ mixin _$AdvancedLocalizationUIState {
throw _privateConstructorUsedError;
String? get p4kGlobalIni => throw _privateConstructorUsedError;
String? get serverGlobalIni => throw _privateConstructorUsedError;
ScLocalizationData? get apiLocalizationData =>
throw _privateConstructorUsedError;
int get p4kGlobalIniLines => throw _privateConstructorUsedError;
int get serverGlobalIniLines => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$AdvancedLocalizationUIStateCopyWith<AdvancedLocalizationUIState>
@ -39,7 +43,10 @@ abstract class $AdvancedLocalizationUIStateCopyWith<$Res> {
{String workingText,
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
String? p4kGlobalIni,
String? serverGlobalIni});
String? serverGlobalIni,
ScLocalizationData? apiLocalizationData,
int p4kGlobalIniLines,
int serverGlobalIniLines});
}
/// @nodoc
@ -60,6 +67,9 @@ class _$AdvancedLocalizationUIStateCopyWithImpl<$Res,
Object? classMap = freezed,
Object? p4kGlobalIni = freezed,
Object? serverGlobalIni = freezed,
Object? apiLocalizationData = freezed,
Object? p4kGlobalIniLines = null,
Object? serverGlobalIniLines = null,
}) {
return _then(_value.copyWith(
workingText: null == workingText
@ -78,6 +88,18 @@ class _$AdvancedLocalizationUIStateCopyWithImpl<$Res,
? _value.serverGlobalIni
: serverGlobalIni // ignore: cast_nullable_to_non_nullable
as String?,
apiLocalizationData: freezed == apiLocalizationData
? _value.apiLocalizationData
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
as ScLocalizationData?,
p4kGlobalIniLines: null == p4kGlobalIniLines
? _value.p4kGlobalIniLines
: p4kGlobalIniLines // ignore: cast_nullable_to_non_nullable
as int,
serverGlobalIniLines: null == serverGlobalIniLines
? _value.serverGlobalIniLines
: serverGlobalIniLines // ignore: cast_nullable_to_non_nullable
as int,
) as $Val);
}
}
@ -95,7 +117,10 @@ abstract class _$$AdvancedLocalizationUIStateImplCopyWith<$Res>
{String workingText,
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
String? p4kGlobalIni,
String? serverGlobalIni});
String? serverGlobalIni,
ScLocalizationData? apiLocalizationData,
int p4kGlobalIniLines,
int serverGlobalIniLines});
}
/// @nodoc
@ -115,6 +140,9 @@ class __$$AdvancedLocalizationUIStateImplCopyWithImpl<$Res>
Object? classMap = freezed,
Object? p4kGlobalIni = freezed,
Object? serverGlobalIni = freezed,
Object? apiLocalizationData = freezed,
Object? p4kGlobalIniLines = null,
Object? serverGlobalIniLines = null,
}) {
return _then(_$AdvancedLocalizationUIStateImpl(
workingText: null == workingText
@ -133,6 +161,18 @@ class __$$AdvancedLocalizationUIStateImplCopyWithImpl<$Res>
? _value.serverGlobalIni
: serverGlobalIni // ignore: cast_nullable_to_non_nullable
as String?,
apiLocalizationData: freezed == apiLocalizationData
? _value.apiLocalizationData
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
as ScLocalizationData?,
p4kGlobalIniLines: null == p4kGlobalIniLines
? _value.p4kGlobalIniLines
: p4kGlobalIniLines // ignore: cast_nullable_to_non_nullable
as int,
serverGlobalIniLines: null == serverGlobalIniLines
? _value.serverGlobalIniLines
: serverGlobalIniLines // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
@ -146,7 +186,10 @@ class _$AdvancedLocalizationUIStateImpl
{this.workingText = "",
final Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
this.p4kGlobalIni,
this.serverGlobalIni})
this.serverGlobalIni,
this.apiLocalizationData,
this.p4kGlobalIniLines = 0,
this.serverGlobalIniLines = 0})
: _classMap = classMap;
@override
@ -166,10 +209,18 @@ class _$AdvancedLocalizationUIStateImpl
final String? p4kGlobalIni;
@override
final String? serverGlobalIni;
@override
final ScLocalizationData? apiLocalizationData;
@override
@JsonKey()
final int p4kGlobalIniLines;
@override
@JsonKey()
final int serverGlobalIniLines;
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return 'AdvancedLocalizationUIState(workingText: $workingText, classMap: $classMap, p4kGlobalIni: $p4kGlobalIni, serverGlobalIni: $serverGlobalIni)';
return 'AdvancedLocalizationUIState(workingText: $workingText, classMap: $classMap, p4kGlobalIni: $p4kGlobalIni, serverGlobalIni: $serverGlobalIni, apiLocalizationData: $apiLocalizationData, p4kGlobalIniLines: $p4kGlobalIniLines, serverGlobalIniLines: $serverGlobalIniLines)';
}
@override
@ -180,7 +231,10 @@ class _$AdvancedLocalizationUIStateImpl
..add(DiagnosticsProperty('workingText', workingText))
..add(DiagnosticsProperty('classMap', classMap))
..add(DiagnosticsProperty('p4kGlobalIni', p4kGlobalIni))
..add(DiagnosticsProperty('serverGlobalIni', serverGlobalIni));
..add(DiagnosticsProperty('serverGlobalIni', serverGlobalIni))
..add(DiagnosticsProperty('apiLocalizationData', apiLocalizationData))
..add(DiagnosticsProperty('p4kGlobalIniLines', p4kGlobalIniLines))
..add(DiagnosticsProperty('serverGlobalIniLines', serverGlobalIniLines));
}
@override
@ -194,7 +248,13 @@ class _$AdvancedLocalizationUIStateImpl
(identical(other.p4kGlobalIni, p4kGlobalIni) ||
other.p4kGlobalIni == p4kGlobalIni) &&
(identical(other.serverGlobalIni, serverGlobalIni) ||
other.serverGlobalIni == serverGlobalIni));
other.serverGlobalIni == serverGlobalIni) &&
(identical(other.apiLocalizationData, apiLocalizationData) ||
other.apiLocalizationData == apiLocalizationData) &&
(identical(other.p4kGlobalIniLines, p4kGlobalIniLines) ||
other.p4kGlobalIniLines == p4kGlobalIniLines) &&
(identical(other.serverGlobalIniLines, serverGlobalIniLines) ||
other.serverGlobalIniLines == serverGlobalIniLines));
}
@override
@ -203,7 +263,10 @@ class _$AdvancedLocalizationUIStateImpl
workingText,
const DeepCollectionEquality().hash(_classMap),
p4kGlobalIni,
serverGlobalIni);
serverGlobalIni,
apiLocalizationData,
p4kGlobalIniLines,
serverGlobalIniLines);
@JsonKey(ignore: true)
@override
@ -219,7 +282,10 @@ abstract class _AdvancedLocalizationUIState
{final String workingText,
final Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
final String? p4kGlobalIni,
final String? serverGlobalIni}) = _$AdvancedLocalizationUIStateImpl;
final String? serverGlobalIni,
final ScLocalizationData? apiLocalizationData,
final int p4kGlobalIniLines,
final int serverGlobalIniLines}) = _$AdvancedLocalizationUIStateImpl;
@override
String get workingText;
@ -230,6 +296,12 @@ abstract class _AdvancedLocalizationUIState
@override
String? get serverGlobalIni;
@override
ScLocalizationData? get apiLocalizationData;
@override
int get p4kGlobalIniLines;
@override
int get serverGlobalIniLines;
@override
@JsonKey(ignore: true)
_$$AdvancedLocalizationUIStateImplCopyWith<_$AdvancedLocalizationUIStateImpl>
get copyWith => throw _privateConstructorUsedError;

View File

@ -7,7 +7,7 @@ part of 'advanced_localization_ui_model.dart';
// **************************************************************************
String _$advancedLocalizationUIModelHash() =>
r'2bb7dfc3cd8d45ecf5056083627136ad5cb7a285';
r'55c9d02d4c78112b2772f789c2758c3ea88808cb';
/// See also [AdvancedLocalizationUIModel].
@ProviderFor(AdvancedLocalizationUIModel)

View File

@ -86,7 +86,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
Row(
children: [
Text(S.current.localization_info_installed_version(
state.patchStatus?.value ?? "")),
"${state.patchStatus?.value ?? ""} ${(state.isInstalledAdvanced ?? false) ? " (高级汉化)" : ""}")),
const Spacer(),
if (state.patchStatus?.value !=
S.current.home_action_info_game_built_in)

View File

@ -32,6 +32,7 @@ class LocalizationUIState with _$LocalizationUIState {
Map<String, ScLocalizationData>? apiLocalizationData,
@Default("") String workingVersion,
MapEntry<bool, String>? patchStatus,
bool? isInstalledAdvanced,
List<String>? customizeList,
@Default(false) bool enableCustomize,
}) = _LocalizationUIState;
@ -222,7 +223,7 @@ class LocalizationUIModel extends _$LocalizationUIModel {
if (!await f.exists()) return;
state = state.copyWith(workingVersion: filePath);
final str = await f.readAsString();
await _installFormString(
await installFormString(
StringBuffer(str),
S.current
.localization_info_custom_file(getCustomizeFileName(filePath)));
@ -230,14 +231,19 @@ class LocalizationUIModel extends _$LocalizationUIModel {
};
}
_installFormString(StringBuffer globalIni, String versionName) async {
installFormString(StringBuffer globalIni, String versionName,
{bool? advanced}) async {
final iniFile = File(
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini");
if (versionName.isNotEmpty) {
if (!globalIni.toString().endsWith("\n")) {
globalIni.write("\n");
}
globalIni.write("_starcitizen_doctor_localization_version=$versionName");
if (advanced ?? false) {
globalIni.write("_starcitizen_doctor_localization_advanced=true\n");
}
globalIni
.write("_starcitizen_doctor_localization_version=$versionName\n");
}
/// write cfg
@ -275,7 +281,7 @@ class LocalizationUIModel extends _$LocalizationUIModel {
if (globalIni.isEmpty) {
throw S.current.localization_info_corrupted_file;
}
await _installFormString(globalIni, value.versionName ?? "");
await installFormString(globalIni, value.versionName ?? "");
} catch (e) {
if (!context.mounted) return;
await showToast(
@ -348,7 +354,19 @@ class LocalizationUIModel extends _$LocalizationUIModel {
await _getLangCfgEnableLang(lang: state.selectedLanguage!),
await _getInstalledIniVersion(
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini"));
state = state.copyWith(patchStatus: patchStatus);
final isInstalledAdvanced = await _checkAdvancedStatus(
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini");
state = state.copyWith(
patchStatus: patchStatus, isInstalledAdvanced: isInstalledAdvanced);
}
Future<bool> _checkAdvancedStatus(String path) async {
final iniFile = File(path);
if (!await iniFile.exists()) {
return false;
}
final iniString = (await iniFile.readAsString());
return iniString.contains("_starcitizen_doctor_localization_advanced=true");
}
Future<bool> _getLangCfgEnableLang({String lang = ""}) async {

View File

@ -21,6 +21,7 @@ mixin _$LocalizationUIState {
throw _privateConstructorUsedError;
String get workingVersion => throw _privateConstructorUsedError;
MapEntry<bool, String>? get patchStatus => throw _privateConstructorUsedError;
bool? get isInstalledAdvanced => throw _privateConstructorUsedError;
List<String>? get customizeList => throw _privateConstructorUsedError;
bool get enableCustomize => throw _privateConstructorUsedError;
@ -40,6 +41,7 @@ abstract class $LocalizationUIStateCopyWith<$Res> {
Map<String, ScLocalizationData>? apiLocalizationData,
String workingVersion,
MapEntry<bool, String>? patchStatus,
bool? isInstalledAdvanced,
List<String>? customizeList,
bool enableCustomize});
}
@ -61,6 +63,7 @@ class _$LocalizationUIStateCopyWithImpl<$Res, $Val extends LocalizationUIState>
Object? apiLocalizationData = freezed,
Object? workingVersion = null,
Object? patchStatus = freezed,
Object? isInstalledAdvanced = freezed,
Object? customizeList = freezed,
Object? enableCustomize = null,
}) {
@ -81,6 +84,10 @@ class _$LocalizationUIStateCopyWithImpl<$Res, $Val extends LocalizationUIState>
? _value.patchStatus
: patchStatus // ignore: cast_nullable_to_non_nullable
as MapEntry<bool, String>?,
isInstalledAdvanced: freezed == isInstalledAdvanced
? _value.isInstalledAdvanced
: isInstalledAdvanced // ignore: cast_nullable_to_non_nullable
as bool?,
customizeList: freezed == customizeList
? _value.customizeList
: customizeList // ignore: cast_nullable_to_non_nullable
@ -106,6 +113,7 @@ abstract class _$$LocalizationUIStateImplCopyWith<$Res>
Map<String, ScLocalizationData>? apiLocalizationData,
String workingVersion,
MapEntry<bool, String>? patchStatus,
bool? isInstalledAdvanced,
List<String>? customizeList,
bool enableCustomize});
}
@ -125,6 +133,7 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res>
Object? apiLocalizationData = freezed,
Object? workingVersion = null,
Object? patchStatus = freezed,
Object? isInstalledAdvanced = freezed,
Object? customizeList = freezed,
Object? enableCustomize = null,
}) {
@ -145,6 +154,10 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res>
? _value.patchStatus
: patchStatus // ignore: cast_nullable_to_non_nullable
as MapEntry<bool, String>?,
isInstalledAdvanced: freezed == isInstalledAdvanced
? _value.isInstalledAdvanced
: isInstalledAdvanced // ignore: cast_nullable_to_non_nullable
as bool?,
customizeList: freezed == customizeList
? _value._customizeList
: customizeList // ignore: cast_nullable_to_non_nullable
@ -165,6 +178,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
final Map<String, ScLocalizationData>? apiLocalizationData,
this.workingVersion = "",
this.patchStatus,
this.isInstalledAdvanced,
final List<String>? customizeList,
this.enableCustomize = false})
: _apiLocalizationData = apiLocalizationData,
@ -188,6 +202,8 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
final String workingVersion;
@override
final MapEntry<bool, String>? patchStatus;
@override
final bool? isInstalledAdvanced;
final List<String>? _customizeList;
@override
List<String>? get customizeList {
@ -204,7 +220,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
@override
String toString() {
return 'LocalizationUIState(selectedLanguage: $selectedLanguage, apiLocalizationData: $apiLocalizationData, workingVersion: $workingVersion, patchStatus: $patchStatus, customizeList: $customizeList, enableCustomize: $enableCustomize)';
return 'LocalizationUIState(selectedLanguage: $selectedLanguage, apiLocalizationData: $apiLocalizationData, workingVersion: $workingVersion, patchStatus: $patchStatus, isInstalledAdvanced: $isInstalledAdvanced, customizeList: $customizeList, enableCustomize: $enableCustomize)';
}
@override
@ -220,6 +236,8 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
other.workingVersion == workingVersion) &&
(identical(other.patchStatus, patchStatus) ||
other.patchStatus == patchStatus) &&
(identical(other.isInstalledAdvanced, isInstalledAdvanced) ||
other.isInstalledAdvanced == isInstalledAdvanced) &&
const DeepCollectionEquality()
.equals(other._customizeList, _customizeList) &&
(identical(other.enableCustomize, enableCustomize) ||
@ -233,6 +251,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
const DeepCollectionEquality().hash(_apiLocalizationData),
workingVersion,
patchStatus,
isInstalledAdvanced,
const DeepCollectionEquality().hash(_customizeList),
enableCustomize);
@ -250,6 +269,7 @@ abstract class _LocalizationUIState implements LocalizationUIState {
final Map<String, ScLocalizationData>? apiLocalizationData,
final String workingVersion,
final MapEntry<bool, String>? patchStatus,
final bool? isInstalledAdvanced,
final List<String>? customizeList,
final bool enableCustomize}) = _$LocalizationUIStateImpl;
@ -262,6 +282,8 @@ abstract class _LocalizationUIState implements LocalizationUIState {
@override
MapEntry<bool, String>? get patchStatus;
@override
bool? get isInstalledAdvanced;
@override
List<String>? get customizeList;
@override
bool get enableCustomize;

View File

@ -7,7 +7,7 @@ part of 'localization_ui_model.dart';
// **************************************************************************
String _$localizationUIModelHash() =>
r'ed47da78fdc6adac904a17909f111640ac84563e';
r'892a302b28ce4446cab7591f54008fbcc2e5eae0';
/// See also [LocalizationUIModel].
@ProviderFor(LocalizationUIModel)

View File

@ -267,6 +267,7 @@ class _TextTempWidget extends HookConsumerWidget {
return CodeEditor(
controller: CodeLineEditingController.fromText('${textData.value}'),
readOnly: true,
);
}
}