完善PR审查后出现的问题
This commit is contained in:
@@ -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 作为备用查询。',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user