import 'package:flutter/material.dart'; import '../../data/models/app_update_model.dart'; import '../../services/update_service.dart'; import 'toast_helper.dart'; class UpdatePrompt extends StatefulWidget { final Widget child; const UpdatePrompt({super.key, required this.child}); @override State createState() => _UpdatePromptState(); } class _UpdatePromptState extends State { static bool _checkedThisRun = false; bool _dialogVisible = false; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) => _checkUpdate()); } Future _checkUpdate() async { if (_checkedThisRun || _dialogVisible || !mounted) return; _checkedThisRun = true; final update = await UpdateService.instance.checkForUpdate(); if (update == null || !mounted) return; final shouldShow = await UpdateService.instance.shouldShowPrompt(update); if (!shouldShow || !mounted) return; _dialogVisible = true; try { await _showUpdateDialog(update); } finally { _dialogVisible = false; } } Future _showUpdateDialog(AppUpdateInfo update) async { await showDialog( context: context, barrierDismissible: false, builder: (dialogContext) { Future openDownloadsPage() async { try { await UpdateService.instance.openDownloadsPage(); if (dialogContext.mounted) Navigator.of(dialogContext).pop(); } catch (e) { ToastHelper.failure('打开下载页面失败: $e'); } } Future skipPrompt() async { await UpdateService.instance.skipPromptForFiveDays(update); if (dialogContext.mounted) Navigator.of(dialogContext).pop(); } final releaseNotes = (update.description ?? '').trim(); return AlertDialog( title: Text('发现新版本 ${update.version}'), content: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420, maxHeight: 360), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('新版本号:${update.version}'), const SizedBox(height: 12), Text( '版本日志', style: Theme.of(dialogContext).textTheme.titleSmall, ), const SizedBox(height: 6), Text(releaseNotes.isEmpty ? update.title : releaseNotes), ], ), ), ), actions: [ TextButton(onPressed: skipPrompt, child: const Text('跳过')), TextButton( onPressed: () => Navigator.of(dialogContext).pop(), child: const Text('取消'), ), FilledButton(onPressed: openDownloadsPage, child: const Text('更新')), ], ); }, ); } @override Widget build(BuildContext context) => widget.child; }