import 'dart:io'; import 'package:flutter/material.dart'; import '../app_upgrade_plugin.dart'; import '../core/upgrade_utils.dart'; /// App升级对话框 class UpgradeDialog extends StatefulWidget { final UpgradeInfo upgradeInfo; final VoidCallback? onCancel; final VoidCallback? onConfirm; final Color? primaryColor; const UpgradeDialog({super.key, required this.upgradeInfo, this.onCancel, this.onConfirm, this.primaryColor}); /// 显示升级对话框 static Future show(BuildContext context, {required UpgradeInfo upgradeInfo, Color? primaryColor}) { return showDialog( context: context, barrierDismissible: !upgradeInfo.isForceUpdate, builder: (BuildContext context) { return UpgradeDialog( upgradeInfo: upgradeInfo, primaryColor: primaryColor, ); }, ); } @override State createState() => _UpgradeDialogState(); } class _UpgradeDialogState extends State { final AppUpgradePlugin _plugin = AppUpgradePlugin(); bool _isDownloading = false; @override Widget build(BuildContext context) { final primaryColor = widget.primaryColor ?? Theme.of(context).primaryColor; return WillPopScope( onWillPop: () async => !widget.upgradeInfo.isForceUpdate && !_isDownloading, child: Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 顶部图片或图标 Container( height: 120, decoration: BoxDecoration( color: primaryColor, borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), ), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.system_update, size: 48, color: Colors.white), const SizedBox(height: 8), Text( '发现新版本 ${widget.upgradeInfo.versionName}', style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold), ), ], ), ), ), // 更新内容 Container( padding: const EdgeInsets.all(16), constraints: const BoxConstraints(maxHeight: 200), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('更新内容:', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)), const SizedBox(height: 8), Text(widget.upgradeInfo.updateContent, style: const TextStyle(fontSize: 14, height: 1.5)), ], ), ), ), // 文件大小提示(如果有) if (widget.upgradeInfo.apkSize != null && Platform.isAndroid) Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( '新版本大小:${formatBytes(widget.upgradeInfo.apkSize!)}', style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ), const SizedBox(height: 16), // 按钮 Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ if (!widget.upgradeInfo.isForceUpdate) ...[ Expanded( child: TextButton( onPressed: _isDownloading ? null : () { widget.onCancel?.call(); Navigator.of(context).pop(false); }, child: Text('稍后更新', style: TextStyle(color: Colors.grey[600])), ), ), const SizedBox(width: 16), ], Expanded( child: ElevatedButton( onPressed: _isDownloading ? null : () => _handleConfirm(), style: ElevatedButton.styleFrom( backgroundColor: primaryColor, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), ), child: const Text('立即更新'), ), ), ], ), ), const SizedBox(height: 8), ], ), ), ); } void _handleConfirm() async { widget.onConfirm?.call(); if (Platform.isAndroid) { // Android平台:下载并安装APK if (widget.upgradeInfo.downloadUrl != null) { setState(() { _isDownloading = true; }); // 显示下载进度对话框 final filePath = await DownloadProgressDialog.show( context, downloadUrl: widget.upgradeInfo.downloadUrl!, primaryColor: widget.primaryColor, ); setState(() { _isDownloading = false; }); if (filePath != null) { // 安装前再次检查并请求权限 final hasInstallPermission = await PermissionHelper.checkAndRequestInstallPermission(context: context); if (!hasInstallPermission) { _showError('未授予安装权限,无法完成更新'); return; } // 安装APK final success = await _plugin.installApk(filePath); if (success) { if (!widget.upgradeInfo.isForceUpdate) { Navigator.of(context).pop(true); } } else { _showError('安装失败,请检查权限设置'); } } } } else if (Platform.isIOS) { // iOS平台:跳转到App Store if (widget.upgradeInfo.appStoreUrl != null) { final success = await _plugin.goToAppStore(widget.upgradeInfo.appStoreUrl!); if (success) { Navigator.of(context).pop(true); } else { _showError('跳转App Store失败'); } } } } void _showError(String message) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message), backgroundColor: Colors.red)); } }