mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
cmd-up cmd-down working, new line type, remotealias
This commit is contained in:
@@ -73,6 +73,15 @@ function createWindow() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (input.meta && (input.code == "ArrowUp" || input.code == "ArrowDown")) {
|
||||
if (input.code == "ArrowUp") {
|
||||
win.webContents.send("meta-arrowup");
|
||||
} else {
|
||||
win.webContents.send("meta-arrowdown");
|
||||
}
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (input.code.startsWith("Digit") && input.meta) {
|
||||
let digitNum = parseInt(input.code.substr(5));
|
||||
if (isNaN(digitNum) || digitNum < 1 || digitNum > 9) {
|
||||
|
||||
+18
-8
@@ -120,7 +120,7 @@ class LineText extends React.Component<{sw : ScreenWindow, line : LineType}, {}>
|
||||
let line = this.props.line;
|
||||
let formattedTime = getLineDateStr(line.ts);
|
||||
return (
|
||||
<div className="line line-text">
|
||||
<div className="line line-text" data-lineid={line.lineid} data-windowid={line.windowid}>
|
||||
<div className="avatar">
|
||||
S
|
||||
</div>
|
||||
@@ -139,7 +139,7 @@ class LineText extends React.Component<{sw : ScreenWindow, line : LineType}, {}>
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width : number, interObs : IntersectionObserver, initVis : boolean}, {}> {
|
||||
class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width : number, interObs : IntersectionObserver, initVis : boolean, cmdRefNum : number}, {}> {
|
||||
termLoaded : mobx.IObservableValue<boolean> = mobx.observable.box(false);
|
||||
lineRef : React.RefObject<any> = React.createRef();
|
||||
iobsVal : InterObsValue = null;
|
||||
@@ -249,7 +249,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
|
||||
render() {
|
||||
let {sw, line, width} = this.props;
|
||||
let model = GlobalModel;
|
||||
let lineid = line.lineid.toString();
|
||||
let lineid = line.lineid;
|
||||
let formattedTime = getLineDateStr(line.ts);
|
||||
let cmd = model.getCmd(line);
|
||||
if (cmd == null) {
|
||||
@@ -271,11 +271,12 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
|
||||
let detached = (status == "detached");
|
||||
let termOpts = cmd.getTermOpts();
|
||||
let isFocused = sw.getIsFocused(line.cmdid);
|
||||
let cmdRefNumStr = (this.props.cmdRefNum == null ? "?" : this.props.cmdRefNum.toString());
|
||||
return (
|
||||
<div className={cn("line", "line-cmd", {"focus": isFocused})} id={"line-" + getLineId(line)} ref={this.lineRef} style={{position: "relative"}}>
|
||||
<div className={cn("line", "line-cmd", {"focus": isFocused})} id={"line-" + getLineId(line)} ref={this.lineRef} style={{position: "relative"}} data-lineid={line.lineid} data-windowid={line.windowid} data-cmdid={line.cmdid}>
|
||||
<div className="line-header">
|
||||
<div className={cn("avatar",{"num4": lineid.length == 4}, {"num5": lineid.length >= 5}, {"running": running}, {"detached": detached})} onClick={this.doRefresh}>
|
||||
{lineid}
|
||||
<div className={cn("avatar",{"num4": cmdRefNumStr.length == 4}, {"num5": cmdRefNumStr.length >= 5}, {"running": running}, {"detached": detached})} onClick={this.doRefresh}>
|
||||
{cmdRefNumStr}
|
||||
</div>
|
||||
<div className="meta-wrap">
|
||||
<div className="meta">
|
||||
@@ -301,7 +302,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class Line extends React.Component<{sw : ScreenWindow, line : LineType, width : number, interObs : IntersectionObserver, initVis : boolean}, {}> {
|
||||
class Line extends React.Component<{sw : ScreenWindow, line : LineType, width : number, interObs : IntersectionObserver, initVis : boolean, cmdRefNum : number}, {}> {
|
||||
render() {
|
||||
let line = this.props.line;
|
||||
if (line.linetype == "text") {
|
||||
@@ -702,6 +703,15 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
|
||||
if (win.lines.length == 0) {
|
||||
linesStyle.display = "none";
|
||||
}
|
||||
let cmdRefMap : Record<string, number> = {};
|
||||
let cmdNum = 1;
|
||||
for (let i=0; i<win.lines.length; i++) {
|
||||
let line = win.lines[i];
|
||||
if (line.cmdid != null) {
|
||||
cmdRefMap[line.lineid] = cmdNum;
|
||||
cmdNum++;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className="window-view" style={this.getWindowViewStyle()} id={this.getWindowViewDOMId()}>
|
||||
<div key="window-tag" className="window-tag">
|
||||
@@ -709,7 +719,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
|
||||
</div>
|
||||
<div key="lines" className="lines" onScroll={this.scrollHandler} id={this.getLinesDOMId()} style={linesStyle}>
|
||||
<For each="line" of={win.lines} index="idx">
|
||||
<Line key={line.lineid} line={line} sw={sw} width={this.width.get()} interObs={this.interObs} initVis={idx > win.lines.length-1-7}/>
|
||||
<Line key={line.lineid} line={line} sw={sw} width={this.width.get()} interObs={this.interObs} initVis={idx > win.lines.length-1-7} cmdRefNum={cmdRefMap[line.lineid] ?? 0}/>
|
||||
</For>
|
||||
</div>
|
||||
<If condition={win.lines.length == 0}>
|
||||
|
||||
+162
-5
@@ -28,6 +28,8 @@ type ElectronApi = {
|
||||
getId : () => string,
|
||||
onTCmd : (callback : (mods : KeyModsType) => void) => void,
|
||||
onICmd : (callback : (mods : KeyModsType) => void) => void,
|
||||
onMetaArrowUp : (callback : () => void) => void,
|
||||
onMetaArrowDown : (callback : () => void) => void,
|
||||
onBracketCmd : (callback : (event : any, arg : {relative : number}, mods : KeyModsType) => void) => void,
|
||||
onDigitCmd : (callback : (event : any, arg : {digit : number}, mods : KeyModsType) => void) => void,
|
||||
contextScreen : (screenOpts : {screenId : string}, position : {x : number, y : number}) => void,
|
||||
@@ -285,7 +287,8 @@ class Window {
|
||||
if (load) {
|
||||
this.loaded.set(true);
|
||||
}
|
||||
genMergeSimpleData(this.lines, win.lines, (l : LineType) => String(l.lineid), (l : LineType) => l.lineid);
|
||||
genMergeSimpleData(this.lines, win.lines, (l : LineType) => String(l.lineid), (l : LineType) => sprintf("%013d:%s", l.ts, l.lineid));
|
||||
|
||||
let cmds = win.cmds || [];
|
||||
for (let i=0; i<cmds.length; i++) {
|
||||
this.cmds[cmds[i].cmdid] = new Cmd(cmds[i]);
|
||||
@@ -308,6 +311,25 @@ class Window {
|
||||
return this.cmds[cmdId];
|
||||
}
|
||||
|
||||
getRunningCmdLines() : LineType[] {
|
||||
let rtn : LineType[] = [];
|
||||
for (let i=0; i<this.lines.length; i++) {
|
||||
let line = this.lines[i];
|
||||
if (line.cmdid == null) {
|
||||
continue;
|
||||
}
|
||||
let cmd = this.getCmd(line.cmdid);
|
||||
if (cmd == null) {
|
||||
continue;
|
||||
}
|
||||
let status = cmd.getStatus();
|
||||
if (status == "running" || status == "detached") {
|
||||
rtn.push(line);
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
getCurRemoteInstance() : RemoteInstanceType {
|
||||
let rname = this.curRemote.get();
|
||||
if (rname == null) {
|
||||
@@ -353,11 +375,12 @@ class Window {
|
||||
let lineIdx = 0;
|
||||
for (lineIdx=0; lineIdx<lines.length; lineIdx++) {
|
||||
let lineId = lines[lineIdx].lineid;
|
||||
let curTs = lines[lineIdx].ts;
|
||||
if (lineId == line.lineid) {
|
||||
this.lines[lineIdx] = line;
|
||||
return;
|
||||
}
|
||||
if (lineId > line.lineid) {
|
||||
if (curTs > line.ts || (curTs == line.ts && lineId > line.lineid)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -637,6 +660,13 @@ class InputModel {
|
||||
}
|
||||
};
|
||||
|
||||
type LineFocusType = {
|
||||
cmdInputFocus : boolean,
|
||||
lineid? : string,
|
||||
windowid? : string,
|
||||
cmdid? : string,
|
||||
};
|
||||
|
||||
class Model {
|
||||
clientId : string;
|
||||
activeSessionId : OV<string> = mobx.observable.box(null);
|
||||
@@ -661,6 +691,8 @@ class Model {
|
||||
this.inputModel = new InputModel();
|
||||
getApi().onTCmd(this.onTCmd.bind(this));
|
||||
getApi().onICmd(this.onICmd.bind(this));
|
||||
getApi().onMetaArrowUp(this.onMetaArrowUp.bind(this));
|
||||
getApi().onMetaArrowDown(this.onMetaArrowDown.bind(this));
|
||||
getApi().onBracketCmd(this.onBracketCmd.bind(this));
|
||||
getApi().onDigitCmd(this.onDigitCmd.bind(this));
|
||||
}
|
||||
@@ -726,13 +758,122 @@ class Model {
|
||||
GlobalInput.createNewScreen();
|
||||
}
|
||||
|
||||
onICmd(mods : KeyModsType) {
|
||||
focusCmdInput() : void {
|
||||
let elem = document.getElementById("main-cmd-input");
|
||||
if (elem != null) {
|
||||
elem.focus();
|
||||
}
|
||||
}
|
||||
|
||||
onICmd(mods : KeyModsType) {
|
||||
this.focusCmdInput();
|
||||
}
|
||||
|
||||
getFocusedLine() : LineFocusType {
|
||||
let elem = document.getElementById("main-cmd-input");
|
||||
if (document.activeElement == elem) {
|
||||
return {cmdInputFocus: true};
|
||||
}
|
||||
let lineElem : any = document.activeElement.closest(".line[data-lineid]");
|
||||
if (lineElem == null) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
cmdInputFocus: false,
|
||||
lineid: lineElem.dataset.lineid,
|
||||
windowid: lineElem.dataset.windowid,
|
||||
cmdid: lineElem.dataset.cmdid,
|
||||
};
|
||||
}
|
||||
|
||||
onMetaArrowUp() : void {
|
||||
let focus = this.getFocusedLine();
|
||||
if (focus == null) {
|
||||
return;
|
||||
}
|
||||
let sw : ScreenWindow = null;
|
||||
if (focus.cmdInputFocus) {
|
||||
sw = this.getActiveSW();
|
||||
}
|
||||
else {
|
||||
sw = this.getSWByWindowId(focus.windowid);
|
||||
}
|
||||
if (sw == null) {
|
||||
return;
|
||||
}
|
||||
let win = sw.getWindow();
|
||||
if (win == null) {
|
||||
return;
|
||||
}
|
||||
let runningLines = win.getRunningCmdLines();
|
||||
if (runningLines.length == 0) {
|
||||
return;
|
||||
}
|
||||
let switchLine : LineType = null;
|
||||
if (focus.cmdInputFocus) {
|
||||
switchLine = runningLines[runningLines.length-1];
|
||||
}
|
||||
else {
|
||||
let foundIdx = -1;
|
||||
for (let i=0; i<runningLines.length; i++) {
|
||||
if (runningLines[i].lineid == focus.lineid) {
|
||||
foundIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundIdx > 0) {
|
||||
switchLine = runningLines[foundIdx-1];
|
||||
}
|
||||
}
|
||||
if (switchLine == null || switchLine.cmdid == null) {
|
||||
return;
|
||||
}
|
||||
let termWrap = sw.getTermWrap(switchLine.cmdid);
|
||||
if (termWrap == null || termWrap.terminal == null) {
|
||||
return;
|
||||
}
|
||||
termWrap.terminal.focus();
|
||||
console.log("arrow-up", this.getFocusedLine(), "=>", switchLine);
|
||||
}
|
||||
|
||||
onMetaArrowDown() : void {
|
||||
let focus = this.getFocusedLine();
|
||||
if (focus == null || focus.cmdInputFocus) {
|
||||
return;
|
||||
}
|
||||
let sw = this.getSWByWindowId(focus.windowid);
|
||||
if (sw == null) {
|
||||
return;
|
||||
}
|
||||
let win = sw.getWindow();
|
||||
if (win == null) {
|
||||
return;
|
||||
}
|
||||
let runningLines = win.getRunningCmdLines();
|
||||
if (runningLines.length == 0) {
|
||||
this.focusCmdInput();
|
||||
return;
|
||||
}
|
||||
let foundIdx = -1;
|
||||
for (let i=0; i<runningLines.length; i++) {
|
||||
if (runningLines[i].lineid == focus.lineid) {
|
||||
foundIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundIdx == -1 || foundIdx == runningLines.length - 1) {
|
||||
this.focusCmdInput();
|
||||
return;
|
||||
}
|
||||
let switchLine = runningLines[foundIdx+1];
|
||||
let termWrap = sw.getTermWrap(switchLine.cmdid);
|
||||
if (termWrap == null || termWrap.terminal == null) {
|
||||
return;
|
||||
}
|
||||
termWrap.terminal.focus();
|
||||
console.log("arrow-down", this.getFocusedLine());
|
||||
}
|
||||
|
||||
onBracketCmd(e : any, arg : {relative: number}, mods : KeyModsType) {
|
||||
console.log("switch screen (bracket)", arg, mods);
|
||||
let activeSession = this.getActiveSession();
|
||||
@@ -801,7 +942,7 @@ class Model {
|
||||
let cmdline : CmdLineUpdateType = update.cmdline;
|
||||
this.inputModel.updateCmdLine(cmdline);
|
||||
}
|
||||
console.log("run-update>", interactive, update);
|
||||
// console.log("run-update>", interactive, update);
|
||||
}
|
||||
|
||||
getActiveSession() : Session {
|
||||
@@ -872,6 +1013,22 @@ class Model {
|
||||
return this.windows.get(screen.sessionId + "/" + activeWindowId);
|
||||
}
|
||||
|
||||
getActiveSW() : ScreenWindow {
|
||||
let screen = this.getActiveScreen();
|
||||
if (screen == null) {
|
||||
return null;
|
||||
}
|
||||
return screen.getActiveSW();
|
||||
}
|
||||
|
||||
getSWByWindowId(windowId : string) : ScreenWindow {
|
||||
let screen = this.getActiveScreen();
|
||||
if (screen == null) {
|
||||
return null;
|
||||
}
|
||||
return screen.getSW(windowId);
|
||||
}
|
||||
|
||||
getActiveScreen() : Screen {
|
||||
let session = this.getActiveSession();
|
||||
if (session == null) {
|
||||
@@ -1049,7 +1206,7 @@ class Model {
|
||||
|
||||
getRemoteByName(name : string) : RemoteType {
|
||||
for (let i=0; i<this.remotes.length; i++) {
|
||||
if (this.remotes[i].remotename == name) {
|
||||
if (this.remotes[i].remotecanonicalname == name || this.remotes[i].remotealias == name) {
|
||||
return this.remotes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ contextBridge.exposeInMainWorld("api", {
|
||||
getId: () => ipcRenderer.sendSync("get-id"),
|
||||
onTCmd: (callback) => ipcRenderer.on("t-cmd", callback),
|
||||
onICmd: (callback) => ipcRenderer.on("i-cmd", callback),
|
||||
onMetaArrowUp: (callback) => ipcRenderer.on("meta-arrowup", callback),
|
||||
onMetaArrowDown: (callback) => ipcRenderer.on("meta-arrowdown", callback),
|
||||
onBracketCmd: (callback) => ipcRenderer.on("bracket-cmd", callback),
|
||||
onDigitCmd: (callback) => ipcRenderer.on("digit-cmd", callback),
|
||||
contextScreen: (screenOpts, position) => ipcRenderer.send("context-screen", screenOpts, position),
|
||||
|
||||
@@ -19,5 +19,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
|
||||
(window as any).mobx = mobx;
|
||||
(window as any).sprintf = sprintf;
|
||||
|
||||
console.log("SCRIPTHAUS", VERSION)
|
||||
|
||||
+2
-1
@@ -194,8 +194,9 @@ class TermWrap {
|
||||
this.dataUpdates.push({data: data, pos: pos});
|
||||
return;
|
||||
}
|
||||
console.log("pty-update", this.cmdId, this.ptyPos, data.length);
|
||||
if (pos > this.ptyPos) {
|
||||
throw new Error(sprintf("invalid pty-update, data-pos[%d] does not match term-pos[%d]", pos, this.ptyPos));
|
||||
throw new Error(sprintf("invalid pty-update, data-pos[%d] does not match term-pos[%d] cmdid[%s]", pos, this.ptyPos, this.cmdId));
|
||||
}
|
||||
if (pos < this.ptyPos) {
|
||||
let diff = this.ptyPos - pos;
|
||||
|
||||
+5
-3
@@ -17,7 +17,7 @@ type SessionDataType = {
|
||||
type LineType = {
|
||||
sessionid : string,
|
||||
windowid : string,
|
||||
lineid : number,
|
||||
lineid : string,
|
||||
ts : number,
|
||||
userid : string,
|
||||
linetype : string,
|
||||
@@ -71,7 +71,9 @@ type ScreenWindowType = {
|
||||
type RemoteType = {
|
||||
remotetype : string,
|
||||
remoteid : string,
|
||||
remotename : string,
|
||||
physicalid : string,
|
||||
remotealias : string,
|
||||
remotecanonicalname : string,
|
||||
remotevars : Record<string, string>,
|
||||
status : string,
|
||||
defaultstate : RemoteStateType,
|
||||
@@ -112,7 +114,7 @@ type HistoryItem = {
|
||||
sessionid : string,
|
||||
screenid : string,
|
||||
windowid : string,
|
||||
lineid : number,
|
||||
lineid : string,
|
||||
haderror : boolean,
|
||||
cmdid : string,
|
||||
cmdstr : string,
|
||||
|
||||
+4
-2
@@ -62,7 +62,7 @@ interface ISimpleDataType {
|
||||
remove? : boolean;
|
||||
}
|
||||
|
||||
function genMergeSimpleData<T extends ISimpleDataType>(objs : mobx.IObservableArray<T>, dataArr : T[], idFn : (obj : T) => string, sortIdxFn : (obj : T) => number) {
|
||||
function genMergeSimpleData<T extends ISimpleDataType>(objs : mobx.IObservableArray<T>, dataArr : T[], idFn : (obj : T) => string, sortIdxFn : (obj : T) => string) {
|
||||
if (dataArr == null || dataArr.length == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -86,7 +86,9 @@ function genMergeSimpleData<T extends ISimpleDataType>(objs : mobx.IObservableAr
|
||||
let newObjs = Object.values(objMap);
|
||||
if (sortIdxFn) {
|
||||
newObjs.sort((a, b) => {
|
||||
return sortIdxFn(a) - sortIdxFn(b);
|
||||
let astr = sortIdxFn(a);
|
||||
let bstr = sortIdxFn(b);
|
||||
return astr.localeCompare(bstr);
|
||||
});
|
||||
}
|
||||
objs.replace(newObjs);
|
||||
|
||||
Reference in New Issue
Block a user