From 237a2b083efa55a2887ff3630e5bf0eb0d02273b Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 3 Feb 2023 18:29:07 -0800 Subject: [PATCH] small refactor to get ready for renderers --- src/main.tsx | 149 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 10 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 9bee71ec..fabb310d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -214,9 +214,128 @@ class Prompt extends React.Component<{rptr : RemotePtrType, festate : FeStateTyp } @mobxReact.observer -class TerminalRenderer extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : HeightChangeCallbackType}, {}> { +class TerminalRenderer extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : () => void}, {}> { + termLoaded : mobx.IObservableValue = mobx.observable.box(false, {name: "linecmd-term-loaded"}); + elemRef : React.RefObject = React.createRef(); + + constructor(props) { + super(props); + } + + componentDidMount() { + this.componentDidUpdate(null, null, null); + } + + componentWillUnmount() { + if (this.termLoaded.get()) { + this.unloadTerminal(true); + } + } + + getSnapshotBeforeUpdate(prevProps, prevState) : {height : number} { + let elem = this.elemRef.current; + if (elem == null) { + return {height: 0}; + } + return {height: elem.offsetHeight}; + } + + componentDidUpdate(prevProps, prevState, snapshot : {height : number}) : void { + if (this.props.onHeightChange == null) { + return; + } + let {line} = this.props; + let curHeight = 0; + let elem = this.elemRef.current; + if (elem != null) { + curHeight = elem.offsetHeight; + } + if (snapshot == null) { + snapshot = {height: 0}; + } + if (snapshot.height != curHeight) { + this.props.onHeightChange(); + // console.log("line height change: ", line.linenum, snapshot.height, "=>", curHeight); + } + this.checkLoad(); + } + + checkLoad() : void { + let {line, staticRender, visible} = this.props; + if (staticRender) { + return; + } + let vis = visible && visible.get(); + let curVis = this.termLoaded.get(); + if (vis && !curVis) { + this.loadTerminal(); + } + else if (!vis && curVis) { + this.unloadTerminal(false); + } + } + + loadTerminal() : void { + let {sw, line} = this.props; + let model = GlobalModel; + let cmd = model.getCmd(line); + if (cmd == null) { + return; + } + let termId = "term-" + getLineId(line); + let termElem = document.getElementById(termId); + if (termElem == null) { + console.log("cannot load terminal, no term elem found", termId); + return; + } + sw.connectElem(termElem, line, cmd, this.props.width); + mobx.action(() => this.termLoaded.set(true))(); + } + + unloadTerminal(unmount : boolean) : void { + let {sw, line} = this.props; + sw.disconnectElem(line.cmdid); + if (!unmount) { + mobx.action(() => this.termLoaded.set(false))(); + let termId = "term-" + getLineId(line); + let termElem = document.getElementById(termId); + if (termElem != null) { + termElem.replaceChildren(); + } + } + } + + @boundMethod + clickTermBlock(e : any) { + let {sw, line} = this.props; + let model = GlobalModel; + let termWrap = sw.getRenderer(line.cmdid); + if (termWrap != null) { + termWrap.giveFocus(); + } + } + render() { - return null; + let {sw, line, width, staticRender, visible} = this.props; + let isPhysicalFocused = mobx.computed(() => sw.getIsFocused(line.linenum), {name: "computed-getIsFocused"}).get(); + let isFocused = mobx.computed(() => { + let swFocusType = sw.focusType.get(); + return isPhysicalFocused && (swFocusType == "cmd" || swFocusType == "cmd-fg") + }, {name: "computed-isFocused"}).get(); + let cmd = GlobalModel.getCmd(line); // will not be null + let usedRows = sw.getUsedRows(line, cmd, width); + let termHeight = termHeightFromRows(usedRows); + let termLoaded = this.termLoaded.get(); + return ( +
+ +
+
+
+
...
+ +
+ ); } } @@ -233,6 +352,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width lineRef : React.RefObject = React.createRef(); rtnStateDiff : mobx.IObservableValue = mobx.observable.box(null, {name: "linecmd-rtn-state-diff"}); rtnStateDiffFetched : boolean = false; + lastHeight : number; constructor(props) { super(props); @@ -385,6 +505,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } } + // TODO: this might not be necessary anymore because we're using this.lastHeight getSnapshotBeforeUpdate(prevProps, prevState) : {height : number} { let elem = this.lineRef.current; if (elem == null) { @@ -394,21 +515,29 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } componentDidUpdate(prevProps, prevState, snapshot : {height : number}) : void { + this.handleHeightChange(); + this.checkLoad(); + this.checkStateDiffLoad(); + } + + @boundMethod + handleHeightChange() { + if (this.props.onHeightChange == null) { + return; + } let {line} = this.props; let curHeight = 0; let elem = this.lineRef.current; if (elem != null) { curHeight = elem.offsetHeight; } - if (snapshot == null) { - snapshot = {height: 0}; + if (this.lastHeight == curHeight) { + return; } - if (snapshot.height != curHeight && this.props.onHeightChange != null) { - this.props.onHeightChange(line.linenum, curHeight, snapshot.height); - // console.log("line height change: ", line.linenum, snapshot.height, "=>", curHeight); - } - this.checkLoad(); - this.checkStateDiffLoad(); + let lastHeight = this.lastHeight; + this.lastHeight = curHeight; + this.props.onHeightChange(line.linenum, curHeight, lastHeight); + // console.log("line height change: ", line.linenum, lastHeight, "=>", curHeight); } @boundMethod