mirror of
https://github.com/fccview/cronmaster.git
synced 2026-01-03 11:29:06 -05:00
59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
|
|
type BeforeInstallPromptEvent = Event & {
|
|
prompt: () => Promise<void>;
|
|
userChoice: Promise<{ outcome: "accepted" | "dismissed" }>;
|
|
};
|
|
|
|
export const PWAInstallPrompt = (): JSX.Element | null => {
|
|
const [deferred, setDeferred] = useState<BeforeInstallPromptEvent | null>(
|
|
null
|
|
);
|
|
const [isInstalled, setIsInstalled] = useState<boolean>(false);
|
|
|
|
useEffect(() => {
|
|
if (typeof window === "undefined") return;
|
|
const onBeforeInstallPrompt = (e: Event) => {
|
|
e.preventDefault();
|
|
setDeferred(e as BeforeInstallPromptEvent);
|
|
};
|
|
const onAppInstalled = () => {
|
|
setDeferred(null);
|
|
setIsInstalled(true);
|
|
};
|
|
window.addEventListener("beforeinstallprompt", onBeforeInstallPrompt);
|
|
window.addEventListener("appinstalled", onAppInstalled);
|
|
if (window.matchMedia("(display-mode: standalone)").matches) {
|
|
setIsInstalled(true);
|
|
}
|
|
return () => {
|
|
window.removeEventListener("beforeinstallprompt", onBeforeInstallPrompt);
|
|
window.removeEventListener("appinstalled", onAppInstalled);
|
|
};
|
|
}, []);
|
|
|
|
const onInstall = useCallback(async () => {
|
|
if (!deferred) return;
|
|
try {
|
|
await deferred.prompt();
|
|
const choice = await deferred.userChoice;
|
|
if (choice.outcome === "accepted") {
|
|
setDeferred(null);
|
|
}
|
|
} catch (_err) { }
|
|
}, [deferred]);
|
|
|
|
if (isInstalled || !deferred) return null;
|
|
|
|
return (
|
|
<button
|
|
className="px-3 py-1 rounded-md border border-border bg-background/80 hover:bg-background/60"
|
|
onClick={onInstall}
|
|
>
|
|
Install App
|
|
</button>
|
|
);
|
|
};
|