"use client"; /** * PwaInstallOverlay PWA 安装提示触发器 * * 行为: * - 检查 PWA 支持(pwaUtil.isSupported) * - 检查 PWA 是否已安装(pwaUtil.isInstalled)—— 已安装则不弹 * - 检查每日是否已显示(使用 AppStorage 持久化) * - 延迟 3.5s 后弹出 PwaInstallDialog * - 生产环境有效;开发环境 1s 后立即弹出(测试用) * * 注意:PWA install prompt API(`beforeinstallprompt`)在浏览器差异较大, * 本轮仅实现"显示时机"逻辑,具体 install prompt 调用由 Dialog 内部处理。 */ import { useEffect } from "react"; import { SpAsyncUtil } from "@/utils/storage"; import { pwaUtil } from "@/utils/pwa"; import { PwaInstallDialog } from "./pwa-install-dialog"; import styles from "./pwa-install-overlay.module.css"; const PWA_DIALOG_KEY = "cozsweet:lastPwaDialogShown"; export function PwaInstallOverlay() { useEffect(() => { let mounted = true; const init = async () => { // 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; // 今天已显示过 // 延迟 3.5s 后显示 setTimeout(() => { if (!mounted) return; showPwaDialog(); }, 3500); }; void init(); return () => { mounted = false; }; }, []); return
; } function showPwaDialog() { if (typeof document === "undefined") return; // 记录显示时间 const today = new Date().toISOString().slice(0, 10); void SpAsyncUtil.setString(PWA_DIALOG_KEY, today); // 创建挂载点 const root = document.createElement("div"); document.body.appendChild(root); // 用 React DOM 渲染(通过 import) import("react-dom/client").then(({ createRoot }) => { const reactRoot = createRoot(root); reactRoot.render(