179 lines
5.4 KiB
Dart
179 lines
5.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../app_upgrade_plugin.dart';
|
|
import '../core/upgrade_utils.dart';
|
|
|
|
/// 下载进度对话框
|
|
class DownloadProgressDialog extends StatefulWidget {
|
|
final String downloadUrl;
|
|
final Color? primaryColor;
|
|
|
|
const DownloadProgressDialog({super.key, required this.downloadUrl, this.primaryColor});
|
|
|
|
/// 显示下载进度对话框
|
|
static Future<String?> show(BuildContext context, {required String downloadUrl, Color? primaryColor}) {
|
|
return showDialog<String?>(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (context) => DownloadProgressDialog(downloadUrl: downloadUrl, primaryColor: primaryColor),
|
|
);
|
|
}
|
|
|
|
@override
|
|
State<DownloadProgressDialog> createState() => _DownloadProgressDialogState();
|
|
}
|
|
|
|
class _DownloadProgressDialogState extends State<DownloadProgressDialog> {
|
|
final AppUpgradePlugin _plugin = AppUpgradePlugin();
|
|
|
|
double _progress = 0.0;
|
|
String _progressText = '准备下载...';
|
|
int _received = 0;
|
|
int _total = 0;
|
|
bool _isDownloading = false;
|
|
String? _errorMessage;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_startDownload();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final primaryColor = widget.primaryColor ?? Theme.of(context).primaryColor;
|
|
|
|
return WillPopScope(
|
|
onWillPop: () async => false,
|
|
child: Dialog(
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
// 图标
|
|
Icon(
|
|
_errorMessage != null ? Icons.error_outline : Icons.download_rounded,
|
|
size: 48,
|
|
color: _errorMessage != null ? Colors.red : primaryColor,
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
// 标题
|
|
Text(
|
|
_errorMessage != null ? '下载失败' : '正在下载更新',
|
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
if (_errorMessage != null) ...[
|
|
// 错误信息
|
|
Text(
|
|
_errorMessage!,
|
|
style: TextStyle(fontSize: 14, color: Colors.grey[600]),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
// 按钮
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop(null);
|
|
},
|
|
child: const Text('取消'),
|
|
),
|
|
),
|
|
const SizedBox(width: 16),
|
|
Expanded(
|
|
child: ElevatedButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
_errorMessage = null;
|
|
_progress = 0.0;
|
|
_progressText = '准备下载...';
|
|
});
|
|
_startDownload();
|
|
},
|
|
style: ElevatedButton.styleFrom(backgroundColor: primaryColor),
|
|
child: const Text('重试'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
] else ...[
|
|
// 进度条
|
|
LinearProgressIndicator(
|
|
value: _isDownloading ? _progress : null,
|
|
backgroundColor: Colors.grey[300],
|
|
valueColor: AlwaysStoppedAnimation<Color>(primaryColor),
|
|
),
|
|
const SizedBox(height: 12),
|
|
|
|
// 进度文本
|
|
Text(_progressText, style: TextStyle(fontSize: 14, color: Colors.grey[600])),
|
|
const SizedBox(height: 8),
|
|
|
|
// 文件大小信息
|
|
if (_total > 0)
|
|
Text(
|
|
'${formatBytes(_received)} / ${formatBytes(_total)}',
|
|
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _startDownload() async {
|
|
setState(() {
|
|
_isDownloading = true;
|
|
_errorMessage = null;
|
|
});
|
|
|
|
try {
|
|
final filePath = await _plugin.downloadApk(
|
|
widget.downloadUrl,
|
|
onProgress: (progress) {
|
|
setState(() {
|
|
_progress = progress.progress;
|
|
_received = progress.received;
|
|
_total = progress.total;
|
|
_progressText = '下载中 ${progress.percentage}%';
|
|
});
|
|
},
|
|
);
|
|
|
|
if (filePath != null) {
|
|
setState(() {
|
|
_progressText = '下载完成';
|
|
});
|
|
|
|
// 延迟一下让用户看到完成状态
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
|
|
// 返回文件路径
|
|
if (mounted) {
|
|
Navigator.of(context).pop(filePath);
|
|
}
|
|
} else {
|
|
setState(() {
|
|
_errorMessage = '下载失败,请检查网络连接';
|
|
_isDownloading = false;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
setState(() {
|
|
_errorMessage = '下载出错:${e.toString()}';
|
|
_isDownloading = false;
|
|
});
|
|
}
|
|
}
|
|
}
|