55 lines
1.5 KiB
JavaScript
55 lines
1.5 KiB
JavaScript
|
import { useEffect } from "react";
|
||
|
|
||
|
// https://stackoverflow.com/a/9039885
|
||
|
function isIOS() {
|
||
|
return (
|
||
|
[
|
||
|
"iPad Simulator",
|
||
|
"iPhone Simulator",
|
||
|
"iPod Simulator",
|
||
|
"iPad",
|
||
|
"iPhone",
|
||
|
"iPod",
|
||
|
].includes(navigator.platform) ||
|
||
|
// iPad on iOS 13 detection
|
||
|
(navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
export function usePageUnload(callback) {
|
||
|
useEffect(() => {
|
||
|
let pageVisibilityTimeout;
|
||
|
|
||
|
function onBeforeUnload(event) {
|
||
|
if (event.type === "visibilitychange") {
|
||
|
if (document.visibilityState === "visible") {
|
||
|
clearTimeout(pageVisibilityTimeout);
|
||
|
} else {
|
||
|
// Wait 5 seconds before closing the page to avoid accidentally leaving
|
||
|
// TODO: Make this configurable?
|
||
|
pageVisibilityTimeout = setTimeout(() => {
|
||
|
callback();
|
||
|
}, 5000);
|
||
|
}
|
||
|
} else {
|
||
|
callback();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// iOS doesn't fire beforeunload event, so leave the call when you hide the page.
|
||
|
if (isIOS()) {
|
||
|
window.addEventListener("pagehide", onBeforeUnload);
|
||
|
document.addEventListener("visibilitychange", onBeforeUnload);
|
||
|
}
|
||
|
|
||
|
window.addEventListener("beforeunload", onBeforeUnload);
|
||
|
|
||
|
return () => {
|
||
|
window.removeEventListener("pagehide", onBeforeUnload);
|
||
|
document.removeEventListener("visibilitychange", onBeforeUnload);
|
||
|
window.removeEventListener("beforeunload", onBeforeUnload);
|
||
|
clearTimeout(pageVisibilityTimeout);
|
||
|
};
|
||
|
}, [callback]);
|
||
|
}
|