From 1949b7635448e9cd8a61fe829d7e0dd8be56f575 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 27 Feb 2023 15:52:55 -0800 Subject: [PATCH] collapse mode for screen window view --- src/main.tsx | 102 ++++++++++++++++++++++++++++++----------- src/model.ts | 2 +- src/sh2.less | 127 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 165 insertions(+), 66 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 604d0855..3f92bc64 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -32,6 +32,7 @@ type OArr = mobx.IObservableArray; type OMap = mobx.ObservableMap; type VisType = "visible" | ""; +type RenderModeType = "normal" | "collapsed"; type HeightChangeCallbackType = (lineNum : number, newHeight : number, oldHeight : number) => void; @@ -192,6 +193,7 @@ class LineAvatar extends React.Component<{line : LineType, cmd : Cmd}, {}> { let lineNumStr = (line.linenumtemp ? "~" : "") + String(line.linenum); let status = (cmd != null ? cmd.getStatus() : "done"); let rtnstate = (cmd != null ? cmd.getRtnState() : false); + let isComment = (line.linetype == "text"); return (
{lineNumStr} @@ -201,13 +203,16 @@ class LineAvatar extends React.Component<{line : LineType, cmd : Cmd}, {}> { + + +
); } } @mobxReact.observer -class LineText extends React.Component<{sw : ScreenWindow, line : LineType}, {}> { +class LineText extends React.Component<{sw : ScreenWindow, line : LineType, renderMode : RenderModeType, topBorder : boolean}, {}> { @boundMethod clickHandler() { let {line} = this.props; @@ -215,12 +220,20 @@ class LineText extends React.Component<{sw : ScreenWindow, line : LineType}, {}> } render() { - let {sw, line} = this.props; + let {sw, line, topBorder, renderMode} = this.props; let formattedTime = getLineDateTimeStr(line.ts); let isSelected = mobx.computed(() => (sw.selectedLine.get() == line.linenum), {name: "computed-isSelected"}).get(); let isFocused = mobx.computed(() => (sw.focusType.get() == "cmd"), {name: "computed-isFocused"}).get(); + let isCollapsed = (renderMode == "collapsed"); + let mainClass = cn( + "line", + "line-text", + "focus-parent", + {"top-border": topBorder}, + {"collapsed": isCollapsed}, + ); return ( -
+
@@ -256,6 +269,10 @@ class Prompt extends React.Component<{rptr : RemotePtrType, festate : FeStateTyp if (remote && remote.remoteopts && remote.remoteopts.color) { colorClass = "color-" + remote.remoteopts.color; } + // TESTING cwd shortening with triple colon character + // if (cwd.startsWith("~/work/gopath/src/github.com/scripthaus-dev")) { + // cwd = cwd.replace("~/work/gopath/src/github.com/scripthaus-dev", "\u22EEscripthaus-dev"); + // } return ( [{remoteStr}] {cwd} {isRoot ? "#" : "$"} ); @@ -506,7 +523,7 @@ class MarkdownRenderer extends React.Component<{sw : ScreenWindow, line : LineTy } @mobxReact.observer -class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : HeightChangeCallbackType, collapsed : OV, topBorder : boolean}, {}> { +class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : HeightChangeCallbackType, topBorder : boolean, renderMode : RenderModeType, overrideCollapsed : OV}, {}> { lineRef : React.RefObject = React.createRef(); cmdTextRef : React.RefObject = React.createRef(); rtnStateDiff : mobx.IObservableValue = mobx.observable.box(null, {name: "linecmd-rtn-state-diff"}); @@ -520,8 +537,8 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } checkStateDiffLoad() : void { - let {line, staticRender, visible, collapsed} = this.props; - if (staticRender || collapsed.get()) { + let {line, staticRender, visible} = this.props; + if (staticRender || this.isCollapsed()) { return; } if (!visible) { @@ -737,9 +754,10 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width @boundMethod handleCollapsedClick() { + let {overrideCollapsed} = this.props; mobx.action(() => { - let isCollapsed = this.props.collapsed.get(); - this.props.collapsed.set(!isCollapsed); + let isCollapsed = overrideCollapsed.get(); + overrideCollapsed.set(!isCollapsed); })(); } @@ -748,23 +766,33 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width return "line-" + getLineId(line); } + isCollapsed() : boolean { + let {renderMode, overrideCollapsed} = this.props; + return (renderMode == "collapsed" && !overrideCollapsed.get()); + } + renderSimple() { - let {sw, line, width, topBorder} = this.props; + let {sw, line, width, topBorder, renderMode} = this.props; let cmd = GlobalModel.getCmd(line); - let usedRows = sw.getUsedRows(line, cmd, width); + let isCollapsed = this.isCollapsed(); let mainDivCn = cn( "line", "line-cmd", {"top-border": topBorder}, + {"collapsed": isCollapsed}, ); // header is 36px tall, padding+border = 6px + // collapsed header is 24px tall + 6px // zero-terminal is 0px // terminal-wrapper overhead is 11px (margin/padding) // inner-height, if zero-lines => 42 // else: 53+(lines*lineheight) - let height = 42; // height of zero height terminal - if (usedRows > 0) { - height = 53 + termHeightFromRows(usedRows, GlobalModel.termFontSize.get()); + let height = (isCollapsed ? 30 : 42); // height of zero height terminal + if (!isCollapsed) { + let usedRows = sw.getUsedRows(line, cmd, width); + if (usedRows > 0) { + height = 53 + termHeightFromRows(usedRows, GlobalModel.termFontSize.get()); + } } return (
@@ -795,7 +823,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } render() { - let {sw, line, width, staticRender, visible, topBorder} = this.props; + let {sw, line, width, staticRender, visible, topBorder, renderMode} = this.props; let model = GlobalModel; let lineid = line.lineid; let isVisible = visible.get(); @@ -825,7 +853,8 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width }, {name: "computed-isFgFocused"}).get(); let isStatic = staticRender; let isRunning = cmd.isRunning() - let isCollapsed = this.props.collapsed.get(); + let isCollapsed = this.isCollapsed(); + let isExpanded = this.isCmdExpanded.get(); let rsdiff = this.rtnStateDiff.get(); // console.log("render", "#" + line.linenum, termHeight, usedRows, cmd.getStatus(), (this.rtnStateDiff.get() != null), (!cmd.isRunning() ? "cmd-done" : "running")); let mainDivCn = cn( @@ -846,12 +875,14 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width ref={this.lineRef} onClick={this.handleClick} data-lineid={line.lineid} data-linenum={line.linenum} data-windowid={line.windowid} data-cmdid={line.cmdid}>
-
+
-
- - -
+ +
+ + +
+
{this.renderMetaWrap(cmd)}
@@ -885,7 +916,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } @mobxReact.observer -class Line extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : HeightChangeCallbackType, collapsed : OV, topBorder : boolean}, {}> { +class Line extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV, onHeightChange : HeightChangeCallbackType, overrideCollapsed : OV, topBorder : boolean, renderMode : RenderModeType}, {}> { render() { let line = this.props.line; if (line.archived) { @@ -2282,7 +2313,7 @@ class CmdInput extends React.Component<{}, {}> { } @mobxReact.observer -class LinesView extends React.Component<{sw : ScreenWindow, width : number, lines : LineType[]}, {}> { +class LinesView extends React.Component<{sw : ScreenWindow, width : number, lines : LineType[], renderMode : RenderModeType}, {}> { rszObs : any; linesRef : React.RefObject; staticRender : OV = mobx.observable.box(true, {name: "static-render"}); @@ -2595,7 +2626,7 @@ class LinesView extends React.Component<{sw : ScreenWindow, width : number, line } render() { - let {sw, width, lines} = this.props; + let {sw, width, lines, renderMode} = this.props; let selectedLine = sw.selectedLine.get(); // for re-rendering let line : LineType = null; for (let i=0; i; + let lineElem = ; lineElements.push(lineElem); } return ( @@ -2649,6 +2680,8 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { height : mobx.IObservableValue = mobx.observable.box(0, {name: "sw-view-height"}); setSize_debounced : (width : number, height : number) => void; + renderMode : OV = mobx.observable.box("normal", {name: "renderMode"}); + constructor(props : any) { super(props); this.setSize_debounced = debounce(1000, this.setSize.bind(this)); @@ -2713,6 +2746,14 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { return {position: "absolute", width: "100%", height: "100%", overflowX: "hidden"}; } + @boundMethod + toggleRenderMode() { + let renderMode = this.renderMode.get(); + mobx.action(() => { + this.renderMode.set(renderMode == "normal" ? "collapsed" : "normal"); + })(); + } + renderError(message : string, fade : boolean) { let {sw} = this.props; return ( @@ -2751,13 +2792,22 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { let isActive = sw.isActive(); let selectedLine = sw.selectedLine.get(); let lines = win.getNonArchivedLines(); + let renderMode = this.renderMode.get(); return (
- {sw.name.get()} +
{sw.name.get()}
+
+ + + + + + +
0}> - +
diff --git a/src/model.ts b/src/model.ts index 4ecab9aa..3b460bdb 100644 --- a/src/model.ts +++ b/src/model.ts @@ -193,7 +193,7 @@ class Cmd { isMultiLineCmdText() : boolean { let cmdText = this.data.get().cmdstr; if (cmdText == null) { - return "(none)"; + return false; } cmdText = cmdText.trim(); let nlIdx = cmdText.indexOf("\n"); diff --git a/src/sh2.less b/src/sh2.less index 8cbb9914..3f01f209 100644 --- a/src/sh2.less +++ b/src/sh2.less @@ -102,13 +102,28 @@ body::-webkit-scrollbar { right: 0; background-color: rgba(78, 154, 6, 0.65); color: black; - padding: 2px 4px 2px 4px; + padding: 2px 8px 2px 4px; border-bottom-left-radius: 5px; z-index: 10; font-size: 12px; &.is-active { - color: white; + color: #ccc; + } + + .window-name { + } + + .render-mode { + padding-top: 2px; + font-size: 16px; + position: relative; + cursor: pointer; + color: #ccc; + + &:hover { + color: white; + } } } @@ -684,17 +699,31 @@ body::-webkit-scrollbar { .line.line-text { flex-direction: row; + padding-top: 5px; .line-content { display: flex; flex-direction: column; flex-grow: 1; + margin-left: 10px; .text { font-size: 1rem; color: #ddd; } } + + &.collapsed { + .meta { + display: none; + } + + min-height: 20px; + } + + &.collapsed.top-border { + min-height: 26px; + } } .line.line-selected { @@ -710,7 +739,6 @@ body::-webkit-scrollbar { .avatar { cursor: pointer; - margin-right: 10px; height: 36px; } @@ -723,13 +751,60 @@ body::-webkit-scrollbar { &.is-expanded { height: auto; } + + &.is-collapsed { + height: 24px; + } + + &.is-expanded.is-collapsed { + height: auto; + } .meta-wrap { flex: 1 1 0px; min-width: 0; display: flex; flex-direction: column; - justify-content: center; + justify-content: flex-start; + margin-left: 10px; + } + + .collapsed-indicator + .meta-wrap { + margin-left: 0; + } + + .line-icon { + display: block; + visibility: hidden; + cursor: pointer; + padding: 3px; + font-size: 1.5rem; + } + + .line-icon.line-bookmark.active { + cursor: auto; + } + + .line-icon + .line-icon { + margin-left: 5px; + } + + .line-icon.active { + visibility: visible; + display: block; + + i.fa-star, i.fa-thumb-tack { + color: @term-bright-yellow; + } + + i.fa-bookmark { + color: @term-bright-blue; + } + } + + &:hover .line-icon { + visibility: visible; + display: block; } } @@ -737,40 +812,6 @@ body::-webkit-scrollbar { margin-left: 2px; } - .line-icon { - display: block; - visibility: hidden; - cursor: pointer; - padding: 3px; - font-size: 1.5rem; - } - - .line-icon.line-bookmark.active { - cursor: auto; - } - - .line-icon + .line-icon { - margin-left: 5px; - } - - .line-icon.active { - visibility: visible; - display: block; - - i.fa-star, i.fa-thumb-tack { - color: @term-bright-yellow; - } - - i.fa-bookmark { - color: @term-bright-blue; - } - } - - &:hover .line-icon { - visibility: visible; - display: block; - } - &.has-rtnstate .terminal-wrapper { padding-bottom: 0; margin-bottom: -5px; @@ -965,7 +1006,6 @@ body::-webkit-scrollbar { font-weight: bold; color: white; font-size: 16px; - margin-right: 10px; border-radius: 5px; position: relative; @@ -980,6 +1020,13 @@ body::-webkit-scrollbar { right: 2px; } + .comment-icon { + font-size: 10px; + position: absolute; + top: 0px; + right: -4px; + } + &.num-4 { font-size: 13px; } @@ -1041,6 +1088,8 @@ body::-webkit-scrollbar { cursor: pointer; margin-left: 2px; margin-right: 2px; + position: relative; + top: -2px; } .meta {