Pull in linting fixes from preact branch (#538)

* Pull in linting fixes from preact branch

* more consts

* one more const

* Revert PureComponent

* revert preact artifavt

* revert another change
This commit is contained in:
Evan Simkowitz 2024-04-02 12:30:17 -07:00 committed by GitHub
parent ca5117cda0
commit dc7fc2c823
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 312 additions and 309 deletions

View File

@ -8,7 +8,7 @@ import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { If } from "tsx-control-statements/components";
import { Choose, If, Otherwise, When } from "tsx-control-statements/components";
import { GlobalModel, GlobalCommandRunner, Cmd } from "@/models";
import { termHeightFromRows } from "@/util/textmeasure";
import cn from "classnames";
@ -25,23 +25,22 @@ import * as lineutil from "./lineutil";
import { ErrorBoundary } from "@/common/error/errorboundary";
import * as appconst from "@/app/appconst";
import * as util from "@/util/util";
import * as textmeasure from "@/util/textmeasure";
import "./line.less";
import { CenteredIcon, RotateIcon } from "../common/icons/icons";
import { RotateIcon } from "../common/icons/icons";
const DebugHeightProblems = false;
const MinLine = 0;
const MaxLine = 1000;
let heightLog = {};
const heightLog = {};
(window as any).heightLog = heightLog;
(window as any).findHeightProblems = function () {
for (let linenum in heightLog) {
let lh = heightLog[linenum];
for (const linenum in heightLog) {
const lh = heightLog[linenum];
if (lh.heightArr == null || lh.heightArr.length < 2) {
continue;
}
let firstHeight = lh.heightArr[0];
const firstHeight = lh.heightArr[0];
for (let i = 1; i < lh.heightArr.length; i++) {
if (lh.heightArr[i] != firstHeight) {
console.log("line", linenum, "heights", lh.heightArr);
@ -57,7 +56,7 @@ function cmdShouldMarkError(cmd: Cmd): boolean {
if (cmd.getStatus() == "error") {
return true;
}
let exitCode = cmd.getExitCode();
const exitCode = cmd.getExitCode();
// 0, SIGINT, or SIGPIPE
if (exitCode == 0 || exitCode == 130 || exitCode == 141) {
return false;
@ -142,7 +141,7 @@ class LineActions extends React.Component<{ screen: LineContainerType; line: Lin
handleLineSettings(e: any): void {
e.preventDefault();
e.stopPropagation();
let { line } = this.props;
const { line } = this.props;
if (line != null) {
mobx.action(() => {
GlobalModel.lineSettingsModal.set(line.linenum);
@ -152,74 +151,89 @@ class LineActions extends React.Component<{ screen: LineContainerType; line: Lin
}
render() {
let { line, screen } = this.props;
const { line, screen } = this.props;
const isMinimized = line.linestate["wave:min"];
const containerType = screen.getContainerType();
return (
<div className="line-actions">
<If condition={containerType == appconst.LineContainer_Main}>
<div key="restart" title="Restart Command" className="line-icon" onClick={this.clickRestart}>
<i className="fa-sharp fa-regular fa-arrows-rotate fa-fw" />
</div>
<div key="delete" title="Delete Line (&#x2318;D)" className="line-icon" onClick={this.clickDelete}>
<i className="fa-sharp fa-regular fa-trash fa-fw" />
</div>
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
</div>
<div
key="minimize"
title={`${isMinimized ? "Show Output" : "Hide Output"}`}
className={cn("line-icon", isMinimized ? "active" : "")}
onClick={this.clickMinimize}
>
<If condition={isMinimized}>
<i className="fa-sharp fa-regular fa-circle-plus fa-fw" />
</If>
<If condition={!isMinimized}>
<i className="fa-sharp fa-regular fa-circle-minus fa-fw" />
</If>
</div>
<div className="line-icon line-sidebar" onClick={this.clickMoveToSidebar} title="Move to Sidebar">
<i className="fa-sharp fa-solid fa-right-to-line fa-fw" />
</div>
<div
key="settings"
title="Line Settings"
className="line-icon line-icon-shrink-left"
onClick={this.handleLineSettings}
>
<i className="fa-sharp fa-regular fa-ellipsis-vertical fa-fw" />
</div>
</If>
<If condition={containerType == appconst.LineContainer_Sidebar}>
<div key="restart" title="Restart Command" className="line-icon" onClick={this.clickRestart}>
<i className="fa-sharp fa-regular fa-arrows-rotate fa-fw" />
</div>
<div key="delete" title="Delete Line (&#x2318;D)" className="line-icon" onClick={this.clickDelete}>
<i className="fa-sharp fa-regular fa-trash fa-fw" />
</div>
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
</div>
<div
className="line-icon line-sidebar"
onClick={this.clickRemoveFromSidebar}
title="Move to Sidebar"
>
<i className="fa-sharp fa-solid fa-left-to-line fa-fw" />
</div>
</If>
<Choose>
<When condition={containerType == appconst.LineContainer_Main}>
<div key="restart" title="Restart Command" className="line-icon" onClick={this.clickRestart}>
<i className="fa-sharp fa-regular fa-arrows-rotate fa-fw" />
</div>
<div
key="delete"
title="Delete Line (&#x2318;D)"
className="line-icon"
onClick={this.clickDelete}
>
<i className="fa-sharp fa-regular fa-trash fa-fw" />
</div>
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
</div>
<div
key="minimize"
title={`${isMinimized ? "Show Output" : "Hide Output"}`}
className={cn("line-icon", isMinimized ? "active" : "")}
onClick={this.clickMinimize}
>
<Choose>
<When condition={isMinimized}>
<i className="fa-sharp fa-regular fa-circle-plus fa-fw" />
</When>
<Otherwise>
<i className="fa-sharp fa-regular fa-circle-minus fa-fw" />
</Otherwise>
</Choose>
</div>
<div
className="line-icon line-sidebar"
onClick={this.clickMoveToSidebar}
title="Move to Sidebar"
>
<i className="fa-sharp fa-solid fa-right-to-line fa-fw" />
</div>
<div
key="settings"
title="Line Settings"
className="line-icon line-icon-shrink-left"
onClick={this.handleLineSettings}
>
<i className="fa-sharp fa-regular fa-ellipsis-vertical fa-fw" />
</div>
</When>
<When condition={containerType == appconst.LineContainer_Sidebar}>
<div
key="delete"
title="Delete Line (&#x2318;D)"
className="line-icon"
onClick={this.clickDelete}
>
<i className="fa-sharp fa-regular fa-trash fa-fw" />
</div>
<div
key="bookmark"
title="Bookmark"
className={cn("line-icon", "line-bookmark")}
onClick={this.clickBookmark}
>
<i className="fa-sharp fa-regular fa-bookmark fa-fw" />
</div>
<div
className="line-icon line-sidebar"
onClick={this.clickRemoveFromSidebar}
title="Move to Sidebar"
>
<i className="fa-sharp fa-solid fa-left-to-line fa-fw" />
</div>
</When>
</Choose>
</div>
);
}
@ -254,9 +268,9 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
}
renderMeta1(cmd: Cmd) {
let { line } = this.props;
const { line } = this.props;
let formattedTime: string = "";
let restartTs = cmd.getRestartTs();
const restartTs = cmd.getRestartTs();
let timeTitle: string = null;
if (restartTs != null && restartTs > 0) {
formattedTime = "restarted @ " + lineutil.getLineDateTimeStr(restartTs);
@ -264,8 +278,8 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
} else {
formattedTime = lineutil.getLineDateTimeStr(line.ts);
}
let renderer = line.renderer;
let durationMs = cmd.getDurationMs();
const renderer = line.renderer;
const durationMs = cmd.getDurationMs();
return (
<div key="meta1" className="meta meta-line1">
<SmallLineAvatar line={line} cmd={cmd} />
@ -287,7 +301,7 @@ class LineHeader extends React.Component<{ screen: LineContainerType; line: Line
}
render() {
let { line, cmd } = this.props;
const { line, cmd } = this.props;
const hidePrompt = getIsHidePrompt(line);
return (
<div key="header" className={cn("line-header", { "hide-prompt": hidePrompt })}>
@ -303,7 +317,7 @@ class SmallLineAvatar extends React.Component<{ line: LineType; cmd: Cmd; onRigh
render() {
const { line, cmd } = this.props;
const lineNumStr = (line.linenumtemp ? "~" : "#") + String(line.linenum);
let status = cmd != null ? cmd.getStatus() : "done";
const status = cmd != null ? cmd.getStatus() : "done";
const exitcode = cmd != null ? cmd.getExitCode() : 0;
const isComment = line.linetype == "text";
let icon = null;
@ -359,7 +373,7 @@ class RtnState extends React.Component<{ cmd: Cmd; line: LineType }> {
}
checkStateDiffLoad(): void {
let cmd = this.props.cmd;
const cmd = this.props.cmd;
if (cmd == null || !cmd.getRtnState() || this.rtnStateDiffFetched) {
return;
}
@ -406,7 +420,7 @@ class RtnState extends React.Component<{ cmd: Cmd; line: LineType }> {
}
render() {
let { cmd } = this.props;
const { cmd } = this.props;
const rsdiff = this.rtnStateDiff.get();
const termFontSize = GlobalModel.getTermFontSize();
let rtnStateDiffSize = termFontSize - 2;
@ -488,7 +502,7 @@ class LineCmd extends React.Component<
if (elem != null) {
curHeight = elem.offsetHeight;
}
let linenum = line.linenum;
const linenum = line.linenum;
if (DebugHeightProblems && linenum >= MinLine && linenum <= MaxLine) {
heightLog[linenum] = heightLog[linenum] || {};
heightLog[linenum].heightArr = heightLog[linenum].heightArr || [];
@ -685,7 +699,7 @@ class LineCmd extends React.Component<
const isFocused = mobx
.computed(
() => {
let screenFocusType = screen.getFocusType();
const screenFocusType = screen.getFocusType();
return isPhysicalFocused && screenFocusType == "cmd";
},
{ name: "computed-isFocused" }
@ -694,7 +708,7 @@ class LineCmd extends React.Component<
const shouldCmdFocus = mobx
.computed(
() => {
let screenFocusType = screen.getFocusType();
const screenFocusType = screen.getFocusType();
return isSelected && screenFocusType == "cmd";
},
{ name: "computed-shouldCmdFocus" }
@ -725,16 +739,9 @@ class LineCmd extends React.Component<
rendererPlugin = PluginModel.getRendererPluginByName(line.renderer);
}
const rendererType = lineutil.getRendererType(line);
const hidePrompt = rendererPlugin?.hidePrompt;
const termFontSize = GlobalModel.getTermFontSize();
const containerType = screen.getContainerType();
const isMinimized = line.linestate["wave:min"] && containerType == appconst.LineContainer_Main;
const lhv: LineChromeHeightVars = {
numCmdLines: lineutil.countCmdLines(cmd.getCmdStr()),
zeroHeight: isMinimized,
hasLine2: !hidePrompt,
};
const chromeHeight = textmeasure.calcLineChromeHeight(GlobalModel.lineHeightEnv, lhv);
return (
<div
className={mainDivCn}
@ -749,55 +756,64 @@ class LineCmd extends React.Component<
</If>
<LineActions screen={screen} line={line} cmd={cmd} />
<LineHeader screen={screen} line={line} cmd={cmd} />
<If condition={!isMinimized && isInSidebar}>
<div className="sidebar-message" style={{ fontSize: termFontSize }}>
&nbsp;&nbsp;showing in sidebar =&gt;
</div>
</If>
<If condition={!isMinimized && !isInSidebar}>
<ErrorBoundary plugin={rendererPlugin?.name} lineContext={lineutil.getRendererContext(line)}>
<If condition={rendererPlugin == null && !isNoneRenderer}>
<TerminalRenderer
screen={screen}
line={line}
width={width}
staticRender={staticRender}
visible={visible}
onHeightChange={this.handleHeightChange}
collapsed={false}
/>
</If>
<If condition={rendererPlugin != null && rendererPlugin.rendererType == "simple"}>
<SimpleBlobRenderer
rendererContainer={screen}
lineId={line.lineid}
plugin={rendererPlugin}
onHeightChange={this.handleHeightChange}
initParams={this.makeRendererModelInitializeParams()}
scrollToBringIntoViewport={this.scrollToBringIntoViewport}
isSelected={isSelected}
shouldFocus={shouldCmdFocus}
/>
</If>
<If condition={rendererPlugin != null && rendererPlugin.rendererType == "full"}>
<IncrementalRenderer
rendererContainer={screen}
lineId={line.lineid}
plugin={rendererPlugin}
onHeightChange={this.handleHeightChange}
initParams={this.makeRendererModelInitializeParams()}
isSelected={isSelected}
/>
</If>
</ErrorBoundary>
<If condition={isRtnState}>
<RtnState cmd={cmd} line={line} />
</If>
<If condition={isSelected && !isFocused && rendererType == "terminal"}>
<div className="cmd-hints">
<div className="hint-item color-nohover-white">focus line ({renderCmdText("L")})</div>
</div>
</If>
<If condition={!isMinimized}>
<Choose>
<When condition={isInSidebar}>
<div className="sidebar-message" style={{ fontSize: termFontSize }}>
&nbsp;&nbsp;showing in sidebar =&gt;
</div>
</When>
<Otherwise>
<ErrorBoundary
plugin={rendererPlugin?.name}
lineContext={lineutil.getRendererContext(line)}
>
<If condition={rendererPlugin == null && !isNoneRenderer}>
<TerminalRenderer
screen={screen}
line={line}
width={width}
staticRender={staticRender}
visible={visible}
onHeightChange={this.handleHeightChange}
collapsed={false}
/>
</If>
<If condition={rendererPlugin != null && rendererPlugin.rendererType == "simple"}>
<SimpleBlobRenderer
rendererContainer={screen}
lineId={line.lineid}
plugin={rendererPlugin}
onHeightChange={this.handleHeightChange}
initParams={this.makeRendererModelInitializeParams()}
scrollToBringIntoViewport={this.scrollToBringIntoViewport}
isSelected={isSelected}
shouldFocus={shouldCmdFocus}
/>
</If>
<If condition={rendererPlugin != null && rendererPlugin.rendererType == "full"}>
<IncrementalRenderer
rendererContainer={screen}
lineId={line.lineid}
plugin={rendererPlugin}
onHeightChange={this.handleHeightChange}
initParams={this.makeRendererModelInitializeParams()}
isSelected={isSelected}
/>
</If>
</ErrorBoundary>
<If condition={isRtnState}>
<RtnState cmd={cmd} line={line} />
</If>
<If condition={isSelected && !isFocused && rendererType == "terminal"}>
<div className="cmd-hints">
<div className="hint-item color-nohover-white">
focus line ({renderCmdText("L")})
</div>
</div>
</If>
</Otherwise>
</Choose>
</If>
</div>
);
@ -877,11 +893,6 @@ class LineText extends React.Component<
name: "computed-isSelected",
})
.get();
const isFocused = mobx
.computed(() => screen.getFocusType() == "cmd", {
name: "computed-isFocused",
})
.get();
const mainClass = cn("line", "line-text", "focus-parent", { selected: isSelected });
return (
<div

View File

@ -11,7 +11,6 @@ import cn from "classnames";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
import { getMonoFontSize } from "@/util/textmeasure";
import * as appconst from "@/app/appconst";
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, WaveKeyboardEvent } from "@/util/keyutil";
type OV<T> = mobx.IObservableValue<T>;
@ -44,8 +43,8 @@ class HistoryKeybindings extends React.Component<{ inputObject: TextAreaInput },
if (GlobalModel.activeMainView != "session") {
return;
}
let inputModel = GlobalModel.inputModel;
let keybindManager = GlobalModel.keybindManager;
const inputModel = GlobalModel.inputModel;
const keybindManager = GlobalModel.keybindManager;
keybindManager.registerKeybinding("pane", "history", "generic:cancel", (waveEvent) => {
inputModel.resetHistory();
return true;
@ -109,15 +108,15 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
if (GlobalModel.activeMainView != "session") {
return;
}
let inputObject = this.props.inputObject;
const inputObject = this.props.inputObject;
this.lastTab = false;
let keybindManager = GlobalModel.keybindManager;
let inputModel = GlobalModel.inputModel;
const keybindManager = GlobalModel.keybindManager;
const inputModel = GlobalModel.inputModel;
keybindManager.registerKeybinding("pane", "cmdinput", "cmdinput:autocomplete", (waveEvent) => {
let lastTab = this.lastTab;
const lastTab = this.lastTab;
this.lastTab = true;
this.curPress = "tab";
let curLine = inputModel.getCurLine();
const curLine = inputModel.getCurLine();
if (lastTab) {
GlobalModel.submitCommand(
"_compgen",
@ -140,8 +139,8 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
keybindManager.registerKeybinding("pane", "cmdinput", "generic:confirm", (waveEvent) => {
GlobalModel.closeTabSettings();
if (GlobalModel.inputModel.isEmpty()) {
let activeWindow = GlobalModel.getScreenLinesForActiveScreen();
let activeScreen = GlobalModel.getActiveScreen();
const activeWindow = GlobalModel.getScreenLinesForActiveScreen();
const activeScreen = GlobalModel.getActiveScreen();
if (activeScreen != null && activeWindow != null && activeWindow.lines.length > 0) {
activeScreen.setSelectedLine(0);
GlobalCommandRunner.screenSelectLine("E");
@ -200,12 +199,12 @@ class CmdInputKeybindings extends React.Component<{ inputObject: TextAreaInput }
});
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectAbove", (waveEvent) => {
this.curPress = "historyupdown";
let rtn = inputObject.arrowUpPressed();
const rtn = inputObject.arrowUpPressed();
return rtn;
});
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectBelow", (waveEvent) => {
this.curPress = "historyupdown";
let rtn = inputObject.arrowDownPressed();
const rtn = inputObject.arrowDownPressed();
return rtn;
});
keybindManager.registerKeybinding("pane", "cmdinput", "generic:selectPageAbove", (waveEvent) => {
@ -259,18 +258,18 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
historyFocused: OV<boolean> = mobx.observable.box(false);
incVersion(): void {
let v = this.version.get();
const v = this.version.get();
mobx.action(() => this.version.set(v + 1))();
}
getCurSP(): StrWithPos {
let textarea = this.mainInputRef.current;
const textarea = this.mainInputRef.current;
if (textarea == null) {
return this.lastSP;
}
let str = textarea.value;
let pos = textarea.selectionStart;
let endPos = textarea.selectionEnd;
const str = textarea.value;
const pos = textarea.selectionStart;
const endPos = textarea.selectionEnd;
if (pos != endPos) {
return { str, pos: appconst.NoStrPos };
}
@ -278,7 +277,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
updateSP(): void {
let curSP = this.getCurSP();
const curSP = this.getCurSP();
if (curSP.str == this.lastSP.str && curSP.pos == this.lastSP.pos) {
return;
}
@ -287,7 +286,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
setFocus(): void {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (inputModel.historyShow.get()) {
this.historyInputRef.current.focus();
} else {
@ -296,25 +295,25 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
getTextAreaMaxCols(): number {
let taElem = this.mainInputRef.current;
const taElem = this.mainInputRef.current;
if (taElem == null) {
return 0;
}
let cs = window.getComputedStyle(taElem);
let padding = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);
let borders = parseFloat(cs.borderLeft) + parseFloat(cs.borderRight);
let contentWidth = taElem.clientWidth - padding - borders;
let fontSize = getMonoFontSize(parseInt(cs.fontSize));
let maxCols = Math.floor(contentWidth / Math.ceil(fontSize.width));
const cs = window.getComputedStyle(taElem);
const padding = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);
const borders = parseFloat(cs.borderLeft) + parseFloat(cs.borderRight);
const contentWidth = taElem.clientWidth - padding - borders;
const fontSize = getMonoFontSize(parseInt(cs.fontSize));
const maxCols = Math.floor(contentWidth / Math.ceil(fontSize.width));
return maxCols;
}
checkHeight(shouldFire: boolean): void {
let elem = this.controlRef.current;
const elem = this.controlRef.current;
if (elem == null) {
return;
}
let curHeight = elem.offsetHeight;
const curHeight = elem.offsetHeight;
if (this.lastHeight == curHeight) {
return;
}
@ -325,9 +324,9 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
componentDidMount() {
let activeScreen = GlobalModel.getActiveScreen();
const activeScreen = GlobalModel.getActiveScreen();
if (activeScreen != null) {
let focusType = activeScreen.focusType.get();
const focusType = activeScreen.focusType.get();
if (focusType == "input") {
this.setFocus();
}
@ -338,16 +337,16 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
componentDidUpdate() {
let activeScreen = GlobalModel.getActiveScreen();
const activeScreen = GlobalModel.getActiveScreen();
if (activeScreen != null) {
let focusType = activeScreen.focusType.get();
const focusType = activeScreen.focusType.get();
if (this.lastFocusType != focusType && focusType == "input") {
this.setFocus();
}
this.lastFocusType = focusType;
}
let inputModel = GlobalModel.inputModel;
let fcpos = inputModel.forceCursorPos.get();
const inputModel = GlobalModel.inputModel;
const fcpos = inputModel.forceCursorPos.get();
if (fcpos != null && fcpos != appconst.NoStrPos) {
if (this.mainInputRef.current != null) {
this.mainInputRef.current.selectionStart = fcpos;
@ -364,24 +363,24 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
getLinePos(elem: any): { numLines: number; linePos: number } {
let numLines = elem.value.split("\n").length;
let linePos = elem.value.substr(0, elem.selectionStart).split("\n").length;
const numLines = elem.value.split("\n").length;
const linePos = elem.value.substr(0, elem.selectionStart).split("\n").length;
return { numLines, linePos };
}
arrowUpPressed(): boolean {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (!inputModel.isHistoryLoaded()) {
this.lastHistoryUpDown = true;
inputModel.loadHistory(false, 1, "screen");
return true;
}
let currentRef = this.mainInputRef.current;
const currentRef = this.mainInputRef.current;
if (currentRef == null) {
return true;
}
let linePos = this.getLinePos(currentRef);
let lastHist = this.lastHistoryUpDown;
const linePos = this.getLinePos(currentRef);
const lastHist = this.lastHistoryUpDown;
if (!lastHist && linePos.linePos > 1) {
// regular arrow
return false;
@ -392,16 +391,16 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
arrowDownPressed(): boolean {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (!inputModel.isHistoryLoaded()) {
return true;
}
let currentRef = this.mainInputRef.current;
const currentRef = this.mainInputRef.current;
if (currentRef == null) {
return true;
}
let linePos = this.getLinePos(currentRef);
let lastHist = this.lastHistoryUpDown;
const linePos = this.getLinePos(currentRef);
const lastHist = this.lastHistoryUpDown;
if (!lastHist && linePos.linePos < linePos.numLines) {
// regular arrow
return false;
@ -412,17 +411,17 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
scrollPage(up: boolean) {
let inputModel = GlobalModel.inputModel;
let infoScroll = inputModel.hasScrollingInfoMsg();
const inputModel = GlobalModel.inputModel;
const infoScroll = inputModel.hasScrollingInfoMsg();
if (infoScroll) {
let div = document.querySelector(".cmd-input-info");
let amt = pageSize(div);
const div = document.querySelector(".cmd-input-info");
const amt = pageSize(div);
scrollDiv(div, up ? -amt : amt);
}
}
modEnter() {
let currentRef = this.mainInputRef.current;
const currentRef = this.mainInputRef.current;
if (currentRef == null) {
return;
}
@ -454,21 +453,21 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
if (this.mainInputRef.current == null) {
return;
}
let selStart = this.mainInputRef.current.selectionStart;
let value = this.mainInputRef.current.value;
const selStart = this.mainInputRef.current.selectionStart;
const value = this.mainInputRef.current.value;
if (selStart > value.length) {
return;
}
let cutValue = value.substr(0, selStart);
let restValue = value.substr(selStart);
let cmdLineUpdate = { str: restValue, pos: 0 };
const cutValue = value.substring(0, selStart);
const restValue = value.substring(selStart);
const cmdLineUpdate = { str: restValue, pos: 0 };
navigator.clipboard.writeText(cutValue);
GlobalModel.inputModel.updateCmdLine(cmdLineUpdate);
}
@boundMethod
controlP() {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (!inputModel.isHistoryLoaded()) {
this.lastHistoryUpDown = true;
inputModel.loadHistory(false, 1, "screen");
@ -480,7 +479,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
@boundMethod
controlN() {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
inputModel.moveHistorySelection(-1);
this.lastHistoryUpDown = true;
}
@ -490,15 +489,15 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
if (this.mainInputRef.current == null) {
return;
}
let selStart = this.mainInputRef.current.selectionStart;
let value = this.mainInputRef.current.value;
const selStart = this.mainInputRef.current.selectionStart;
const value = this.mainInputRef.current.value;
if (selStart > value.length) {
return;
}
let cutSpot = selStart - 1;
let initial = true;
for (; cutSpot >= 0; cutSpot--) {
let ch = value[cutSpot];
const ch = value[cutSpot];
if (ch == " " && initial) {
continue;
}
@ -511,10 +510,10 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
if (cutSpot == -1) {
cutSpot = 0;
}
let cutValue = value.slice(cutSpot, selStart);
let prevValue = value.slice(0, cutSpot);
let restValue = value.slice(selStart);
let cmdLineUpdate = { str: prevValue + restValue, pos: prevValue.length };
const cutValue = value.slice(cutSpot, selStart);
const prevValue = value.slice(0, cutSpot);
const restValue = value.slice(selStart);
const cmdLineUpdate = { str: prevValue + restValue, pos: prevValue.length };
navigator.clipboard.writeText(cutValue);
GlobalModel.inputModel.updateCmdLine(cmdLineUpdate);
}
@ -524,26 +523,26 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
if (this.mainInputRef.current == null) {
return;
}
let pastePromise = navigator.clipboard.readText();
const pastePromise = navigator.clipboard.readText();
pastePromise.then((clipText) => {
clipText = clipText ?? "";
let selStart = this.mainInputRef.current.selectionStart;
let selEnd = this.mainInputRef.current.selectionEnd;
let value = this.mainInputRef.current.value;
const selStart = this.mainInputRef.current.selectionStart;
const selEnd = this.mainInputRef.current.selectionEnd;
const value = this.mainInputRef.current.value;
if (selStart > value.length || selEnd > value.length) {
return;
}
let newValue = value.substr(0, selStart) + clipText + value.substr(selEnd);
let cmdLineUpdate = { str: newValue, pos: selStart + clipText.length };
const newValue = value.substr(0, selStart) + clipText + value.substr(selEnd);
const cmdLineUpdate = { str: newValue, pos: selStart + clipText.length };
GlobalModel.inputModel.updateCmdLine(cmdLineUpdate);
});
}
@boundMethod
handleHistoryInput(e: any) {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
mobx.action(() => {
let opts = mobx.toJS(inputModel.historyQueryOpts.get());
const opts = mobx.toJS(inputModel.historyQueryOpts.get());
opts.queryStr = e.target.value;
inputModel.setHistoryQueryOpts(opts);
})();
@ -551,7 +550,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
@boundMethod
handleMainFocus(e: any) {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (inputModel.historyShow.get()) {
e.preventDefault();
if (this.historyInputRef.current != null) {
@ -578,7 +577,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
@boundMethod
handleHistoryFocus(e: any) {
let inputModel = GlobalModel.inputModel;
const inputModel = GlobalModel.inputModel;
if (!inputModel.historyShow.get()) {
e.preventDefault();
if (this.mainInputRef.current != null) {
@ -604,53 +603,51 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
}
render() {
let model = GlobalModel;
let inputModel = model.inputModel;
let curLine = inputModel.getCurLine();
let fcp = inputModel.forceCursorPos.get(); // for reaction
const model = GlobalModel;
const inputModel = model.inputModel;
const curLine = inputModel.getCurLine();
let displayLines = 1;
let numLines = curLine.split("\n").length;
let maxCols = this.getTextAreaMaxCols();
const numLines = curLine.split("\n").length;
const maxCols = this.getTextAreaMaxCols();
let longLine = false;
let version = this.version.get(); // to force reactions
if (maxCols != 0 && curLine.length >= maxCols - 4) {
longLine = true;
}
if (numLines > 1 || longLine || inputModel.inputExpanded.get()) {
displayLines = 5;
}
let disabled = inputModel.historyShow.get();
const disabled = inputModel.historyShow.get();
if (disabled) {
displayLines = 1;
}
let activeScreen = GlobalModel.getActiveScreen();
const activeScreen = GlobalModel.getActiveScreen();
if (activeScreen != null) {
activeScreen.focusType.get(); // for reaction
}
let termFontSize = GlobalModel.getTermFontSize();
let fontSize = getMonoFontSize(termFontSize);
let termPad = fontSize.pad;
let computedInnerHeight = displayLines * fontSize.height + 2 * termPad;
let computedOuterHeight = computedInnerHeight + 2 * termPad;
const termFontSize = GlobalModel.getTermFontSize();
const fontSize = getMonoFontSize(termFontSize);
const termPad = fontSize.pad;
const computedInnerHeight = displayLines * fontSize.height + 2 * termPad;
const computedOuterHeight = computedInnerHeight + 2 * termPad;
let shellType: string = "";
let screen = GlobalModel.getActiveScreen();
const screen = GlobalModel.getActiveScreen();
if (screen != null) {
let ri = screen.getCurRemoteInstance();
const ri = screen.getCurRemoteInstance();
if (ri != null && ri.shelltype != null) {
shellType = ri.shelltype;
}
if (shellType == "") {
let rptr = screen.curRemote.get();
const rptr = screen.curRemote.get();
if (rptr != null) {
let remote = GlobalModel.getRemote(rptr.remoteid);
const remote = GlobalModel.getRemote(rptr.remoteid);
if (remote != null) {
shellType = remote.defaultshelltype;
}
}
}
}
let isMainInputFocused = this.mainInputFocused.get();
let isHistoryFocused = this.historyFocused.get();
const isMainInputFocused = this.mainInputFocused.get();
const isHistoryFocused = this.historyFocused.get();
return (
<div
className="textareainput-div control is-expanded"

View File

@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { If, For } from "tsx-control-statements/components";
import { If } from "tsx-control-statements/components";
import cn from "classnames";
import { debounce } from "throttle-debounce";
import dayjs from "dayjs";
@ -18,7 +18,6 @@ import { LinesView } from "@/app/line/linesview";
import * as util from "@/util/util";
import * as appconst from "@/app/appconst";
import * as textmeasure from "@/util/textmeasure";
import { NewTabSettings } from "./newtabsettings";
import "./screenview.less";
import "./tabs.less";
@ -38,18 +37,17 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
constructor(props: { session: Session; screen: Screen }) {
super(props);
this.handleResize_debounced = debounce(100, this.handleResize.bind(this));
let screen = this.props.screen;
const screen = this.props.screen;
let hasSidebar = false;
if (screen != null) {
let viewOpts = screen.viewOpts.get();
const viewOpts = screen.viewOpts.get();
hasSidebar = viewOpts?.sidebar?.open;
}
this.sidebarShowing = mobx.observable.box(hasSidebar, { name: "screenview-sidebarShowing" });
}
componentDidMount(): void {
let { screen } = this.props;
let elem = this.screenViewRef.current;
const elem = this.screenViewRef.current;
if (elem != null) {
this.rszObs = new ResizeObserver(this.handleResize_debounced);
this.rszObs.observe(elem);
@ -58,12 +56,12 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
}
componentDidUpdate(): void {
let { screen } = this.props;
const { screen } = this.props;
if (screen == null) {
return;
}
let viewOpts = screen.viewOpts.get();
let hasSidebar = viewOpts?.sidebar?.open;
const viewOpts = screen.viewOpts.get();
const hasSidebar = viewOpts?.sidebar?.open;
if (hasSidebar && !this.sidebarShowing.get()) {
this.sidebarShowingTimeoutId = setTimeout(() => {
mobx.action(() => {
@ -87,7 +85,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
}
handleResize() {
let elem = this.screenViewRef.current;
const elem = this.screenViewRef.current;
if (elem == null) {
return;
}
@ -107,13 +105,13 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
}
render() {
let { session, screen } = this.props;
let screenWidth = this.width.get();
const { session, screen } = this.props;
const screenWidth = this.width.get();
if (screenWidth == null) {
return <div className="screen-view" ref={this.screenViewRef}></div>;
}
if (session == null) {
let sessionCount = GlobalModel.sessionList.length;
const sessionCount = GlobalModel.sessionList.length;
return (
<div className="screen-view" ref={this.screenViewRef}>
<div className="window-view" style={{ width: "100%" }}>
@ -133,7 +131,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
);
}
if (screen == null) {
let screens = GlobalModel.getSessionScreens(session.sessionId);
const screens = GlobalModel.getSessionScreens(session.sessionId);
return (
<div className="screen-view" ref={this.screenViewRef}>
<div className="window-view" style={{ width: "100%" }}>
@ -152,14 +150,14 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
</div>
);
}
let fontSize = GlobalModel.getTermFontSize();
let dprStr = sprintf("%0.3f", GlobalModel.devicePixelRatio.get());
let viewOpts = screen.viewOpts.get();
let hasSidebar = viewOpts?.sidebar?.open;
const fontSize = GlobalModel.getTermFontSize();
const dprStr = sprintf("%0.3f", GlobalModel.devicePixelRatio.get());
const viewOpts = screen.viewOpts.get();
const hasSidebar = viewOpts?.sidebar?.open;
let winWidth = "100%";
let sidebarWidth = "0px";
if (hasSidebar) {
let targetWidth = viewOpts?.sidebar?.width;
const targetWidth = viewOpts?.sidebar?.width;
let realWidth = 0;
if (util.isBlank(targetWidth) || screenWidth < MagicLayout.ScreenSidebarMinWidth * 2) {
realWidth = Math.floor(screenWidth / 2) - MagicLayout.ScreenSidebarWidthPadding;
@ -168,7 +166,6 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
if (targetPercent > 100) {
targetPercent = 100;
}
let targetMul = targetPercent / 100;
realWidth = Math.floor((screenWidth * targetPercent) / 100);
realWidth = util.boundInt(
realWidth,
@ -177,7 +174,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
);
} else {
// screen is at least 400px wide
let targetWidthNum = parseInt(targetWidth);
const targetWidthNum = parseInt(targetWidth);
realWidth = util.boundInt(
targetWidthNum,
MagicLayout.ScreenSidebarMinWidth,
@ -382,9 +379,15 @@ class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {
}
}
interface ScreenWindowViewProps {
session: Session;
screen: Screen;
width: string;
}
// screen is not null
@mobxReact.observer
class ScreenWindowView extends React.Component<{ session: Session; screen: Screen; width: string }, {}> {
class ScreenWindowView extends React.Component<ScreenWindowViewProps, {}> {
rszObs: ResizeObserver;
windowViewRef: React.RefObject<any>;
@ -402,7 +405,7 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
}
setSize(width: number, height: number): void {
let { screen } = this.props;
const { screen } = this.props;
if (screen == null) {
return;
}
@ -418,10 +421,10 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
componentDidMount() {
const { screen } = this.props;
let wvElem = this.windowViewRef.current;
const wvElem = this.windowViewRef.current;
if (wvElem != null) {
let width = wvElem.offsetWidth;
let height = wvElem.offsetHeight;
const width = wvElem.offsetWidth;
const height = wvElem.offsetHeight;
this.setSize(width, height);
this.rszObs = new ResizeObserver(this.handleResize.bind(this));
this.rszObs.observe(wvElem);
@ -444,16 +447,16 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
if (entries.length == 0) {
return;
}
let entry = entries[0];
let width = entry.target.offsetWidth;
let height = entry.target.offsetHeight;
const entry = entries[0];
const width = entry.target.offsetWidth;
const height = entry.target.offsetHeight;
mobx.action(() => {
this.setSize_debounced(width, height);
})();
}
getScreenLines(): ScreenLines {
let { screen } = this.props;
const { screen } = this.props;
let win = GlobalModel.getScreenLinesById(screen.screenId);
if (win == null) {
win = GlobalModel.loadScreenLines(screen.screenId);
@ -463,21 +466,16 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
@boundMethod
toggleRenderMode() {
let renderMode = this.renderMode.get();
const renderMode = this.renderMode.get();
mobx.action(() => {
this.renderMode.set(renderMode == "normal" ? "collapsed" : "normal");
})();
}
renderError(message: string, fade: boolean) {
let { screen } = this.props;
const { screen, width } = this.props;
return (
<div
className="window-view"
ref={this.windowViewRef}
data-screenid={screen.screenId}
style={{ width: this.props.width }}
>
<div className="window-view" ref={this.windowViewRef} data-screenid={screen.screenId} style={{ width }}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty", { "should-fade": fade })}>
<div className="text-standard">{message}</div>
@ -488,8 +486,8 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
@boundMethod
copyShareLink(): void {
let { screen } = this.props;
let shareLink = screen.getWebShareUrl();
const { screen } = this.props;
const shareLink = screen.getWebShareUrl();
if (shareLink == null) {
return;
}
@ -506,22 +504,22 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
@boundMethod
openScreenSettings(): void {
let { screen } = this.props;
const { screen } = this.props;
mobx.action(() => {
GlobalModel.screenSettingsModal.set({ sessionId: screen.sessionId, screenId: screen.screenId });
})();
}
@boundMethod
buildLineComponent(lineProps: LineFactoryProps): JSX.Element {
let { screen } = this.props;
let { line, ...restProps } = lineProps;
let realLine: LineType = line as LineType;
buildLineComponent(lineProps: LineFactoryProps): React.JSX.Element {
const { screen } = this.props;
const { line, ...restProps } = lineProps;
const realLine: LineType = line as LineType;
return <Line key={realLine.lineid} screen={screen} line={realLine} {...restProps} />;
}
determineVisibleLines(win: ScreenLines): LineType[] {
let { screen } = this.props;
const { screen } = this.props;
if (screen.filterRunning.get()) {
return win.getRunningCmdLines();
}
@ -530,16 +528,16 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
@boundMethod
disableFilter() {
let { screen } = this.props;
const { screen } = this.props;
mobx.action(() => {
screen.filterRunning.set(false);
})();
}
render() {
let { session, screen } = this.props;
let win = this.getScreenLines();
if (win == null || !win.loaded.get()) {
const { session, screen, width } = this.props;
const win = this.getScreenLines();
if (!win.loaded.get()) {
return this.renderError("...", true);
}
if (win.loadError.get() != null) {
@ -548,28 +546,25 @@ class ScreenWindowView extends React.Component<{ session: Session; screen: Scree
if (this.width.get() == 0) {
return this.renderError("", false);
}
let cdata = GlobalModel.clientData.get();
const cdata = GlobalModel.clientData.get();
if (cdata == null) {
return this.renderError("loading client data", true);
}
let isActive = screen.isActive();
let lines = this.determineVisibleLines(win);
let renderMode = this.renderMode.get();
const lines = this.determineVisibleLines(win);
const renderMode = this.renderMode.get();
return (
<div className="window-view" ref={this.windowViewRef} style={{ width: this.props.width }}>
<If condition={lines.length == 0}>
<If condition={screen.nextLineNum.get() != 1}>
<div className="window-empty" ref={this.windowViewRef} data-screenid={screen.screenId}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty")}>
<div>
<code className="text-standard">
[workspace="{session.name.get()}" tab="{screen.name.get()}"]
</code>
</div>
<div className="window-view" ref={this.windowViewRef} style={{ width }}>
<If condition={lines.length == 0 && screen.nextLineNum.get() != 1}>
<div className="window-empty" ref={this.windowViewRef} data-screenid={screen.screenId}>
<div key="lines" className="lines"></div>
<div key="window-empty" className={cn("window-empty")}>
<div>
<code className="text-standard">
[workspace="{session.name.get()}" tab="{screen.name.get()}"]
</code>
</div>
</div>
</If>
</div>
</If>
<If condition={lines.length > 0}>
<LinesView

View File

@ -24,7 +24,7 @@ class IncrementalRenderer extends React.Component<
constructor(props: any) {
super(props);
let { rendererContainer, lineId, plugin, initParams } = this.props;
const { rendererContainer, lineId, plugin, initParams } = this.props;
this.model = plugin.modelCtor();
this.model.initialize(initParams);
rendererContainer.registerRenderer(lineId, this.model);
@ -40,7 +40,7 @@ class IncrementalRenderer extends React.Component<
this.props.onHeightChange();
}
if (this.wrapperDivRef.current != null) {
let height = this.wrapperDivRef.current.offsetHeight;
const height = this.wrapperDivRef.current.offsetHeight;
this.updateHeight_debounced(height);
}
}
@ -61,7 +61,7 @@ class IncrementalRenderer extends React.Component<
}
componentWillUnmount() {
let { rendererContainer, lineId } = this.props;
const { rendererContainer, lineId } = this.props;
rendererContainer.unloadRenderer(lineId);
if (this.rszObs != null) {
this.rszObs.disconnect();
@ -74,8 +74,8 @@ class IncrementalRenderer extends React.Component<
}
render() {
let { plugin } = this.props;
let Comp = plugin.fullComponent;
const { plugin } = this.props;
const Comp = plugin.fullComponent;
if (Comp == null) {
<div ref={this.wrapperDivRef}>(no component found in plugin)</div>;
}