196 lines
6.5 KiB
Dart
196 lines
6.5 KiB
Dart
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<bool?> show(BuildContext context, {required UpgradeInfo upgradeInfo, Color? primaryColor}) {
|
||
return showDialog<bool>(
|
||
context: context,
|
||
barrierDismissible: !upgradeInfo.isForceUpdate,
|
||
builder: (BuildContext context) {
|
||
return UpgradeDialog(
|
||
upgradeInfo: upgradeInfo,
|
||
primaryColor: primaryColor,
|
||
);
|
||
},
|
||
);
|
||
}
|
||
|
||
@override
|
||
State<UpgradeDialog> createState() => _UpgradeDialogState();
|
||
}
|
||
|
||
class _UpgradeDialogState extends State<UpgradeDialog> {
|
||
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));
|
||
}
|
||
}
|