Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 16x 16x 16x 16x 16x 627x 627x 232x 232x 75x 265x 627x 627x 627x 232x 232x 3835x 1435x | // SPDX-License-Identifier: GPL-3.0-only
// Copyright (C) 2026 Max Boksem. See NOTICE for additional terms under GPLv3 section 7.
import { useSyncExternalStore } from "react";
import { nowSeconds } from "@/lib/date";
export const NOW_TICK_MS = 30_000;
let now = nowSeconds();
let timer: ReturnType<typeof setInterval> | null = null;
const listeners = new Set<() => void>();
// One timer serves every component on screen, and it only runs while one of
// them is mounted.
const subscribe = (listener: () => void) => {
listeners.add(listener);
if (timer === null) {
now = nowSeconds();
timer = setInterval(() => {
now = nowSeconds();
listeners.forEach((l) => l());
}, NOW_TICK_MS);
}
return () => {
listeners.delete(listener);
if (listeners.size === 0 && timer !== null) {
clearInterval(timer);
timer = null;
}
};
};
const getSnapshot = () => now;
/** The current Unix time in seconds, updated every 30 seconds. */
export const useNow = (): number => useSyncExternalStore(subscribe, getSnapshot);
|