Files
usa/src/store/situationStore.ts
2026-03-02 23:21:07 +08:00

86 lines
2.5 KiB
TypeScript

import { create } from 'zustand'
import type { MilitarySituation } from '@/data/mockData'
import { INITIAL_MOCK_DATA } from '@/data/mockData'
import { fetchSituation } from '@/api/situation'
import { connectSituationWebSocket } from '@/api/websocket'
import { useStatsStore } from './statsStore'
interface SituationState {
situation: MilitarySituation
isConnected: boolean
lastError: string | null
isLoading: boolean
setSituation: (situation: MilitarySituation) => void
fetchAndSetSituation: () => Promise<void>
setConnected: (connected: boolean) => void
setLastError: (error: string | null) => void
}
export const useSituationStore = create<SituationState>((set) => ({
situation: INITIAL_MOCK_DATA,
isConnected: false,
lastError: null,
isLoading: false,
setSituation: (situation) => set({ situation }),
fetchAndSetSituation: async () => {
set({ isLoading: true, lastError: null })
try {
const situation = await fetchSituation()
set({ situation })
} catch (err) {
set({
lastError: err instanceof Error ? err.message : 'Failed to fetch situation',
})
} finally {
set({ isLoading: false })
}
},
setConnected: (isConnected) => set({ isConnected }),
setLastError: (lastError) => set({ lastError }),
}))
export function fetchAndSetSituation(): Promise<void> {
return useSituationStore.getState().fetchAndSetSituation()
}
let disconnectWs: (() => void) | null = null
let pollInterval: ReturnType<typeof setInterval> | null = null
const POLL_INTERVAL_MS = 3000
function pollSituation() {
fetchSituation()
.then((situation) => useSituationStore.getState().setSituation(situation))
.catch(() => {})
}
export function startSituationWebSocket(): () => void {
useSituationStore.getState().setLastError(null)
disconnectWs = connectSituationWebSocket((payload) => {
const { situation, stats } = payload as { situation?: MilitarySituation; stats?: { viewers?: number; cumulative?: number; feedbackCount?: number; shareCount?: number } }
useSituationStore.getState().setConnected(true)
if (situation) useSituationStore.getState().setSituation(situation)
if (stats) useStatsStore.getState().setStats(stats)
})
pollSituation()
pollInterval = setInterval(pollSituation, POLL_INTERVAL_MS)
return stopSituationWebSocket
}
export function stopSituationWebSocket(): void {
disconnectWs?.()
disconnectWs = null
if (pollInterval) {
clearInterval(pollInterval)
pollInterval = null
}
useSituationStore.getState().setConnected(false)
}