feat(mobile-app): 非强制更新时下载完成后让用户选择是否安装
- 强制更新:下载完成后自动安装 - 非强制更新:下载完成后显示"稍后安装"和"立即安装"按钮 - 更新提示对话框中"稍后"改为"暂时不更新" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
fe593714ae
commit
9c7dc6f511
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import '../version_checker.dart';
|
import '../version_checker.dart';
|
||||||
|
|
@ -202,7 +203,7 @@ class SelfHostedUpdater {
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
child: Text(
|
child: Text(
|
||||||
'稍后',
|
'暂时不更新',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.sp,
|
fontSize: 14.sp,
|
||||||
color: const Color(0xFF78716C),
|
color: const Color(0xFF78716C),
|
||||||
|
|
@ -240,6 +241,7 @@ class SelfHostedUpdater {
|
||||||
builder: (context) => _DownloadProgressDialog(
|
builder: (context) => _DownloadProgressDialog(
|
||||||
versionInfo: versionInfo,
|
versionInfo: versionInfo,
|
||||||
downloadManager: downloadManager,
|
downloadManager: downloadManager,
|
||||||
|
forceUpdate: versionInfo.forceUpdate,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -254,10 +256,12 @@ class SelfHostedUpdater {
|
||||||
class _DownloadProgressDialog extends StatefulWidget {
|
class _DownloadProgressDialog extends StatefulWidget {
|
||||||
final VersionInfo versionInfo;
|
final VersionInfo versionInfo;
|
||||||
final DownloadManager downloadManager;
|
final DownloadManager downloadManager;
|
||||||
|
final bool forceUpdate;
|
||||||
|
|
||||||
const _DownloadProgressDialog({
|
const _DownloadProgressDialog({
|
||||||
required this.versionInfo,
|
required this.versionInfo,
|
||||||
required this.downloadManager,
|
required this.downloadManager,
|
||||||
|
required this.forceUpdate,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -270,6 +274,8 @@ class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
|
||||||
String _statusText = '准备下载...';
|
String _statusText = '准备下载...';
|
||||||
bool _isDownloading = true;
|
bool _isDownloading = true;
|
||||||
bool _hasError = false;
|
bool _hasError = false;
|
||||||
|
bool _downloadCompleted = false;
|
||||||
|
File? _downloadedApkFile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -282,6 +288,7 @@ class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
|
||||||
_statusText = '正在下载...';
|
_statusText = '正在下载...';
|
||||||
_isDownloading = true;
|
_isDownloading = true;
|
||||||
_hasError = false;
|
_hasError = false;
|
||||||
|
_downloadCompleted = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
final apkFile = await widget.downloadManager.downloadApk(
|
final apkFile = await widget.downloadManager.downloadApk(
|
||||||
|
|
@ -312,13 +319,34 @@ class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_downloadedApkFile = apkFile;
|
||||||
|
|
||||||
|
// 强制更新:直接安装
|
||||||
|
// 非强制更新:显示完成状态,让用户选择
|
||||||
|
if (widget.forceUpdate) {
|
||||||
|
setState(() {
|
||||||
|
_statusText = '下载完成,准备安装...';
|
||||||
|
});
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
await _installApk();
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_statusText = '下载完成';
|
||||||
|
_isDownloading = false;
|
||||||
|
_downloadCompleted = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _installApk() async {
|
||||||
|
if (_downloadedApkFile == null) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_statusText = '下载完成,准备安装...';
|
_statusText = '正在安装...';
|
||||||
|
_isDownloading = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
final installed = await ApkInstaller.installApk(_downloadedApkFile!);
|
||||||
|
|
||||||
final installed = await ApkInstaller.installApk(apkFile);
|
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
|
|
@ -344,11 +372,20 @@ class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
String title;
|
||||||
|
if (_downloadCompleted && !_hasError) {
|
||||||
|
title = '下载完成';
|
||||||
|
} else if (_hasError) {
|
||||||
|
title = '更新失败';
|
||||||
|
} else {
|
||||||
|
title = '正在更新';
|
||||||
|
}
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: !_isDownloading,
|
canPop: !_isDownloading && !widget.forceUpdate,
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
title: Text(
|
title: Text(
|
||||||
'正在更新',
|
title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18.sp,
|
fontSize: 18.sp,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|
@ -423,6 +460,30 @@ class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
// 非强制更新,下载完成后显示选择按钮
|
||||||
|
if (_downloadCompleted && !_hasError) ...[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(
|
||||||
|
'稍后安装',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: const Color(0xFF78716C),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _installApk,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFFD4A84B),
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'立即安装',
|
||||||
|
style: TextStyle(fontSize: 14.sp),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue