diff --git a/src/sh2.less b/src/sh2.less index d13d6b8b..7b1d5ee4 100644 --- a/src/sh2.less +++ b/src/sh2.less @@ -3211,6 +3211,7 @@ body.prompt-webshare #main { .web-screen-view { height: 100%; + width: 100%; flex-grow: 1; display: flex; flex-direction: column; diff --git a/src/types.ts b/src/types.ts index 87e0a570..b60ca693 100644 --- a/src/types.ts +++ b/src/types.ts @@ -551,6 +551,7 @@ type WebScreenUpdate = { lines : WebLine[], cmds : WebCmd[], ptydata : PtyDataUpdate[], + removedlines : string[], }; type WebShareWSMessage = { diff --git a/src/webshare-elems.tsx b/src/webshare-elems.tsx index 02ebf9a6..d9fc5200 100644 --- a/src/webshare-elems.tsx +++ b/src/webshare-elems.tsx @@ -12,6 +12,7 @@ import {PluginModel} from "./plugins"; import * as lineutil from "./lineutil"; import * as util from "./util"; import {windowWidthToCols, windowHeightToRows, termHeightFromRows, termWidthFromCols} from "./textmeasure"; +import {debounce, throttle} from "throttle-debounce"; type OV = mobx.IObservableValue; type OArr = mobx.IObservableArray; @@ -21,6 +22,8 @@ type OMap = mobx.ObservableMap; // TODO bug with finishing up the ptydata // TODO bug with ptydata late -- not updating usedrows // TODO scroll screen when new cmds arrive (selection) +// TODO archived should delete line +// TODO implement linedel function makeFullRemoteRef(ownerName : string, remoteRef : string, name : string) : string { if (isBlank(ownerName) && isBlank(name)) { @@ -112,7 +115,7 @@ class LineAvatar extends React.Component<{line : T.WebLine, cmd : T.WebCmd}, {}> } @mobxReact.observer -class WebLineCmdView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, topBorder : boolean}, {}> { +class WebLineCmdView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, topBorder : boolean, width: number}, {}> { isCmdExpanded : OV = mobx.observable.box(false, {name: "cmd-expanded"}); isOverflow : OV = mobx.observable.box(false, {name: "line-overflow"}); cmdTextRef : React.RefObject = React.createRef(); @@ -209,6 +212,10 @@ class WebLineCmdView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, let rendererType = lineutil.getRendererType(line); let mainCn = cn("web-line line line-cmd", {"top-border": topBorder}); let visObs = mobx.observable.box(true, {name: "visObs"}); + let width = this.props.width; + if (width == 0) { + width = 1024; + } return (
@@ -216,7 +223,7 @@ class WebLineCmdView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, {this.renderMetaWrap()}
- +
); } @@ -358,7 +365,7 @@ class TerminalRenderer extends React.Component<{line : T.WebLine, cmd : T.WebCmd } @mobxReact.observer -class WebLineView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, topBorder : boolean}, {}> { +class WebLineView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, topBorder : boolean, width : number}, {}> { render() { let {line} = this.props; if (line.linetype == "text") { @@ -375,6 +382,56 @@ class WebLineView extends React.Component<{line : T.WebLine, cmd : T.WebCmd, top @mobxReact.observer class WebScreenView extends React.Component<{screen : T.WebFullScreen}, {}> { + viewRef : React.RefObject = React.createRef(); + width : OV = mobx.observable.box(0, {name: "webScreenView-width"}); + rszObs : ResizeObserver; + handleResize_debounced : (entries : any) => void; + + constructor(props : any) { + super(props); + this.handleResize_debounced = debounce(1000, this.handleResize.bind(this)); + } + + componentDidMount() : void { + if (this.viewRef.current != null) { + let linesElem = this.viewRef.current; + this.rszObs = new ResizeObserver(this.handleResize_debounced.bind(this)); + this.rszObs.observe(linesElem); + let width = linesElem.offsetWidth; + if (width > 0) { + mobx.action(() => { + this.width.set(width); + })(); + } + } + } + + handleResize(entries : any) : void { + let linesElem = this.viewRef.current; + if (linesElem == null) { + return; + } + let width = linesElem.offsetWidth; + let height = linesElem.offsetHeight; + if (width != this.width.get()) { + WebShareModel.resizeWindow({width: width, height: height}); + console.log("width-update", width); + mobx.action(() => { + this.width.set(width); + })(); + } + } + + renderEmpty() : any { + return ( +
+
+
+
+
+ ); + } + render() { let {screen} = this.props; let lines = screen.lines ?? []; @@ -388,6 +445,10 @@ class WebScreenView extends React.Component<{screen : T.WebFullScreen}, {}> { let todayStr = util.getTodayStr(); let yesterdayStr = util.getYesterdayStr(); let prevDateStr : string = null; + let width = this.width.get(); + if (width == 0) { + return this.renderEmpty(); + } for (let idx=0; idx { lineElements.push(sepElem); } let topBorder = (dateSepStr == null) && (idx != 0); - let lineElem = ; + let lineElem = ; lineElements.push(lineElem); } return ( -
+
-
+
{lineElements}
diff --git a/src/webshare-model.ts b/src/webshare-model.ts index 77e4846b..ceaa1df8 100644 --- a/src/webshare-model.ts +++ b/src/webshare-model.ts @@ -58,6 +58,14 @@ class WebShareModelClass { return 12; } + resizeWindow(winSize : T.WindowSize) : void { + let cols = windowWidthToCols(winSize.width, this.getTermFontSize()); + for (let lineId in this.terminals) { + let termWrap = this.terminals[lineId]; + termWrap.resizeCols(cols); + } + } + mergeLine(fullScreen : T.WebFullScreen, newLine : T.WebLine) { for (let i=0; i this.setCmdDone(cmd.lineid), 300); + } fullScreen.cmds[i] = newCmd; return; } @@ -111,7 +149,14 @@ class WebShareModelClass { if (termWrap == null) { continue; } - termWrap.receiveData(data.ptypos, base64ToArray(data.data)); + let dataArr = base64ToArray(data.data); + termWrap.receiveData(data.ptypos, dataArr); + console.log("receivedata", data.lineid, data.ptypos + dataArr.length); + } + } + if (msg.removedlines != null && msg.removedlines.length > 0) { + for (let lineid of msg.removedlines) { + this.removeLine(fullScreen, lineid); } } })();