spb/internetpressure
Public
TypeScript 36.3%
Python 31.8%
Go 18%
JavaScript 9.8%
Shell 1.9%
SQL 1.4%
CSS 0.5%
1'use client';23import { useDegraded, useLive, useNow } from '@/lib/live';45/** "LIVE • updated 3 s ago" — the text ticks every second from the last real event; the data does not move. */6export function LiveIndicator({ className = '', compact = false }: { className?: string; compact?: boolean }) {7 const { lastEventAt, connection } = useLive((s) => ({ lastEventAt: s.lastEventAt, connection: s.connection }));8 const { degraded } = useDegraded();9 const now = useNow(1000);10 const ago = lastEventAt ? Math.max(0, Math.round((now - lastEventAt) / 1000)) : null;11 const live = connection === 'open' && !degraded;12 const color = degraded ? 'var(--warn)' : connection === 'open' ? 'var(--ok)' : 'var(--ink-3)';13 const word = degraded ? 'DEGRADED' : connection === 'open' ? 'LIVE' : connection === 'reconnecting' ? 'RECONNECTING' : connection === 'connecting' ? 'CONNECTING' : 'OFFLINE';14 return (15 <span className={`inline-flex items-center gap-2 text-[11px] tracking-[0.1em] ${className}`} aria-live="off" suppressHydrationWarning>16 <span className="relative inline-flex size-1.5">17 <span className="size-1.5 rounded-full" style={{ background: color }} />18 {live && ago != null && ago < 2 && <span className="absolute inset-0 rounded-full opacity-60" style={{ background: color, transform: 'scale(2)', transition: 'transform 0.4s, opacity 0.4s', opacity: 0 }} />}19 </span>20 <span style={{ color }}>{word}</span>21 {!compact && ago != null && (22 <span className="num text-ink-3">23 · updated {ago < 60 ? `${ago} s` : `${Math.floor(ago / 60)} min`} ago24 </span>25 )}26 </span>27 );28}29