yx_app_upgrade_flutter/lib/widgets/upgrade_dialog.dart

196 lines
6.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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));
}
}