working on refactoring out a 'renderer' type from TermWrap

This commit is contained in:
sawka 2023-02-03 18:12:50 -08:00
parent d6e0c038e4
commit a25deff1a2
4 changed files with 99 additions and 55 deletions

View File

@ -213,6 +213,20 @@ class Prompt extends React.Component<{rptr : RemotePtrType, festate : FeStateTyp
}
}
@mobxReact.observer
class TerminalRenderer extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV<boolean>, onHeightChange : HeightChangeCallbackType}, {}> {
render() {
return null;
}
}
@mobxReact.observer
class MarkdownRenderer extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV<boolean>, onHeightChange : HeightChangeCallbackType}, {}> {
render() {
return null;
}
}
@mobxReact.observer
class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width : number, staticRender : boolean, visible : OV<boolean>, onHeightChange : HeightChangeCallbackType}, {}> {
termLoaded : mobx.IObservableValue<boolean> = mobx.observable.box(false, {name: "linecmd-term-loaded"});
@ -338,7 +352,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
doRefresh() {
let {sw, line} = this.props;
let model = GlobalModel;
let termWrap = sw.getTermWrap(line.cmdid);
let termWrap = sw.getRenderer(line.cmdid);
if (termWrap != null) {
termWrap.reload(500);
}
@ -365,9 +379,9 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
clickTermBlock(e : any) {
let {sw, line} = this.props;
let model = GlobalModel;
let termWrap = sw.getTermWrap(line.cmdid);
let termWrap = sw.getRenderer(line.cmdid);
if (termWrap != null) {
termWrap.focusTerminal();
termWrap.giveFocus();
}
}
@ -1038,7 +1052,7 @@ class InfoRemoteShow extends React.Component<{}, {}> {
clickTermBlock(e : any) {
let inputModel = GlobalModel.inputModel;
if (inputModel.remoteTermWrap != null) {
inputModel.remoteTermWrap.focusTerminal();
inputModel.remoteTermWrap.giveFocus();
}
}

View File

@ -5,7 +5,7 @@ import {debounce} from "throttle-debounce";
import {handleJsonFetchResponse, base64ToArray, genMergeData, genMergeSimpleData, boundInt, isModKeyPress} from "./util";
import {TermWrap} from "./term";
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, NormalTermContext} 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} from "./types";
import {WSControl} from "./ws";
var GlobalUser = "sawka";
@ -306,7 +306,7 @@ class ScreenWindow {
termLineNumFocus : OV<number>;
// cmdid => TermWrap
terms : Record<string, TermWrap> = {};
renderers : Record<string, RendererModel> = {};
setAnchor_debounced : (anchorLine : number, anchorOffset : number) => void;
@ -366,9 +366,9 @@ class ScreenWindow {
(document.activeElement as HTMLElement).blur();
}
if (sline != null && sline.cmdid != null) {
let termWrap = this.getTermWrap(sline.cmdid);
if (termWrap != null && termWrap.terminal != null) {
termWrap.focusTerminal();
let termWrap = this.getRenderer(sline.cmdid);
if (termWrap != null) {
termWrap.giveFocus();
}
}
}
@ -455,12 +455,12 @@ class ScreenWindow {
updatePtyData(ptyMsg : PtyDataUpdateType) {
let cmdId = ptyMsg.cmdid;
let term = this.terms[cmdId];
if (term == null) {
let renderer = this.renderers[cmdId];
if (renderer == null) {
return;
}
let data = base64ToArray(ptyMsg.ptydata64);
term.updatePtyData(ptyMsg.ptypos, data, "from-sw");
renderer.receiveData(ptyMsg.ptypos, data, "from-sw");
}
isActive() : boolean {
@ -480,14 +480,14 @@ class ScreenWindow {
}
this.lastRows = rows;
this.lastCols = cols;
for (let cmdid in this.terms) {
this.terms[cmdid].resizeCols(cols);
for (let cmdid in this.renderers) {
this.renderers[cmdid].resizeCols(cols);
}
GlobalCommandRunner.resizeWindow(this.windowId, rows, cols);
}
getTermWrap(cmdId : string) : TermWrap {
return this.terms[cmdId];
getRenderer(cmdId : string) : RendererModel {
return this.renderers[cmdId];
}
setTermFocus(lineNum : number, focus : boolean) : void {
@ -547,7 +547,7 @@ class ScreenWindow {
connectElem(elem : Element, line : LineType, cmd : Cmd, width : number) {
let cmdId = cmd.cmdId;
let termWrap = this.getTermWrap(cmdId);
let termWrap = this.getRenderer(cmdId);
if (termWrap != null) {
console.log("term-wrap already exists for", this.screenId, this.windowId, cmdId);
return;
@ -568,18 +568,18 @@ class ScreenWindow {
isRunning: cmd.isRunning(),
customKeyHandler: this.termCustomKeyHandler.bind(this),
});
this.terms[cmdId] = termWrap;
this.renderers[cmdId] = termWrap;
if ((this.focusType.get() == "cmd" || this.focusType.get() == "cmd-fg") && this.selectedLine.get() == line.linenum) {
termWrap.focusTerminal();
termWrap.giveFocus();
}
return;
}
disconnectElem(cmdId : string) {
let termWrap = this.terms[cmdId];
let termWrap = this.renderers[cmdId];
if (termWrap != null) {
termWrap.dispose();
delete this.terms[cmdId];
delete this.renderers[cmdId];
}
}
@ -588,7 +588,7 @@ class ScreenWindow {
if (!termOpts.flexrows) {
return termOpts.rows;
}
let termWrap = this.getTermWrap(cmd.cmdId);
let termWrap = this.getRenderer(cmd.cmdId);
if (termWrap == null) {
let cols = widthToCols(width);
let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, cols);
@ -600,7 +600,7 @@ class ScreenWindow {
}
return (cmd.isRunning() ? 1 : 0);
}
return termWrap.usedRows.get();
return termWrap.getUsedRows();
}
getIsFocused(lineNum : number) : boolean {
@ -1669,7 +1669,7 @@ class Model {
return this.termUsedRowsCache[key];
}
setTUR(termContext : NormalTermContext, size : TermWinSize, usedRows : number) : void {
setTUR(termContext : RendererContext, size : TermWinSize, usedRows : number) : void {
let key = termContext.sessionId + "/" + termContext.cmdId + "/" + size.cols;
this.termUsedRowsCache[key] = usedRows;
GlobalCommandRunner.setTermUsedRows(termContext, usedRows);
@ -1754,13 +1754,17 @@ class Model {
}
cmdStatusUpdate(sessionId : string, cmdId : string, origStatus : string, newStatus : string) {
// console.log("cmd status", sessionId, cmdId, origStatus, "=>", newStatus);
let lines = this.getActiveLinesByCmdId(sessionId, cmdId);
for (let ptr of lines) {
let sw = ptr.sw;
let term = sw.getTermWrap(cmdId);
if (term != null) {
term.setIsRunning(cmdStatusIsRunning(newStatus));
let wasRunning = cmdStatusIsRunning(origStatus);
let isRunning = cmdStatusIsRunning(newStatus);
if (wasRunning && !isRunning) {
// console.log("cmd status", sessionId, cmdId, origStatus, "=>", newStatus);
let lines = this.getActiveLinesByCmdId(sessionId, cmdId);
for (let ptr of lines) {
let sw = ptr.sw;
let renderer = sw.getRenderer(cmdId);
if (renderer != null) {
renderer.cmdDone();
}
}
}
}
@ -1829,7 +1833,7 @@ class Model {
return;
}
let ptyData = base64ToArray(ptyMsg.ptydata64);
this.inputModel.remoteTermWrap.updatePtyData(ptyMsg.ptypos, ptyData);
this.inputModel.remoteTermWrap.receiveData(ptyMsg.ptypos, ptyData);
return;
}
}
@ -2360,7 +2364,7 @@ class CommandRunner {
GlobalModel.submitCommand("sw", "set", null, kwargs, true);
}
setTermUsedRows(termContext : NormalTermContext, height : number) {
setTermUsedRows(termContext : RendererContext, height : number) {
let kwargs : Record<string, string> = {};
kwargs["session"] = termContext.sessionId;
kwargs["screen"] = termContext.screenId;

View File

@ -3,26 +3,21 @@ import {Terminal} from 'xterm';
import {sprintf} from "sprintf-js";
import {boundMethod} from "autobind-decorator";
import {v4 as uuidv4} from "uuid";
import {GlobalModel, widthToCols, GlobalCommandRunner} from "./model";
import {GlobalModel, widthToCols, GlobalCommandRunner, termHeightFromRows, termRowsFromHeight} from "./model";
import {boundInt} from "./util";
import type {TermOptsType, TermWinSize, NormalTermContext} from "./types";
import type {TermOptsType, TermWinSize, RendererContext, WindowSize} from "./types";
type DataUpdate = {
data : Uint8Array,
pos : number,
}
type WindowSize = {
height : number,
width: number,
};
const MinTermCols = 10;
const MaxTermCols = 1024;
type RemoteTermContext = {remoteId : string};
type TermContext = NormalTermContext | RemoteTermContext;
type TermContext = RendererContext | RemoteTermContext;
type TermWrapOpts = {
termContext : TermContext,
@ -112,6 +107,10 @@ class TermWrap {
this.reload(0);
}
getUsedRows() : number {
return this.usedRows.get();
}
@boundMethod
elemScrollHandler(e : any) {
// this stops a weird behavior in the terminal
@ -132,7 +131,7 @@ class TermWrap {
return null;
}
getNormalTermContext() : NormalTermContext {
getRendererContext() : RendererContext {
if ("remoteId" in this.termContext) {
return null;
}
@ -150,7 +149,10 @@ class TermWrap {
}
}
focusTerminal() {
giveFocus() {
if (this.terminal == null) {
return;
}
this.terminal.focus();
setTimeout(() => this.terminal._core.viewport.syncScrollArea(true), 0)
}
@ -191,7 +193,7 @@ class TermWrap {
if (!this.flexRows) {
return;
}
let termContext = this.getNormalTermContext();
let termContext = this.getRendererContext();
if ("remoteId" in termContext) {
return;
}
@ -218,11 +220,11 @@ class TermWrap {
})();
}
resizeCols(cols : number) {
resizeCols(cols : number) : void {
this.resize({rows: this.termSize.rows, cols: cols});
}
resize(size : TermWinSize) {
resize(size : TermWinSize) : void {
if (this.terminal == null) {
return;
}
@ -236,11 +238,17 @@ class TermWrap {
this.updateUsedRows(true, "resize");
}
resizeWindow(size : WindowSize) : void {
let cols = widthToCols(size.width);
let rows = termRowsFromHeight(size.height);
this.resize({rows, cols});
}
_getReloadUrl() : string {
if (this.getContextRemoteId() != null) {
return sprintf(GlobalModel.getBaseHostPort() + "/api/remote-pty?remoteid=%s", this.getContextRemoteId());
}
let termContext = this.getNormalTermContext();
let termContext = this.getRendererContext();
return sprintf(GlobalModel.getBaseHostPort() + "/api/ptyout?sessionid=%s&cmdid=%s", termContext.sessionId, termContext.cmdId);
}
@ -268,9 +276,9 @@ class TermWrap {
setTimeout(() => {
this.reloading = false;
this.ptyPos = ptyOffset;
this.updatePtyData(ptyOffset, new Uint8Array(buf), "reload-main");
this.receiveData(ptyOffset, new Uint8Array(buf), "reload-main");
for (let i=0; i<this.dataUpdates.length; i++) {
this.updatePtyData(this.dataUpdates[i].pos, this.dataUpdates[i].data, "reload-update-" + i);
this.receiveData(this.dataUpdates[i].pos, this.dataUpdates[i].data, "reload-update-" + i);
}
this.dataUpdates = [];
this.terminal.write(new Uint8Array(), () => {
@ -282,7 +290,7 @@ class TermWrap {
});
}
updatePtyData(pos : number, data : Uint8Array, reason? : string) {
receiveData(pos : number, data : Uint8Array, reason? : string) {
// console.log("update-pty-data", pos, data.length, reason);
if (this.terminal == null) {
return;
@ -313,9 +321,9 @@ class TermWrap {
});
}
setIsRunning(isRunning : boolean) {
this.isRunning = isRunning;
this.updateUsedRows(true, "cmd-status");
cmdDone() : void {
this.isRunning = false;
this.updateUsedRows(true, "cmd-done");
}
}

View File

@ -333,7 +333,7 @@ type ContextMenuOpts = {
type UpdateMessage = PtyDataUpdateType | ModelUpdateType;
type NormalTermContext = {
type RendererContext = {
sessionId : string,
screenId : string,
windowId : string,
@ -342,4 +342,22 @@ type NormalTermContext = {
lineNum : 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, NormalTermContext};
type RendererModel = {
reload : (delayMs : number) => void,
dispose : () => void,
receiveData : (pos : number, data : Uint8Array, reason? : string) => void,
cmdDone : () => void,
resizeWindow : (size : WindowSize) => void,
resizeCols : (cols : number) => void,
giveFocus : () => void,
getUsedRows : () => number,
focusHandler : (focus : boolean) => void;
};
type WindowSize = {
height : 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};