;
private resizeObserver: ResizeObserver;
constructor(props: OutputProps) {
super(props);
this.clear = this.clear.bind(this);
this.logLine = this.logLine.bind(this);
this.logLines = this.logLines.bind(this);
this.updateDimensions = this.updateDimensions.bind(this);
this.outputRef = React.createRef();
this.listRef = React.createRef();
this.resizeObserver = new ResizeObserver(this.updateDimensions);
this.state = {
lines: [],
color: "",
grouper: new OutputGrouper(),
height: 10,
width: 10,
state: SizeState.Final,
};
this.state.grouper.handler = (lines: string[]) => {
this.setState((s) => mergeLines(s, lines));
};
}
componentDidMount() {
this.updateDimensions();
if (this.outputRef.current) {
this.resizeObserver.observe(this.outputRef.current);
}
}
componentWillUnmount() {
this.resizeObserver.disconnect();
}
componentDidUpdate(_: OutputProps, prevState: FullOutputState) {
if (
prevState.lines.length == this.state.lines.length ||
!this.listRef.current
) {
return;
}
this.listRef.current.scrollToItem(this.state.lines.length - 1);
}
clear() {
this.state.grouper.clear();
this.setState({
lines: [],
color: "",
});
}
updateDimensions() {
if (!this.outputRef.current) {
return;
}
if (this.state.state == SizeState.Updating) {
this.setState({
width: this.outputRef.current.offsetWidth - 1,
height: this.outputRef.current.offsetHeight - 1,
state: SizeState.Final,
});
return;
}
this.setState(
{
width: 0,
height: 0,
state: SizeState.Updating,
},
this.triggerDimensionUpdate.bind(this),
);
}
triggerDimensionUpdate() {
requestAnimationFrame(() => {
this.updateDimensions();
});
}
logLines(lines: string[]) {
this.state.grouper.storeLines(lines);
}
logLine(line: string) {
this.logLines([line]);
}
render() {
return (
{({ index, style }) => {
const line = this.state.lines[index];
return (
{line.text}
);
}}
);
}
}