move reload url code to model from term

This commit is contained in:
sawka 2023-02-05 23:01:02 -08:00
parent 5e7fe63877
commit c87d4f787c
4 changed files with 65 additions and 41 deletions

View File

@ -288,7 +288,7 @@ class TerminalRenderer extends React.Component<{sw : ScreenWindow, line : LineTy
console.log("cannot load terminal, no term elem found", termId); console.log("cannot load terminal, no term elem found", termId);
return; return;
} }
sw.connectElem(termElem, line, cmd, this.props.width); sw.loadTerminalRenderer(termElem, line, cmd, this.props.width);
mobx.action(() => this.termLoaded.set(true))(); mobx.action(() => this.termLoaded.set(true))();
} }

View File

@ -5,8 +5,9 @@ import {debounce} from "throttle-debounce";
import {handleJsonFetchResponse, base64ToArray, genMergeData, genMergeSimpleData, boundInt, isModKeyPress} from "./util"; import {handleJsonFetchResponse, base64ToArray, genMergeData, genMergeSimpleData, boundInt, isModKeyPress} from "./util";
import {TermWrap} from "./term"; import {TermWrap} from "./term";
import {v4 as uuidv4} from "uuid"; import {v4 as uuidv4} from "uuid";
import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, RemotePtrType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, UIContextType, HistoryInfoType, HistoryQueryOpts, FeInputPacketType, TermWinSize, RemoteInputPacketType, FeStateType, ContextMenuOpts, RendererContext, RendererModel} from "./types"; import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, RemotePtrType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, UIContextType, HistoryInfoType, HistoryQueryOpts, FeInputPacketType, TermWinSize, RemoteInputPacketType, FeStateType, ContextMenuOpts, RendererContext, RendererModel, PtyDataType} from "./types";
import {WSControl} from "./ws"; import {WSControl} from "./ws";
import {ImageRenderer} from "./imagerenderer";
var GlobalUser = "sawka"; var GlobalUser = "sawka";
const DefaultCellWidth = 7.203125; const DefaultCellWidth = 7.203125;
@ -549,7 +550,7 @@ class ScreenWindow {
return false; return false;
} }
connectElem(elem : Element, line : LineType, cmd : Cmd, width : number) { loadTerminalRenderer(elem : Element, line : LineType, cmd : Cmd, width : number) {
let cmdId = cmd.cmdId; let cmdId = cmd.cmdId;
let termWrap = this.getRenderer(cmdId); let termWrap = this.getRenderer(cmdId);
if (termWrap != null) { if (termWrap != null) {
@ -2415,6 +2416,33 @@ function cmdPacketString(pk : FeCmdPacketType) : string {
return parts.join(" "); return parts.join(" ");
} }
function _getPtyDataFromUrl(url : string) : Promise<PtyDataType> {
let ptyOffset = 0;
let fetchHeaders = GlobalModel.getFetchHeaders();
return fetch(url, {headers: fetchHeaders}).then((resp) => {
if (!resp.ok) {
throw new Error(sprintf("Bad fetch response for /api/ptyout: %d %s", resp.status, resp.statusText));
}
let ptyOffsetStr = resp.headers.get("X-PtyDataOffset");
if (ptyOffsetStr != null && !isNaN(parseInt(ptyOffsetStr))) {
ptyOffset = parseInt(ptyOffsetStr);
}
return resp.arrayBuffer();
}).then((buf) => {
return {pos: ptyOffset, data: new Uint8Array(buf)};
});
}
function getPtyData(sessionId : string, cmdId : string) {
let url = sprintf(GlobalModel.getBaseHostPort() + "/api/ptyout?sessionid=%s&cmdid=%s", sessionId, cmdId);
return _getPtyDataFromUrl(url);
}
function getRemotePtyData(remoteId : string) {
let url = sprintf(GlobalModel.getBaseHostPort() + "/api/remote-pty?remoteid=%s", this.getContextRemoteId());
return _getPtyDataFromUrl(url);
}
let GlobalModel : Model = null; let GlobalModel : Model = null;
let GlobalCommandRunner : CommandRunner = null; let GlobalCommandRunner : CommandRunner = null;
if ((window as any).GlobalModel == null) { if ((window as any).GlobalModel == null) {
@ -2424,6 +2452,6 @@ if ((window as any).GlobalModel == null) {
GlobalModel = (window as any).GlobalModel; GlobalModel = (window as any).GlobalModel;
GlobalCommandRunner = (window as any).GlobalCommandRunner; GlobalCommandRunner = (window as any).GlobalCommandRunner;
export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr, windowWidthToCols, windowHeightToRows, termWidthFromCols, termHeightFromRows}; export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr, windowWidthToCols, windowHeightToRows, termWidthFromCols, termHeightFromRows, getPtyData, getRemotePtyData};

View File

@ -3,9 +3,9 @@ import {Terminal} from 'xterm';
import {sprintf} from "sprintf-js"; import {sprintf} from "sprintf-js";
import {boundMethod} from "autobind-decorator"; import {boundMethod} from "autobind-decorator";
import {v4 as uuidv4} from "uuid"; import {v4 as uuidv4} from "uuid";
import {GlobalModel, GlobalCommandRunner, termHeightFromRows, windowWidthToCols, windowHeightToRows} from "./model"; import {GlobalModel, GlobalCommandRunner, termHeightFromRows, windowWidthToCols, windowHeightToRows, getPtyData, getRemotePtyData} from "./model";
import {boundInt} from "./util"; import {boundInt} from "./util";
import type {TermOptsType, TermWinSize, RendererContext, WindowSize} from "./types"; import type {TermOptsType, TermWinSize, RendererContext, WindowSize, PtyDataType} from "./types";
type DataUpdate = { type DataUpdate = {
data : Uint8Array, data : Uint8Array,
@ -244,12 +244,17 @@ class TermWrap {
this.resize({rows, cols}); this.resize({rows, cols});
} }
_getReloadUrl() : string { _reloadThenHandler(ptydata : PtyDataType) {
if (this.getContextRemoteId() != null) { this.reloading = false;
return sprintf(GlobalModel.getBaseHostPort() + "/api/remote-pty?remoteid=%s", this.getContextRemoteId()); this.ptyPos = ptydata.pos;
this.receiveData(ptydata.pos, ptydata.data, "reload-main");
for (let i=0; i<this.dataUpdates.length; i++) {
this.receiveData(this.dataUpdates[i].pos, this.dataUpdates[i].data, "reload-update-" + i);
} }
let termContext = this.getRendererContext(); this.dataUpdates = [];
return sprintf(GlobalModel.getBaseHostPort() + "/api/ptyout?sessionid=%s&cmdid=%s", termContext.sessionId, termContext.cmdId); this.terminal.write(new Uint8Array(), () => {
this.updateUsedRows(true, "reload");
});
} }
reload(delayMs : number) { reload(delayMs : number) {
@ -258,35 +263,23 @@ class TermWrap {
} }
this.reloading = true; this.reloading = true;
this.terminal.reset(); this.terminal.reset();
let url = this._getReloadUrl(); let rtnp : Promise<PtyDataType> = null;
let ptyOffset = 0; if (this.getContextRemoteId() != null) {
let fetchHeaders = GlobalModel.getFetchHeaders(); rtnp = getRemotePtyData(this.getContextRemoteId());
fetch(url, {headers: fetchHeaders}).then((resp) => {
if (!resp.ok) {
mobx.action(() => { this.loadError.set(true); })();
this.dataUpdates = [];
throw new Error(sprintf("Bad fetch response for /api/ptyout: %d %s", resp.status, resp.statusText));
} }
let ptyOffsetStr = resp.headers.get("X-PtyDataOffset"); else {
if (ptyOffsetStr != null && !isNaN(parseInt(ptyOffsetStr))) { let termContext = this.getRendererContext();
ptyOffset = parseInt(ptyOffsetStr); rtnp = getPtyData(termContext.sessionId, termContext.cmdId);
} }
return resp.arrayBuffer(); rtnp.then((ptydata) => {
}).then((buf) => {
setTimeout(() => { setTimeout(() => {
this.reloading = false; this._reloadThenHandler(ptydata);
this.ptyPos = ptyOffset;
this.receiveData(ptyOffset, new Uint8Array(buf), "reload-main");
for (let i=0; i<this.dataUpdates.length; i++) {
this.receiveData(this.dataUpdates[i].pos, this.dataUpdates[i].data, "reload-update-" + i);
}
this.dataUpdates = [];
this.terminal.write(new Uint8Array(), () => {
this.updateUsedRows(true, "reload");
});
}, delayMs); }, delayMs);
}).catch((e) => { }).catch((e) => {
console.log("error reloading terminal", e); mobx.action(() => { this.loadError.set(true); })();
this.dataUpdates = [];
this.reloading = false;
console.log("error reloading terminal", this.termContext, e);
}); });
} }

View File

@ -343,16 +343,14 @@ type RendererContext = {
}; };
type RendererModel = { type RendererModel = {
reload : (delayMs : number) => void,
dispose : () => void, dispose : () => void,
reload : (delayMs : number) => void,
receiveData : (pos : number, data : Uint8Array, reason? : string) => void, receiveData : (pos : number, data : Uint8Array, reason? : string) => void,
cmdDone : () => void, cmdDone : () => void,
resizeWindow : (size : WindowSize) => void, resizeWindow : (size : WindowSize) => void,
resizeCols : (cols : number) => void, resizeCols : (cols : number) => void,
giveFocus : () => void, giveFocus : () => void,
getUsedRows : () => number, getUsedRows : () => number,
focusHandler : (focus : boolean) => void;
}; };
type WindowSize = { type WindowSize = {
@ -360,4 +358,9 @@ type WindowSize = {
width: number, width: number,
}; };
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel}; type PtyDataType = {
pos : number,
data : Uint8Array,
};
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel, PtyDataType};