SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
yesterdaylast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%
1.2 KB · 28 lines tsx
Raw Blame History
1"use client";23import { useCallback, useSyncExternalStore } from "react";4import { fmtDateTimeUtc, fmtRelative } from "@/lib/format";56/**7 * Hydration-safe relative time: SSR renders the deterministic UTC date; after mount we switch to8 * "3 min ago" and refresh every `refreshMs`. Implemented as an external store (time bucket) so no9 * setState runs inside effects. suppressHydrationWarning guards against locale drift.10 */11export function RelativeTime({ iso, className, refreshMs = 60_000 }: { iso: string | null | undefined; className?: string; refreshMs?: number }) {12  const subscribe = useCallback(13    (cb: () => void) => {14      const t = setInterval(cb, refreshMs);15      return () => clearInterval(t);16    },17    [refreshMs],18  );19  // snapshot = current time bucket (ms rounded to the refresh period); null on the server20  const bucket = useSyncExternalStore(subscribe, () => Math.floor(Date.now() / refreshMs) * refreshMs, () => null);21  if (!iso) return <span className={className}>—</span>;22  return (23    <time dateTime={iso} title={fmtDateTimeUtc(iso)} className={className} suppressHydrationWarning>24      {bucket === null ? fmtDateTimeUtc(iso) : fmtRelative(iso, bucket + refreshMs / 2)}25    </time>26  );27}28