import { atom } from 'jotai'; import { ServerStatus } from '../utils/kumaStatus'; /** * [Gitea #124] The homeserver's status from its Kuma status page (null: none * configured, not fetched yet, or Kuma unreachable — all mean "no banner"), * plus whether this client's own connection is currently lost. */ export const serverStatusAtom = atom<{ status: ServerStatus | null; syncLost: boolean; /** When this client's connection dropped (ms), null while connected. */ lostAt: number | null; }>({ status: null, syncLost: false, lostAt: null, }); const DISMISS_KEY = 'lotus-status-banner-dismissed'; const DISMISS_MAX = 50; const readDismissed = (): string[] => { try { const v = JSON.parse(localStorage.getItem(DISMISS_KEY) ?? '[]'); return Array.isArray(v) ? v.filter((k): k is string => typeof k === 'string') : []; } catch { return []; } }; const baseDismissedAtom = atom(readDismissed()); /** * [Gitea #307] Status strips the user dismissed (by banner key), shared so * the security nudge knows a dismissed announcement isn't on screen. * Persisted to localStorage; session-only if storage is unavailable. */ export const statusDismissedAtom = atom( (get) => get(baseDismissedAtom), (get, set, key: string) => { const next = [...get(baseDismissedAtom).filter((k) => k !== key), key].slice(-DISMISS_MAX); try { localStorage.setItem(DISMISS_KEY, JSON.stringify(next)); } catch { // storage unavailable — dismissed for this session only } set(baseDismissedAtom, next); }, );