54 lines
1.2 KiB
TypeScript
54 lines
1.2 KiB
TypeScript
import { usePageVisibility } from "@solid-primitives/page-visibility";
|
|
import {
|
|
Accessor,
|
|
createContext,
|
|
createRenderEffect,
|
|
createSignal,
|
|
onCleanup,
|
|
untrack,
|
|
useContext,
|
|
} from "solid-js";
|
|
|
|
const TimeSourceContext = createContext<Accessor<Date>>();
|
|
|
|
export const TimeSourceProvider = TimeSourceContext.Provider;
|
|
|
|
export function createTimeSource() {
|
|
let id: ReturnType<typeof setTimeout> | undefined;
|
|
const [get, set] = createSignal(new Date());
|
|
const visible = usePageVisibility();
|
|
|
|
const cancelTimer = () => {
|
|
if (typeof id !== "undefined") {
|
|
clearInterval(id);
|
|
}
|
|
id = undefined;
|
|
};
|
|
|
|
const resetTimer = () => {
|
|
cancelTimer();
|
|
set(new Date());
|
|
id = setTimeout(() => {
|
|
set(new Date());
|
|
}, 30 * 1000); // refresh rate: 30s
|
|
};
|
|
|
|
createRenderEffect(() => {
|
|
onCleanup(cancelTimer);
|
|
if (visible()) {
|
|
resetTimer();
|
|
} else {
|
|
console.debug("createTimeSource: page is invisible, cancel the timer")
|
|
}
|
|
});
|
|
|
|
return get;
|
|
}
|
|
|
|
export function useTimeSource() {
|
|
return (
|
|
useContext(TimeSourceContext) ??
|
|
(console.warn("useTimeSource() is used but no source is provided"),
|
|
createTimeSource())
|
|
);
|
|
}
|