Files
homarr/packages/widgets/src/clock/use-current-time.ts
T
Thomas Camlong 240397e7ac refactor: drop server-seeded widget clock
The WidgetTimeProvider plumbed a server timestamp and the container's
timezone down to useWidgetNow so clock widgets would paint a real time in
the SSR HTML instead of "--:--". That traded a cosmetic first-paint win for
a wrong clock: the seeded timezone is the server's, so anyone whose timezone
differs from the container's saw an incorrect time for the whole hydration
window. Fixing that properly needs a client-set timezone cookie read during
RSC render, which is far more plumbing than the problem warrants.

Revert the clock to release/v2 behaviour ("--:--" until hydration) and drop
the provider, the @homarr/widgets/time export and their tests. The e2e clock
assertions now wait on hydration explicitly instead of the seeded paint.

Also restore the widget.beszel.getSystemStats persistence exclusion. #6289
added it deliberately to keep those large time-series payloads out of the
persisted cache, and this branch had removed it with no stated rationale.

Query-cache persistence and the background-refresh indicator are unchanged.
2026-08-23 09:00:34 +02:00

28 lines
1003 B
TypeScript

import { useEffect, useMemo, useRef, useState } from "react";
import dayjs from "dayjs";
export const useCurrentTime = ({ showSeconds }: { showSeconds: boolean }) => {
const [time, setTime] = useState<Date | null>(null);
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(null);
const intervalRef = useRef<ReturnType<typeof setInterval>>(null);
const intervalMultiplier = useMemo(() => (showSeconds ? 1 : 60), [showSeconds]);
useEffect(() => {
setTime(new Date());
timeoutRef.current = setTimeout(
() => {
setTime(new Date());
intervalRef.current = setInterval(() => setTime(new Date()), intervalMultiplier * 1000);
},
intervalMultiplier * 1000 - (1000 * (showSeconds ? 0 : dayjs().second()) + dayjs().millisecond()),
);
return () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
if (intervalRef.current) clearInterval(intervalRef.current);
};
}, [intervalMultiplier, showSeconds]);
return time;
};