fix: harden PWA install prompt
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export type InstallPromptState = "unsupported" | "available" | "ios-instructions" | "installed";
|
||||
|
||||
@@ -26,6 +26,7 @@ export function useInstallPrompt() {
|
||||
});
|
||||
const [deferred, setDeferred] = useState<BeforeInstallPromptEvent | null>(null);
|
||||
const [dismissed, setDismissed] = useState(false);
|
||||
const installInFlight = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isStandalone()) {
|
||||
@@ -40,6 +41,7 @@ export function useInstallPrompt() {
|
||||
};
|
||||
const onInstalled = () => {
|
||||
setDeferred(null);
|
||||
setDismissed(false);
|
||||
setState("installed");
|
||||
};
|
||||
|
||||
@@ -52,13 +54,21 @@ export function useInstallPrompt() {
|
||||
}, []);
|
||||
|
||||
const install = async () => {
|
||||
if (!deferred) return;
|
||||
if (!deferred || installInFlight.current) return;
|
||||
const event = deferred;
|
||||
installInFlight.current = true;
|
||||
setDeferred(null);
|
||||
await event.prompt();
|
||||
const choice = await event.userChoice;
|
||||
if (choice.outcome === "accepted") setState("installed");
|
||||
else setDismissed(true);
|
||||
try {
|
||||
await event.prompt();
|
||||
const choice = await event.userChoice;
|
||||
if (choice.outcome === "accepted") setState("installed");
|
||||
else setDismissed(true);
|
||||
} catch {
|
||||
setDeferred(event);
|
||||
setState("available");
|
||||
} finally {
|
||||
installInFlight.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
return { state: dismissed ? "unsupported" : state, install, dismiss: () => setDismissed(true) };
|
||||
|
||||
Reference in New Issue
Block a user