fix(pwa): tighten install support detection

This commit is contained in:
2026-07-04 11:18:01 +08:00
parent f470119a1b
commit 82ac9e86a5
5 changed files with 301 additions and 73 deletions
+22 -14
View File
@@ -19,7 +19,7 @@ import {
canShowPwaInstallPromptOnce,
recordPwaInstallPromptShown,
} from "@/lib/chat/pwa_install_prompt";
import { BrowserDetector, pwaUtil } from "@/utils";
import { pwaUtil } from "@/utils";
import { PwaInstallDialog } from "./pwa-install-dialog";
import styles from "./pwa-install-overlay.module.css";
@@ -37,29 +37,39 @@ export function PwaInstallOverlay({ enabled }: PwaInstallOverlayProps) {
let mounted = true;
let timer: number | undefined;
let unsubscribe: (() => void) | undefined;
const init = async () => {
// const isDev = AppEnvUtil.isDevelopment();
const isDev = false;
const shouldShowDialog = await shouldShowPwaInstallDialog(isDev);
if (!shouldShowDialog) return;
// 提前挂 beforeinstallprompt 监听,避免用户点 OK 时事件已在更早时机丢失。
pwaUtil.prepareInstallPrompt();
// 达到聊天数量阈值后稍作停顿,避免弹窗与消息刷新挤在同一瞬间。
const delay = isDev
? DEVELOPMENT_DIALOG_DELAY_MS
: PRODUCTION_DIALOG_DELAY_MS;
timer = window.setTimeout(() => {
if (!mounted) return;
showPwaDialog();
}, delay);
const tryScheduleDialog = async () => {
const shouldShowDialog = await shouldShowPwaInstallDialog(isDev);
if (!mounted || !shouldShowDialog || timer !== undefined) return;
// 达到聊天数量阈值后稍作停顿,避免弹窗与消息刷新挤在同一瞬间。
const delay = isDev
? DEVELOPMENT_DIALOG_DELAY_MS
: PRODUCTION_DIALOG_DELAY_MS;
timer = window.setTimeout(() => {
if (!mounted) return;
showPwaDialog();
}, delay);
};
await tryScheduleDialog();
unsubscribe = pwaUtil.subscribe(() => {
void tryScheduleDialog();
});
};
void init();
return () => {
mounted = false;
unsubscribe?.();
if (timer !== undefined) window.clearTimeout(timer);
};
}, [enabled]);
@@ -69,9 +79,7 @@ export function PwaInstallOverlay({ enabled }: PwaInstallOverlayProps) {
async function shouldShowPwaInstallDialog(isDevelopment: boolean) {
// PWA 支持 / 安装 双重门禁(两种环境都检查)。
if (!pwaUtil.isSupported()) return false;
if (pwaUtil.isInstalled()) return false;
if (BrowserDetector.isInAppBrowser()) return false;
if (!pwaUtil.canShowInstallEntry()) return false;
// 开发环境:跳过"只弹一次"门禁,每次进入都弹,方便 UI 测试。
if (isDevelopment) return true;