feat(pwa): implement PwaUtil class for PWA support and installation checks

This commit is contained in:
2026-06-16 18:59:17 +08:00
parent 8d786f1e04
commit 5be40949a1
2 changed files with 182 additions and 5 deletions
@@ -3,7 +3,8 @@
* PwaInstallOverlay PWA 安装提示触发器
*
* 行为:
* - 检查 PWA 支持
* - 检查 PWA 支持pwaUtil.isSupported
* - 检查 PWA 是否已安装(pwaUtil.isInstalled)—— 已安装则不弹
* - 检查每日是否已显示(使用 AppStorage 持久化)
* - 延迟 3.5s 后弹出 PwaInstallDialog
* - 生产环境有效;开发环境 1s 后立即弹出(测试用)
@@ -14,6 +15,7 @@
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";
@@ -25,16 +27,18 @@ export function PwaInstallOverlay() {
let mounted = true;
const init = async () => {
// 0) PWA 支持 / 安装 双重门禁:
// isSupported() 检查 serviceWorker + windowSSR 安全)
// 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; // 今天已显示过
// 检查 PWA 支持
if (typeof window === "undefined") return;
if (!("serviceWorker" in navigator)) return;
// 延迟 3.5s 后显示
setTimeout(() => {
if (!mounted) return;