From d6f2cb7c5695b3d9d02f4df728527ad67eb11850 Mon Sep 17 00:00:00 2001 From: chenhang Date: Tue, 16 Jun 2026 19:05:50 +0800 Subject: [PATCH] fix(pwa): enhance PWA install overlay logic for daily display limits and environment handling --- .../chat/components/pwa-install-overlay.tsx | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/app/chat/components/pwa-install-overlay.tsx b/src/app/chat/components/pwa-install-overlay.tsx index 3cbac902..b7b32616 100644 --- a/src/app/chat/components/pwa-install-overlay.tsx +++ b/src/app/chat/components/pwa-install-overlay.tsx @@ -27,23 +27,29 @@ export function PwaInstallOverlay() { let mounted = true; const init = async () => { - // 0) PWA 支持 / 安装 双重门禁: + // 0) PWA 支持 / 安装 双重门禁(两种环境都检查): // isSupported() 检查 serviceWorker + window(SSR 安全) // isInstalled() 检查 standalone display-mode(避免给已安装用户再弹) if (!pwaUtil.isSupported()) return; if (pwaUtil.isInstalled()) return; - // 检查每日是否已显示 - const lastResult = await SpAsyncUtil.getString(PWA_DIALOG_KEY); - if (!lastResult.success) return; - const today = new Date().toISOString().slice(0, 10); - if (lastResult.data === today) return; // 今天已显示过 + const isDev = process.env.NODE_ENV === "development"; - // 延迟 3.5s 后显示 + if (!isDev) { + // 生产环境:每日只弹一次(防骚扰) + const lastResult = await SpAsyncUtil.getString(PWA_DIALOG_KEY); + if (!lastResult.success) return; + const today = new Date().toISOString().slice(0, 10); + if (lastResult.data === today) return; // 今天已显示过 + } + // 开发环境:跳过"每日一次"门禁,每次进入都弹,方便 UI 测试 + + // 开发环境 1s 后弹(快);生产环境 3.5s 后弹(让用户先看到聊天内容) + const delay = isDev ? 1000 : 3500; setTimeout(() => { if (!mounted) return; showPwaDialog(); - }, 3500); + }, delay); }; void init(); @@ -84,6 +90,16 @@ function PwaInstallDialogMount({ reactRoot.unmount(); rootEl.remove(); }} + onInstall={async () => { + // 走 pwaUtil.install(): + // - 挂 beforeinstallprompt 监听(如未挂) + // - 等待 deferred 事件 ready(3s 超时) + // - 调浏览器原生 prompt + // - 返 "accepted" / "dismissed" / "unavailable" + // 当前不消费返回值 —— 用户已经看到 dialog 点了 OK,是否真装上是浏览器的事。 + // 后续可在此接 metrics 上报(pwa_accepted / pwa_dismissed / pwa_unavailable)。 + void pwaUtil.install(); + }} /> ); }