SPB Git

Repository Public

connection-indicator.tsx 1.7 KB 34 lines tsx

1'use client';2import { useConn } from '@/stores/conn';3import { Tooltip } from '@/components/ui/tooltip';4import { Wifi, WifiOff } from 'lucide-react';5import { Dot, type Tone } from '@/components/ui/badge';6import { cn } from '@/lib/cn';78/** Live connection state of the events channel. */9export function useConnectionSummary(): { tone: Tone; label: string; detail: string; pulse: boolean } {10  const { events, online } = useConn();11  if (!online) return { tone: 'error', label: 'Offline', detail: 'No network. Missions keep running on the server.', pulse: false };12  if (events !== 'open') return { tone: 'warning', label: events === 'connecting' ? 'Connecting' : 'Reconnecting', detail: 'Live updates are not connected; the console resumes from the last event it received.', pulse: true };13  return { tone: 'success', label: 'Live', detail: 'Live updates connected.', pulse: false };14}1516export function ConnectionIndicator({ compact, className }: { compact?: boolean; className?: string }) {17  const s = useConnectionSummary();18  return (19    <Tooltip content={s.detail}>20      <span role="status" aria-label={`Connection: ${s.label}`} data-testid="conn-indicator" data-tone={s.tone} className={cn('tnum inline-flex items-center gap-1.5 text-[11px] text-text-2', className)}>21        {compact ? (22          // an icon, not a dot: on phones it sits in the title bar23          s.tone === 'error' ? <WifiOff className="size-4 text-error" aria-hidden /> : <Wifi className={cn('size-4', s.tone === 'success' ? 'text-success' : 'text-warning', s.pulse && 'anim-pulse')} aria-hidden />24        ) : (25          <>26            <Dot tone={s.tone} pulse={s.pulse} />27            {s.label}28          </>29        )}30      </span>31    </Tooltip>32  );33}34
Files main
Menu

Theme