use new global input model

This commit is contained in:
sawka
2022-07-15 17:38:58 -07:00
parent 6340a3e9ff
commit d297477807
4 changed files with 87 additions and 65 deletions
+5 -5
View File
@@ -10,7 +10,7 @@ import cn from "classnames"
import {TermWrap} from "./term";
import type {SessionDataType, LineType, CmdDataType, RemoteType} from "./types";
import localizedFormat from 'dayjs/plugin/localizedFormat';
import {GlobalModel, Session, Cmd, Window, Screen, ScreenWindow} from "./model";
import {GlobalModel, GlobalInput, Session, Cmd, Window, Screen, ScreenWindow} from "./model";
dayjs.extend(localizedFormat)
@@ -305,7 +305,7 @@ class CmdInput extends React.Component<{}, {}> {
let commandStr = this.getCurLine();
let hitem = {cmdtext: commandStr};
this.clearCurLine();
model.submitCommand(commandStr);
model.submitRawCommand(commandStr);
}
render() {
@@ -543,7 +543,7 @@ class ScreenTabs extends React.Component<{session : Session}, {}> {
@boundMethod
handleNewScreen() {
let {session} = this.props;
GlobalModel.createNewScreen(session, null, true);
GlobalInput.createNewScreen();
}
@boundMethod
@@ -559,7 +559,7 @@ class ScreenTabs extends React.Component<{session : Session}, {}> {
if (screen == null) {
return;
}
GlobalModel.submitCommand(sprintf("/s %s", screenId));
GlobalInput.switchScreen(screenId);
}
render() {
@@ -572,7 +572,7 @@ class ScreenTabs extends React.Component<{session : Session}, {}> {
return (
<div className="screen-tabs">
<For each="screen" index="index" of={session.screens}>
<div key={screen.screenId} className={cn("screen-tab", {"is-active": session.activeScreenId.get() == screen.screenId})} onClick={() => this.handleSwitchScreen(screen.screenId, index+1)}>
<div key={screen.screenId} className={cn("screen-tab", {"is-active": session.activeScreenId.get() == screen.screenId})} onClick={() => this.handleSwitchScreen(screen.screenId)}>
{screen.name.get()}
<If condition={index+1 <= 9}>
<div className="tab-index">&#x2318;{index+1}</div>
+69 -52
View File
@@ -4,7 +4,7 @@ import {boundMethod} from "autobind-decorator";
import {handleJsonFetchResponse, base64ToArray, genMergeData} from "./util";
import {TermWrap} from "./term";
import {v4 as uuidv4} from "uuid";
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, SessionUpdateType, WindowUpdateType} from "./types";
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, SessionUpdateType, WindowUpdateType, UpdateMessage} from "./types";
import {WSControl} from "./ws";
var GlobalUser = "sawka";
@@ -505,7 +505,7 @@ class Model {
this.clientId = getApi().getId();
this.loadRemotes();
this.loadSessionList();
this.ws = new WSControl(this.clientId, this.onWSMessage.bind(this))
this.ws = new WSControl(this.clientId, this.runUpdate.bind(this))
this.ws.reconnect();
getApi().onTCmd(this.onTCmd.bind(this));
getApi().onICmd(this.onICmd.bind(this));
@@ -515,6 +515,7 @@ class Model {
onTCmd(mods : KeyModsType) {
console.log("got cmd-t", mods);
GlobalInput.createNewScreen();
}
onICmd(mods : KeyModsType) {
@@ -534,21 +535,21 @@ class Model {
if (newScreenId == null) {
return;
}
this.submitCommand(sprintf("/s %s", newScreenId));
GlobalInput.switchScreen(newScreenId);
}
onDigitCmd(e : any, arg : {digit: number}, mods : KeyModsType) {
console.log("switch screen (digit)", arg, mods);
this.submitCommand(sprintf("/s %d", arg.digit));
GlobalInput.switchScreen(String(arg.digit));
}
isConnected() : boolean {
return this.ws.open.get();
}
onWSMessage(message : any) {
if ("ptydata64" in message) {
let ptyMsg : PtyDataUpdateType = message;
runUpdate(update : UpdateMessage) {
if ("ptydata64" in update) {
let ptyMsg : PtyDataUpdateType = update;
let activeScreen = this.getActiveScreen();
if (!activeScreen || activeScreen.sessionId != ptyMsg.sessionid) {
return;
@@ -556,8 +557,8 @@ class Model {
activeScreen.updatePtyData(ptyMsg);
return;
}
if ("sessions" in message) {
let sessionUpdateMsg : SessionUpdateType = message;
if ("sessions" in update) {
let sessionUpdateMsg : SessionUpdateType = update;
mobx.action(() => {
let oldActiveScreen = this.getActiveScreen();
genMergeData(this.sessionList, sessionUpdateMsg.sessions, (s : Session) => s.sessionId, (sdata : SessionDataType) => sdata.sessionid, (sdata : SessionDataType) => new Session(sdata), (s : Session) => s.sessionIdx.get());
@@ -573,7 +574,7 @@ class Model {
})();
}
console.log("ws-message", message);
console.log("run-update>", update);
}
removeSession(sessionId : string) {
@@ -664,35 +665,27 @@ class Model {
win.addLineCmd(line, cmd, interactive);
}
submitCommand(cmdStr : string) {
console.log("submit-command>", cmdStr);
getClientKwargs() : Record<string, string> {
let session = this.getActiveSession();
let win = this.getActiveWindow();
if (win == null) {
this.errorHandler("cannot submit command, no active window", null)
return;
}
let screen = this.getActiveScreen();
if (screen == null) {
this.errorHandler("cannot submit command, no active screen", null)
return;
let rtn : Record<string, string> = {};
if (session != null) {
rtn.session = session.sessionId;
}
let data : FeCmdPacketType = {
type: "fecmd",
sessionid: win.sessionId,
screenid: screen.screenId,
windowid: win.windowId,
cmdstr: cmdStr,
userid: GlobalUser,
remotestate: null
};
let rstate = win.getCurRemoteInstance();
if (rstate == null) {
this.errorHandler("cannot submit command, no remote state found", null);
return;
if (screen != null) {
rtn.screen = screen.screenId;
}
data.remotestate = {remoteid: rstate.remoteid, remotename: rstate.name, ...rstate.state};
if (win != null) {
rtn.window = win.windowId;
rtn.remote = win.curRemote.get();
}
return rtn;
}
submitCommandPacket(cmdPk : FeCmdPacketType) {
let url = sprintf("http://localhost:8080/api/run-command");
fetch(url, {method: "post", body: JSON.stringify(data)}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
fetch(url, {method: "post", body: JSON.stringify(cmdPk)}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
mobx.action(() => {
if (data.data != null && data.data.line != null) {
this.addLineCmd(data.data.line, data.data.cmd, true);
@@ -703,6 +696,27 @@ class Model {
});
}
submitCommand(metaCmd : string, metaSubCmd : string, args : string[], kwargs : Record<string, string>) {
let pk : FeCmdPacketType = {
type: "fecmd",
metacmd: metaCmd,
metasubcmd: metaSubCmd,
args: args,
kwargs: Object.assign({}, this.getClientKwargs(), kwargs),
};
this.submitCommandPacket(pk);
}
submitRawCommand(cmdStr : string) {
let pk : FeCmdPacketType = {
type: "fecmd",
metacmd: "eval",
args: [cmdStr],
kwargs: this.getClientKwargs(),
};
this.submitCommandPacket(pk)
}
loadSessionList() {
let url = new URL("http://localhost:8080/api/get-all-sessions");
fetch(url).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
@@ -751,23 +765,6 @@ class Model {
this.ws.pushMessage({type: "watchscreen", sessionid: curScreen.sessionId, screenid: curScreen.screenId});
}
createNewScreen(session : Session, name : string, activate : boolean) {
let params : Record<string, string> = {sessionid: session.sessionId};
if (name != null) {
params.name = name;
}
if (activate) {
params.activate = "1";
}
let usp = new URLSearchParams(params);
let url = new URL("http://localhost:8080/api/create-screen?" + usp.toString());
fetch(url).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
console.log("created screen", data.data);
}).catch((err) => {
this.errorHandler(sprintf("creating screen session=%s", session.sessionId), err);
});
}
loadWindow(sessionId : string, windowId : string) : Window {
let newWin = new Window(sessionId, windowId);
this.windows.set(sessionId + "/" + windowId, newWin);
@@ -837,12 +834,32 @@ class Model {
}
}
class InputClass {
constructor() {
}
switchScreen(screen : string) {
GlobalModel.submitCommand("screen", null, [screen], null);
}
createNewScreen() {
GlobalModel.submitCommand("screen", "open", null, null);
}
closeScreen(screen : string) {
GlobalModel.submitCommand("screen", "close", [screen], null);
}
};
let GlobalModel : Model = null;
let GlobalInput : InputClass = null;
if ((window as any).GlobalModal == null) {
(window as any).GlobalModel = new Model();
(window as any).GlobalInput = new InputClass();
}
GlobalModel = (window as any).GlobalModel;
GlobalInput = (window as any).GlobalInput;
export {Model, Session, Window, GlobalModel, Cmd, Screen, ScreenWindow};
export {Model, Session, Window, GlobalModel, GlobalInput, Cmd, Screen, ScreenWindow};
+7 -7
View File
@@ -114,12 +114,10 @@ type CmdRemoteStateType = {
type FeCmdPacketType = {
type : string,
sessionid : string,
screenid : string,
windowid : string,
userid : string,
cmdstr : string,
remotestate : CmdRemoteStateType,
metacmd : string,
metasubcmd? : string,
args : string[],
kwargs : Record<string, string>;
};
type WatchScreenPacketType = {
@@ -177,9 +175,11 @@ type SessionUpdateType = {
sessions: SessionDataType[],
};
type UpdateMessage = PtyDataUpdateType | SessionUpdateType;
type WindowUpdateType = {
window: WindowDataType,
remove: boolean,
}
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, SessionUpdateType, WindowUpdateType};
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, SessionUpdateType, WindowUpdateType, UpdateMessage};
+6 -1
View File
@@ -5,14 +5,19 @@ function fetchJsonData(resp : any, ctErr : boolean) : Promise<any> {
let contentType = resp.headers.get("Content-Type");
if (contentType != null && contentType.startsWith("application/json")) {
return resp.text().then((textData) => {
let rtnData : any = null;
try {
return JSON.parse(textData);
rtnData = JSON.parse(textData);
}
catch (err) {
let errMsg = sprintf("Unparseable JSON: " + err.message);
let rtnErr = new Error(errMsg);
throw rtnErr;
}
if (rtnData != null && rtnData.error) {
throw new Error(rtnData.error);
}
return rtnData;
});
}
if (ctErr) {