mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-09 13:00:53 +01:00
working on refactoring out a 'renderer' type from TermWrap
This commit is contained in:
parent
d6e0c038e4
commit
a25deff1a2
22
src/main.tsx
22
src/main.tsx
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
62
src/model.ts
62
src/model.ts
@ -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;
|
||||
|
48
src/term.ts
48
src/term.ts
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
22
src/types.ts
22
src/types.ts
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user