mosaicmap/app/ws-context.tsx
2025-08-13 21:54:20 +08:00

85 lines
1.8 KiB
TypeScript

'use client'
import React, { createContext, useContext, useRef, useState, ReactNode, useEffect } from 'react'
import { Map } from 'maplibre-gl';
import { gql, useSubscription } from '@apollo/client';
// 定义MapContext的类型
interface WSContextType {
wsStatus: WsStatus
setWsStatus: (status: WsStatus) => void
data: any
loading: boolean
error: any
restart: () => void
}
enum WsStatus {
CONNECTING = 'connecting',
CONNECTED = 'connected',
DISCONNECTED = 'disconnected'
}
// 创建Context
const WSContext = createContext<WSContextType | undefined>(undefined)
// Provider组件的Props类型
interface MapProviderProps {
children: ReactNode
}
const SUBSCRIPTION_QUERY = gql`
subscription {
statusUpdates {
id
message
status
timestamp
newestDt
}
}
`
// Provider组件
export function WSProvider({ children }: MapProviderProps) {
const [wsStatus, setWsStatus] = useState<WsStatus>(WsStatus.DISCONNECTED)
const { data, loading, error, restart } = useSubscription(SUBSCRIPTION_QUERY)
useEffect(() => {
if (loading) {
setWsStatus(WsStatus.CONNECTING)
} else if (error) {
setWsStatus(WsStatus.DISCONNECTED)
} else {
setWsStatus(WsStatus.CONNECTED)
}
}, [data])
const value: WSContextType = {
wsStatus,
setWsStatus,
data,
loading,
error,
restart
}
return (
<WSContext.Provider value={value}>
{children}
</WSContext.Provider>
)
}
// 自定义Hook用于使用MapContext
export function useWS() {
const context = useContext(WSContext)
if (context === undefined) {
throw new Error('useWS must be used within a WSProvider')
}
return context
}