mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Merge pull request #15056 from overleaf/td-ide-connection-load
IDE page: connection manager and loading screen GitOrigin-RevId: 2cbc8c09aeb36a14eae66da78b267c7a830fb71a
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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 | null>(null)
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { ConnectionProvider } from './connection-context'
|
||||
import { FC } from 'react'
|
||||
|
||||
export const ReactContextRoot: FC = ({ children }) => {
|
||||
return <ConnectionProvider>{children}</ConnectionProvider>
|
||||
}
|
||||
Reference in New Issue
Block a user