Auto-reload app every 24h when inactive
This commit is contained in:
@@ -8,6 +8,7 @@ import { LoadingIndicatorBar } from "~/components/LoadingIndicator";
|
||||
import SkipNavContent from "~/components/SkipNavContent";
|
||||
import SkipNavLink from "~/components/SkipNavLink";
|
||||
import env from "~/env";
|
||||
import useAutoRefresh from "~/hooks/useAutoRefresh";
|
||||
import useKeyDown from "~/hooks/useKeyDown";
|
||||
import { MenuProvider } from "~/hooks/useMenuContext";
|
||||
import useStores from "~/hooks/useStores";
|
||||
@@ -28,6 +29,8 @@ const Layout: React.FC<Props> = ({
|
||||
const { ui } = useStores();
|
||||
const sidebarCollapsed = !sidebar || ui.sidebarIsClosed;
|
||||
|
||||
useAutoRefresh();
|
||||
|
||||
useKeyDown(".", (event) => {
|
||||
if (isModKey(event)) {
|
||||
ui.toggleCollapsedSidebar();
|
||||
|
||||
33
app/hooks/useAutoRefresh.ts
Normal file
33
app/hooks/useAutoRefresh.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import * as React from "react";
|
||||
import { Minute } from "@shared/utils/time";
|
||||
import Logger from "~/utils/Logger";
|
||||
import useIdle from "./useIdle";
|
||||
import useInterval from "./useInterval";
|
||||
import usePageVisibility from "./usePageVisibility";
|
||||
|
||||
/**
|
||||
* Hook to reload the app around once a day to stop old code from running.
|
||||
*/
|
||||
export default function useAutoRefresh() {
|
||||
const [minutes, setMinutes] = React.useState(0);
|
||||
const isVisible = usePageVisibility();
|
||||
const isIdle = useIdle(15 * Minute);
|
||||
|
||||
useInterval(() => {
|
||||
setMinutes((prev) => prev + 1);
|
||||
|
||||
if (minutes >= 60 * 24) {
|
||||
if (isVisible) {
|
||||
Logger.debug("lifecycle", "Skipping reload due to app visible");
|
||||
return;
|
||||
}
|
||||
if (!isIdle) {
|
||||
Logger.debug("lifecycle", "Skipping reload due to user activity");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.debug("lifecycle", "Auto-reloading app…");
|
||||
window.location.reload();
|
||||
}
|
||||
}, Minute);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from "react";
|
||||
import { Minute } from "@shared/utils/time";
|
||||
|
||||
const activityEvents = [
|
||||
"click",
|
||||
@@ -18,7 +19,7 @@ const activityEvents = [
|
||||
* @param {number} timeToIdle
|
||||
* @returns boolean if the user is idle
|
||||
*/
|
||||
export default function useIdle(timeToIdle: number = 3 * 60 * 1000) {
|
||||
export default function useIdle(timeToIdle: number = 3 * Minute) {
|
||||
const [isIdle, setIsIdle] = React.useState(false);
|
||||
const timeout = React.useRef<ReturnType<typeof setTimeout>>();
|
||||
|
||||
|
||||
32
app/hooks/useInterval.ts
Normal file
32
app/hooks/useInterval.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as React from "react";
|
||||
|
||||
type Callback = () => void;
|
||||
|
||||
/**
|
||||
* Hook to set up an interval that calls a callback.
|
||||
*
|
||||
* @param callback The callback to call.
|
||||
* @param delay The delay in milliseconds.
|
||||
*/
|
||||
export default function useInterval(callback: Callback, delay: number) {
|
||||
const savedCallback = React.useRef<Callback>();
|
||||
|
||||
// Remember the latest callback.
|
||||
React.useEffect(() => {
|
||||
savedCallback.current = callback;
|
||||
}, [callback]);
|
||||
|
||||
// Set up the interval.
|
||||
React.useEffect(() => {
|
||||
function tick() {
|
||||
savedCallback.current?.();
|
||||
}
|
||||
|
||||
if (delay !== null) {
|
||||
const id = setInterval(tick, delay);
|
||||
return () => clearInterval(id);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [delay]);
|
||||
}
|
||||
Reference in New Issue
Block a user