app/lib/ui/home/localization/localization_dialog_ui.dart

445 lines
18 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
import 'package:starcitizen_doctor/widgets/widgets.dart';
import 'localization_ui_model.dart';
class LocalizationDialogUI extends HookConsumerWidget {
const LocalizationDialogUI({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(localizationUIModelProvider);
final model = ref.read(localizationUIModelProvider.notifier);
final curInstallInfo = state.apiLocalizationData?[state.patchStatus?.value];
useEffect(() {
addPostFrameCallback(() {
model.checkUserCfg(context);
});
return null;
}, []);
return ContentDialog(
title: makeTitle(context, model, state),
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * .7,
minHeight: MediaQuery.of(context).size.height * .9),
content: Padding(
padding: const EdgeInsets.only(left: 12, right: 12, top: 12),
child: SingleChildScrollView(
child: Column(
children: [
AnimatedSize(
duration: const Duration(milliseconds: 130),
child: state.patchStatus?.key == true &&
state.patchStatus?.value == "游戏内置"
? Padding(
padding: const EdgeInsets.only(bottom: 12),
child: InfoBar(
title: const Text("警告"),
content: const Text(
"您正在使用游戏内置文本官方文本目前为机器翻译截至3.21.0),建议您在下方安装社区汉化。"),
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,
),
),
makeListContainer(
"汉化状态",
[
if (state.patchStatus == null)
makeLoading(context)
else ...[
const SizedBox(height: 6),
Row(
children: [
Center(
child: Text(
"启用(${LocalizationUIModel.languageSupport[state.selectedLanguage]}"),
),
const Spacer(),
ToggleSwitch(
checked: state.patchStatus?.key == true,
onChanged: model.updateLangCfg,
)
],
),
const SizedBox(height: 12),
Row(
children: [
Text("已安装版本:${state.patchStatus?.value}"),
const Spacer(),
if (state.patchStatus?.value != "游戏内置")
Row(
children: [
Button(
onPressed: model.goFeedback,
child: const Padding(
padding: EdgeInsets.all(4),
child: Row(
children: [
Icon(FluentIcons.feedback),
SizedBox(width: 6),
Text("汉化反馈"),
],
),
)),
const SizedBox(width: 16),
Button(
onPressed: model.doDelIniFile(),
child: const Padding(
padding: EdgeInsets.all(4),
child: Row(
children: [
Icon(FluentIcons.delete),
SizedBox(width: 6),
Text("卸载汉化"),
],
),
)),
],
),
],
),
AnimatedSize(
duration: const Duration(milliseconds: 130),
child: (curInstallInfo != null &&
curInstallInfo.note != null &&
curInstallInfo.note!.isNotEmpty)
? Padding(
padding: const EdgeInsets.only(top: 12),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: FluentTheme.of(context).cardColor,
borderRadius: BorderRadius.circular(7)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Text(
"备注:",
style: TextStyle(fontSize: 18),
),
const SizedBox(height: 6),
Text(
"${curInstallInfo.note}",
style: TextStyle(
color:
Colors.white.withOpacity(.8)),
)
],
),
),
),
)
: SizedBox(
width: MediaQuery.of(context).size.width,
),
),
],
],
context),
makeListContainer(
"社区汉化",
[
if (state.apiLocalizationData == null)
makeLoading(context)
else if (state.apiLocalizationData!.isEmpty)
Center(
child: Text(
"该语言/版本 暂无可用汉化,敬请期待!",
style: TextStyle(
fontSize: 13,
color: Colors.white.withOpacity(.8)),
),
)
else
for (final item in state.apiLocalizationData!.entries)
makeRemoteList(context, model, item, state),
],
context),
const SizedBox(height: 12),
IconButton(
icon: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(state.enableCustomize
? FluentIcons.chevron_up
: FluentIcons.chevron_down),
const SizedBox(width: 12),
const Text("高级功能"),
],
),
onPressed: model.toggleCustomize),
AnimatedSize(
duration: const Duration(milliseconds: 130),
child: Column(
children: [
const SizedBox(height: 12),
state.enableCustomize
? makeListContainer(
"自定义文本",
[
if (state.customizeList == null)
makeLoading(context)
else if (state.customizeList!.isEmpty)
Center(
child: Text(
"暂无自定义文本",
style: TextStyle(
fontSize: 13,
color: Colors.white.withOpacity(.8)),
),
)
else ...[
for (final file in state.customizeList!)
Row(
children: [
Text(
model.getCustomizeFileName(file),
),
const Spacer(),
if (state.workingVersion == file)
const Padding(
padding: EdgeInsets.only(right: 12),
child: ProgressRing(),
)
else
Button(
onPressed:
model.doLocalInstall(file),
child: const Padding(
padding: EdgeInsets.only(
left: 8,
right: 8,
top: 4,
bottom: 4),
child: Text("安装"),
))
],
)
],
],
context,
actions: [
Button(
onPressed: () => model.openDir(context),
child: const Padding(
padding: EdgeInsets.all(4),
child: Row(
children: [
Icon(FluentIcons.folder_open),
SizedBox(width: 6),
Text("打开文件夹"),
],
),
)),
])
: SizedBox(
width: MediaQuery.of(context).size.width,
)
],
),
),
],
),
),
),
);
}
Widget makeRemoteList(BuildContext context, LocalizationUIModel model,
MapEntry<String, ScLocalizationData> item, LocalizationUIState state) {
final isWorking = state.workingVersion.isNotEmpty;
final isMineWorking = state.workingVersion == item.key;
final isInstalled = state.patchStatus?.value == item.key;
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Column(
children: [
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${item.value.info}",
style: const TextStyle(fontSize: 19),
),
const SizedBox(height: 4),
Text(
"版本号:${item.value.versionName}",
style: TextStyle(color: Colors.white.withOpacity(.6)),
),
const SizedBox(height: 4),
Text(
"通道:${item.value.gameChannel}",
style: TextStyle(color: Colors.white.withOpacity(.6)),
),
const SizedBox(height: 4),
Text(
"更新时间:${item.value.updateAt}",
style: TextStyle(color: Colors.white.withOpacity(.6)),
),
],
),
const Spacer(),
if (isMineWorking)
const Padding(
padding: EdgeInsets.only(right: 12),
child: ProgressRing(),
)
else
Button(
onPressed: ((item.value.enable == true &&
!isWorking &&
!isInstalled)
? model.doRemoteInstall(context, item.value)
: null),
child: Padding(
padding: const EdgeInsets.only(
left: 8, right: 8, top: 4, bottom: 4),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 6),
child: Icon(isInstalled
? FluentIcons.check_mark
: (item.value.enable ?? false)
? FluentIcons.download
: FluentIcons.disable_updates),
),
Text(isInstalled
? "已安装"
: ((item.value.enable ?? false) ? "安装" : "不可用")),
],
),
)),
],
),
const SizedBox(height: 6),
Container(
color: Colors.white.withOpacity(.05),
height: 1,
),
],
),
);
}
Widget makeListContainer(
String title, List<Widget> children, BuildContext context,
{List<Widget> actions = const []}) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: AnimatedSize(
duration: const Duration(milliseconds: 130),
child: Container(
decoration: BoxDecoration(
color: FluentTheme.of(context).cardColor,
borderRadius: BorderRadius.circular(7)),
child: Padding(
padding:
const EdgeInsets.only(top: 12, bottom: 12, left: 24, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
title,
style: const TextStyle(fontSize: 22),
),
const Spacer(),
if (actions.isNotEmpty) ...actions,
],
),
const SizedBox(
height: 6,
),
Container(
color: Colors.white.withOpacity(.1),
height: 1,
),
const SizedBox(height: 12),
...children
],
),
),
),
),
);
}
Widget makeTitle(BuildContext context, LocalizationUIModel model,
LocalizationUIState state) {
return Row(
children: [
IconButton(
icon: const Icon(
FluentIcons.back,
size: 22,
),
onPressed: model.onBack(context)),
const SizedBox(width: 12),
const Text("汉化管理"),
const SizedBox(width: 24),
Text(
"${model.getScInstallPath()}",
style: const TextStyle(fontSize: 13),
),
const Spacer(),
SizedBox(
height: 36,
child: Row(
children: [
const Text(
"语言: ",
style: TextStyle(fontSize: 16),
),
ComboBox<String>(
value: state.selectedLanguage,
items: [
for (final lang
in LocalizationUIModel.languageSupport.entries)
ComboBoxItem(
value: lang.key,
child: Text(lang.value),
)
],
onChanged: state.workingVersion.isNotEmpty
? null
: (v) {
if (v == null) return;
model.selectLang(v);
},
)
],
),
),
const SizedBox(width: 12),
Button(
onPressed: model.doRefresh(),
child: const Padding(
padding: EdgeInsets.all(6),
child: Icon(FluentIcons.refresh),
)),
],
);
}
}