chore: parse ansi
This commit is contained in:
@@ -1,19 +1,13 @@
|
||||
import useSetChunkRequest from '@/hooks/use-chunk-request';
|
||||
import useSetChunkFetch from '@/hooks/use-chunk-fetch';
|
||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||
import { FitAddon } from '@xterm/addon-fit';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import '@xterm/xterm/css/xterm.css';
|
||||
import classNames from 'classnames';
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import './index.less';
|
||||
import useSize from './use-size';
|
||||
import parseAnsi from './parse-ansi';
|
||||
|
||||
interface LogsViewerProps {
|
||||
height: number;
|
||||
@@ -22,39 +16,41 @@ interface LogsViewerProps {
|
||||
params?: object;
|
||||
}
|
||||
const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
const { height, content, url } = props;
|
||||
const { setChunkRequest } = useSetChunkRequest();
|
||||
const { height, url } = props;
|
||||
const { initialize, updateScrollerPosition } = useOverlayScroller({
|
||||
theme: 'os-theme-light'
|
||||
});
|
||||
const { setChunkFetch } = useSetChunkFetch();
|
||||
const chunkRequedtRef = useRef<any>(null);
|
||||
const scroller = useRef<any>({});
|
||||
const termRef = useRef<any>({});
|
||||
const termwrapRef = useRef<any>({});
|
||||
const fitAddonRef = useRef<any>({});
|
||||
const cacheDataRef = useRef<any>('');
|
||||
const [logs, setLogs] = useState('');
|
||||
const size = useSize(scroller);
|
||||
const uidRef = useRef<any>(0);
|
||||
const [logs, setLogs] = useState<any[]>([]);
|
||||
|
||||
const throttleScroll = _.throttle(() => {
|
||||
termRef.current?.scrollToBottom?.();
|
||||
}, 100);
|
||||
|
||||
const updateContent = useCallback(
|
||||
_.throttle((data: string) => {
|
||||
cacheDataRef.current = '';
|
||||
termRef.current?.clear?.();
|
||||
cacheDataRef.current = data;
|
||||
termRef.current?.write?.(data);
|
||||
setLogs(data);
|
||||
}, 100),
|
||||
[]
|
||||
);
|
||||
|
||||
const fitTerm = () => {
|
||||
fitAddonRef.current?.fit?.();
|
||||
const setId = () => {
|
||||
uidRef.current += 1;
|
||||
return uidRef.current;
|
||||
};
|
||||
|
||||
const clearScreen = () => {
|
||||
cacheDataRef.current = '';
|
||||
};
|
||||
|
||||
const updateContent = useCallback(
|
||||
(data: string) => {
|
||||
cacheDataRef.current += data;
|
||||
const res = parseAnsi(cacheDataRef.current, setId, clearScreen);
|
||||
setLogs(res);
|
||||
},
|
||||
[setLogs, setId]
|
||||
);
|
||||
|
||||
const createChunkConnection = async () => {
|
||||
chunkRequedtRef.current?.current?.cancel?.();
|
||||
chunkRequedtRef.current = setChunkRequest({
|
||||
chunkRequedtRef.current?.current?.abort?.();
|
||||
chunkRequedtRef.current = setChunkFetch({
|
||||
url,
|
||||
params: {
|
||||
...props.params,
|
||||
@@ -65,7 +61,8 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const initTerm = () => {
|
||||
const initTerm = useCallback(() => {
|
||||
termRef.current?.clear?.();
|
||||
termRef.current?.dispose?.();
|
||||
termRef.current = new Terminal({
|
||||
lineHeight: 1.2,
|
||||
@@ -84,43 +81,38 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
fitAddonRef.current = new FitAddon();
|
||||
termRef.current.loadAddon(fitAddonRef.current);
|
||||
termRef.current.open(termwrapRef.current);
|
||||
};
|
||||
|
||||
const handleResize = _.throttle(() => {
|
||||
fitTerm();
|
||||
}, 100);
|
||||
}, [termwrapRef.current]);
|
||||
|
||||
useEffect(() => {
|
||||
createChunkConnection();
|
||||
return () => {
|
||||
chunkRequedtRef.current?.current?.cancel?.();
|
||||
chunkRequedtRef.current?.current?.abort?.();
|
||||
};
|
||||
}, [url, props.params]);
|
||||
|
||||
useEffect(() => {
|
||||
if (termwrapRef.current) {
|
||||
initTerm();
|
||||
if (scroller.current) {
|
||||
initialize(scroller.current);
|
||||
}
|
||||
return () => {
|
||||
termRef.current?.dispose?.();
|
||||
};
|
||||
}, [termwrapRef.current]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (size) {
|
||||
handleResize();
|
||||
}
|
||||
}, [size]);
|
||||
}, [scroller.current, initialize]);
|
||||
|
||||
useEffect(() => {
|
||||
throttleScroll();
|
||||
if (logs) {
|
||||
updateScrollerPosition();
|
||||
}
|
||||
}, [logs]);
|
||||
|
||||
return (
|
||||
<div className="logs-viewer-wrap-w2">
|
||||
<div className="wrap" style={{ height: height }} ref={scroller}>
|
||||
<div className={classNames('content')}>
|
||||
<div className="text" ref={termwrapRef}></div>
|
||||
{_.map(logs, (item: any, index: number) => {
|
||||
return (
|
||||
<div key={item.uid} className="text">
|
||||
{item.content}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user