move width from ScreenWindowView to ScreenWindow. pass termopts.cols in uicontext to cmdrunner

This commit is contained in:
sawka 2022-09-03 23:39:50 -07:00
parent 4a2b3cc381
commit 225f120fbe
4 changed files with 62 additions and 40 deletions

View File

@ -887,15 +887,19 @@ class CmdInput extends React.Component<{}, {}> {
}
}
// sw is not null
@mobxReact.observer
class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
mutObs : any;
rszObs : any;
interObs : IntersectionObserver;
randomId : string;
width : mobx.IObservableValue<number> = mobx.observable.box(0);
lastHeight : number = null;
constructor(props : any) {
super(props);
}
scrollToBottom(reason : string) {
let elem = document.getElementById(this.getLinesDOMId());
if (elem == null) {
@ -911,7 +915,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
let {sw} = this.props;
let target = event.target;
let atBottom = (target.scrollTop + 30 > (target.scrollHeight - target.offsetHeight));
if (sw && sw.shouldFollow.get() != atBottom) {
if (sw.shouldFollow.get() != atBottom) {
mobx.action(() => sw.shouldFollow.set(atBottom))();
}
// console.log("scroll-handler (sw)>", atBottom, target.scrollTop, target.scrollHeight, event);
@ -924,7 +928,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
this.mutObs.observe(elem, {childList: true});
elem.addEventListener("termresize", this.handleTermResize);
let {sw} = this.props;
if (sw && sw.shouldFollow.get()) {
if (sw.shouldFollow.get()) {
setTimeout(() => this.scrollToBottom("mount"), 0);
}
this.interObs = new IntersectionObserver(interObsCallback, {
@ -940,12 +944,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
}
}
updateWidth(width : number) {
mobx.action(() => {
this.width.set(width);
})();
}
componentWillUnmount() {
if (this.mutObs) {
this.mutObs.disconnect();
@ -956,6 +954,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
if (this.interObs) {
this.interObs.disconnect();
}
this.props.sw.setWidth(0);
}
handleResize(entries : any) {
@ -964,7 +963,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
}
let entry = entries[0];
let width = entry.target.offsetWidth;
this.updateWidth(width);
this.props.sw.setWidth(width);
if (this.lastHeight == null) {
this.lastHeight = entry.target.offsetHeight;
return;
@ -981,16 +980,13 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
doConditionalScrollToBottom(reason : string) {
let {sw} = this.props;
if (sw && sw.shouldFollow.get()) {
if (sw.shouldFollow.get()) {
setTimeout(() => this.scrollToBottom(reason), 0);
}
}
getWindow() : Window {
let {sw} = this.props;
if (sw == null) {
return null;
}
let win = GlobalModel.getWindowById(sw.sessionId, sw.windowId);
if (win == null) {
win = GlobalModel.loadWindow(sw.sessionId, sw.windowId);
@ -1005,7 +1001,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
@boundMethod
handleTermResize(e : any) {
let {sw} = this.props;
if (sw && sw.shouldFollow.get()) {
if (sw.shouldFollow.get()) {
setTimeout(() => this.scrollToBottom("termresize"), 0);
}
}
@ -1017,12 +1013,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
getWindowId() : string {
let {sw} = this.props;
if (sw == null) {
if (!this.randomId) {
this.randomId = uuidv4();
}
return this.randomId;
}
return sw.windowId;
}
@ -1035,9 +1025,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
return (
<div className="window-view" style={this.getWindowViewStyle()} id={this.getWindowViewDOMId()}>
<div key="window-tag" className="window-tag">
<If condition={sw != null}>
<span>{sw.name.get()}{sw.shouldFollow.get() ? "*" : ""}</span>
</If>
<span>{sw.name.get()}{sw.shouldFollow.get() ? "*" : ""}</span>
</div>
<div key="lines" className="lines" id={this.getLinesDOMId()}></div>
<div key="window-empty" className="window-empty">
@ -1049,9 +1037,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
render() {
let {sw} = this.props;
if (sw == null) {
return this.renderError("(no screen window)");
}
let win = this.getWindow();
if (win == null || !win.loaded.get()) {
return this.renderError("(loading)");
@ -1059,7 +1044,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
if (win.loadError.get() != null) {
return this.renderError(sprintf("(%s)", win.loadError.get()));
}
if (this.width.get() == 0) {
if (sw.width.get() == 0) {
return this.renderError("");
}
let idx = 0;
@ -1087,7 +1072,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
<div key="lines" className="lines" onScroll={this.scrollHandler} id={this.getLinesDOMId()} style={linesStyle}>
<div className="lines-spacer"></div>
<For each="line" of={win.lines} index="idx">
<Line key={line.lineid} line={line} sw={sw} width={this.width.get()} interObs={this.interObs} initVis={idx > win.lines.length-1-7} cmdRefNum={cmdRefMap[line.lineid] ?? 0}/>
<Line key={line.lineid} line={line} sw={sw} width={sw.width.get()} interObs={this.interObs} initVis={idx > win.lines.length-1-7} cmdRefNum={cmdRefMap[line.lineid] ?? 0}/>
</For>
</div>
<If condition={win.lines.length == 0}>
@ -1104,14 +1089,17 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
class ScreenView extends React.Component<{screen : Screen}, {}> {
render() {
let {screen} = this.props;
if (screen == null) {
let sw : ScreenWindow = null;
if (screen != null) {
sw = screen.getActiveSW();
}
if (screen == null || sw == null) {
return (
<div className="screen-view">
(no screen)
(no screen or window)
</div>
);
}
let sw = screen.getActiveSW();
return (
<div className="screen-view">
<ScreenWindowView key={sw.windowId} sw={sw}/>

View File

@ -8,6 +8,16 @@ import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem,
import {WSControl} from "./ws";
var GlobalUser = "sawka";
const DefaultCellWidth = 8;
const DefaultCellHeight = 16;
function widthToCols(width : number) : number {
let cols = Math.trunc((width - 25) / DefaultCellWidth) - 1;
if (cols < 0) {
return 0;
}
return cols;
}
type OV<V> = mobx.IObservableValue<V>;
type OArr<V> = mobx.IObservableArray<V>;
@ -242,6 +252,7 @@ class ScreenWindow {
name : OV<string>;
layout : OV<LayoutType>;
shouldFollow : OV<boolean> = mobx.observable.box(true);
width : OV<number> = mobx.observable.box(0);
// cmdid => TermWrap
terms : Record<string, TermWrap> = {};
@ -264,6 +275,12 @@ class ScreenWindow {
term.updatePtyData(ptyMsg.ptypos, data);
}
setWidth(width : number) : void {
mobx.action(() => {
this.width.set(width);
})();
}
getTermWrap(cmdId : string) : TermWrap {
return this.terms[cmdId];
}
@ -275,7 +292,8 @@ class ScreenWindow {
console.log("term-wrap already exists for", this.screenId, this.windowId, cmdId);
return;
}
let usedRows = GlobalModel.getTUR(this.sessionId, cmdId, width);
let cols = widthToCols(width);
let usedRows = GlobalModel.getTUR(this.sessionId, cmdId, cols);
termWrap = new TermWrap(elem, this.sessionId, cmdId, usedRows, cmd.getTermOpts(), {height: 0, width: width}, cmd.handleKey.bind(cmd));
this.terms[cmdId] = termWrap;
return;
@ -296,7 +314,8 @@ class ScreenWindow {
}
let termWrap = this.getTermWrap(cmd.cmdId);
if (termWrap == null) {
let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, width);
let cols = widthToCols(width);
let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, cols);
if (usedRows != null) {
return usedRows;
}
@ -1127,13 +1146,13 @@ class Model {
getApi().onDigitCmd(this.onDigitCmd.bind(this));
}
getTUR(sessionId : string, cmdId : string, width : number) : number {
let key = sessionId + "/" + cmdId + "/" + width;
getTUR(sessionId : string, cmdId : string, cols : number) : number {
let key = sessionId + "/" + cmdId + "/" + cols;
return this.termUsedRowsCache[key];
}
setTUR(sessionId : string, cmdId : string, width : number, usedRows : number) : void {
let key = sessionId + "/" + cmdId + "/" + width;
setTUR(sessionId : string, cmdId : string, cols : number, usedRows : number) : void {
let key = sessionId + "/" + cmdId + "/" + cols;
this.termUsedRowsCache[key] = usedRows;
}
@ -1148,6 +1167,7 @@ class Model {
screenid : null,
windowid : null,
remote : null,
termopts : {},
};
let session = this.getActiveSession();
if (session != null) {
@ -1160,6 +1180,10 @@ class Model {
rtn.windowid = win.windowId;
rtn.remote = win.curRemote.get();
}
let sw = screen.getActiveSW();
if (sw != null) {
rtn.termopts.cols = widthToCols(sw.width.get());
}
}
}
return rtn;
@ -1731,6 +1755,6 @@ if ((window as any).GlobalModal == null) {
GlobalModel = (window as any).GlobalModel;
GlobalCommandRunner = (window as any).GlobalCommandRunner;
export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr};
export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr, widthToCols};

View File

@ -48,6 +48,7 @@ class TermWrap {
loadError : mobx.IObservableValue<boolean> = mobx.observable.box(false);
winSize : WindowSize;
numParseErrors : number = 0;
termCols : number;
constructor(elem : Element, sessionId : string, cmdId : string, usedRows : number, termOpts : TermOptsType, winSize : WindowSize, keyHandler : (event : any) => void) {
this.sessionId = sessionId;
@ -68,6 +69,7 @@ class TermWrap {
if (maxCols > cols) {
cols = maxCols;
}
this.termCols = maxCols;
this.terminal = new Terminal({rows: termOpts.rows, cols: maxCols, fontSize: 14, theme: {foreground: "#d3d7cf"}});
this.terminal._core._inputHandler._parser.setErrorHandler((state) => {
this.numParseErrors++;
@ -155,7 +157,7 @@ class TermWrap {
mobx.action(() => {
let oldUsedRows = this.usedRows.get();
this.usedRows.set(tur);
GlobalModel.setTUR(this.sessionId, this.cmdId, this.winSize.width, tur);
GlobalModel.setTUR(this.sessionId, this.cmdId, this.termCols, tur);
if (this.connectedElem) {
let resizeEvent = new CustomEvent("termresize", {
bubbles: true,

View File

@ -139,11 +139,19 @@ type CmdRemoteStateType = {
cwd : string,
};
type UIContextTermOptsType = {
rows? : number,
cols? : number,
term? : string,
maxptysize? : number,
};
type UIContextType = {
sessionid : string,
screenid : string,
windowid : string,
remote : RemotePtrType,
termopts : UIContextTermOptsType,
};
type FeCmdPacketType = {