diff --git a/addon/web/client/src/App.tsx b/addon/web/client/src/App.tsx index 1b99798..369a0d2 100644 --- a/addon/web/client/src/App.tsx +++ b/addon/web/client/src/App.tsx @@ -10,6 +10,7 @@ import ViewFlow from './components/ViewFlow' import { FlowManager } from './flow' import { parseMessage, SendMessageType, buildMessageMeta, Flow, MessageType } from './message' +import { isInViewPort } from './utils' interface IState { flows: Flow[] @@ -27,6 +28,7 @@ class App extends React.Component { private flowMgr: FlowManager private ws: WebSocket | null private wsUnmountClose: boolean + private tableBottomRef: React.RefObject private wsReconnCount = -1 @@ -44,6 +46,7 @@ class App extends React.Component { this.ws = null this.wsUnmountClose = false + this.tableBottomRef = React.createRef() } componentDidMount() { @@ -106,7 +109,16 @@ class App extends React.Component { if (msg.type === MessageType.REQUEST) { const flow = new Flow(msg) this.flowMgr.add(flow) - this.setState({ flows: this.flowMgr.showList() }) + + let shouldScroll = false + if (this.tableBottomRef?.current && isInViewPort(this.tableBottomRef.current)) { + shouldScroll = true + } + this.setState({ flows: this.flowMgr.showList() }, () => { + if (shouldScroll) { + this.tableBottomRef?.current?.scrollIntoView({ behavior: 'auto' }) + } + }) } else if (msg.type === MessageType.REQUEST_BODY) { const flow = this.flowMgr.get(msg.id) @@ -192,7 +204,7 @@ class App extends React.Component { } -
+
{ return str } + +// https://github.com/febobo/web-interview/issues/84 +export function isInViewPort(element: HTMLElement) { + const viewWidth = window.innerWidth || document.documentElement.clientWidth + const viewHeight = window.innerHeight || document.documentElement.clientHeight + const { + top, + right, + bottom, + left, + } = element.getBoundingClientRect() + + return ( + top >= 0 && + left >= 0 && + right <= viewWidth && + bottom <= viewHeight + ) +}