完善PR审查后出现的问题

This commit is contained in:
2026-05-31 10:13:36 +08:00
parent 61ad85f6fc
commit 5ee6ba1e28
4 changed files with 161 additions and 50 deletions
@@ -167,9 +167,8 @@ class _SettingsPageState extends State<SettingsPage> {
subtitle: const Text('gongyun_app'),
trailing: const Icon(Icons.open_in_new, size: 16),
onTap: () {
launchUrl(
_openExternalUrl(
Uri.parse('https://git.saont.net/gongyun/app'),
mode: LaunchMode.externalApplication,
);
},
),
@@ -179,11 +178,10 @@ class _SettingsPageState extends State<SettingsPage> {
subtitle: const Text('cloudreve4_flutter'),
trailing: const Icon(Icons.open_in_new, size: 16),
onTap: () {
launchUrl(
_openExternalUrl(
Uri.parse(
'https://github.com/LimoYuan/cloudreve4_flutter',
),
mode: LaunchMode.externalApplication,
);
},
),
@@ -405,13 +403,16 @@ class _SettingsPageState extends State<SettingsPage> {
return AnimatedBuilder(
animation: UpdateService.instance,
builder: (context, _) {
final hasUpdate = UpdateService.instance.hasUpdate;
return ListTile(
leading: const Icon(Icons.tag),
leading: Icon(
hasUpdate ? Icons.new_releases_outlined : Icons.tag,
color: hasUpdate ? Theme.of(context).colorScheme.primary : null,
),
title: const Text('版本号'),
subtitle: Text(_appVersion.isEmpty ? '加载中...' : _appVersion),
trailing: UpdateService.instance.hasUpdate
? const _BlinkingUpdateDot()
: null,
onTap: hasUpdate ? () => _openDownloadsPage() : null,
trailing: hasUpdate ? const _UpdateAvailableBadge() : null,
);
},
);
@@ -562,6 +563,25 @@ class _SettingsPageState extends State<SettingsPage> {
}
}
Future<void> _openExternalUrl(Uri uri) async {
try {
final opened = await launchUrl(uri, mode: LaunchMode.externalApplication);
if (!opened) {
ToastHelper.failure('无法打开链接: $uri');
}
} catch (e) {
ToastHelper.failure('无法打开链接: $e');
}
}
Future<void> _openDownloadsPage() async {
try {
await UpdateService.instance.openDownloadsPage();
} catch (e) {
ToastHelper.failure('打开下载页面失败: $e');
}
}
Future<void> _openNetworkTest(BuildContext context) async {
final agreed = await showDialog<bool>(
context: context,
@@ -569,13 +589,11 @@ class _SettingsPageState extends State<SettingsPage> {
builder: (dialogContext) => AlertDialog(
title: const Text('会话信息授权'),
content: _NetworkTestConsentText(
onOpenPrivacy: () => launchUrl(
onOpenPrivacy: () => _openExternalUrl(
Uri.parse('https://www.gongyun.org/policy/privacy.html'),
mode: LaunchMode.externalApplication,
),
onOpenTerms: () => launchUrl(
onOpenTerms: () => _openExternalUrl(
Uri.parse('https://www.gongyun.org/policy/terms.html'),
mode: LaunchMode.externalApplication,
),
),
actions: [
@@ -641,14 +659,14 @@ class _SettingsPageState extends State<SettingsPage> {
}
}
class _BlinkingUpdateDot extends StatefulWidget {
const _BlinkingUpdateDot();
class _UpdateAvailableBadge extends StatefulWidget {
const _UpdateAvailableBadge();
@override
State<_BlinkingUpdateDot> createState() => _BlinkingUpdateDotState();
State<_UpdateAvailableBadge> createState() => _UpdateAvailableBadgeState();
}
class _BlinkingUpdateDotState extends State<_BlinkingUpdateDot>
class _UpdateAvailableBadgeState extends State<_UpdateAvailableBadge>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _opacity;
@@ -674,15 +692,31 @@ class _BlinkingUpdateDotState extends State<_BlinkingUpdateDot>
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return FadeTransition(
opacity: _opacity,
child: Container(
width: 10,
height: 10,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: colorScheme.error,
shape: BoxShape.circle,
),
),
const SizedBox(width: 6),
Text(
'发现新版本',
style: TextStyle(
color: colorScheme.error,
fontWeight: FontWeight.w700,
),
),
const SizedBox(width: 4),
Icon(Icons.chevron_right, size: 18, color: colorScheme.error),
],
),
);
}
@@ -734,9 +768,8 @@ class _NetworkTestConsentTextState extends State<_NetworkTestConsentText> {
fontWeight: FontWeight.w700,
);
return RichText(
text: TextSpan(
style: Theme.of(context).textTheme.bodyMedium,
return Text.rich(
TextSpan(
children: [
const TextSpan(text: '您需同意'),
TextSpan(
@@ -750,7 +783,10 @@ class _NetworkTestConsentTextState extends State<_NetworkTestConsentText> {
style: linkStyle,
recognizer: _termsRecognizer,
),
const TextSpan(text: '方可进入网络测试页。'),
const TextSpan(
text:
'方可进入网络测试页。测试会访问公云存储服务,并通过第三方服务 ipwho.is 查询当前网络 IP、AS 与运营商信息;如 ipwho.is 不可用,将使用 ipapi.co 作为备用查询。',
),
],
),
);