mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-28 07:54:44 +08:00
feat: 42kit Nav
feat: Animation Optimization
This commit is contained in:
@ -30,8 +30,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _makeAbout(BuildContext context, WidgetRef ref,
|
||||
ValueNotifier<bool> isTipTextCn, PageController pageCtrl) {
|
||||
Widget _makeAbout(BuildContext context, WidgetRef ref, ValueNotifier<bool> isTipTextCn, PageController pageCtrl) {
|
||||
return Stack(
|
||||
children: [
|
||||
Center(
|
||||
@ -42,9 +41,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(height: 32),
|
||||
Image.asset("assets/app_logo.png", width: 128, height: 128),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
Text(S.current.app_index_version_info(ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
const SizedBox(height: 12),
|
||||
Button(
|
||||
@ -56,18 +53,15 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(height: 32),
|
||||
Container(
|
||||
margin: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
decoration:
|
||||
BoxDecoration(color: FluentTheme.of(context).cardColor, borderRadius: BorderRadius.circular(12)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
S.current.about_app_description,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withValues(alpha: .9)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .9)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -86,9 +80,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * .35,
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context)
|
||||
.cardColor
|
||||
.withValues(alpha: .06),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: IconButton(
|
||||
icon: Padding(
|
||||
@ -96,9 +88,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
child: Text(
|
||||
isTipTextCn.value ? tipTextCN : tipTextEN,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white.withValues(alpha: .9)),
|
||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .9)),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
@ -126,8 +116,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _makeDonate(
|
||||
BuildContext context, WidgetRef ref, PageController pageCtrl) {
|
||||
Widget _makeDonate(BuildContext context, WidgetRef ref, PageController pageCtrl) {
|
||||
final donationTypeNotifier = useState('alipay');
|
||||
final bubbleMessages = [
|
||||
S.current.support_dev_thanks_message,
|
||||
@ -171,8 +160,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
for (var i = 0; i < bubbleMessages.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: SelectionArea(
|
||||
child: ChatBubble(message: bubbleMessages[i])),
|
||||
child: SelectionArea(child: ChatBubble(message: bubbleMessages[i])),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -261,14 +249,10 @@ class AboutUI extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Button(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith((states) =>
|
||||
isSelected
|
||||
? ButtonThemeData.buttonColor(context, states)
|
||||
.withAlpha((255.0 * 0.08).round())
|
||||
: ButtonThemeData.buttonColor(context, states)
|
||||
.withAlpha((255.0 * 0.005).round())),
|
||||
padding: WidgetStateProperty.all(
|
||||
EdgeInsets.symmetric(horizontal: 16, vertical: 8)),
|
||||
backgroundColor: WidgetStateProperty.resolveWith((states) => isSelected
|
||||
? ButtonThemeData.buttonColor(context, states).withAlpha((255.0 * 0.08).round())
|
||||
: ButtonThemeData.buttonColor(context, states).withAlpha((255.0 * 0.005).round())),
|
||||
padding: WidgetStateProperty.all(EdgeInsets.symmetric(horizontal: 16, vertical: 8)),
|
||||
),
|
||||
onPressed: onTap,
|
||||
child: Column(
|
||||
@ -328,16 +312,13 @@ class AboutUI extends HookConsumerWidget {
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context)
|
||||
.cardColor
|
||||
.withAlpha((255 * .1).round()),
|
||||
color: FluentTheme.of(context).cardColor.withAlpha((255 * .1).round()),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(S.current.support_dev_in_game_id,
|
||||
style: TextStyle(fontSize: 16)),
|
||||
Text(S.current.support_dev_in_game_id, style: TextStyle(fontSize: 16)),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () {
|
||||
@ -386,8 +367,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
return Column(
|
||||
key: ValueKey(type),
|
||||
children: [
|
||||
Text(title,
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
Text(title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
width: 200,
|
||||
@ -413,19 +393,13 @@ class AboutUI extends HookConsumerWidget {
|
||||
icon: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
pageIndex == 0
|
||||
? FluentIcons.chevron_up
|
||||
: FluentIcons.chevron_down,
|
||||
size: 12),
|
||||
Icon(pageIndex == 0 ? FluentIcons.chevron_up : FluentIcons.chevron_down, size: 12),
|
||||
SizedBox(width: 8),
|
||||
Text(pageIndex == 0
|
||||
? S.current.support_dev_back_button
|
||||
: S.current.support_dev_scroll_hint),
|
||||
Text(pageIndex == 0 ? S.current.support_dev_back_button : S.current.support_dev_scroll_hint),
|
||||
],
|
||||
),
|
||||
onPressed: () => pageCtrl.animateToPage(pageIndex,
|
||||
duration: const Duration(milliseconds: 300), curve: Curves.ease),
|
||||
onPressed: () =>
|
||||
pageCtrl.animateToPage(pageIndex, duration: const Duration(milliseconds: 300), curve: Curves.ease),
|
||||
);
|
||||
}
|
||||
|
||||
@ -440,8 +414,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_btn_faq,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -457,8 +430,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_online_feedback,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -474,8 +446,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_qq_group,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -492,8 +463,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_email,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -509,8 +479,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_open_source,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -528,6 +497,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
static String get tipTextCN => S.current.about_disclaimer;
|
||||
|
||||
Widget makeAnalyticsWidget(BuildContext context) {
|
||||
var buildIndex = 0;
|
||||
return LoadingWidget(
|
||||
onLoadData: AnalyticsApi.getAnalyticsData,
|
||||
autoRefreshDuration: const Duration(seconds: 60),
|
||||
@ -547,20 +517,18 @@ class AboutUI extends HookConsumerWidget {
|
||||
"performance_apply",
|
||||
"p4k_download",
|
||||
].contains(item["Type"]))
|
||||
makeAnalyticsItem(
|
||||
context: context,
|
||||
name: item["Type"] as String,
|
||||
value: item["Count"] as int)
|
||||
GridItemAnimator(
|
||||
index: buildIndex++,
|
||||
child: makeAnalyticsItem(
|
||||
context: context, name: item["Type"] as String, value: item["Count"] as int),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeAnalyticsItem(
|
||||
{required BuildContext context,
|
||||
required String name,
|
||||
required int value}) {
|
||||
Widget makeAnalyticsItem({required BuildContext context, required String name, required int value}) {
|
||||
final names = {
|
||||
"launch": S.current.about_analytics_launch,
|
||||
"gameLaunch": S.current.about_analytics_launch_game,
|
||||
@ -573,14 +541,12 @@ class AboutUI extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.all(12),
|
||||
margin: const EdgeInsets.only(left: 18, right: 18),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06), borderRadius: BorderRadius.circular(12)),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
names[name] ?? name,
|
||||
style: TextStyle(
|
||||
fontSize: 13, color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
@ -606,8 +572,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
launchUrlString("ms-windows-store://pdp/?productid=9NF3SWFWNKL1");
|
||||
return;
|
||||
} else {
|
||||
final hasUpdate =
|
||||
await ref.read(appGlobalModelProvider.notifier).checkUpdate(context);
|
||||
final hasUpdate = await ref.read(appGlobalModelProvider.notifier).checkUpdate(context);
|
||||
if (!hasUpdate) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.about_info_latest_version);
|
||||
@ -626,8 +591,7 @@ class ChatBubble extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
FluentTheme.of(context).accentColor.withAlpha((255.0 * .2).round()),
|
||||
color: FluentTheme.of(context).accentColor.withAlpha((255.0 * .2).round()),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(4),
|
||||
topRight: Radius.circular(18),
|
||||
@ -645,8 +609,7 @@ class ChatBubble extends StatelessWidget {
|
||||
|
||||
class DonationQrCodeData {
|
||||
static const alipay = "https://qr.alipay.com/tsx16308c4uai0ticmz4j96";
|
||||
static const wechat =
|
||||
"wxp://f2f0J40rTCX7Vt79yooWNbiqH3U6UmwGJkqjcAYnrv9OZVzKyS5_W6trp8mo3KP-CTQ5";
|
||||
static const wechat = "wxp://f2f0J40rTCX7Vt79yooWNbiqH3U6UmwGJkqjcAYnrv9OZVzKyS5_W6trp8mo3KP-CTQ5";
|
||||
static const qq =
|
||||
"https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&u=3334969096&n=xkeyC&ac=CAEQiK6etgwY8ZuKvgYyGOa1geWKqOaRiuS9jee7j-iQpeaUtuasvjgBQiAzY2Y4NWY3MDI1MWUxYWEwMGYyN2Q0OTM4Y2U2ODFlMw%3D%3D_xxx_sign";
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
onSwitchFile() async {
|
||||
final sb = await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
const LocalizationFromFileDialogUI(isInAdvancedMode: true),
|
||||
builder: (BuildContext context) => const LocalizationFromFileDialogUI(isInAdvancedMode: true),
|
||||
);
|
||||
if (sb is (StringBuffer, bool)) {
|
||||
model.setCustomizeGlobalIni(sb.$1.toString());
|
||||
@ -42,8 +41,7 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
}, const []);
|
||||
|
||||
return makeDefaultPage(
|
||||
title: S.current.home_localization_advanced_title(
|
||||
homeUIState.scInstalledPath ?? "-"),
|
||||
title: S.current.home_localization_advanced_title(homeUIState.scInstalledPath ?? "-"),
|
||||
context,
|
||||
content: state.workingText.isNotEmpty
|
||||
? Center(
|
||||
@ -71,15 +69,13 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
S.current.home_localization_advanced_msg_version(
|
||||
state.apiLocalizationData?.versionName ??
|
||||
"-"),
|
||||
state.apiLocalizationData?.versionName ?? "-"),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: onSwitchFile,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 6, vertical: 3),
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 3),
|
||||
child: Icon(FluentIcons.switch_widget),
|
||||
)),
|
||||
if (state.customizeGlobalIni != null) ...[
|
||||
@ -89,23 +85,19 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
model.setCustomizeGlobalIni(null);
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 6, vertical: 3),
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 3),
|
||||
child: Icon(FluentIcons.delete),
|
||||
)),
|
||||
]
|
||||
],
|
||||
)),
|
||||
Text(S.current.home_localization_advanced_title_msg(
|
||||
state.serverGlobalIniLines,
|
||||
state.p4kGlobalIniLines)),
|
||||
Text(S.current
|
||||
.home_localization_advanced_title_msg(state.serverGlobalIniLines, state.p4kGlobalIniLines)),
|
||||
const SizedBox(width: 32),
|
||||
Button(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12, right: 12, top: 4, bottom: 4),
|
||||
child: Text(S.current
|
||||
.home_localization_advanced_action_install),
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4),
|
||||
child: Text(S.current.home_localization_advanced_action_install),
|
||||
),
|
||||
onPressed: () {
|
||||
model.onInstall(context);
|
||||
@ -113,19 +105,13 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child:
|
||||
_makeBody(context, homeUIState, state, ref, model)),
|
||||
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: 4,
|
||||
@ -134,109 +120,104 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.all(12),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = state.classMap!.values.elementAt(index);
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 6, bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .05),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
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.withValues(alpha: .6),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 6, bottom: 12),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 1,
|
||||
color: Colors.white.withValues(alpha: .1),
|
||||
),
|
||||
if (item.isWorking)
|
||||
Column(
|
||||
children: [
|
||||
makeLoading(context),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
S.current.home_localization_advanced_action_mod_change),
|
||||
],
|
||||
)
|
||||
else ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(S
|
||||
.current.home_localization_advanced_action_mode)),
|
||||
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,
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top: 6, bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .05),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: item.isWorking ? null : () => _showContent(context, item),
|
||||
icon: 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: [
|
||||
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.withValues(alpha: .6),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
const SizedBox(width: 6),
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 6, bottom: 12),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 1,
|
||||
color: Colors.white.withValues(alpha: .1),
|
||||
),
|
||||
if (item.isWorking)
|
||||
Column(
|
||||
children: [
|
||||
makeLoading(context),
|
||||
const SizedBox(height: 6),
|
||||
Text(S.current.home_localization_advanced_action_mod_change),
|
||||
],
|
||||
)
|
||||
else ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Text(S.current.home_localization_advanced_action_mode)),
|
||||
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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -244,8 +225,7 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
_showContent(
|
||||
BuildContext context, AppAdvancedLocalizationClassKeysData item) {
|
||||
_showContent(BuildContext context, AppAdvancedLocalizationClassKeysData item) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@ -282,8 +262,7 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
const SizedBox(
|
||||
width: 24,
|
||||
),
|
||||
Text(S.current.home_localization_advanced_title_preview(
|
||||
item.className ?? "-")),
|
||||
Text(S.current.home_localization_advanced_title_preview(item.className ?? "-")),
|
||||
],
|
||||
),
|
||||
content: textData.value.isEmpty
|
||||
@ -295,13 +274,10 @@ class AdvancedLocalizationUI extends HookConsumerWidget {
|
||||
),
|
||||
child: CodeEditor(
|
||||
readOnly: true,
|
||||
controller:
|
||||
CodeLineEditingController.fromText(textData.value),
|
||||
controller: CodeLineEditingController.fromText(textData.value),
|
||||
style: CodeEditorStyle(
|
||||
codeTheme: CodeHighlightTheme(
|
||||
languages: {
|
||||
'ini': CodeHighlightThemeMode(mode: langIni)
|
||||
},
|
||||
languages: {'ini': CodeHighlightThemeMode(mode: langIni)},
|
||||
theme: vs2015Theme,
|
||||
),
|
||||
),
|
||||
|
@ -30,8 +30,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
return ContentDialog(
|
||||
title: makeTitle(context, model, state),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .7,
|
||||
minHeight: MediaQuery.of(context).size.height * .9),
|
||||
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(
|
||||
@ -40,18 +39,15 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 130),
|
||||
child: state.patchStatus?.key == true &&
|
||||
state.patchStatus?.value ==
|
||||
S.current.home_action_info_game_built_in
|
||||
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),
|
||||
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));
|
||||
return const BoxDecoration(color: Color.fromRGBO(155, 7, 7, 1.0));
|
||||
}, iconColor: (severity) {
|
||||
return Colors.white;
|
||||
}),
|
||||
@ -65,10 +61,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
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),
|
||||
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);
|
||||
@ -89,9 +83,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
Center(
|
||||
child: Text(S.current.localization_info_enabled(
|
||||
LocalizationUIModel.languageSupport[
|
||||
state.selectedLanguage] ??
|
||||
"")),
|
||||
LocalizationUIModel.languageSupport[state.selectedLanguage] ?? "")),
|
||||
),
|
||||
const Spacer(),
|
||||
ToggleSwitch(
|
||||
@ -109,20 +101,15 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
Text(S.current.localization_info_installed_version(
|
||||
"${state.patchStatus?.value ?? ""} ${(state.isInstalledAdvanced ?? false) ? S.current.home_localization_msg_version_advanced : ""}")),
|
||||
SizedBox(width: 24),
|
||||
if (state
|
||||
.installedCommunityInputMethodSupportVersion !=
|
||||
null)
|
||||
if (state.installedCommunityInputMethodSupportVersion != null)
|
||||
Text(
|
||||
S.current
|
||||
.input_method_community_input_method_support_version(
|
||||
state.installedCommunityInputMethodSupportVersion ??
|
||||
"?"),
|
||||
S.current.input_method_community_input_method_support_version(
|
||||
state.installedCommunityInputMethodSupportVersion ?? "?"),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (state.patchStatus?.value !=
|
||||
S.current.home_action_info_game_built_in)
|
||||
if (state.patchStatus?.value != S.current.home_action_info_game_built_in)
|
||||
Row(
|
||||
children: [
|
||||
Button(
|
||||
@ -133,8 +120,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const Icon(FluentIcons.feedback),
|
||||
const SizedBox(width: 6),
|
||||
Text(S.current
|
||||
.localization_action_translation_feedback),
|
||||
Text(S.current.localization_action_translation_feedback),
|
||||
],
|
||||
),
|
||||
)),
|
||||
@ -147,8 +133,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const Icon(FluentIcons.delete),
|
||||
const SizedBox(width: 6),
|
||||
Text(S.current
|
||||
.localization_action_uninstall_translation),
|
||||
Text(S.current.localization_action_uninstall_translation),
|
||||
],
|
||||
),
|
||||
)),
|
||||
@ -167,11 +152,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
else if (state.apiLocalizationData!.isEmpty)
|
||||
Center(
|
||||
child: Text(
|
||||
S.current
|
||||
.localization_info_no_translation_available,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white.withValues(alpha: .8)),
|
||||
S.current.localization_info_no_translation_available,
|
||||
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .8)),
|
||||
),
|
||||
)
|
||||
else
|
||||
@ -180,9 +162,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = state.apiLocalizationData!.entries
|
||||
.elementAt(index);
|
||||
return makeRemoteList(context, model, item, state);
|
||||
final item = state.apiLocalizationData!.entries.elementAt(index);
|
||||
return makeRemoteList(context, model, item, state, index);
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
@ -198,136 +179,124 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeRemoteList(BuildContext context, LocalizationUIModel model,
|
||||
MapEntry<String, ScLocalizationData> item, LocalizationUIState state) {
|
||||
Widget makeRemoteList(BuildContext context, LocalizationUIModel model, MapEntry<String, ScLocalizationData> item,
|
||||
LocalizationUIState state, int index) {
|
||||
final isWorking = state.workingVersion.isNotEmpty;
|
||||
final isMineWorking = state.workingVersion == item.key;
|
||||
final isInstalled = state.patchStatus?.value == item.key;
|
||||
final isItemEnabled = ((item.value.enable ?? false));
|
||||
final tapDisabled =
|
||||
isInstalled || isWorking || !isItemEnabled || isMineWorking;
|
||||
return Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
disable: tapDisabled,
|
||||
child: GestureDetector(
|
||||
onTap: tapDisabled
|
||||
? null
|
||||
: () => model.onRemoteInsTall(context, item, state),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: tapDisabled ? .03 : .05),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${item.value.info}",
|
||||
style: const TextStyle(fontSize: 19),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_version_number(
|
||||
item.value.versionName ?? ""),
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_channel(
|
||||
item.value.gameChannel ?? ""),
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_update_time(
|
||||
item.value.updateAt ?? ""),
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isMineWorking)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: 12),
|
||||
child: ProgressRing(),
|
||||
)
|
||||
else ...[
|
||||
Icon(
|
||||
isInstalled
|
||||
? FluentIcons.check_mark
|
||||
: isItemEnabled
|
||||
? FluentIcons.download
|
||||
: FluentIcons.disable_updates,
|
||||
color: Colors.white.withValues(alpha: .8),
|
||||
size: 18,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
isInstalled
|
||||
? S.current.localization_info_installed
|
||||
: (isItemEnabled
|
||||
? S.current.localization_action_install
|
||||
: S.current.localization_info_unavailable),
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .8),
|
||||
final tapDisabled = isInstalled || isWorking || !isItemEnabled || isMineWorking;
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
disable: tapDisabled,
|
||||
child: GestureDetector(
|
||||
onTap: tapDisabled ? null : () => model.onRemoteInsTall(context, item, state),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: tapDisabled ? .03 : .05),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${item.value.info}",
|
||||
style: const TextStyle(fontSize: 19),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_version_number(item.value.versionName ?? ""),
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_channel(item.value.gameChannel ?? ""),
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
S.current.localization_info_update_time(item.value.updateAt ?? ""),
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
if ((!isInstalled) && isItemEnabled)
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
if (isMineWorking)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: 12),
|
||||
child: ProgressRing(),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
if (item.value.note != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
"${item.value.note}",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
fontSize: 13,
|
||||
),
|
||||
else ...[
|
||||
Icon(
|
||||
isInstalled
|
||||
? FluentIcons.check_mark
|
||||
: isItemEnabled
|
||||
? FluentIcons.download
|
||||
: FluentIcons.disable_updates,
|
||||
color: Colors.white.withValues(alpha: .8),
|
||||
size: 18,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
isInstalled
|
||||
? S.current.localization_info_installed
|
||||
: (isItemEnabled
|
||||
? S.current.localization_action_install
|
||||
: S.current.localization_info_unavailable),
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .8),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
if ((!isInstalled) && isItemEnabled)
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
if (item.value.note != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
"${item.value.note}",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeListContainer(
|
||||
String title, List<Widget> children, BuildContext context,
|
||||
{List<Widget> actions = const [],
|
||||
bool gridViewMode = false,
|
||||
int gridViewCrossAxisCount = 2}) {
|
||||
Widget makeListContainer(String title, List<Widget> children, BuildContext context,
|
||||
{List<Widget> actions = const [], bool gridViewMode = false, int gridViewCrossAxisCount = 2}) {
|
||||
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)),
|
||||
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),
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 12, left: 24, right: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -371,8 +340,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeTitle(BuildContext context, LocalizationUIModel model,
|
||||
LocalizationUIState state) {
|
||||
Widget makeTitle(BuildContext context, LocalizationUIModel model, LocalizationUIState state) {
|
||||
return Row(
|
||||
children: [
|
||||
IconButton(
|
||||
@ -401,8 +369,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
ComboBox<String>(
|
||||
value: state.selectedLanguage,
|
||||
items: [
|
||||
for (final lang
|
||||
in LocalizationUIModel.languageSupport.entries)
|
||||
for (final lang in LocalizationUIModel.languageSupport.entries)
|
||||
ComboBoxItem(
|
||||
value: lang.key,
|
||||
child: Text(lang.value),
|
||||
@ -429,8 +396,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeToolsListContainer(BuildContext context, LocalizationUIModel model,
|
||||
LocalizationUIState state) {
|
||||
Widget makeToolsListContainer(BuildContext context, LocalizationUIModel model, LocalizationUIState state) {
|
||||
final toolsMenu = {
|
||||
"launcher_mod": (
|
||||
const Icon(FluentIcons.c_plus_plus, size: 24),
|
||||
@ -469,8 +435,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
case "custom_files":
|
||||
final sb = await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
const LocalizationFromFileDialogUI(),
|
||||
builder: (BuildContext context) => const LocalizationFromFileDialogUI(),
|
||||
);
|
||||
if (sb is (StringBuffer, bool)) {
|
||||
await model.installFormString(
|
||||
|
@ -12,6 +12,7 @@ import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import 'about/about_ui.dart';
|
||||
import 'home/home_ui.dart';
|
||||
import 'nav/nav_ui.dart';
|
||||
import 'settings/settings_ui.dart';
|
||||
import 'tools/tools_ui.dart';
|
||||
|
||||
@ -42,8 +43,7 @@ class IndexUI extends HookConsumerWidget {
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev")),
|
||||
Text(S.current.app_index_version_info(ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev")),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -77,8 +77,7 @@ class IndexUI extends HookConsumerWidget {
|
||||
key: Key("NavigationPane_${S.current.app_language_code}"),
|
||||
selected: curIndex.value,
|
||||
items: getNavigationPaneItems(curIndex),
|
||||
size: NavigationPaneSize(
|
||||
openWidth: S.current.app_language_code.startsWith("zh") ? 64 : 74),
|
||||
size: NavigationPaneSize(openWidth: S.current.app_language_code.startsWith("zh") ? 64 : 74),
|
||||
),
|
||||
paneBodyBuilder: (item, child) {
|
||||
return item!.body;
|
||||
@ -95,18 +94,15 @@ class IndexUI extends HookConsumerWidget {
|
||||
S.current.app_index_menu_tools,
|
||||
const ToolsUI(),
|
||||
),
|
||||
FluentIcons.settings: (
|
||||
S.current.app_index_menu_settings,
|
||||
const SettingsUI()
|
||||
),
|
||||
FluentIcons.power_apps: ("导航", const NavUI()),
|
||||
FluentIcons.settings: (S.current.app_index_menu_settings, const SettingsUI()),
|
||||
FluentIcons.info: (
|
||||
S.current.app_index_menu_about,
|
||||
const AboutUI(),
|
||||
),
|
||||
};
|
||||
|
||||
List<NavigationPaneItem> getNavigationPaneItems(
|
||||
ValueNotifier<int> curIndexState) {
|
||||
List<NavigationPaneItem> getNavigationPaneItems(ValueNotifier<int> curIndexState) {
|
||||
// width = 64
|
||||
return [
|
||||
for (final kv in pageMenus.entries)
|
||||
@ -136,8 +132,7 @@ class IndexUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
void _onTapIndexMenu(String value, ValueNotifier<int> curIndexState) {
|
||||
final pageIndex =
|
||||
pageMenus.values.toList().indexWhere((element) => element.$1 == value);
|
||||
final pageIndex = pageMenus.values.toList().indexWhere((element) => element.$1 == value);
|
||||
curIndexState.value = pageIndex;
|
||||
}
|
||||
|
||||
@ -156,8 +151,7 @@ class IndexUI extends HookConsumerWidget {
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 6, right: 6, bottom: 1.5, top: 1.5),
|
||||
padding: const EdgeInsets.only(left: 6, right: 6, bottom: 1.5, top: 1.5),
|
||||
child: Text(
|
||||
"${aria2cState.aria2TotalTaskNum}",
|
||||
style: const TextStyle(
|
||||
|
41
lib/ui/nav/nav_state.dart
Normal file
41
lib/ui/nav/nav_state.dart
Normal file
@ -0,0 +1,41 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/api/udb.dart';
|
||||
import 'package:starcitizen_doctor/data/nav_api_data.dart';
|
||||
|
||||
part 'nav_state.freezed.dart';
|
||||
|
||||
part 'nav_state.g.dart';
|
||||
|
||||
@freezed
|
||||
class NavState with _$NavState {
|
||||
const factory NavState({
|
||||
List<NavApiDocsItemData>? items,
|
||||
@Default("") String errorInfo,
|
||||
}) = _NavState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class Nav extends _$Nav {
|
||||
bool _mounted = true;
|
||||
|
||||
@override
|
||||
NavState build() {
|
||||
state = NavState();
|
||||
loadData(1);
|
||||
ref.onDispose(() {
|
||||
_mounted = false;
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
void loadData(int pageNo) async {
|
||||
if (!_mounted) return;
|
||||
try {
|
||||
final r = await UDBNavApi.getNavItems(pageNo: pageNo);
|
||||
state = state.copyWith(items: r.docs, errorInfo: "");
|
||||
} catch (e) {
|
||||
state = state.copyWith(errorInfo: e.toString());
|
||||
}
|
||||
}
|
||||
}
|
173
lib/ui/nav/nav_state.freezed.dart
Normal file
173
lib/ui/nav/nav_state.freezed.dart
Normal file
@ -0,0 +1,173 @@
|
||||
// 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 'nav_state.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 _$NavState {
|
||||
List<NavApiDocsItemData>? get items => throw _privateConstructorUsedError;
|
||||
String get errorInfo => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of NavState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$NavStateCopyWith<NavState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $NavStateCopyWith<$Res> {
|
||||
factory $NavStateCopyWith(NavState value, $Res Function(NavState) then) =
|
||||
_$NavStateCopyWithImpl<$Res, NavState>;
|
||||
@useResult
|
||||
$Res call({List<NavApiDocsItemData>? items, String errorInfo});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$NavStateCopyWithImpl<$Res, $Val extends NavState>
|
||||
implements $NavStateCopyWith<$Res> {
|
||||
_$NavStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of NavState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? items = freezed,
|
||||
Object? errorInfo = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
items: freezed == items
|
||||
? _value.items
|
||||
: items // ignore: cast_nullable_to_non_nullable
|
||||
as List<NavApiDocsItemData>?,
|
||||
errorInfo: null == errorInfo
|
||||
? _value.errorInfo
|
||||
: errorInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$NavStateImplCopyWith<$Res>
|
||||
implements $NavStateCopyWith<$Res> {
|
||||
factory _$$NavStateImplCopyWith(
|
||||
_$NavStateImpl value, $Res Function(_$NavStateImpl) then) =
|
||||
__$$NavStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({List<NavApiDocsItemData>? items, String errorInfo});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$NavStateImplCopyWithImpl<$Res>
|
||||
extends _$NavStateCopyWithImpl<$Res, _$NavStateImpl>
|
||||
implements _$$NavStateImplCopyWith<$Res> {
|
||||
__$$NavStateImplCopyWithImpl(
|
||||
_$NavStateImpl _value, $Res Function(_$NavStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of NavState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? items = freezed,
|
||||
Object? errorInfo = null,
|
||||
}) {
|
||||
return _then(_$NavStateImpl(
|
||||
items: freezed == items
|
||||
? _value._items
|
||||
: items // ignore: cast_nullable_to_non_nullable
|
||||
as List<NavApiDocsItemData>?,
|
||||
errorInfo: null == errorInfo
|
||||
? _value.errorInfo
|
||||
: errorInfo // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$NavStateImpl implements _NavState {
|
||||
const _$NavStateImpl(
|
||||
{final List<NavApiDocsItemData>? items, this.errorInfo = ""})
|
||||
: _items = items;
|
||||
|
||||
final List<NavApiDocsItemData>? _items;
|
||||
@override
|
||||
List<NavApiDocsItemData>? get items {
|
||||
final value = _items;
|
||||
if (value == null) return null;
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final String errorInfo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NavState(items: $items, errorInfo: $errorInfo)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$NavStateImpl &&
|
||||
const DeepCollectionEquality().equals(other._items, _items) &&
|
||||
(identical(other.errorInfo, errorInfo) ||
|
||||
other.errorInfo == errorInfo));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, const DeepCollectionEquality().hash(_items), errorInfo);
|
||||
|
||||
/// Create a copy of NavState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$NavStateImplCopyWith<_$NavStateImpl> get copyWith =>
|
||||
__$$NavStateImplCopyWithImpl<_$NavStateImpl>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _NavState implements NavState {
|
||||
const factory _NavState(
|
||||
{final List<NavApiDocsItemData>? items,
|
||||
final String errorInfo}) = _$NavStateImpl;
|
||||
|
||||
@override
|
||||
List<NavApiDocsItemData>? get items;
|
||||
@override
|
||||
String get errorInfo;
|
||||
|
||||
/// Create a copy of NavState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$NavStateImplCopyWith<_$NavStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
24
lib/ui/nav/nav_state.g.dart
Normal file
24
lib/ui/nav/nav_state.g.dart
Normal file
@ -0,0 +1,24 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nav_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$navHash() => r'2019b3f675fbaec4be794049d900bf2dcc8d5e37';
|
||||
|
||||
/// See also [Nav].
|
||||
@ProviderFor(Nav)
|
||||
final navProvider = AutoDisposeNotifierProvider<Nav, NavState>.internal(
|
||||
Nav.new,
|
||||
name: r'navProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$navHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$Nav = AutoDisposeNotifier<NavState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
203
lib/ui/nav/nav_ui.dart
Normal file
203
lib/ui/nav/nav_ui.dart
Normal file
@ -0,0 +1,203 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/gestures.dart' show TapGestureRecognizer;
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:flutter_tilt/flutter_tilt.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/ui/nav/nav_state.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
|
||||
class NavUI extends HookConsumerWidget {
|
||||
const NavUI({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: buildBody(context, ref),
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(children: [
|
||||
TextSpan(text: "*对应链接指向的服务由第三方提供,我们不对其做任何担保,请用户自行判断使用风险 | "),
|
||||
TextSpan(text: "网站导航数据由"),
|
||||
TextSpan(
|
||||
text: " 42kit ",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
launchUrlString("https://42kit.citizenwiki.cn/nav");
|
||||
},
|
||||
),
|
||||
TextSpan(text: "提供"),
|
||||
]),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildBody(BuildContext context, WidgetRef ref) {
|
||||
final data = ref.watch(navProvider);
|
||||
if (data.errorInfo.isNotEmpty) {
|
||||
return Center(
|
||||
child: Text(
|
||||
data.errorInfo,
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.items == null) {
|
||||
return const Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ProgressRing(),
|
||||
SizedBox(height: 12),
|
||||
Text("正在获取数据..."),
|
||||
],
|
||||
));
|
||||
}
|
||||
return MasonryGridView.count(
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
itemCount: data.items!.length,
|
||||
padding: EdgeInsets.only(left: 12, right: 12, bottom: 12),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
const itemHeight = 160.0;
|
||||
|
||||
final item = data.items![index];
|
||||
final itemName = item.name;
|
||||
final itemImage = item.image.url;
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
launchUrlString(item.link);
|
||||
},
|
||||
child: Tilt(
|
||||
shadowConfig: const ShadowConfig(maxIntensity: .3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: SizedBox(
|
||||
height: itemHeight,
|
||||
width: double.infinity,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: CacheNetImage(
|
||||
height: itemHeight,
|
||||
width: double.infinity,
|
||||
url: itemImage,
|
||||
fit: BoxFit.fitWidth,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withValues(alpha: .55),
|
||||
),
|
||||
),
|
||||
ClipRect(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
|
||||
blendMode: BlendMode.srcOver,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: itemHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: CacheNetImage(
|
||||
url: itemImage,
|
||||
height: 48,
|
||||
width: 48,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Flexible(
|
||||
child: Text(
|
||||
itemName,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.abstract_,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .75)),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
for (var value in item.tags)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.withValues(alpha: .6),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
|
||||
margin: EdgeInsets.only(right: 6),
|
||||
child: Text(
|
||||
value.name,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -40,13 +40,9 @@ class ToolsUI extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: state.working
|
||||
? null
|
||||
: () =>
|
||||
model.loadToolsCard(context, skipPathScan: false),
|
||||
onPressed: state.working ? null : () => model.loadToolsCard(context, skipPathScan: false),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 30, bottom: 30, left: 12, right: 12),
|
||||
padding: EdgeInsets.only(top: 30, bottom: 30, left: 12, right: 12),
|
||||
child: Icon(FluentIcons.refresh),
|
||||
),
|
||||
),
|
||||
@ -75,90 +71,86 @@ class ToolsUI extends HookConsumerWidget {
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
itemCount: (state.isItemLoading)
|
||||
? state.items.length + 1
|
||||
: state.items.length,
|
||||
itemCount: (state.isItemLoading) ? state.items.length + 1 : state.items.length,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == state.items.length) {
|
||||
return Container(
|
||||
width: 300,
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: makeLoading(context));
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: Container(
|
||||
width: 300,
|
||||
height: 160,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: makeLoading(context)),
|
||||
);
|
||||
}
|
||||
final item = state.items[index];
|
||||
return Container(
|
||||
width: 300,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Colors.white.withValues(alpha: .2),
|
||||
borderRadius:
|
||||
BorderRadius.circular(1000)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: item.icon,
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: Container(
|
||||
width: 300,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .2),
|
||||
borderRadius: BorderRadius.circular(1000)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: item.icon,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.name,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
)),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
item.infoString,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
Button(
|
||||
onPressed: state.working
|
||||
? null
|
||||
: item.onTap == null
|
||||
? null
|
||||
: () {
|
||||
try {
|
||||
item.onTap?.call();
|
||||
} catch (e) {
|
||||
showToast(
|
||||
context,
|
||||
S.current
|
||||
.tools_info_processing_failed(
|
||||
e));
|
||||
}
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.play),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.name,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
)),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
item.infoString,
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
Button(
|
||||
onPressed: state.working
|
||||
? null
|
||||
: item.onTap == null
|
||||
? null
|
||||
: () {
|
||||
try {
|
||||
item.onTap?.call();
|
||||
} catch (e) {
|
||||
showToast(context, S.current.tools_info_processing_failed(e));
|
||||
}
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.play),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -188,8 +180,7 @@ class ToolsUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeGamePathSelect(
|
||||
BuildContext context, ToolsUIModel model, ToolsUIState state) {
|
||||
Widget makeGamePathSelect(BuildContext context, ToolsUIModel model, ToolsUIState state) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@ -223,8 +214,7 @@ class ToolsUI extends HookConsumerWidget {
|
||||
),
|
||||
onPressed: () {
|
||||
if (state.scInstalledPath.trim().isEmpty) {
|
||||
showToast(context,
|
||||
S.current.tools_action_info_star_citizen_not_found);
|
||||
showToast(context, S.current.tools_action_info_star_citizen_not_found);
|
||||
return;
|
||||
}
|
||||
model.openDir(state.scInstalledPath);
|
||||
@ -233,8 +223,7 @@ class ToolsUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeGameLauncherPathSelect(
|
||||
BuildContext context, ToolsUIModel model, ToolsUIState state) {
|
||||
Widget makeGameLauncherPathSelect(BuildContext context, ToolsUIModel model, ToolsUIState state) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@ -268,10 +257,7 @@ class ToolsUI extends HookConsumerWidget {
|
||||
),
|
||||
onPressed: () {
|
||||
if (state.scInstalledPath.trim().isEmpty) {
|
||||
showToast(
|
||||
context,
|
||||
S.current
|
||||
.tools_rsi_launcher_enhance_msg_error_launcher_notfound);
|
||||
showToast(context, S.current.tools_rsi_launcher_enhance_msg_error_launcher_notfound);
|
||||
return;
|
||||
}
|
||||
model.openDir(state.rsiLauncherInstalledPath);
|
||||
|
@ -6,7 +6,7 @@ part of 'tools_ui_model.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$toolsUIModelHash() => r'cd72f7833fa5696baf9022d16d10d7951387df7e';
|
||||
String _$toolsUIModelHash() => r'c8830e26df6c0ee572dd5e78c4ccef3317f8b4e6';
|
||||
|
||||
/// See also [ToolsUIModel].
|
||||
@ProviderFor(ToolsUIModel)
|
||||
|
Reference in New Issue
Block a user