Fix log live updating and add autoscrolling

This commit is contained in:
Tulir Asokan 2018-11-29 12:27:31 +02:00
parent b858b5a056
commit 2b8a5353be
3 changed files with 55 additions and 9 deletions

View file

@ -113,13 +113,57 @@ class LogEntry extends PureComponent {
}
class Log extends PureComponent {
constructor(props) {
super(props)
this.linesRef = React.createRef()
this.linesBottomRef = React.createRef()
}
getSnapshotBeforeUpdate() {
if (this.linesRef.current && this.linesBottomRef.current) {
return Log.isVisible(this.linesRef.current, this.linesBottomRef.current)
}
return false
}
componentDidUpdate(_1, _2, wasVisible) {
if (wasVisible) {
Log.scrollParentToChild(this.linesRef.current, this.linesBottomRef.current)
}
}
componentDidMount() {
if (this.linesRef.current && this.linesBottomRef.current) {
Log.scrollParentToChild(this.linesRef.current, this.linesBottomRef.current)
}
}
static scrollParentToChild(parent, child) {
const parentRect = parent.getBoundingClientRect()
const childRect = child.getBoundingClientRect()
if (!Log.isVisible(parent, child)) {
parent.scrollBy({ top: (childRect.top + parent.scrollTop) - parentRect.top })
}
}
static isVisible(parent, child) {
const parentRect = parent.getBoundingClientRect()
const childRect = child.getBoundingClientRect()
return (childRect.top >= parentRect.top)
&& (childRect.top <= parentRect.top + parent.clientHeight)
}
render() {
return (
<div className="log">
<div className="log" ref={this.linesRef}>
<div className="lines">
{this.props.lines.map(data => <LogEntry key={data.id} line={data}
focus={this.props.focus}/>)}
</div>
<div ref={this.linesBottomRef}/>
</div>
)
}

View file

@ -30,6 +30,7 @@ class Modal extends Component {
open = () => this.setState({ open: true })
close = () => this.setState({ open: false })
isOpen = () => this.state.open
render() {
return this.state.open && (

View file

@ -34,11 +34,11 @@ class Dashboard extends Component {
sidebarOpen: false,
modalOpen: false,
logFocus: null,
logLines: [],
}
this.logLines = []
this.logMap = {}
this.logModal = {
open: () => undefined,
isOpen: () => false,
}
window.maubot = this
}
@ -80,20 +80,21 @@ class Dashboard extends Component {
} else if (entry.name.startsWith("instance.")) {
entry.nameLink = `/instance/${entry.name.substr("instance.".length)}`
}
(this.logMap[entry.name] || (this.logMap[entry.name] = [])).push(entry)
}
logs.onHistory = history => {
for (const data of history) {
processEntry(data)
}
this.logLines = history
this.setState({ logFocus: this.state.logFocus })
this.setState({
logLines: history,
})
}
logs.onLog = data => {
processEntry(data)
this.logLines.push(data)
this.setState({ logFocus: this.state.logFocus })
this.setState({
logLines: this.state.logLines.concat(data),
})
}
}
@ -209,7 +210,7 @@ class Dashboard extends Component {
renderModal() {
return <Modal ref={ref => this.logModal = ref}>
<Log lines={this.logLines} focus={this.state.logFocus}/>
<Log lines={this.state.logLines} focus={this.state.logFocus}/>
</Modal>
}