78 lines
2.5 KiB
Dart
78 lines
2.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
/// 强制更新页:检测到新版本时的全屏阻塞页。
|
|
/// PopScope 禁返回(Android 系统返回 / iOS 边缘滑动均不可退出),
|
|
/// 仅「立即更新」跳转系统浏览器下载 APK。
|
|
/// 点击更新时回调 onUpdateAccepted(调用方持久化服务器版本号,
|
|
/// 使 APK 版本号不递增时也不反复提示)。
|
|
class UpdateScreen extends StatelessWidget {
|
|
final String version;
|
|
final String url;
|
|
final String notes;
|
|
final VoidCallback? onUpdateAccepted;
|
|
|
|
const UpdateScreen({
|
|
super.key,
|
|
required this.version,
|
|
required this.url,
|
|
this.notes = '',
|
|
this.onUpdateAccepted,
|
|
});
|
|
|
|
Future<void> _launch() async {
|
|
onUpdateAccepted?.call();
|
|
final uri = Uri.tryParse(url);
|
|
if (uri == null) return;
|
|
try {
|
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
|
} catch (_) {
|
|
// 跳转失败保持页面,用户可重试
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
return PopScope(
|
|
canPop: false,
|
|
child: Scaffold(
|
|
body: Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(32),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.system_update_alt,
|
|
size: 64, color: theme.colorScheme.primary),
|
|
const SizedBox(height: 16),
|
|
Text('发现新版本 $version',
|
|
style: theme.textTheme.headlineSmall),
|
|
const SizedBox(height: 12),
|
|
if (notes.isNotEmpty)
|
|
Text(notes,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(height: 1.6)),
|
|
const SizedBox(height: 24),
|
|
FilledButton.icon(
|
|
onPressed: _launch,
|
|
icon: const Icon(Icons.download),
|
|
label: const Text('立即更新'),
|
|
style: FilledButton.styleFrom(
|
|
minimumSize: const Size(200, 48),
|
|
textStyle: const TextStyle(fontSize: 16),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
Text('不更新将无法继续使用',
|
|
style: theme.textTheme.bodySmall
|
|
?.copyWith(color: theme.colorScheme.error)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|