From 3d29d0d34efd4288ea6b8aff901d89577a2baf4b Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 7 Jul 2022 21:49:15 -0700 Subject: [PATCH] integrate cmd status into fe tailing --- src/main.tsx | 6 +++-- src/session.ts | 10 ++++++-- src/sh2.less | 9 ++++++-- src/term.ts | 62 ++++++++++++++++++++++++++++++++++++++++++-------- src/ws.ts | 8 +++++-- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index ac433c04..8b8a8233 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -168,6 +168,7 @@ class LineCmd extends React.Component<{line : LineType, session : Session, chang let {session, line} = this.props; let lineid = line.lineid.toString(); let running = false; + let detached = false; let rows = 0; let cols = 0; let termWrap = session.getTermWrapByLine(line); @@ -181,10 +182,12 @@ class LineCmd extends React.Component<{line : LineType, session : Session, chang let remote : RemoteType = null; if (cmd != null) { remote = session.getRemote(cmd.remoteid); + running = (cmd.status == "running"); + detached = (cmd.status == "detached"); } return (
-
= 5}, {"running": running})}> +
= 5}, {"running": running}, {"detached": detached})}> {lineid}
@@ -353,7 +356,6 @@ class SessionView extends React.Component<{session : Session}, {}> { @boundMethod changeSizeCallback(term : TermWrap) { - console.log("changesize", term); if (this.shouldFollow.get()) { let session = this.props.session; let window = session.getActiveWindow(); diff --git a/src/session.ts b/src/session.ts index 83e427e2..3dca4c57 100644 --- a/src/session.ts +++ b/src/session.ts @@ -318,13 +318,19 @@ class Session { } getTermWrapByLine(line : LineType) : TermWrap { + if (!line.cmdid) { + return null; + } let termKey = makeTermKey(line.sessionid, line.cmdid, line.windowid, line.lineid); let termWrap = this.termMap[termKey]; if (termWrap != null) { return termWrap; } - termWrap = new TermWrap(line.sessionid, line.cmdid); - console.log("create term", termWrap); + let cmd = this.getCmd(line.cmdid); + if (!cmd) { + return null; + } + termWrap = new TermWrap(line.sessionid, line.cmdid, cmd.status); this.termMap[termKey] = termWrap; this.termMapById[termWrap.termId] = termWrap; termWrap.initialized = true; diff --git a/src/sh2.less b/src/sh2.less index 617f6645..dbcf7605 100644 --- a/src/sh2.less +++ b/src/sh2.less @@ -203,7 +203,7 @@ html, body, #main { .avatar { height: 38px; width: 38px; - background-color: #729fcf; + background-color: #555; display: flex; align-items: center; justify-content: center; @@ -222,7 +222,12 @@ html, body, #main { } &.running { - background-color: #cc0000; + background-color: #729fcf; + } + + &.detached { + background-color: #729fcf; + outline: 2px solid white; } } diff --git a/src/term.ts b/src/term.ts index ef7a4c6e..90e8f95c 100644 --- a/src/term.ts +++ b/src/term.ts @@ -34,41 +34,79 @@ class TermWrap { initialized : boolean = false; changeSizeCallback : (TermWrap) => void = null; usedRows : number; + tailReqId : string; + cmdStatus : string; - constructor(sessionId : string, cmdId : string) { + constructor(sessionId : string, cmdId : string, status : string) { this.termId = uuidv4(); this.sessionId = sessionId; this.cmdId = cmdId; + this.cmdStatus = status; this.terminal = new Terminal({rows: 25, cols: 80, theme: {foreground: "#d3d7cf"}}); this.usedRows = 2; } destroy() { - + this.stopPtyTail(); + } + + setCmdStatus(status : string) { + if (this.cmdStatus == status) { + return; + } + this.cmdStatus = status; + if (!this.canTailPty() && this.tailReqId) { + this.stopPtyTail(); + } + } + + canTailPty() : boolean { + return this.cmdStatus == "running" || this.cmdStatus == "detached"; } @boundMethod onKeyHandler(event : any) { let inputPacket = { type: "input", - sessionid: this.sessionId, - cmdid: this.cmdId, + ck: this.sessionId + "/" + this.cmdId, inputdata: event.key, }; GlobalWS.pushMessage(inputPacket); } + stopPtyTail() { + if (this.tailReqId == null) { + return; + } + let untailCmdPacket = { + type: "untailcmd", + reqid: uuidv4(), + ck: this.sessionId + "/" + this.cmdId, + }; + GlobalWS.sendMessage(untailCmdPacket); + GlobalWS.unregisterReq(this.tailReqId); + this.tailReqId = null; + } + startPtyTail() { + if (this.tailReqId != null) { + return; + } + if (!this.canTailPty()) { + return; + } + this.tailReqId = uuidv4(); let getCmdPacket = { type: "getcmd", - reqid: this.termId, - sessionid: this.sessionId, - cmdid: this.cmdId, + reqid: this.tailReqId, + ck: this.sessionId + "/" + this.cmdId, ptypos: this.ptyPos, tail: true, + ptyonly: true, }; GlobalWS.registerAndSendGetCmd(getCmdPacket, (dataPacket) => { - this.updatePtyData(this.ptyPos, dataPacket.ptydata, dataPacket.ptydatalen); + let realData = atob(dataPacket.ptydata64); + this.updatePtyData(this.ptyPos, realData, dataPacket.ptydatalen); }); } @@ -109,7 +147,13 @@ class TermWrap { usedRows = i+1; } } - this.usedRows = usedRows; + if (this.usedRows != usedRows) { + this.usedRows = usedRows; + if (this.changeSizeCallback != null) { + let cb = this.changeSizeCallback; + setTimeout(() => cb(this), 0); + } + } return; } diff --git a/src/ws.ts b/src/ws.ts index cf1bda2e..f0d2f4e3 100644 --- a/src/ws.ts +++ b/src/ws.ts @@ -29,6 +29,10 @@ class WSControl { this.pushMessage(pk) } + unregisterReq(reqid : string) { + delete this.reqMap[reqid]; + } + reconnect() { if (this.open.get()) { this.wsConn.close(); @@ -123,9 +127,9 @@ class WSControl { return; } if (eventData.type == "cmddata") { - let cb = this.reqMap[eventData.reqid]; + let cb = this.reqMap[eventData.respid]; if (!cb) { - console.log(sprintf("websocket cmddata req=%s -- no callback", eventData.reqid)); + console.log(sprintf("websocket cmddata req=%s -- no callback", eventData.respid)); return; } cb(eventData);