import React, { useEffect } from 'react'
import type { ConnectionStatus } from './types'
import { useSocketManager } from './use-socket-manager'
import {
ActionButton,
ConnectionBadge,
DiagnosticItem,
ErrorAlert,
} from './diagnostic-component'
import { Container } from 'react-bootstrap-5'
import MaterialIcon from '@/shared/components/material-icon'
import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox'
type NetworkInformation = {
downlink: number
effectiveType: string
rtt: number
saveData: boolean
type: string
}
const NavigatorInfo = () => {
if (!('connection' in navigator)) {
return
Network Information API not supported
}
const connection = navigator.connection as NetworkInformation
return (
<>
Downlink: {connection.downlink} Mbps
Effective Type: {connection.effectiveType}
Round Trip Time: {connection.rtt} ms
Save Data: {connection.saveData ? 'Enabled' : 'Disabled'}
Platform: {navigator.platform}
{/* @ts-ignore */}
Device Memory: {navigator.deviceMemory}
Hardware Concurrency: {navigator.hardwareConcurrency}
>
)
}
const useCurrentTime = () => {
const [time, setTime] = React.useState(new Date())
useEffect(() => {
const interval = setInterval(() => setTime(new Date()), 1000)
return () => clearInterval(interval)
}, [])
return time
}
export const SocketDiagnostics = () => {
const {
socketState,
debugInfo,
disconnectSocket,
forceReconnect,
socket,
autoping,
setAutoping,
} = useSocketManager()
const now = useCurrentTime()
const getConnectionState = (): ConnectionStatus => {
if (socketState.connected) return 'connected'
if (socketState.connecting) return 'connecting'
return 'disconnected'
}
const lastReceivedS = debugInfo.lastReceived
? Math.round((now.getTime() - debugInfo.lastReceived) / 1000)
: null
const isLate =
!!debugInfo.unansweredSince &&
now.getTime() - debugInfo.unansweredSince >= 3000
return (
Socket Diagnostics
{socketState.lastError && }
Connection Stats
setAutoping(e.target.checked)}
/>
{debugInfo.received} / {debugInfo.sent}
{lastReceivedS !== null && (
<>
Last received {lastReceivedS}s ago
>
)}
>
}
type={isLate === null ? undefined : isLate ? 'danger' : 'success'}
/>
{debugInfo.latency} ms
Max: {debugInfo.maxLatency} ms
>
) : (
'-'
)
}
type={
debugInfo.latency
? debugInfo.latency < 450
? 'success'
: 'danger'
: undefined
}
/>
{new Date(debugInfo.client.connectedAt).toUTCString()} (
{Math.round(
(Date.now() - debugInfo.client.connectedAt) / 1000
)}
s)
>
) : (
'-'
)
}
/>
}
/>
)
}