fix(mobile-app): 升级弹窗禁止点击外部或返回键关闭,必须通过按钮操作

问题:
检测到新版本弹出升级对话框时,用户点击弹窗外部区域或按系统返回键
即可直接关闭弹窗,绕过升级提示,导致用户可能永远不会注意到更新。

修复:
对所有 3 个升级弹窗统一加两层防护:
- barrierDismissible: false — 禁止点击弹窗外部区域关闭
- PopScope(canPop: false) — 禁止系统返回键关闭

涉及弹窗:
1. self_hosted_updater.dart - _showSelfHostedUpdateDialog(自建APK更新)
2. self_hosted_updater.dart - _showMarketUpdateDialog(应用市场引导更新)
3. update_service.dart - _checkGooglePlayUpdate(Google Play 更新)

用户必须通过弹窗内按钮操作:
- 非强制更新:点击「稍后」/「暂时不更新」关闭,或点击「立即更新」开始更新
- 强制更新:只有「立即更新」按钮,无法跳过

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-25 08:01:52 -08:00
parent 8f8a9230d0
commit e02bcf418c
2 changed files with 45 additions and 41 deletions

View File

@ -51,9 +51,9 @@ class SelfHostedUpdater {
void _showMarketUpdateDialog(BuildContext context, VersionInfo versionInfo) { void _showMarketUpdateDialog(BuildContext context, VersionInfo versionInfo) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: !versionInfo.forceUpdate, barrierDismissible: false,
builder: (context) => PopScope( builder: (context) => PopScope(
canPop: !versionInfo.forceUpdate, canPop: false,
child: AlertDialog( child: AlertDialog(
title: Text( title: Text(
versionInfo.forceUpdate ? '发现重要更新' : '发现新版本', versionInfo.forceUpdate ? '发现重要更新' : '发现新版本',
@ -144,9 +144,9 @@ class SelfHostedUpdater {
BuildContext context, VersionInfo versionInfo) { BuildContext context, VersionInfo versionInfo) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: !versionInfo.forceUpdate, barrierDismissible: false,
builder: (context) => PopScope( builder: (context) => PopScope(
canPop: !versionInfo.forceUpdate, canPop: false,
child: AlertDialog( child: AlertDialog(
title: Text( title: Text(
versionInfo.forceUpdate ? '发现重要更新' : '发现新版本', versionInfo.forceUpdate ? '发现重要更新' : '发现新版本',

View File

@ -110,48 +110,52 @@ class UpdateService {
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => AlertDialog( barrierDismissible: false,
title: Text( builder: (context) => PopScope(
'发现新版本', canPop: false,
style: TextStyle( child: AlertDialog(
fontSize: 18.sp, title: Text(
fontWeight: FontWeight.w600, '发现新版本',
color: const Color(0xFF292524), style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w600,
color: const Color(0xFF292524),
),
), ),
), content: Text(
content: Text( '有新版本可用,是否立即更新?',
'有新版本可用,是否立即更新?', style: TextStyle(
style: TextStyle( fontSize: 14.sp,
fontSize: 14.sp, color: const Color(0xFF57534E),
color: const Color(0xFF57534E), ),
), ),
), actions: [
actions: [ 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), ),
), ),
), ),
), ElevatedButton(
ElevatedButton( onPressed: () {
onPressed: () { Navigator.pop(context);
Navigator.pop(context); GooglePlayUpdater.performFlexibleUpdate();
GooglePlayUpdater.performFlexibleUpdate(); },
}, style: ElevatedButton.styleFrom(
style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFD4A84B),
backgroundColor: const Color(0xFFD4A84B), foregroundColor: Colors.white,
foregroundColor: Colors.white, ),
child: Text(
'更新',
style: TextStyle(fontSize: 14.sp),
),
), ),
child: Text( ],
'更新', ),
style: TextStyle(fontSize: 14.sp),
),
),
],
), ),
); );
} }