diff --git a/src/main.tsx b/src/main.tsx index 89878cd4..34a0fe5b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -508,9 +508,12 @@ 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}, {}> { lineRef : React.RefObject = React.createRef(); + cmdTextRef : React.RefObject = React.createRef(); rtnStateDiff : mobx.IObservableValue = mobx.observable.box(null, {name: "linecmd-rtn-state-diff"}); rtnStateDiffFetched : boolean = false; lastHeight : number; + isOverflow : OV = mobx.observable.box(false, {name: "line-overflow"}); + isCmdExpanded : OV = mobx.observable.box(false, {name: "cmd-expanded"}); constructor(props) { super(props); @@ -567,6 +570,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width componentDidMount() { this.componentDidUpdate(null, null, null); + this.checkCmdText(); } // FIXME @@ -585,6 +589,13 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width } } + @boundMethod + handleExpandCmd() : void { + mobx.action(() => { + this.isCmdExpanded.set(true); + })(); + } + renderCmdText(cmd : Cmd, remote : RemoteType) : any { if (cmd == null) { return ( @@ -593,11 +604,31 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width ); } - let remoteStr = getRemoteStr(cmd.remote); - let cwd = getCwdStr(remote, cmd.getRemoteFeState()); + if (this.isCmdExpanded.get()) { + return ( + +
+
+ +
+
+
+
{cmd.getFullCmdText()}
+
+
+ ); + } + let isMultiLine = cmd.isMultiLineCmdText(); return ( -
- {cmd.getSingleLineCmdText()} +
+
+ + + {cmd.getSingleLineCmdText()} +
+ +
...▼
+
); } @@ -614,6 +645,28 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width componentDidUpdate(prevProps, prevState, snapshot : {height : number}) : void { this.handleHeightChange(); this.checkStateDiffLoad(); + this.checkCmdText(); + } + + checkCmdText() { + let metaElem = this.cmdTextRef.current; + if (metaElem == null || metaElem.childNodes.length == 0) { + return; + } + let metaElemWidth = metaElem.offsetWidth; + let metaChild = metaElem.firstChild; + let children = metaChild.childNodes; + let childWidth = 0; + for (let i=0; i metaElemWidth); + if (isOverflow != this.isOverflow.get()) { + mobx.action(() => { + this.isOverflow.set(isOverflow); + })(); + } } @boundMethod @@ -719,6 +772,27 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
); } + + renderMetaWrap(cmd : Cmd) { + let {line} = this.props; + let model = GlobalModel; + let formattedTime = getLineDateTimeStr(line.ts); + let termOpts = cmd.getTermOpts(); + let remote = model.getRemote(cmd.remoteId); + return ( +
+
+
{formattedTime}
+
 
+
+ ({termOpts.rows}x{termOpts.cols}) + +
+
+ {this.renderCmdText(cmd, remote)} +
+ ); + } render() { let {sw, line, width, staticRender, visible, topBorder} = this.props; @@ -737,9 +811,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width ); } - let remote = model.getRemote(cmd.remoteId); let status = cmd.getStatus(); - let termOpts = cmd.getTermOpts(); let lineNumStr = (line.linenumtemp ? "~" : "") + String(line.linenum); let isSelected = mobx.computed(() => (sw.selectedLine.get() == line.linenum), {name: "computed-isSelected"}).get(); let isPhysicalFocused = mobx.computed(() => sw.getIsFocused(line.linenum), {name: "computed-getIsFocused"}).get(); @@ -768,33 +840,19 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width let RendererComponent : RendererComponentType = TerminalRenderer; if (line.renderer == "image") { RendererComponent = ImageRenderer; - } - + } return (
-
+
-
-
-
{formattedTime}
-
 
-
- ({termOpts.rows}x{termOpts.cols}) - -
-
-
- {this.renderCmdText(cmd, remote)} -
-
-
+ {this.renderMetaWrap(cmd)}
@@ -2175,8 +2233,6 @@ class CmdInput extends React.Component<{}, {}> { remote = GlobalModel.getRemote(ri.remoteid); remoteState = ri.festate; } - let remoteStr = getRemoteStr(rptr); - let cwdStr = getCwdStr(remote, remoteState); let infoShow = inputModel.infoShow.get(); let historyShow = !infoShow && inputModel.historyShow.get(); let infoMsg = inputModel.infoMsg.get(); diff --git a/src/model.ts b/src/model.ts index e877386f..4ecab9aa 100644 --- a/src/model.ts +++ b/src/model.ts @@ -190,6 +190,16 @@ class Cmd { return this.data.get().festate; } + isMultiLineCmdText() : boolean { + let cmdText = this.data.get().cmdstr; + if (cmdText == null) { + return "(none)"; + } + cmdText = cmdText.trim(); + let nlIdx = cmdText.indexOf("\n"); + return (nlIdx != -1); + } + getSingleLineCmdText() { let cmdText = this.data.get().cmdstr; if (cmdText == null) { @@ -198,11 +208,17 @@ class Cmd { cmdText = cmdText.trim(); let nlIdx = cmdText.indexOf("\n"); if (nlIdx != -1) { - cmdText = cmdText.substr(0, nlIdx) + "..."; + cmdText = cmdText.substr(0, nlIdx); } - if (cmdText.length > 80) { - cmdText = cmdText.substr(0, 77) + "..."; + return cmdText; + } + + getFullCmdText() { + let cmdText = this.data.get().cmdstr; + if (cmdText == null) { + return "(none)"; } + cmdText = cmdText.trim(); return cmdText; } diff --git a/src/sh2.less b/src/sh2.less index 204d8a9c..6b5b6dfb 100644 --- a/src/sh2.less +++ b/src/sh2.less @@ -714,9 +714,15 @@ body::-webkit-scrollbar { display: flex; flex-direction: row; height: 36px; + width: 100%; + + &.is-expanded { + height: auto; + } .meta-wrap { - flex-grow: 1; + flex: 1 1 0px; + min-width: 0; display: flex; flex-direction: column; justify-content: center; @@ -728,7 +734,8 @@ body::-webkit-scrollbar { } .line-icon { - display: none; + display: block; + visibility: hidden; cursor: pointer; padding: 3px; font-size: 1.5rem; @@ -743,6 +750,7 @@ body::-webkit-scrollbar { } .line-icon.active { + visibility: visible; display: block; i.fa-star, i.fa-thumb-tack { @@ -755,6 +763,7 @@ body::-webkit-scrollbar { } &:hover .line-icon { + visibility: visible; display: block; } @@ -1035,7 +1044,7 @@ body::-webkit-scrollbar { flex-direction: row; font-size: 1rem; margin-top: -4px; - + .user { color: lighten(@soft-blue, 10%); font-weight: bold; @@ -1079,6 +1088,31 @@ body::-webkit-scrollbar { overflow: hidden; margin-left: 0; } + + .cmdtext-overflow { + flex-shrink: 0; + padding-right: 2px; + color: white; + cursor: pointer; + .mono-font(16px); + margin-top: 4px; + } + } + + .cmdtext-expanded-wrapper { + margin-top: 2px; + padding-left: 6px; + overflow-y: auto; + max-height: 54px; + border-left: 2px solid #333; + margin-left: 3px; + + .cmdtext-expanded { + white-space: pre; + .mono-font(14px); + color: white; + padding-bottom: 5px; + } } }