init commit,
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from "react";
|
||||
|
||||
type BeforeInstallPromptContextType = {
|
||||
event: BeforeInstallPromptEvent | null;
|
||||
clearEvent: () => void;
|
||||
};
|
||||
export const BeforeInstallPromptContext =
|
||||
createContext<BeforeInstallPromptContextType>({
|
||||
event: null,
|
||||
clearEvent: () => {},
|
||||
});
|
||||
|
||||
interface BeforeInstallPromptProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function BeforeInstallPromptProvider({
|
||||
children,
|
||||
}: BeforeInstallPromptProviderProps) {
|
||||
const [beforeInstallPromptEvent, setBeforeInstallPromptEvent] =
|
||||
useState<BeforeInstallPromptEvent | null>(null);
|
||||
|
||||
const handleBeforeInstallPrompt = useCallback(
|
||||
(event: BeforeInstallPromptEvent) => {
|
||||
event.preventDefault();
|
||||
setBeforeInstallPromptEvent(event);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const handleBeforeInstallPromptEvent = (
|
||||
event: BeforeInstallPromptEvent,
|
||||
) => {
|
||||
handleBeforeInstallPrompt(event);
|
||||
};
|
||||
|
||||
window.addEventListener(
|
||||
"beforeinstallprompt",
|
||||
handleBeforeInstallPromptEvent as never,
|
||||
);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener(
|
||||
"beforeinstallprompt",
|
||||
handleBeforeInstallPromptEvent as never,
|
||||
);
|
||||
};
|
||||
}, [handleBeforeInstallPrompt]);
|
||||
|
||||
const clearEvent = useCallback(() => {
|
||||
setBeforeInstallPromptEvent(null);
|
||||
}, []);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ event: beforeInstallPromptEvent, clearEvent }),
|
||||
[beforeInstallPromptEvent, clearEvent],
|
||||
);
|
||||
|
||||
return (
|
||||
<BeforeInstallPromptContext.Provider value={value}>
|
||||
{children}
|
||||
</BeforeInstallPromptContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The BeforeInstallPromptEvent is fired at the Window.onbeforeinstallprompt handler
|
||||
* before a user is prompted to "install" a web site to a home screen on mobile.
|
||||
*/
|
||||
interface BeforeInstallPromptEvent extends Event {
|
||||
/**
|
||||
* Returns an array of DOMString items containing the platforms on which the event was dispatched.
|
||||
* This is provided for user agents that want to present a choice of versions to the user such as,
|
||||
* for example, "web" or "play" which would allow the user to chose between a web version or
|
||||
* an Android version.
|
||||
*/
|
||||
readonly platforms: Array<string>;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves to a DOMString containing either "accepted" or "dismissed".
|
||||
*/
|
||||
readonly userChoice: Promise<{
|
||||
outcome: "accepted" | "dismissed";
|
||||
platform: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Allows a developer to show the install prompt at a time of their own choosing.
|
||||
* This method returns a Promise.
|
||||
*/
|
||||
prompt(): Promise<void>;
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
import { useContext } from "react";
|
||||
import { BeforeInstallPromptContext } from "./BeforeInstallPromptProvider";
|
||||
import {
|
||||
isAppleDeviceInstallable,
|
||||
isInstalled,
|
||||
isTouchDevice,
|
||||
} from "../../helpers/device";
|
||||
|
||||
export default function useShouldInstall() {
|
||||
const { event } = useContext(BeforeInstallPromptContext);
|
||||
|
||||
if (isInstalled()) return false;
|
||||
if (isAppleDeviceInstallable()) return true;
|
||||
if (!isTouchDevice()) return false;
|
||||
if (event) return true;
|
||||
|
||||
return false;
|
||||
}
|
Reference in New Issue
Block a user