mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
switch to new model of ws notification -> screen update fetch
This commit is contained in:
@@ -36,7 +36,7 @@ class SimpleBlobRendererModel {
|
|||||||
this.savedHeight = params.savedHeight;
|
this.savedHeight = params.savedHeight;
|
||||||
this.ptyDataSource = params.ptyDataSource;
|
this.ptyDataSource = params.ptyDataSource;
|
||||||
if (this.isDone.get()) {
|
if (this.isDone.get()) {
|
||||||
this.reload(0);
|
setTimeout(() => this.reload(0), 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +74,10 @@ class SimpleBlobRendererModel {
|
|||||||
this.loading.set(true);
|
this.loading.set(true);
|
||||||
})();
|
})();
|
||||||
let rtnp = this.ptyDataSource(this.context);
|
let rtnp = this.ptyDataSource(this.context);
|
||||||
|
if (rtnp == null) {
|
||||||
|
console.log("no promise returned from ptyDataSource (simplerenderer)", this.context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
rtnp.then((ptydata) => {
|
rtnp.then((ptydata) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.ptyData = ptydata;
|
this.ptyData = ptydata;
|
||||||
|
|||||||
+5
-1
@@ -109,7 +109,7 @@ class TermWrap {
|
|||||||
if (opts.customKeyHandler != null) {
|
if (opts.customKeyHandler != null) {
|
||||||
this.terminal.attachCustomKeyEventHandler((e) => opts.customKeyHandler(e, this));
|
this.terminal.attachCustomKeyEventHandler((e) => opts.customKeyHandler(e, this));
|
||||||
}
|
}
|
||||||
this.reload(0);
|
setTimeout(() => this.reload(0), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsedRows() : number {
|
getUsedRows() : number {
|
||||||
@@ -281,6 +281,10 @@ class TermWrap {
|
|||||||
this.reloading = true;
|
this.reloading = true;
|
||||||
this.terminal.reset();
|
this.terminal.reset();
|
||||||
let rtnp = this.ptyDataSource(this.termContext);
|
let rtnp = this.ptyDataSource(this.termContext);
|
||||||
|
if (rtnp == null) {
|
||||||
|
console.log("no promise returned from ptyDataSource (termwrap)", this.termContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
rtnp.then((ptydata) => {
|
rtnp.then((ptydata) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this._reloadThenHandler(ptydata);
|
this._reloadThenHandler(ptydata);
|
||||||
|
|||||||
+3
-11
@@ -535,9 +535,11 @@ type WebCmd = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type WebFullScreen = {
|
type WebFullScreen = {
|
||||||
|
screenid : string,
|
||||||
screen : WebScreen,
|
screen : WebScreen,
|
||||||
lines : WebLine[],
|
lines : WebLine[],
|
||||||
cmds : WebCmd[],
|
cmds : WebCmd[],
|
||||||
|
cmdptymap : Record<string, number>,
|
||||||
vts : number,
|
vts : number,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,16 +550,6 @@ type PtyDataUpdate = {
|
|||||||
data : string,
|
data : string,
|
||||||
};
|
};
|
||||||
|
|
||||||
type WebScreenUpdate = {
|
|
||||||
type : string,
|
|
||||||
screenid : string,
|
|
||||||
screen : WebScreen,
|
|
||||||
lines : WebLine[],
|
|
||||||
cmds : WebCmd[],
|
|
||||||
ptydata : PtyDataUpdate[],
|
|
||||||
removedlines : string[],
|
|
||||||
};
|
|
||||||
|
|
||||||
type WebShareWSMessage = {
|
type WebShareWSMessage = {
|
||||||
type : string,
|
type : string,
|
||||||
screenid : string,
|
screenid : string,
|
||||||
@@ -589,4 +581,4 @@ type RendererContainerType = {
|
|||||||
|
|
||||||
type LineHeightChangeCallbackType = (lineNum : number, newHeight : number, oldHeight : number) => void;
|
type LineHeightChangeCallbackType = (lineNum : number, newHeight : number, oldHeight : number) => void;
|
||||||
|
|
||||||
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel, PtyDataType, BookmarkType, ClientDataType, PlaybookType, PlaybookEntryType, HistoryViewDataType, RenderModeType, AlertMessageType, HistorySearchParams, ScreenLinesType, FocusTypeStrs, HistoryTypeStrs, RendererOpts, RendererPluginType, SimpleBlobRendererComponent, RendererModelContainerApi, RendererModelInitializeParams, RendererOptsUpdate, ClientMigrationInfo, WebShareOpts, RemoteStatusTypeStrs, WebFullScreen, WebScreen, WebLine, WebCmd, RemoteTermContext, TermContextUnion, WebRemote, WebScreenUpdate, PtyDataUpdate, WebShareWSMessage, LineHeightChangeCallbackType, LineFactoryProps, LineInterface, RendererContainerType};
|
export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel, PtyDataType, BookmarkType, ClientDataType, PlaybookType, PlaybookEntryType, HistoryViewDataType, RenderModeType, AlertMessageType, HistorySearchParams, ScreenLinesType, FocusTypeStrs, HistoryTypeStrs, RendererOpts, RendererPluginType, SimpleBlobRendererComponent, RendererModelContainerApi, RendererModelInitializeParams, RendererOptsUpdate, ClientMigrationInfo, WebShareOpts, RemoteStatusTypeStrs, WebFullScreen, WebScreen, WebLine, WebCmd, RemoteTermContext, TermContextUnion, WebRemote, PtyDataUpdate, WebShareWSMessage, LineHeightChangeCallbackType, LineFactoryProps, LineInterface, RendererContainerType};
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ type OMap<K,V> = mobx.ObservableMap<K,V>;
|
|||||||
let foo = LinesView;
|
let foo = LinesView;
|
||||||
|
|
||||||
// TODO reshare
|
// TODO reshare
|
||||||
// TODO debounce some of the updates
|
|
||||||
|
|
||||||
function makeFullRemoteRef(ownerName : string, remoteRef : string, name : string) : string {
|
function makeFullRemoteRef(ownerName : string, remoteRef : string, name : string) : string {
|
||||||
if (isBlank(ownerName) && isBlank(name)) {
|
if (isBlank(ownerName) && isBlank(name)) {
|
||||||
@@ -624,7 +623,7 @@ class WebScreenView extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let fullScreen = WebShareModel.screen.get();
|
let fullScreen = WebShareModel.fullScreen.get();
|
||||||
if (fullScreen == null || fullScreen.lines.length == 0) {
|
if (fullScreen == null || fullScreen.lines.length == 0) {
|
||||||
return this.renderEmpty();
|
return this.renderEmpty();
|
||||||
}
|
}
|
||||||
@@ -643,7 +642,7 @@ class WebShareMain extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let screen = WebShareModel.screen.get();
|
let screen = WebShareModel.fullScreen.get();
|
||||||
let errMessage = WebShareModel.errMessage.get();
|
let errMessage = WebShareModel.errMessage.get();
|
||||||
let shareName = "";
|
let shareName = "";
|
||||||
if (screen != null) {
|
if (screen != null) {
|
||||||
|
|||||||
+195
-51
@@ -14,6 +14,10 @@ type OArr<V> = mobx.IObservableArray<V>;
|
|||||||
type OMap<K,V> = mobx.ObservableMap<K,V>;
|
type OMap<K,V> = mobx.ObservableMap<K,V>;
|
||||||
type CV<V> = mobx.IComputedValue<V>;
|
type CV<V> = mobx.IComputedValue<V>;
|
||||||
|
|
||||||
|
type PtyListener = {
|
||||||
|
receiveData(ptyPos : number, data : Uint8Array, reason? : string);
|
||||||
|
};
|
||||||
|
|
||||||
function isBlank(s : string) {
|
function isBlank(s : string) {
|
||||||
return (s == null || s == "");
|
return (s == null || s == "");
|
||||||
}
|
}
|
||||||
@@ -30,7 +34,7 @@ class WebShareModelClass {
|
|||||||
viewKey : string;
|
viewKey : string;
|
||||||
screenId : string;
|
screenId : string;
|
||||||
errMessage : OV<string> = mobx.observable.box(null, {name: "errMessage"});
|
errMessage : OV<string> = mobx.observable.box(null, {name: "errMessage"});
|
||||||
screen : OV<T.WebFullScreen> = mobx.observable.box(null, {name: "webScreen"});
|
fullScreen : OV<T.WebFullScreen> = mobx.observable.box(null, {name: "webScreen"});
|
||||||
terminals : Record<string, TermWrap> = {}; // lineid => TermWrap
|
terminals : Record<string, TermWrap> = {}; // lineid => TermWrap
|
||||||
renderers : Record<string, T.RendererModel> = {}; // lineid => RendererModel
|
renderers : Record<string, T.RendererModel> = {}; // lineid => RendererModel
|
||||||
contentHeightCache : Record<string, number> = {}; // lineid => height
|
contentHeightCache : Record<string, number> = {}; // lineid => height
|
||||||
@@ -39,12 +43,17 @@ class WebShareModelClass {
|
|||||||
selectedLine : OV<number> = mobx.observable.box(0, {name: "selectedLine"});
|
selectedLine : OV<number> = mobx.observable.box(0, {name: "selectedLine"});
|
||||||
syncSelectedLine : OV<boolean> = mobx.observable.box(true, {name: "syncSelectedLine"});
|
syncSelectedLine : OV<boolean> = mobx.observable.box(true, {name: "syncSelectedLine"});
|
||||||
lastScreenSize : T.WindowSize = null;
|
lastScreenSize : T.WindowSize = null;
|
||||||
|
activePtyFetch : Record<string, boolean> = {}; // lineid -> active
|
||||||
|
localPtyOffsetMap : Record<string, number> = {};
|
||||||
|
remotePtyOffsetMap : Record<string, number> = {};
|
||||||
|
activeUpdateFetch : boolean = false;
|
||||||
|
remoteScreenVts : number = 0;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
let urlParams = new URLSearchParams(window.location.search);
|
let urlParams = new URLSearchParams(window.location.search);
|
||||||
this.viewKey = urlParams.get("viewkey");
|
this.viewKey = urlParams.get("viewkey");
|
||||||
this.screenId = urlParams.get("screenid");
|
this.screenId = urlParams.get("screenid");
|
||||||
setTimeout(() => this.loadFullScreenData(), 10);
|
setTimeout(() => this.loadFullScreenData(false), 10);
|
||||||
this.wsControl = new WebShareWSControl(getBaseWSUrl(), this.screenId, this.viewKey, this.wsMessageCallback.bind(this));
|
this.wsControl = new WebShareWSControl(getBaseWSUrl(), this.screenId, this.viewKey, this.wsMessageCallback.bind(this));
|
||||||
document.addEventListener("keydown", this.docKeyDownHandler.bind(this));
|
document.addEventListener("keydown", this.docKeyDownHandler.bind(this));
|
||||||
}
|
}
|
||||||
@@ -59,7 +68,7 @@ class WebShareModelClass {
|
|||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
this.syncSelectedLine.set(val);
|
this.syncSelectedLine.set(val);
|
||||||
if (val) {
|
if (val) {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen != null) {
|
if (fullScreen != null) {
|
||||||
this.selectedLine.set(fullScreen.screen.selectedline);
|
this.selectedLine.set(fullScreen.screen.selectedline);
|
||||||
}
|
}
|
||||||
@@ -103,7 +112,7 @@ class WebShareModelClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getServerSelectedLine() : number {
|
getServerSelectedLine() : number {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen != null) {
|
if (fullScreen != null) {
|
||||||
return fullScreen.screen.selectedline;
|
return fullScreen.screen.selectedline;
|
||||||
}
|
}
|
||||||
@@ -116,7 +125,7 @@ class WebShareModelClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSelectedLineIndex(delta : number) : void {
|
updateSelectedLineIndex(delta : number) : void {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen == null) {
|
if (fullScreen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -209,14 +218,20 @@ class WebShareModelClass {
|
|||||||
fullScreen.cmds.push(newCmd);
|
fullScreen.cmds.push(newCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeUpdate(msg : T.WebScreenUpdate) {
|
mergeUpdate(msg : T.WebFullScreen) {
|
||||||
if (msg.screenid != this.screenId) {
|
if (msg.screenid != this.screenId) {
|
||||||
console.log("bad WebScreenUpdate, wrong screenid", msg.screenid);
|
console.log("bad WebFullScreen update, wrong screenid", msg.screenid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("merge", msg);
|
console.log("merge screen-update", "vts=" + msg.vts);
|
||||||
|
// console.log("merge", "vts=" + msg.vts, msg);
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
|
if (fullScreen.vts >= msg.vts) {
|
||||||
|
console.log("stale merge", "cur-vts=" + fullScreen.vts, "merge-vts=" + msg.vts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fullScreen.vts = msg.vts;
|
||||||
if (msg.screen) {
|
if (msg.screen) {
|
||||||
fullScreen.screen = msg.screen;
|
fullScreen.screen = msg.screen;
|
||||||
if (this.syncSelectedLine.get()) {
|
if (this.syncSelectedLine.get()) {
|
||||||
@@ -225,6 +240,10 @@ class WebShareModelClass {
|
|||||||
}
|
}
|
||||||
if (msg.lines != null && msg.lines.length > 0) {
|
if (msg.lines != null && msg.lines.length > 0) {
|
||||||
for (let line of msg.lines) {
|
for (let line of msg.lines) {
|
||||||
|
if (line.archived) {
|
||||||
|
this.removeLine(fullScreen, line.lineid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
this.mergeLine(fullScreen, line);
|
this.mergeLine(fullScreen, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,33 +252,118 @@ class WebShareModelClass {
|
|||||||
this.mergeCmd(fullScreen, cmd);
|
this.mergeCmd(fullScreen, cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg.ptydata != null && msg.ptydata.length > 0) {
|
this.handleCmdPtyMap(msg.cmdptymap);
|
||||||
for (let data of msg.ptydata) {
|
})();
|
||||||
let termWrap = this.getTermWrap(data.lineid);
|
}
|
||||||
if (termWrap == null) {
|
|
||||||
continue;
|
handleCmdPtyMap(ptyMap : Record<string, number>) {
|
||||||
}
|
if (ptyMap == null) {
|
||||||
let dataArr = base64ToArray(data.data);
|
return;
|
||||||
termWrap.receiveData(data.ptypos, dataArr, "ws:ptydata");
|
}
|
||||||
}
|
for (let lineId in ptyMap) {
|
||||||
|
let newOffset = ptyMap[lineId];
|
||||||
|
this.remotePtyOffsetMap[lineId] = newOffset;
|
||||||
|
let localOffset = this.localPtyOffsetMap[lineId];
|
||||||
|
if (localOffset != null && localOffset < newOffset) {
|
||||||
|
this.runPtyFetch(lineId);
|
||||||
}
|
}
|
||||||
if (msg.removedlines != null && msg.removedlines.length > 0) {
|
}
|
||||||
for (let lineid of msg.removedlines) {
|
}
|
||||||
this.removeLine(fullScreen, lineid);
|
|
||||||
|
runPtyFetch(lineId : string) {
|
||||||
|
let prtn = this.checkFetchPtyData(lineId, false);
|
||||||
|
let ptyListener = this.getPtyListener(lineId);
|
||||||
|
if (ptyListener != null) {
|
||||||
|
prtn.then((ptydata) => {
|
||||||
|
ptyListener.receiveData(ptydata.pos, ptydata.data, "model-fetch");
|
||||||
|
if (ptydata.data.length > 0) {
|
||||||
|
setTimeout(() => this.checkFetchPtyData(lineId, false), 100);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPtyListener(lineId : string) {
|
||||||
|
let termWrap = this.getTermWrap(lineId);
|
||||||
|
if (termWrap != null) {
|
||||||
|
return termWrap;
|
||||||
|
}
|
||||||
|
let renderer = this.getRenderer(lineId);
|
||||||
|
if (renderer != null) {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
receivePtyData(lineId : string, ptyPos : number, data : Uint8Array, reason? : string) : void {
|
||||||
|
let termWrap = this.getTermWrap(lineId);
|
||||||
|
if (termWrap != null) {
|
||||||
|
termWrap.receiveData(ptyPos, data, reason);
|
||||||
|
}
|
||||||
|
let renderer = this.getRenderer(lineId);
|
||||||
|
if (renderer != null) {
|
||||||
|
renderer.receiveData(ptyPos, data, reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFetchPtyData(lineId : string, reload : boolean) : Promise<T.PtyDataType> {
|
||||||
|
let lineNum = this.getLineNumFromId(lineId);
|
||||||
|
if (this.activePtyFetch[lineId]) {
|
||||||
|
// console.log("check-fetch", lineNum, "already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (reload) {
|
||||||
|
this.localPtyOffsetMap[lineId] = 0;
|
||||||
|
}
|
||||||
|
let ptyOffset = this.localPtyOffsetMap[lineId];
|
||||||
|
if (ptyOffset == null) {
|
||||||
|
// console.log("check-fetch", lineNum, "no local offset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let remotePtyOffset = this.remotePtyOffsetMap[lineId];
|
||||||
|
if (ptyOffset >= remotePtyOffset) {
|
||||||
|
// up to date
|
||||||
|
return Promise.resolve({pos: ptyOffset, data: new Uint8Array(0)});
|
||||||
|
}
|
||||||
|
this.activePtyFetch[lineId] = true;
|
||||||
|
let viewKey = WebShareModel.viewKey;
|
||||||
|
// console.log("fetch pty", lineNum, "pos=" + ptyOffset);
|
||||||
|
let usp = new URLSearchParams({screenid: this.screenId, viewkey: viewKey, lineid: lineId, pos: String(ptyOffset)});
|
||||||
|
let url = new URL(getBaseUrl() + "/webshare/ptydata?" + usp.toString());
|
||||||
|
return fetch(url, {method: "GET", mode: "cors", cache: "no-cache"}).then((resp) => {
|
||||||
|
if (!resp.ok) {
|
||||||
|
throw new Error(sprintf("Bad fetch response for /webshare/ptydata: %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) => {
|
||||||
|
let dataArr = new Uint8Array(buf);
|
||||||
|
let newOffset = ptyOffset + dataArr.length;
|
||||||
|
console.log("fetch pty success", lineNum, "len=" + dataArr.length, "pos => " + newOffset);
|
||||||
|
this.localPtyOffsetMap[lineId] = newOffset;
|
||||||
|
return {pos: ptyOffset, data: dataArr};
|
||||||
|
}).finally(() => {
|
||||||
|
this.activePtyFetch[lineId] = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
wsMessageCallback(msg : any) {
|
wsMessageCallback(msg : any) {
|
||||||
if (msg.type == "webscreen:update") {
|
if (msg.type == "webscreen:update") {
|
||||||
this.mergeUpdate(msg);
|
console.log("[ws] update vts", msg.vts);
|
||||||
|
if (msg.vts > this.remoteScreenVts) {
|
||||||
|
this.remoteScreenVts = msg.vts;
|
||||||
|
setTimeout(() => this.checkUpdateScreenData(), 10);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("ws message", msg);
|
console.log("[ws] unhandled message", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
setWebFullScreen(screen : T.WebFullScreen) {
|
setWebFullScreen(screen : T.WebFullScreen) {
|
||||||
|
console.log("got initial screen", "vts=" + screen.vts);
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
if (screen.lines == null) {
|
if (screen.lines == null) {
|
||||||
screen.lines = [];
|
screen.lines = [];
|
||||||
@@ -267,7 +371,9 @@ class WebShareModelClass {
|
|||||||
if (screen.cmds == null) {
|
if (screen.cmds == null) {
|
||||||
screen.cmds = [];
|
screen.cmds = [];
|
||||||
}
|
}
|
||||||
this.screen.set(screen);
|
this.handleCmdPtyMap(screen.cmdptymap);
|
||||||
|
screen.cmdptymap = null;
|
||||||
|
this.fullScreen.set(screen);
|
||||||
this.wsControl.reconnect(true);
|
this.wsControl.reconnect(true);
|
||||||
if (this.syncSelectedLine.get()) {
|
if (this.syncSelectedLine.get()) {
|
||||||
this.selectedLine.set(screen.screen.selectedline);
|
this.selectedLine.set(screen.screen.selectedline);
|
||||||
@@ -303,6 +409,10 @@ class WebShareModelClass {
|
|||||||
onUpdateContentHeight: (termContext : T.RendererContext, height : number) => { this.setContentHeight(termContext, height); },
|
onUpdateContentHeight: (termContext : T.RendererContext, height : number) => { this.setContentHeight(termContext, height); },
|
||||||
});
|
});
|
||||||
this.terminals[lineId] = termWrap;
|
this.terminals[lineId] = termWrap;
|
||||||
|
if (this.localPtyOffsetMap[lineId] == null) {
|
||||||
|
this.localPtyOffsetMap[lineId] = 0;
|
||||||
|
}
|
||||||
|
this.localPtyOffsetMap[lineId] = 0;
|
||||||
if (this.getSelectedLine() == line.linenum) {
|
if (this.getSelectedLine() == line.linenum) {
|
||||||
termWrap.giveFocus();
|
termWrap.giveFocus();
|
||||||
}
|
}
|
||||||
@@ -358,6 +468,7 @@ class WebShareModelClass {
|
|||||||
term.dispose();
|
term.dispose();
|
||||||
delete this.terminals[lineId];
|
delete this.terminals[lineId];
|
||||||
}
|
}
|
||||||
|
delete this.localPtyOffsetMap[lineId];
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsedRows(context : T.RendererContext, line : T.WebLine, cmd : T.WebCmd, width : number) : number {
|
getUsedRows(context : T.RendererContext, line : T.WebLine, cmd : T.WebCmd, width : number) : number {
|
||||||
@@ -391,11 +502,26 @@ class WebShareModelClass {
|
|||||||
return this.renderers[lineId];
|
return this.renderers[lineId];
|
||||||
}
|
}
|
||||||
|
|
||||||
registerRenderer(cmdId : string, renderer : T.RendererModel) {
|
registerRenderer(lineId : string, renderer : T.RendererModel) {
|
||||||
this.renderers[cmdId] = renderer;
|
this.renderers[lineId] = renderer;
|
||||||
|
if (this.localPtyOffsetMap[lineId] == null) {
|
||||||
|
this.localPtyOffsetMap[lineId] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFullScreenData() : void {
|
checkUpdateScreenData() : void {
|
||||||
|
let fullScreen = this.fullScreen.get();
|
||||||
|
if (fullScreen == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log("check-update", "vts=" + fullScreen.vts, "remote-vts=" + this.remoteScreenVts);
|
||||||
|
if (fullScreen.vts >= this.remoteScreenVts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadFullScreenData(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFullScreenData(update : boolean) : void {
|
||||||
if (isBlank(this.screenId)) {
|
if (isBlank(this.screenId)) {
|
||||||
this.setErrMessage("No ScreenId Specified, Cannot Load.");
|
this.setErrMessage("No ScreenId Specified, Cannot Load.");
|
||||||
return;
|
return;
|
||||||
@@ -404,20 +530,53 @@ class WebShareModelClass {
|
|||||||
this.setErrMessage("No ViewKey Specified, Cannot Load.");
|
this.setErrMessage("No ViewKey Specified, Cannot Load.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let usp = new URLSearchParams({screenid: this.screenId, viewkey: this.viewKey});
|
if (this.activeUpdateFetch) {
|
||||||
|
// console.log("there is already an active update fetch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log("running screen-data update");
|
||||||
|
this.activeUpdateFetch = true;
|
||||||
|
let urlParams : Record<string, string> = {screenid: this.screenId, viewkey: this.viewKey};
|
||||||
|
if (update) {
|
||||||
|
let fullScreen = this.fullScreen.get();
|
||||||
|
if (fullScreen != null) {
|
||||||
|
urlParams.vts = String(fullScreen.vts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let usp = new URLSearchParams(urlParams);
|
||||||
let url = new URL(getBaseUrl() + "/webshare/screen?" + usp.toString());
|
let url = new URL(getBaseUrl() + "/webshare/screen?" + usp.toString());
|
||||||
fetch(url, {method: "GET", mode: "cors", cache: "no-cache"}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
|
fetch(url, {method: "GET", mode: "cors", cache: "no-cache"}).then((resp) => handleJsonFetchResponse(url, resp)).then((data) => {
|
||||||
mobx.action(() => {
|
let screen : T.WebFullScreen = data;
|
||||||
let screen : T.WebFullScreen = data;
|
if (update) {
|
||||||
|
this.mergeUpdate(screen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.setWebFullScreen(screen);
|
this.setWebFullScreen(screen);
|
||||||
})();
|
}
|
||||||
|
setTimeout(() => this.checkUpdateScreenData(), 300);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.errMessage.set("Cannot get screen: " + err.message);
|
this.errMessage.set("Cannot get screen: " + err.message);
|
||||||
|
}).finally(() => {
|
||||||
|
this.activeUpdateFetch = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLineNumFromId(lineId : string) : number {
|
||||||
|
let fullScreen = this.fullScreen.get();
|
||||||
|
if (fullScreen == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (let i=0; i<fullScreen.lines.length; i++) {
|
||||||
|
let line = fullScreen.lines[i];
|
||||||
|
if (line.lineid == lineId) {
|
||||||
|
return line.linenum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
getLineIndex(lineNum : number) : number {
|
getLineIndex(lineNum : number) : number {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen == null) {
|
if (fullScreen == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -431,7 +590,7 @@ class WebShareModelClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNumLines() : number {
|
getNumLines() : number {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen == null) {
|
if (fullScreen == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -439,7 +598,7 @@ class WebShareModelClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCmdById(lineId : string) : T.WebCmd {
|
getCmdById(lineId : string) : T.WebCmd {
|
||||||
let fullScreen = this.screen.get();
|
let fullScreen = this.fullScreen.get();
|
||||||
if (fullScreen == null) {
|
if (fullScreen == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -468,22 +627,7 @@ function getTermPtyData(termContext : T.TermContextUnion) : Promise<T.PtyDataTyp
|
|||||||
if ("remoteId" in termContext) {
|
if ("remoteId" in termContext) {
|
||||||
throw new Error("remote term ptydata is not supported in webshare");
|
throw new Error("remote term ptydata is not supported in webshare");
|
||||||
}
|
}
|
||||||
let ptyOffset = 0;
|
return WebShareModel.checkFetchPtyData(termContext.lineId, true);
|
||||||
let viewKey = WebShareModel.viewKey;
|
|
||||||
let usp = new URLSearchParams({screenid: termContext.screenId, viewkey: viewKey, lineid: termContext.lineId});
|
|
||||||
let url = new URL(getBaseUrl() + "/webshare/ptydata?" + usp.toString());
|
|
||||||
return fetch(url, {method: "GET", mode: "cors", cache: "no-cache"}).then((resp) => {
|
|
||||||
if (!resp.ok) {
|
|
||||||
throw new Error(sprintf("Bad fetch response for /webshare/ptydata: %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)};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let WebShareModel : WebShareModelClass = null;
|
let WebShareModel : WebShareModelClass = null;
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ class WebShareWSControl {
|
|||||||
this.viewKey = viewKey;
|
this.viewKey = viewKey;
|
||||||
this.open = mobx.observable.box(false, {name: "WSOpen"});
|
this.open = mobx.observable.box(false, {name: "WSOpen"});
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
setInterval(this.sendPing, 15000);
|
setInterval(this.sendPing, 20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
close() : void {
|
close() : void {
|
||||||
|
|||||||
Reference in New Issue
Block a user