24 lines
1.2 KiB
TypeScript
24 lines
1.2 KiB
TypeScript
"use client";
|
|
import { useEffect, useState } from "react";
|
|
|
|
type InstallPrompt = Event & { prompt: () => Promise<void>; userChoice: Promise<{ outcome: "accepted" | "dismissed" }> };
|
|
|
|
export default function PwaRegister() {
|
|
const [prompt, setPrompt] = useState<InstallPrompt | null>(null);
|
|
const [isIos, setIsIos] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if ("serviceWorker" in navigator) navigator.serviceWorker.register("/sw.js", { updateViaCache: "none" }).catch(() => undefined);
|
|
setIsIos(/iphone|ipad|ipod/i.test(navigator.userAgent));
|
|
const receivePrompt = (event: Event) => { event.preventDefault(); setPrompt(event as InstallPrompt); };
|
|
window.addEventListener("beforeinstallprompt", receivePrompt);
|
|
return () => window.removeEventListener("beforeinstallprompt", receivePrompt);
|
|
}, []);
|
|
|
|
if (!prompt && !isIos) return null;
|
|
return <div className="pwa-install" role="status">
|
|
<span>把打卡站点安装到桌面,打开更快捷。</span>
|
|
{prompt ? <button onClick={async () => { await prompt.prompt(); const result = await prompt.userChoice; if (result.outcome === "accepted") setPrompt(null); }}>安装应用</button> : <span className="pwa-ios">Safari 点“分享”→“添加到主屏幕”</span>}
|
|
</div>;
|
|
}
|