From afee4b5aec54bd30c0c9951cb17417efa2f1bd6f Mon Sep 17 00:00:00 2001 From: jingyun <> Date: Tue, 1 Sep 2026 15:03:27 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E6=8E=A8=E9=80=81=E6=9D=83?= =?UTF-8?q?=E9=99=90=E5=BC=B9=E7=AA=97=E6=97=B6=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/push/notification_permission.dart | 10 +++++++-- .../widgets/notification_permission_tip.dart | 22 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/common/push/notification_permission.dart b/lib/common/push/notification_permission.dart index a3933da..ceda7ae 100644 --- a/lib/common/push/notification_permission.dart +++ b/lib/common/push/notification_permission.dart @@ -23,9 +23,15 @@ abstract final class NotificationPermission { return isGranted(); } if (await isGranted() || !context.mounted) return true; - await showNotificationPermissionTip(context); + final tip = showNotificationPermissionTip(context); await StorageService.to.setBool(storagePushPermissionPrompted, true); - return (await Permission.notification.request()).isGranted; + try { + // Match the legacy app's persistent top snackbar: keep the in-app + // explanation on screen until the system authorization dialog closes. + return (await Permission.notification.request()).isGranted; + } finally { + tip.remove(); + } } /// 设置页不使用顶部说明;iOS/Android 都直接请求系统授权。 diff --git a/lib/common/widgets/notification_permission_tip.dart b/lib/common/widgets/notification_permission_tip.dart index ca292d7..dd824e9 100644 --- a/lib/common/widgets/notification_permission_tip.dart +++ b/lib/common/widgets/notification_permission_tip.dart @@ -73,10 +73,26 @@ class NotificationPermissionTip extends StatelessWidget { } } -Future showNotificationPermissionTip(BuildContext context) async { +/// Keeps the explanation visible while Android's system permission dialog is +/// presented. Call [remove] after the permission request completes. +NotificationPermissionTipHandle showNotificationPermissionTip( + BuildContext context, +) { final overlay = Overlay.of(context, rootOverlay: true); final entry = OverlayEntry(builder: (_) => const NotificationPermissionTip()); overlay.insert(entry); - await Future.delayed(const Duration(milliseconds: 500)); - entry.remove(); + return NotificationPermissionTipHandle._(entry); +} + +class NotificationPermissionTipHandle { + NotificationPermissionTipHandle._(this._entry); + + final OverlayEntry _entry; + bool _isRemoved = false; + + void remove() { + if (_isRemoved) return; + _isRemoved = true; + _entry.remove(); + } }