| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- import {
- createContext,
- useContext,
- useEffect,
- useState,
- FC,
- useCallback,
- useMemo,
- } from 'react'
- import { ConnectionState } from '../connection/types/connection-state'
- import { ConnectionManager } from '@/features/ide-react/connection/connection-manager'
- import { Socket } from '@/features/ide-react/connection/types/socket'
- import { secondsUntil } from '@/features/ide-react/connection/utils'
- type ConnectionContextValue = {
- socket: Socket
- connectionState: ConnectionState
- isConnected: boolean
- isStillReconnecting: boolean
- secondsUntilReconnect: () => number
- tryReconnectNow: () => void
- registerUserActivity: () => void
- }
- const ConnectionContext = createContext<ConnectionContextValue | undefined>(
- undefined
- )
- export const ConnectionProvider: FC = ({ children }) => {
- const [connectionManager] = useState(() => new ConnectionManager())
- const [connectionState, setConnectionState] = useState(
- connectionManager.state
- )
- useEffect(() => {
- function handleStateChange(event: { state: ConnectionState }) {
- setConnectionState(event.state)
- }
- connectionManager.on('statechange', handleStateChange)
- return () => {
- connectionManager.off('statechange', handleStateChange)
- }
- }, [connectionManager])
- const isConnected = connectionState.readyState === WebSocket.OPEN
- const isStillReconnecting =
- connectionState.readyState === WebSocket.CONNECTING &&
- performance.now() - connectionState.lastConnectionAttempt > 1000
- const secondsUntilReconnect = useCallback(
- () => secondsUntil(connectionState.reconnectAt),
- [connectionState.reconnectAt]
- )
- const tryReconnectNow = useCallback(
- () => connectionManager.tryReconnectNow(),
- [connectionManager]
- )
- const registerUserActivity = useCallback(
- () => connectionManager.registerUserActivity(),
- [connectionManager]
- )
- const value = useMemo<ConnectionContextValue>(
- () => ({
- socket: connectionManager.socket,
- connectionState,
- isConnected,
- isStillReconnecting,
- secondsUntilReconnect,
- tryReconnectNow,
- registerUserActivity,
- }),
- [
- connectionManager.socket,
- connectionState,
- isConnected,
- isStillReconnecting,
- registerUserActivity,
- secondsUntilReconnect,
- tryReconnectNow,
- ]
- )
- return (
- <ConnectionContext.Provider value={value}>
- {children}
- </ConnectionContext.Provider>
- )
- }
- export function useConnectionContext(): ConnectionContextValue {
- const context = useContext(ConnectionContext)
- if (!context) {
- throw new Error(
- 'useConnectionContext is only available inside ConnectionProvider'
- )
- }
- return context
- }
|