import { useEffect, useMemo, useRef, useState } from 'react' import { useRecoilValue } from 'recoil' import { serverURL } from '../atoms/settings' import { useI18n } from '../hooks/useI18n' const token = localStorage.getItem('token') const LogTerminal: React.FC = () => { const [logBuffer, setLogBuffer] = useState([]) const [isConnecting, setIsConnecting] = useState(true) const boxRef = useRef(null) const serverAddr = useRecoilValue(serverURL) const { i18n } = useI18n() const eventSource = useMemo( () => new EventSource(`${serverAddr}/log/sse?token=${token}`), [serverAddr] ) useEffect(() => { eventSource.addEventListener('log', event => { const msg: string[] = JSON.parse(event.data) setLogBuffer(buff => [...buff, ...msg].slice(-500)) boxRef.current?.scrollTo(0, boxRef.current.scrollHeight) }) // TODO: in dev mode it breaks sse return () => eventSource.close() }, [eventSource]) useEffect(() => { eventSource.onopen = () => setIsConnecting(false) }, [eventSource]) const logEntryStyle = (data: string) => { const sx = {} if (data.includes("level=ERROR")) { return { ...sx, color: 'red' } } if (data.includes("level=WARN")) { return { ...sx, color: 'orange' } } return sx } return (
{isConnecting ?
{'Connecting...'}
:
{'Connected!'}
} {logBuffer.length === 0 &&
{i18n.t('awaitingLogs')}
} {logBuffer.map((log, idx) => (
{log}
))}
) } export default LogTerminal