import 'package:flutter/material.dart'; import '../../providers/update_provider.dart'; import '../../widgets/ds/ds_atoms.dart'; import 'app_updater_io.dart' if (dart.library.js_interop) 'app_updater_web.dart' as impl; /// 应用内更新统一入口。 /// - Web:刷新页面。 /// - Windows/macOS:应用内下载安装包并自动安装/重启(带进度对话框)。 /// - 其它平台 / 无对应下载地址:回退浏览器下载(launchUpdateUrl)。 Future startInAppUpdate(BuildContext context, AppUpdateInfo info) async { if (impl.isWeb) { impl.reloadForUpdate(); return; } final url = impl.platformDownloadUrl(info.downloadUrls); if (!impl.isInAppSupported || url == null || url.isEmpty) { await launchUpdateUrl(info.downloadUrls); // 兜底:开浏览器/商店 return; } await _runWithProgress(context, info, url); } Future _runWithProgress( BuildContext context, AppUpdateInfo info, String url) async { final progress = ValueNotifier(0); // 不可关闭的进度对话框;下载完成后 impl 会让进程退出。 showDialog( context: context, barrierDismissible: false, builder: (_) => PopScope( canPop: false, child: AlertDialog( title: Text('正在更新到 v${info.latestVersion}'), content: ValueListenableBuilder( valueListenable: progress, builder: (_, p, __) => Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ LinearProgressIndicator(value: p > 0 ? p : null), const SizedBox(height: 12), Text(p >= 1 ? '下载完成,正在安装,应用即将重启…' : '正在下载… ${(p * 100).toStringAsFixed(0)}%'), ], ), ), ), ), ); try { await impl.downloadAndInstall(url, (p) => progress.value = p); // 桌面端到此通常已 exit(0),不会继续执行。 } catch (e) { if (!context.mounted) return; Navigator.of(context, rootNavigator: true).pop(); // 关进度对话框 if (!context.mounted) return; showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('更新失败'), content: Text('$e\n\n可改用浏览器下载更新。'), actions: [ DsButton('取消', onPressed: () => Navigator.pop(ctx)), DsButton('浏览器下载', variant: DsBtnVariant.primary, onPressed: () { Navigator.pop(ctx); launchUpdateUrl(info.downloadUrls); }), ], ), ); } finally { progress.dispose(); } }