mirror of
https://mirror.ghproxy.com/https://github.com/StarCitizenToolBox/app.git
synced 2024-12-23 07:43:42 +08:00
feat: download Localization
This commit is contained in:
parent
308480095b
commit
07f2ab03cb
@ -215,7 +215,7 @@ class _$AppGlobalStateImpl implements _AppGlobalState {
|
|||||||
this.appLocale,
|
this.appLocale,
|
||||||
this.appConfBox,
|
this.appConfBox,
|
||||||
this.backgroundImageAssetsPath =
|
this.backgroundImageAssetsPath =
|
||||||
"assets/backgrounds/SC_01_Wallpaper_3840x2160.jpg"});
|
"assets/backgrounds/SC_01_Wallpaper_3840x2160.webp"});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String? deviceUUID;
|
final String? deviceUUID;
|
||||||
|
@ -167,7 +167,7 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
)),
|
)),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Button(
|
Button(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(6),
|
padding: EdgeInsets.all(6),
|
||||||
child: Icon(FluentIcons.folder_open),
|
child: Icon(FluentIcons.folder_open),
|
||||||
@ -788,15 +788,10 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
|
|
||||||
_onMenuTap(BuildContext context, String key, HomeUIModelState homeState,
|
_onMenuTap(BuildContext context, String key, HomeUIModelState homeState,
|
||||||
WidgetRef ref) async {
|
WidgetRef ref) async {
|
||||||
String gameInstallReqInfo =
|
// String gameInstallReqInfo =
|
||||||
S.current.home_action_info_valid_install_location_required;
|
// S.current.home_action_info_valid_install_location_required;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "localization":
|
case "localization":
|
||||||
if (homeState.scInstalledPath == "not_install") {
|
|
||||||
// TODO
|
|
||||||
// ToolsUIModel.English(context, showNotGameInstallMsg: true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
final model = ref.watch(homeUIModelProvider.notifier);
|
final model = ref.watch(homeUIModelProvider.notifier);
|
||||||
model.checkLocalizationUpdate();
|
model.checkLocalizationUpdate();
|
||||||
await showDialog(
|
await showDialog(
|
||||||
@ -807,14 +802,18 @@ class HomeUI extends HookConsumerWidget {
|
|||||||
model.checkLocalizationUpdate(skipReload: true);
|
model.checkLocalizationUpdate(skipReload: true);
|
||||||
break;
|
break;
|
||||||
case "performance":
|
case "performance":
|
||||||
if (homeState.scInstalledPath == "not_install") {
|
return;
|
||||||
showToast(context, gameInstallReqInfo);
|
// if (homeState.scInstalledPath == "not_install") {
|
||||||
break;
|
// showToast(context, gameInstallReqInfo);
|
||||||
}
|
// break;
|
||||||
context.push("/index/$key");
|
// }
|
||||||
break;
|
// context.push("/index/$key");
|
||||||
|
// break;
|
||||||
|
case "game_doctor":
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
context.push("/index/$key");
|
return;
|
||||||
|
// context.push("/index/$key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ part of 'home_ui_model.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$homeUIModelHash() => r'6a768281606856766737a63aaeebb392c4613d2b';
|
String _$homeUIModelHash() => r'422565027563e9bfd3ebddb08e518cade1c967d0';
|
||||||
|
|
||||||
/// See also [HomeUIModel].
|
/// See also [HomeUIModel].
|
||||||
@ProviderFor(HomeUIModel)
|
@ProviderFor(HomeUIModel)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
@ -9,7 +8,6 @@ import 'package:starcitizen_doctor/common/utils/log.dart';
|
|||||||
import 'package:starcitizen_doctor/data/app_advanced_localization_data.dart';
|
import 'package:starcitizen_doctor/data/app_advanced_localization_data.dart';
|
||||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||||
|
|
||||||
import '../home_ui_model.dart';
|
|
||||||
import 'advanced_localization_ui.json.dart';
|
import 'advanced_localization_ui.json.dart';
|
||||||
import 'localization_ui_model.dart';
|
import 'localization_ui_model.dart';
|
||||||
|
|
||||||
@ -178,40 +176,7 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
|||||||
|
|
||||||
Future<(String, String)> _readIni(LocalizationUIState localizationUIState,
|
Future<(String, String)> _readIni(LocalizationUIState localizationUIState,
|
||||||
LocalizationUIModel localizationUIModel) async {
|
LocalizationUIModel localizationUIModel) async {
|
||||||
final homeUIState = ref.read(homeUIModelProvider);
|
return ("", "");
|
||||||
final gameDir = homeUIState.scInstalledPath;
|
|
||||||
if (gameDir == null) return ("", "");
|
|
||||||
state = state.copyWith(
|
|
||||||
workingText: S.current.home_localization_advanced_msg_reading_p4k);
|
|
||||||
final p4kGlobalIni = await readEnglishInI(gameDir);
|
|
||||||
dPrint("read p4kGlobalIni => ${p4kGlobalIni.length}");
|
|
||||||
state = state.copyWith(
|
|
||||||
workingText: S.current
|
|
||||||
.home_localization_advanced_msg_reading_server_localization_text);
|
|
||||||
|
|
||||||
if (state.customizeGlobalIni != null) {
|
|
||||||
final apiLocalizationData = ScLocalizationData(
|
|
||||||
versionName: S.current.localization_info_custom_files,
|
|
||||||
info: "Customize");
|
|
||||||
state = state.copyWith(apiLocalizationData: apiLocalizationData);
|
|
||||||
return (p4kGlobalIni, state.customizeGlobalIni!);
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
state = state.copyWith(apiLocalizationData: 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 {
|
Future<String> readEnglishInI(String gameDir) async {
|
||||||
|
@ -7,7 +7,7 @@ part of 'advanced_localization_ui_model.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$advancedLocalizationUIModelHash() =>
|
String _$advancedLocalizationUIModelHash() =>
|
||||||
r'60ccd50f54b948d16be001f5ea07972a0fd9ed3f';
|
r'5aa7e690f1db04febf5a747f4c8cd2eb79a0ed44';
|
||||||
|
|
||||||
/// See also [AdvancedLocalizationUIModel].
|
/// See also [AdvancedLocalizationUIModel].
|
||||||
@ProviderFor(AdvancedLocalizationUIModel)
|
@ProviderFor(AdvancedLocalizationUIModel)
|
||||||
|
@ -21,127 +21,19 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
|||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
addPostFrameCallback(() {
|
addPostFrameCallback(() {
|
||||||
model.checkUserCfg(context);
|
// model.checkUserCfg(context);
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return ContentDialog(
|
return ContentDialog(
|
||||||
title: makeTitle(context, model, state),
|
title: makeTitle(context, model, state),
|
||||||
constraints: BoxConstraints(
|
constraints: const BoxConstraints(maxWidth: 1080, minHeight: 920),
|
||||||
maxWidth: MediaQuery.of(context).size.width * .7,
|
|
||||||
minHeight: MediaQuery.of(context).size.height * .9),
|
|
||||||
content: Padding(
|
content: Padding(
|
||||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 12),
|
padding: const EdgeInsets.only(left: 12, right: 12, top: 12),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
AnimatedSize(
|
|
||||||
duration: const Duration(milliseconds: 130),
|
|
||||||
child: state.patchStatus?.key == true &&
|
|
||||||
state.patchStatus?.value ==
|
|
||||||
S.current.home_action_info_game_built_in
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 12),
|
|
||||||
child: InfoBar(
|
|
||||||
title: Text(S.current.home_action_info_warning),
|
|
||||||
content: Text(S.current
|
|
||||||
.localization_info_machine_translation_warning),
|
|
||||||
severity: InfoBarSeverity.info,
|
|
||||||
style: InfoBarThemeData(decoration: (severity) {
|
|
||||||
return const BoxDecoration(
|
|
||||||
color: Color.fromRGBO(155, 7, 7, 1.0));
|
|
||||||
}, iconColor: (severity) {
|
|
||||||
return Colors.white;
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!(model.getScInstallPath() ?? "").contains("LIVE"))
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 12),
|
|
||||||
child: InfoBar(
|
|
||||||
title: Text(S.current
|
|
||||||
.home_localization_ptu_advanced_localization_tip_title),
|
|
||||||
content: Text(S.current
|
|
||||||
.home_localization_ptu_advanced_localization_tip_title_info),
|
|
||||||
severity: InfoBarSeverity.info,
|
|
||||||
style: InfoBarThemeData(decoration: (severity) {
|
|
||||||
return BoxDecoration(color: Colors.orange);
|
|
||||||
}, iconColor: (severity) {
|
|
||||||
return Colors.white;
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
makeListContainer(
|
|
||||||
S.current.localization_info_translation_status,
|
|
||||||
[
|
|
||||||
if (state.patchStatus == null)
|
|
||||||
makeLoading(context)
|
|
||||||
else ...[
|
|
||||||
const SizedBox(height: 6),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Center(
|
|
||||||
child: Text(S.current.localization_info_enabled(
|
|
||||||
LocalizationUIModel.languageSupport[
|
|
||||||
state.selectedLanguage] ??
|
|
||||||
"")),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
ToggleSwitch(
|
|
||||||
checked: state.patchStatus?.key == true,
|
|
||||||
onChanged: model.updateLangCfg,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(S.current.localization_info_installed_version(
|
|
||||||
"${state.patchStatus?.value ?? ""} ${(state.isInstalledAdvanced ?? false) ? S.current.home_localization_msg_version_advanced : ""}")),
|
|
||||||
const Spacer(),
|
|
||||||
if (state.patchStatus?.value !=
|
|
||||||
S.current.home_action_info_game_built_in)
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Button(
|
|
||||||
onPressed: model.goFeedback,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(4),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Icon(FluentIcons.feedback),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Text(S.current
|
|
||||||
.localization_action_translation_feedback),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Button(
|
|
||||||
onPressed: model.doDelIniFile(),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(4),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Icon(FluentIcons.delete),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
Text(S.current
|
|
||||||
.localization_action_uninstall_translation),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
context),
|
|
||||||
makeListContainer(
|
makeListContainer(
|
||||||
S.current.localization_info_community_translation,
|
S.current.localization_info_community_translation,
|
||||||
[
|
[
|
||||||
@ -352,15 +244,37 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
|||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(S.current.home_action_localization_management),
|
Text(S.current.home_action_localization_management),
|
||||||
const SizedBox(width: 24),
|
const SizedBox(width: 24),
|
||||||
Text(
|
// Text(
|
||||||
"${model.getScInstallPath()}",
|
// "${model.getScInstallPath()}",
|
||||||
style: const TextStyle(fontSize: 13),
|
// style: const TextStyle(fontSize: 13),
|
||||||
),
|
// ),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 36,
|
height: 36,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
Text(
|
||||||
|
S.current.localization_info_channel(""),
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
ComboBox<String>(
|
||||||
|
value: state.selectedChannel,
|
||||||
|
items: [
|
||||||
|
for (final channel in ["LIVE", "PTU"])
|
||||||
|
ComboBoxItem(
|
||||||
|
value: channel,
|
||||||
|
child: Text(channel),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
onChanged: state.workingVersion.isNotEmpty
|
||||||
|
? null
|
||||||
|
: (v) {
|
||||||
|
if (v == null) return;
|
||||||
|
model.selectChannel(v);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(width: 24),
|
||||||
Text(
|
Text(
|
||||||
S.current.localization_info_language,
|
S.current.localization_info_language,
|
||||||
style: const TextStyle(fontSize: 16),
|
style: const TextStyle(fontSize: 16),
|
||||||
@ -453,8 +367,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
confirm: S.current.localization_action_install,
|
confirm: S.current.localization_action_install,
|
||||||
cancel: S.current.home_action_cancel,
|
cancel: S.current.home_action_cancel,
|
||||||
constraints:
|
constraints: const BoxConstraints(maxWidth: 720),
|
||||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .45),
|
|
||||||
);
|
);
|
||||||
if (userOK) {
|
if (userOK) {
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
@ -1,26 +1,24 @@
|
|||||||
// ignore_for_file: avoid_build_context_in_providers
|
// ignore_for_file: avoid_build_context_in_providers
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'package:archive/archive.dart';
|
||||||
|
import 'dart:js_interop';
|
||||||
import 'package:archive/archive_io.dart';
|
|
||||||
import 'package:fluent_ui/fluent_ui.dart';
|
import 'package:fluent_ui/fluent_ui.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
|
||||||
import 'package:starcitizen_doctor/api/api.dart';
|
import 'package:starcitizen_doctor/api/api.dart';
|
||||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
|
||||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
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/data/sc_localization_data.dart';
|
||||||
import 'package:starcitizen_doctor/generated/no_l10n_strings.dart';
|
import 'package:starcitizen_doctor/generated/no_l10n_strings.dart';
|
||||||
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
|
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
|
||||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import 'package:web/web.dart' as web;
|
||||||
|
|
||||||
part 'localization_ui_model.g.dart';
|
part 'localization_ui_model.g.dart';
|
||||||
|
|
||||||
part 'localization_ui_model.freezed.dart';
|
part 'localization_ui_model.freezed.dart';
|
||||||
@ -29,6 +27,7 @@ part 'localization_ui_model.freezed.dart';
|
|||||||
class LocalizationUIState with _$LocalizationUIState {
|
class LocalizationUIState with _$LocalizationUIState {
|
||||||
factory LocalizationUIState({
|
factory LocalizationUIState({
|
||||||
String? selectedLanguage,
|
String? selectedLanguage,
|
||||||
|
@Default("LIVE") String selectedChannel,
|
||||||
Map<String, ScLocalizationData>? apiLocalizationData,
|
Map<String, ScLocalizationData>? apiLocalizationData,
|
||||||
@Default("") String workingVersion,
|
@Default("") String workingVersion,
|
||||||
MapEntry<bool, String>? patchStatus,
|
MapEntry<bool, String>? patchStatus,
|
||||||
@ -44,16 +43,6 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
"chinese_(traditional)": NoL10n.langZHT,
|
"chinese_(traditional)": NoL10n.langZHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
Directory get _downloadDir =>
|
|
||||||
Directory("${appGlobalState.applicationSupportDir}\\Localizations");
|
|
||||||
|
|
||||||
Directory getDownloadDir() => _downloadDir;
|
|
||||||
|
|
||||||
Directory get _scDataDir =>
|
|
||||||
Directory("${ref.read(homeUIModelProvider).scInstalledPath}\\data");
|
|
||||||
|
|
||||||
File get _cfgFile => File("${_scDataDir.absolute.path}\\system.cfg");
|
|
||||||
|
|
||||||
StreamSubscription? _customizeDirListenSub;
|
StreamSubscription? _customizeDirListenSub;
|
||||||
|
|
||||||
String get _scInstallPath => ref.read(homeUIModelProvider).scInstalledPath!;
|
String get _scInstallPath => ref.read(homeUIModelProvider).scInstalledPath!;
|
||||||
@ -66,9 +55,6 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _init() async {
|
Future<void> _init() async {
|
||||||
if (_scInstallPath == "not_install") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
_customizeDirListenSub?.cancel();
|
_customizeDirListenSub?.cancel();
|
||||||
_customizeDirListenSub = null;
|
_customizeDirListenSub = null;
|
||||||
@ -85,14 +71,13 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
|
|
||||||
Future<void> _loadData() async {
|
Future<void> _loadData() async {
|
||||||
_allVersionLocalizationData.clear();
|
_allVersionLocalizationData.clear();
|
||||||
await _updateStatus();
|
|
||||||
for (var lang in languageSupport.keys) {
|
for (var lang in languageSupport.keys) {
|
||||||
final l = await Api.getScLocalizationData(lang).unwrap();
|
final l = await Api.getScLocalizationData(lang).unwrap();
|
||||||
if (l != null) {
|
if (l != null) {
|
||||||
if (lang == state.selectedLanguage) {
|
if (lang == state.selectedLanguage) {
|
||||||
final apiLocalizationData = <String, ScLocalizationData>{};
|
final apiLocalizationData = <String, ScLocalizationData>{};
|
||||||
for (var element in l) {
|
for (var element in l) {
|
||||||
final isPTU = !_scInstallPath.contains("LIVE");
|
final isPTU = !state.selectedChannel.contains("LIVE");
|
||||||
if (isPTU && element.gameChannel == "PTU") {
|
if (isPTU && element.gameChannel == "PTU") {
|
||||||
apiLocalizationData[element.versionName ?? ""] = element;
|
apiLocalizationData[element.versionName ?? ""] = element;
|
||||||
} else if (!isPTU && element.gameChannel == "PU") {
|
} else if (!isPTU && element.gameChannel == "PU") {
|
||||||
@ -110,87 +95,19 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkUserCfg(BuildContext context) async {
|
Future<String> genLangCfg() async {
|
||||||
final userCfgFile = File("$_scInstallPath\\USER.cfg");
|
|
||||||
if (await userCfgFile.exists()) {
|
|
||||||
final cfgString = await userCfgFile.readAsString();
|
|
||||||
if (cfgString.contains("g_language") &&
|
|
||||||
!cfgString.contains("g_language=${state.selectedLanguage}")) {
|
|
||||||
if (!context.mounted) return;
|
|
||||||
final ok = await showConfirmDialogs(
|
|
||||||
context,
|
|
||||||
S.current.localization_info_remove_incompatible_translation_params,
|
|
||||||
Text(S.current
|
|
||||||
.localization_info_incompatible_translation_params_warning),
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
maxWidth: MediaQuery.of(context).size.width * .35));
|
|
||||||
if (ok == true) {
|
|
||||||
var finalString = "";
|
|
||||||
for (var item in cfgString.split("\n")) {
|
|
||||||
if (!item.trim().startsWith("g_language")) {
|
|
||||||
finalString = "$finalString$item\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await userCfgFile.delete();
|
|
||||||
await userCfgFile.create();
|
|
||||||
await userCfgFile.writeAsString(finalString, flush: true);
|
|
||||||
_loadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> updateLangCfg(bool enable) async {
|
|
||||||
final selectedLanguage = state.selectedLanguage!;
|
final selectedLanguage = state.selectedLanguage!;
|
||||||
final status = await _getLangCfgEnableLang(lang: selectedLanguage);
|
|
||||||
final exists = await _cfgFile.exists();
|
|
||||||
if (status == enable) {
|
|
||||||
await _updateStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StringBuffer newStr = StringBuffer();
|
StringBuffer newStr = StringBuffer();
|
||||||
var str = <String>[];
|
if (!newStr.toString().contains("sys_languages=$selectedLanguage")) {
|
||||||
if (exists) {
|
newStr.writeln("sys_languages=$selectedLanguage");
|
||||||
str = (await _cfgFile.readAsString()).replaceAll(" ", "").split("\n");
|
|
||||||
}
|
}
|
||||||
if (enable) {
|
if (!newStr.toString().contains("g_language=$selectedLanguage")) {
|
||||||
if (exists) {
|
newStr.writeln("g_language=$selectedLanguage");
|
||||||
for (var value in str) {
|
|
||||||
if (value.contains("sys_languages")) {
|
|
||||||
value = "sys_languages=$selectedLanguage";
|
|
||||||
} else if (value.contains("g_language")) {
|
|
||||||
value = "g_language=$selectedLanguage";
|
|
||||||
} else if (value.contains("g_languageAudio")) {
|
|
||||||
value = "g_language=english";
|
|
||||||
}
|
|
||||||
if (value.trim().isNotEmpty) newStr.writeln(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!newStr.toString().contains("sys_languages=$selectedLanguage")) {
|
|
||||||
newStr.writeln("sys_languages=$selectedLanguage");
|
|
||||||
}
|
|
||||||
if (!newStr.toString().contains("g_language=$selectedLanguage")) {
|
|
||||||
newStr.writeln("g_language=$selectedLanguage");
|
|
||||||
}
|
|
||||||
if (!newStr.toString().contains("g_languageAudio")) {
|
|
||||||
newStr.writeln("g_languageAudio=english");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (exists) {
|
|
||||||
for (var value in str) {
|
|
||||||
if (value.contains("sys_languages=")) {
|
|
||||||
continue;
|
|
||||||
} else if (value.contains("g_language")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
newStr.writeln(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (exists) await _cfgFile.delete(recursive: true);
|
if (!newStr.toString().contains("g_languageAudio")) {
|
||||||
await _cfgFile.create(recursive: true);
|
newStr.writeln("g_languageAudio=english");
|
||||||
await _cfgFile.writeAsString(newStr.toString());
|
}
|
||||||
await _updateStatus();
|
return newStr.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void goFeedback() {
|
void goFeedback() {
|
||||||
@ -198,13 +115,7 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VoidCallback? doDelIniFile() {
|
VoidCallback? doDelIniFile() {
|
||||||
return () async {
|
return () async {};
|
||||||
final iniFile = File(
|
|
||||||
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini");
|
|
||||||
if (await iniFile.exists()) await iniFile.delete();
|
|
||||||
await updateLangCfg(false);
|
|
||||||
await _updateStatus();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getCustomizeFileName(String path) {
|
String getCustomizeFileName(String path) {
|
||||||
@ -214,8 +125,7 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
installFormString(StringBuffer globalIni, String versionName,
|
installFormString(StringBuffer globalIni, String versionName,
|
||||||
{bool? advanced}) async {
|
{bool? advanced}) async {
|
||||||
dPrint("LocalizationUIModel -> installFormString $versionName");
|
dPrint("LocalizationUIModel -> installFormString $versionName");
|
||||||
final iniFile = File(
|
|
||||||
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini");
|
|
||||||
if (versionName.isNotEmpty) {
|
if (versionName.isNotEmpty) {
|
||||||
if (!globalIni.toString().endsWith("\n")) {
|
if (!globalIni.toString().endsWith("\n")) {
|
||||||
globalIni.write("\n");
|
globalIni.write("\n");
|
||||||
@ -226,39 +136,40 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
globalIni
|
globalIni
|
||||||
.write("_starcitizen_doctor_localization_version=$versionName\n");
|
.write("_starcitizen_doctor_localization_version=$versionName\n");
|
||||||
}
|
}
|
||||||
|
final selectedLanguage = state.selectedLanguage!;
|
||||||
|
final iniFileString = "\uFEFF${globalIni.toString().trim()}";
|
||||||
|
final cfg = await genLangCfg();
|
||||||
|
final archive = Archive();
|
||||||
|
archive.addFile(ArchiveFile(
|
||||||
|
"data/Localization/$selectedLanguage/global.ini", 0, iniFileString));
|
||||||
|
archive.addFile(ArchiveFile("data/system.cfg", 0, cfg));
|
||||||
|
final zip = await compute(_encodeZipFile, archive);
|
||||||
|
if (zip == null) return;
|
||||||
|
final blob = Blob.fromBytes(zip, opt: {
|
||||||
|
"type": "application/zip",
|
||||||
|
});
|
||||||
|
final url = web.URL.createObjectURL(blob);
|
||||||
|
jsDownloadBlobFile(url, "Localization_$versionName.zip");
|
||||||
|
}
|
||||||
|
|
||||||
/// write cfg
|
List<int>? _encodeZipFile(Archive archive) {
|
||||||
if (await _cfgFile.exists()) {}
|
final zip = ZipEncoder().encode(archive);
|
||||||
|
return zip;
|
||||||
/// write ini
|
|
||||||
if (await iniFile.exists()) {
|
|
||||||
await iniFile.delete();
|
|
||||||
}
|
|
||||||
await iniFile.create(recursive: true);
|
|
||||||
await iniFile.writeAsString("\uFEFF${globalIni.toString().trim()}",
|
|
||||||
flush: true);
|
|
||||||
await updateLangCfg(true);
|
|
||||||
await _updateStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VoidCallback? doRemoteInstall(
|
VoidCallback? doRemoteInstall(
|
||||||
BuildContext context, ScLocalizationData value) {
|
BuildContext context, ScLocalizationData value) {
|
||||||
return () async {
|
return () async {
|
||||||
AnalyticsApi.touch("install_localization");
|
// AnalyticsApi.touch("install_localization");
|
||||||
|
|
||||||
final savePath =
|
// final savePath =
|
||||||
File("${_downloadDir.absolute.path}\\${value.versionName}.sclang");
|
// File("${_downloadDir.absolute.path}\\${value.versionName}.sclang");
|
||||||
try {
|
try {
|
||||||
state = state.copyWith(workingVersion: value.versionName!);
|
state = state.copyWith(workingVersion: value.versionName!);
|
||||||
if (!await savePath.exists()) {
|
final data = await downloadLocalizationFile(value);
|
||||||
// download
|
|
||||||
await downloadLocalizationFile(savePath, value);
|
|
||||||
} else {
|
|
||||||
dPrint("use cache $savePath");
|
|
||||||
}
|
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
// check file
|
// check file
|
||||||
final globalIni = await compute(readArchive, savePath.absolute.path);
|
final globalIni = await compute(readArchive, data);
|
||||||
if (globalIni.isEmpty) {
|
if (globalIni.isEmpty) {
|
||||||
throw S.current.localization_info_corrupted_file;
|
throw S.current.localization_info_corrupted_file;
|
||||||
}
|
}
|
||||||
@ -267,30 +178,25 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
await showToast(
|
await showToast(
|
||||||
context, S.current.localization_info_installation_error(e));
|
context, S.current.localization_info_installation_error(e));
|
||||||
if (await savePath.exists()) await savePath.delete();
|
|
||||||
}
|
}
|
||||||
state = state.copyWith(workingVersion: "");
|
state = state.copyWith(workingVersion: "");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> downloadLocalizationFile(
|
Future<Uint8List> downloadLocalizationFile(ScLocalizationData value) async {
|
||||||
File savePath, ScLocalizationData value) async {
|
dPrint("downloading downloadLocalizationFile ...");
|
||||||
dPrint("downloading file to $savePath");
|
|
||||||
final downloadUrl =
|
final downloadUrl =
|
||||||
"${URLConf.gitlabLocalizationUrl}/archive/${value.versionName}.tar.gz";
|
"${URLConf.gitlabLocalizationUrl}/archive/${value.versionName}.tar.gz";
|
||||||
final r = await RSHttp.get(downloadUrl);
|
final r = await RSHttp.get(downloadUrl);
|
||||||
if (r.statusCode == 200 && r.data != null) {
|
if (r.statusCode == 200 && r.data != null) {
|
||||||
await savePath.create(recursive: true);
|
return r.data!;
|
||||||
await savePath.writeAsBytes(r.data!, flush: true);
|
|
||||||
} else {
|
} else {
|
||||||
throw "statusCode Error : ${r.statusCode}";
|
throw "statusCode Error : ${r.statusCode}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringBuffer readArchive(String savePath) {
|
static StringBuffer readArchive(Uint8List data) {
|
||||||
final inputStream = InputFileStream(savePath);
|
final archive = TarDecoder().decodeBytes(GZipDecoder().decodeBytes(data));
|
||||||
final archive =
|
|
||||||
TarDecoder().decodeBytes(GZipDecoder().decodeBuffer(inputStream));
|
|
||||||
StringBuffer globalIni = StringBuffer("");
|
StringBuffer globalIni = StringBuffer("");
|
||||||
for (var element in archive.files) {
|
for (var element in archive.files) {
|
||||||
if (element.name.contains("global.ini")) {
|
if (element.name.contains("global.ini")) {
|
||||||
@ -331,57 +237,6 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateStatus() async {
|
|
||||||
final patchStatus = MapEntry(
|
|
||||||
await _getLangCfgEnableLang(lang: state.selectedLanguage!),
|
|
||||||
await _getInstalledIniVersion(
|
|
||||||
"${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini"));
|
|
||||||
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 = "", String gamePath = ""}) async {
|
|
||||||
if (gamePath.isEmpty) {
|
|
||||||
gamePath = _scInstallPath;
|
|
||||||
}
|
|
||||||
final cfgFile = File("${_scDataDir.absolute.path}\\system.cfg");
|
|
||||||
if (!await cfgFile.exists()) return false;
|
|
||||||
final str = (await cfgFile.readAsString()).replaceAll(" ", "");
|
|
||||||
return str.contains("sys_languages=$lang") &&
|
|
||||||
str.contains("g_language=$lang") &&
|
|
||||||
str.contains("g_languageAudio=english");
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<String> _getInstalledIniVersion(String iniPath) async {
|
|
||||||
final iniFile = File(iniPath);
|
|
||||||
if (!await iniFile.exists()) {
|
|
||||||
return S.current.home_action_info_game_built_in;
|
|
||||||
}
|
|
||||||
final iniStringSplit = (await iniFile.readAsString()).split("\n");
|
|
||||||
for (var i = iniStringSplit.length - 1; i > 0; i--) {
|
|
||||||
if (iniStringSplit[i]
|
|
||||||
.contains("_starcitizen_doctor_localization_version=")) {
|
|
||||||
final v = iniStringSplit[i]
|
|
||||||
.trim()
|
|
||||||
.split("_starcitizen_doctor_localization_version=")[1];
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S.current.localization_info_custom_files;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<String>> checkLangUpdate({bool skipReload = false}) async {
|
Future<List<String>> checkLangUpdate({bool skipReload = false}) async {
|
||||||
if (_scInstallPath == "not_install") {
|
if (_scInstallPath == "not_install") {
|
||||||
return [];
|
return [];
|
||||||
@ -394,40 +249,29 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
|||||||
if (homeState.scInstallPaths.isEmpty) return [];
|
if (homeState.scInstallPaths.isEmpty) return [];
|
||||||
|
|
||||||
List<String> updates = [];
|
List<String> updates = [];
|
||||||
|
|
||||||
for (var scInstallPath in homeState.scInstallPaths) {
|
|
||||||
// 读取游戏安装文件夹
|
|
||||||
final scDataDir = Directory("$scInstallPath\\data\\Localization");
|
|
||||||
// 扫描目录确认已安装的语言
|
|
||||||
final dirList = await scDataDir.list().toList();
|
|
||||||
for (var element in dirList) {
|
|
||||||
for (var lang in languageSupport.keys) {
|
|
||||||
if (element.path.contains(lang) &&
|
|
||||||
await _getLangCfgEnableLang(
|
|
||||||
lang: lang, gamePath: scInstallPath)) {
|
|
||||||
final installedVersion =
|
|
||||||
await _getInstalledIniVersion("${element.path}\\global.ini");
|
|
||||||
if (installedVersion == S.current.home_action_info_game_built_in ||
|
|
||||||
installedVersion == S.current.localization_info_custom_files) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final curData = _allVersionLocalizationData[lang];
|
|
||||||
dPrint("check Localization update $scInstallPath");
|
|
||||||
if (!(curData?.keys.contains(installedVersion) ?? false)) {
|
|
||||||
// has update
|
|
||||||
for (var channel in ConstConf.gameChannels) {
|
|
||||||
if (scInstallPath.contains(channel)) {
|
|
||||||
dPrint("check Localization update: has update -> $channel");
|
|
||||||
updates.add(channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dPrint("check Localization update: up to date");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectChannel(String v) {
|
||||||
|
state = state.copyWith(selectedChannel: v);
|
||||||
|
_loadData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JS("Blob")
|
||||||
|
extension type Blob._(JSObject _) implements JSObject {
|
||||||
|
external factory Blob(JSArray<JSArrayBuffer> blobParts, JSAny? options);
|
||||||
|
|
||||||
|
factory Blob.fromBytes(List<int> bytes, {Map? opt}) {
|
||||||
|
final data = Uint8List.fromList(bytes).buffer.toJS;
|
||||||
|
|
||||||
|
return Blob([data].toJS, opt?.jsify());
|
||||||
|
}
|
||||||
|
|
||||||
|
external JSArrayBuffer? get blobParts;
|
||||||
|
|
||||||
|
external JSObject? get options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
external void jsDownloadBlobFile(String blobUrl, String filename);
|
||||||
|
@ -17,6 +17,7 @@ final _privateConstructorUsedError = UnsupportedError(
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$LocalizationUIState {
|
mixin _$LocalizationUIState {
|
||||||
String? get selectedLanguage => throw _privateConstructorUsedError;
|
String? get selectedLanguage => throw _privateConstructorUsedError;
|
||||||
|
String get selectedChannel => throw _privateConstructorUsedError;
|
||||||
Map<String, ScLocalizationData>? get apiLocalizationData =>
|
Map<String, ScLocalizationData>? get apiLocalizationData =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
String get workingVersion => throw _privateConstructorUsedError;
|
String get workingVersion => throw _privateConstructorUsedError;
|
||||||
@ -39,6 +40,7 @@ abstract class $LocalizationUIStateCopyWith<$Res> {
|
|||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String? selectedLanguage,
|
{String? selectedLanguage,
|
||||||
|
String selectedChannel,
|
||||||
Map<String, ScLocalizationData>? apiLocalizationData,
|
Map<String, ScLocalizationData>? apiLocalizationData,
|
||||||
String workingVersion,
|
String workingVersion,
|
||||||
MapEntry<bool, String>? patchStatus,
|
MapEntry<bool, String>? patchStatus,
|
||||||
@ -62,6 +64,7 @@ class _$LocalizationUIStateCopyWithImpl<$Res, $Val extends LocalizationUIState>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? selectedLanguage = freezed,
|
Object? selectedLanguage = freezed,
|
||||||
|
Object? selectedChannel = null,
|
||||||
Object? apiLocalizationData = freezed,
|
Object? apiLocalizationData = freezed,
|
||||||
Object? workingVersion = null,
|
Object? workingVersion = null,
|
||||||
Object? patchStatus = freezed,
|
Object? patchStatus = freezed,
|
||||||
@ -73,6 +76,10 @@ class _$LocalizationUIStateCopyWithImpl<$Res, $Val extends LocalizationUIState>
|
|||||||
? _value.selectedLanguage
|
? _value.selectedLanguage
|
||||||
: selectedLanguage // ignore: cast_nullable_to_non_nullable
|
: selectedLanguage // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
|
selectedChannel: null == selectedChannel
|
||||||
|
? _value.selectedChannel
|
||||||
|
: selectedChannel // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
apiLocalizationData: freezed == apiLocalizationData
|
apiLocalizationData: freezed == apiLocalizationData
|
||||||
? _value.apiLocalizationData
|
? _value.apiLocalizationData
|
||||||
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
|
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
|
||||||
@ -107,6 +114,7 @@ abstract class _$$LocalizationUIStateImplCopyWith<$Res>
|
|||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String? selectedLanguage,
|
{String? selectedLanguage,
|
||||||
|
String selectedChannel,
|
||||||
Map<String, ScLocalizationData>? apiLocalizationData,
|
Map<String, ScLocalizationData>? apiLocalizationData,
|
||||||
String workingVersion,
|
String workingVersion,
|
||||||
MapEntry<bool, String>? patchStatus,
|
MapEntry<bool, String>? patchStatus,
|
||||||
@ -128,6 +136,7 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? selectedLanguage = freezed,
|
Object? selectedLanguage = freezed,
|
||||||
|
Object? selectedChannel = null,
|
||||||
Object? apiLocalizationData = freezed,
|
Object? apiLocalizationData = freezed,
|
||||||
Object? workingVersion = null,
|
Object? workingVersion = null,
|
||||||
Object? patchStatus = freezed,
|
Object? patchStatus = freezed,
|
||||||
@ -139,6 +148,10 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res>
|
|||||||
? _value.selectedLanguage
|
? _value.selectedLanguage
|
||||||
: selectedLanguage // ignore: cast_nullable_to_non_nullable
|
: selectedLanguage // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String?,
|
||||||
|
selectedChannel: null == selectedChannel
|
||||||
|
? _value.selectedChannel
|
||||||
|
: selectedChannel // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
apiLocalizationData: freezed == apiLocalizationData
|
apiLocalizationData: freezed == apiLocalizationData
|
||||||
? _value._apiLocalizationData
|
? _value._apiLocalizationData
|
||||||
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
|
: apiLocalizationData // ignore: cast_nullable_to_non_nullable
|
||||||
@ -168,6 +181,7 @@ class __$$LocalizationUIStateImplCopyWithImpl<$Res>
|
|||||||
class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
||||||
_$LocalizationUIStateImpl(
|
_$LocalizationUIStateImpl(
|
||||||
{this.selectedLanguage,
|
{this.selectedLanguage,
|
||||||
|
this.selectedChannel = "LIVE",
|
||||||
final Map<String, ScLocalizationData>? apiLocalizationData,
|
final Map<String, ScLocalizationData>? apiLocalizationData,
|
||||||
this.workingVersion = "",
|
this.workingVersion = "",
|
||||||
this.patchStatus,
|
this.patchStatus,
|
||||||
@ -178,6 +192,9 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
final String? selectedLanguage;
|
final String? selectedLanguage;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final String selectedChannel;
|
||||||
final Map<String, ScLocalizationData>? _apiLocalizationData;
|
final Map<String, ScLocalizationData>? _apiLocalizationData;
|
||||||
@override
|
@override
|
||||||
Map<String, ScLocalizationData>? get apiLocalizationData {
|
Map<String, ScLocalizationData>? get apiLocalizationData {
|
||||||
@ -208,7 +225,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'LocalizationUIState(selectedLanguage: $selectedLanguage, apiLocalizationData: $apiLocalizationData, workingVersion: $workingVersion, patchStatus: $patchStatus, isInstalledAdvanced: $isInstalledAdvanced, customizeList: $customizeList)';
|
return 'LocalizationUIState(selectedLanguage: $selectedLanguage, selectedChannel: $selectedChannel, apiLocalizationData: $apiLocalizationData, workingVersion: $workingVersion, patchStatus: $patchStatus, isInstalledAdvanced: $isInstalledAdvanced, customizeList: $customizeList)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -218,6 +235,8 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
|||||||
other is _$LocalizationUIStateImpl &&
|
other is _$LocalizationUIStateImpl &&
|
||||||
(identical(other.selectedLanguage, selectedLanguage) ||
|
(identical(other.selectedLanguage, selectedLanguage) ||
|
||||||
other.selectedLanguage == selectedLanguage) &&
|
other.selectedLanguage == selectedLanguage) &&
|
||||||
|
(identical(other.selectedChannel, selectedChannel) ||
|
||||||
|
other.selectedChannel == selectedChannel) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other._apiLocalizationData, _apiLocalizationData) &&
|
.equals(other._apiLocalizationData, _apiLocalizationData) &&
|
||||||
(identical(other.workingVersion, workingVersion) ||
|
(identical(other.workingVersion, workingVersion) ||
|
||||||
@ -234,6 +253,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
|||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
selectedLanguage,
|
selectedLanguage,
|
||||||
|
selectedChannel,
|
||||||
const DeepCollectionEquality().hash(_apiLocalizationData),
|
const DeepCollectionEquality().hash(_apiLocalizationData),
|
||||||
workingVersion,
|
workingVersion,
|
||||||
patchStatus,
|
patchStatus,
|
||||||
@ -253,6 +273,7 @@ class _$LocalizationUIStateImpl implements _LocalizationUIState {
|
|||||||
abstract class _LocalizationUIState implements LocalizationUIState {
|
abstract class _LocalizationUIState implements LocalizationUIState {
|
||||||
factory _LocalizationUIState(
|
factory _LocalizationUIState(
|
||||||
{final String? selectedLanguage,
|
{final String? selectedLanguage,
|
||||||
|
final String selectedChannel,
|
||||||
final Map<String, ScLocalizationData>? apiLocalizationData,
|
final Map<String, ScLocalizationData>? apiLocalizationData,
|
||||||
final String workingVersion,
|
final String workingVersion,
|
||||||
final MapEntry<bool, String>? patchStatus,
|
final MapEntry<bool, String>? patchStatus,
|
||||||
@ -262,6 +283,8 @@ abstract class _LocalizationUIState implements LocalizationUIState {
|
|||||||
@override
|
@override
|
||||||
String? get selectedLanguage;
|
String? get selectedLanguage;
|
||||||
@override
|
@override
|
||||||
|
String get selectedChannel;
|
||||||
|
@override
|
||||||
Map<String, ScLocalizationData>? get apiLocalizationData;
|
Map<String, ScLocalizationData>? get apiLocalizationData;
|
||||||
@override
|
@override
|
||||||
String get workingVersion;
|
String get workingVersion;
|
||||||
|
@ -7,7 +7,7 @@ part of 'localization_ui_model.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$localizationUIModelHash() =>
|
String _$localizationUIModelHash() =>
|
||||||
r'd08a3d100c72b3f1f4a6c96944d4a73bb3c21808';
|
r'404f40f1f2c04494ce570173262ee0d8579b30b4';
|
||||||
|
|
||||||
/// See also [LocalizationUIModel].
|
/// See also [LocalizationUIModel].
|
||||||
@ProviderFor(LocalizationUIModel)
|
@ProviderFor(LocalizationUIModel)
|
||||||
|
@ -14,6 +14,8 @@ import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
|||||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||||
|
|
||||||
|
import 'package:web/web.dart' as web;
|
||||||
|
|
||||||
class SplashUI extends HookConsumerWidget {
|
class SplashUI extends HookConsumerWidget {
|
||||||
const SplashUI({super.key});
|
const SplashUI({super.key});
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ class SplashUI extends HookConsumerWidget {
|
|||||||
if (userOk) {
|
if (userOk) {
|
||||||
await appConf.put("splash_alert_info_version", _alertInfoVersion);
|
await appConf.put("splash_alert_info_version", _alertInfoVersion);
|
||||||
} else {
|
} else {
|
||||||
exit(0);
|
web.window.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ dependencies:
|
|||||||
super_sliver_list: ^0.4.1
|
super_sliver_list: ^0.4.1
|
||||||
re_editor: ^0.3.0
|
re_editor: ^0.3.0
|
||||||
re_highlight: ^0.0.3
|
re_highlight: ^0.0.3
|
||||||
|
cross_file: ^0.3.4+2
|
||||||
|
web: ^1.0.0
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
http: ^1.1.2
|
http: ^1.1.2
|
||||||
|
|
||||||
|
@ -1,40 +1,55 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<!--
|
<!--
|
||||||
If you are serving your web app in a path other than the root, change the
|
If you are serving your web app in a path other than the root, change the
|
||||||
href value below to reflect the base path you are serving from.
|
href value below to reflect the base path you are serving from.
|
||||||
|
|
||||||
The path provided below has to start and end with a slash "/" in order for
|
The path provided below has to start and end with a slash "/" in order for
|
||||||
it to work correctly.
|
it to work correctly.
|
||||||
|
|
||||||
For more details:
|
For more details:
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||||
|
|
||||||
This is a placeholder for base href that will be replaced by the value of
|
This is a placeholder for base href that will be replaced by the value of
|
||||||
the `--base-href` argument provided to `flutter build`.
|
the `--base-href` argument provided to `flutter build`.
|
||||||
-->
|
-->
|
||||||
<base href="$FLUTTER_BASE_HREF">
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||||
<meta name="description" content="A new Flutter project.">
|
<meta name="description" content="A new Flutter project.">
|
||||||
|
|
||||||
<!-- iOS meta tags & icons -->
|
<!-- iOS meta tags & icons -->
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="starcitizentoolbox_web">
|
<meta name="apple-mobile-web-app-title" content="starcitizentoolbox_web">
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>starcitizentoolbox_web</title>
|
<title>starcitizentoolbox_web</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<script type="application/javascript" src="/assets/packages/flutter_inappwebview_web/assets/web/web_support.js" defer></script>
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function jsDownloadBlobFile(blobUrl, filename) {
|
||||||
|
const a = document.createElement("a");
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.href = blobUrl;
|
||||||
|
a.download = filename;
|
||||||
|
a.click();
|
||||||
|
setTimeout(() => {
|
||||||
|
window.URL.revokeObjectURL(blobUrl);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="flutter_bootstrap.js" async></script>
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user