import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'update_cubit.dart'; import 'update_state.dart'; import 'version_check_service.dart'; /// 更新对话框(带完整流程提示) class UpdateDialog extends StatelessWidget { final AppVersionInfo versionInfo; const UpdateDialog({super.key, required this.versionInfo}); @override Widget build(BuildContext context) { return BlocListener( listener: (context, state) { if (state is UpdateSuccess) { Navigator.of(context).pop(); if (versionInfo.updateType == 'patch') { _showRestartDialog(context); } } else if (state is UpdateFailure) { Navigator.of(context).pop(); String errorMessage = state.error; bool showApkPath = false; String? apkPath; if (errorMessage.contains('APK 文件位于:')) { final parts = errorMessage.split('APK 文件位于:'); if (parts.length > 1) { apkPath = parts[1].trim(); showApkPath = true; errorMessage = '您取消了安装'; } } _showErrorDialog(context, errorMessage, showApkPath: showApkPath, apkPath: apkPath); } }, child: AlertDialog( title: const Text('发现新版本'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('版本号: ${versionInfo.version}'), const SizedBox(height: 8), Text('更新类型: ${versionInfo.updateType == "patch" ? "差量更新" : "整包更新"}'), const SizedBox(height: 8), if (versionInfo.forceUpdate) Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.red.shade50, borderRadius: BorderRadius.circular(4), ), child: const Text( '⚠️ 强制更新', style: TextStyle(color: Colors.red), ), ), const SizedBox(height: 12), const Text('更新内容:', style: TextStyle(fontWeight: FontWeight.bold)), const SizedBox(height: 4), Text(versionInfo.updateDesc.isEmpty ? '优化用户体验,修复已知问题' : versionInfo.updateDesc), ], ), ), actions: [ if (!versionInfo.forceUpdate) TextButton( onPressed: () { context.read().cancelUpdate(); Navigator.of(context).pop(); }, child: const Text('稍后'), ), BlocBuilder( builder: (context, state) { if (state is UpdateDownloading) { return Column( mainAxisSize: MainAxisSize.min, children: [ Text( state.isPatch ? '⬇️ 正在下载补丁...' : '⬇️ 正在下载 APK...', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), SizedBox( width: 60, height: 60, child: Stack( alignment: Alignment.center, children: [ CircularProgressIndicator( value: state.progress, strokeWidth: 3, ), Text('${(state.progress * 100).toInt()}%'), ], ), ), ], ); } else if (state is UpdateClearingVersion) { return const Column( mainAxisSize: MainAxisSize.min, children: [ Text('✅ 版本号清理完成', style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold)), SizedBox(height: 4), Text('正在调起安装页面...', style: TextStyle(fontSize: 12)), SizedBox(height: 8), CircularProgressIndicator(), ], ); } else if (state is UpdateReadyToInstall) { return ElevatedButton.icon( onPressed: () { context.read().triggerInstall(state.apkPath); }, icon: const Icon(Icons.install_mobile), label: const Text('去安装'), ); } else if (state is UpdateInstalling) { return const Column( mainAxisSize: MainAxisSize.min, children: [ Text('📦 正在打开安装页面...', style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold)), SizedBox(height: 4), Text('请在系统安装界面确认安装', style: TextStyle(fontSize: 12)), SizedBox(height: 8), CircularProgressIndicator(), ], ); } else { return ElevatedButton( onPressed: () { if (versionInfo.updateType == 'patch' && versionInfo.patchUrl != null) { context.read().applyPatch( versionInfo.patchUrl!, versionInfo.version, versionInfo.versionCode, md5: versionInfo.patchMd5, ); } else if (versionInfo.apkUrl != null) { context.read().downloadAndInstallApk(versionInfo.apkUrl!); } }, child: const Text('立即更新'), ); } }, ), ], ), ); } void _showRestartDialog(BuildContext context) { showDialog( context: context, barrierDismissible: false, builder: (ctx) => AlertDialog( title: const Text('更新完成'), content: const Text('差量更新已应用,需要重启应用才能生效。\n是否立即重启?'), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), child: const Text('稍后'), ), ElevatedButton( onPressed: () { Navigator.of(ctx).pop(); SystemNavigator.pop(); }, child: const Text('立即重启'), ), ], ), ); } void _showErrorDialog(BuildContext context, String message, {bool showApkPath = false, String? apkPath}) { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('更新提示'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(message), if (showApkPath && apkPath != null) ...[ const SizedBox(height: 12), Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(6), border: Border.all(color: Colors.blue.shade200), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '📁 APK 文件位置', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13), ), const SizedBox(height: 6), Text( apkPath, style: const TextStyle(fontSize: 11, fontFamily: 'monospace'), ), const SizedBox(height: 6), const Text( '您可以到该目录手动点击 APK 文件进行安装', style: TextStyle(fontSize: 11, color: Colors.grey), ), ], ), ), ], ], ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), child: const Text('确定'), ), ], ), ); } } /// 显示整包更新提示(在浏览器中下载) class FullApkUpdateDialog extends StatelessWidget { final AppVersionInfo versionInfo; const FullApkUpdateDialog({super.key, required this.versionInfo}); @override Widget build(BuildContext context) { return AlertDialog( title: const Text('发现新版本'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('版本号: ${versionInfo.version}'), const SizedBox(height: 8), const Text('更新类型: 整包更新'), const SizedBox(height: 12), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.blue.shade200), ), child: const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '📱 整包更新说明', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14), ), SizedBox(height: 8), Text( '• 点击"立即下载"将在浏览器中打开下载链接\n' '• 下载完成后请手动安装 APK\n' '• 安装完成后重启应用即可', style: TextStyle(fontSize: 13, height: 1.5), ), ], ), ), const SizedBox(height: 12), if (versionInfo.updateDesc.isNotEmpty) ...[ const Text('更新内容:', style: TextStyle(fontWeight: FontWeight.bold)), const SizedBox(height: 4), Text(versionInfo.updateDesc), ], ], ), ), actions: [ if (!versionInfo.forceUpdate) TextButton( onPressed: () { context.read().cancelUpdate(); Navigator.of(context).pop(); }, child: const Text('稍后'), ), ElevatedButton( onPressed: () { if (versionInfo.apkUrl != null) { context.read().downloadAndInstallApk(versionInfo.apkUrl!); Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('正在浏览器中打开下载链接...'), duration: Duration(seconds: 2), ), ); } }, child: const Text('立即下载'), ), ], ); } }