mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-19 21:11:32 +01:00
merge branch 'main' into 'ssh--auth-control'
This was mostly straightforward, but it appears that a previous commit to main broke the user input modals by deleting a function. This adds that back in addition to the merge.
This commit is contained in:
parent
6bd60e8330
commit
5abff8075b
@ -7,10 +7,9 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { ContextMenuOpts } from "../types/types";
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { isBlank } from "../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import { WorkspaceView } from "./workspace/workspaceview";
|
import { WorkspaceView } from "./workspace/workspaceview";
|
||||||
import { PluginsView } from "./pluginsview/pluginsview";
|
import { PluginsView } from "./pluginsview/pluginsview";
|
||||||
import { BookmarksView } from "./bookmarks/bookmarks";
|
import { BookmarksView } from "./bookmarks/bookmarks";
|
||||||
@ -25,8 +24,6 @@ import "./app.less";
|
|||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class App extends React.Component<{}, {}> {
|
class App extends React.Component<{}, {}> {
|
||||||
dcWait: OV<boolean> = mobx.observable.box(false, { name: "dcWait" });
|
dcWait: OV<boolean> = mobx.observable.box(false, { name: "dcWait" });
|
||||||
|
@ -47,3 +47,13 @@ export const TabIcons = [
|
|||||||
export const VERSION = __WAVETERM_VERSION__;
|
export const VERSION = __WAVETERM_VERSION__;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const BUILD = __WAVETERM_BUILD__;
|
export const BUILD = __WAVETERM_BUILD__;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Levels for the screen status indicator
|
||||||
|
*/
|
||||||
|
export enum StatusIndicatorLevel {
|
||||||
|
None = 0,
|
||||||
|
Output = 1,
|
||||||
|
Success = 2,
|
||||||
|
Error = 3,
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.bookmarks-view {
|
.bookmarks-view {
|
||||||
background-color: @background-session;
|
background-color: @background-session;
|
||||||
|
@ -7,15 +7,14 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If, For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import type { BookmarkType } from "../../types/types";
|
import { GlobalModel } from "@/models";
|
||||||
import { GlobalModel } from "../../models";
|
import { CmdStrCode, Markdown } from "@/common/elements";
|
||||||
import { CmdStrCode, Markdown } from "../common/elements";
|
|
||||||
|
|
||||||
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
|
import { ReactComponent as XmarkIcon } from "@/assets/icons/line/xmark.svg";
|
||||||
import { ReactComponent as CopyIcon } from "../assets/icons/favourites/copy.svg";
|
import { ReactComponent as CopyIcon } from "@/assets/icons/favourites/copy.svg";
|
||||||
import { ReactComponent as PenIcon } from "../assets/icons/favourites/pen.svg";
|
import { ReactComponent as PenIcon } from "@/assets/icons/favourites/pen.svg";
|
||||||
import { ReactComponent as TrashIcon } from "../assets/icons/favourites/trash.svg";
|
import { ReactComponent as TrashIcon } from "@/assets/icons/favourites/trash.svg";
|
||||||
import { ReactComponent as FavoritesIcon } from "../assets/icons/favourites.svg";
|
import { ReactComponent as FavoritesIcon } from "@/assets/icons/favourites.svg";
|
||||||
|
|
||||||
import "./bookmarks.less";
|
import "./bookmarks.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.clientsettings-view {
|
.clientsettings-view {
|
||||||
background-color: @background-session;
|
background-color: @background-session;
|
||||||
|
@ -6,20 +6,19 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "../../models";
|
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
|
||||||
import { Toggle, InlineSettingsTextEdit, SettingsError, Dropdown } from "../common/elements";
|
import { Toggle, InlineSettingsTextEdit, SettingsError, Dropdown } from "@/common/elements";
|
||||||
import * as types from "../../types/types";
|
import { commandRtnHandler, isBlank } from "@/util/util";
|
||||||
import { commandRtnHandler, isBlank } from "../../util/util";
|
import * as appconst from "@/app/appconst";
|
||||||
import * as appconst from "../appconst";
|
|
||||||
|
|
||||||
import "./clientsettings.less";
|
import "./clientsettings.less";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||||
fontSizeDropdownActive: types.OV<boolean> = mobx.observable.box(false, {
|
fontSizeDropdownActive: OV<boolean> = mobx.observable.box(false, {
|
||||||
name: "clientSettings-fontSizeDropdownActive",
|
name: "clientSettings-fontSizeDropdownActive",
|
||||||
});
|
});
|
||||||
errorMessage: types.OV<string> = mobx.observable.box(null, { name: "ClientSettings-errorMessage" });
|
errorMessage: OV<string> = mobx.observable.box(null, { name: "ClientSettings-errorMessage" });
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
dismissError(): void {
|
dismissError(): void {
|
||||||
@ -48,7 +47,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleChangeTelemetry(val: boolean): void {
|
handleChangeTelemetry(val: boolean): void {
|
||||||
let prtn: Promise<types.CommandRtnType> = null;
|
let prtn: Promise<CommandRtnType> = null;
|
||||||
if (val) {
|
if (val) {
|
||||||
prtn = GlobalCommandRunner.telemetryOn(false);
|
prtn = GlobalCommandRunner.telemetryOn(false);
|
||||||
} else {
|
} else {
|
||||||
@ -59,7 +58,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleChangeReleaseCheck(val: boolean): void {
|
handleChangeReleaseCheck(val: boolean): void {
|
||||||
let prtn: Promise<types.CommandRtnType> = null;
|
let prtn: Promise<CommandRtnType> = null;
|
||||||
if (val) {
|
if (val) {
|
||||||
prtn = GlobalCommandRunner.releaseCheckAutoOn(false);
|
prtn = GlobalCommandRunner.releaseCheckAutoOn(false);
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +111,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cdata: types.ClientDataType = GlobalModel.clientData.get();
|
let cdata: ClientDataType = GlobalModel.clientData.get();
|
||||||
let openAIOpts = cdata.openaiopts ?? {};
|
let openAIOpts = cdata.openaiopts ?? {};
|
||||||
let apiTokenStr = isBlank(openAIOpts.apitoken) ? "(not set)" : "********";
|
let apiTokenStr = isBlank(openAIOpts.apitoken) ? "(not set)" : "********";
|
||||||
let maxTokensStr = String(
|
let maxTokensStr = String(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-button {
|
.wave-button {
|
||||||
background: none;
|
background: none;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.cmdstr-code {
|
.cmdstr-code {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -6,8 +6,8 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
|
|
||||||
import { ReactComponent as CheckIcon } from "../../assets/icons/line/check.svg";
|
import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
|
||||||
import { ReactComponent as CopyIcon } from "../../assets/icons/history/copy.svg";
|
import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
|
||||||
|
|
||||||
import "./cmdstrcode.less";
|
import "./cmdstrcode.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-dropdown {
|
.wave-dropdown {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.inline-edit {
|
.inline-edit {
|
||||||
.icon {
|
.icon {
|
||||||
|
@ -7,12 +7,10 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../../../util/keyutil";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
|
|
||||||
import "./inlinesettingstextedit.less";
|
import "./inlinesettingstextedit.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class InlineSettingsTextEdit extends React.Component<
|
class InlineSettingsTextEdit extends React.Component<
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-input-decoration {
|
.wave-input-decoration {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.markdown {
|
.markdown {
|
||||||
color: @term-white;
|
color: @term-white;
|
||||||
|
@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
|
|||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
|
|
||||||
import "./markdown.less";
|
import "./markdown.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-modal-container {
|
.wave-modal-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -10,8 +10,6 @@ import { IconButton } from "./iconbutton";
|
|||||||
|
|
||||||
import "./modal.less";
|
import "./modal.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
interface ModalHeaderProps {
|
interface ModalHeaderProps {
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-password {
|
.wave-password {
|
||||||
.wave-textfield-inner-eye {
|
.wave-textfield-inner-eye {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.sidebar-handle {
|
.sidebar-handle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -6,13 +6,11 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||||
import { MagicLayout } from "../../magiclayout";
|
import { MagicLayout } from "@/app/magiclayout";
|
||||||
|
|
||||||
import "./resizablesidebar.less";
|
import "./resizablesidebar.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
interface ResizableSidebarProps {
|
interface ResizableSidebarProps {
|
||||||
parentRef: React.RefObject<HTMLElement>;
|
parentRef: React.RefObject<HTMLElement>;
|
||||||
position: "left" | "right";
|
position: "left" | "right";
|
||||||
|
@ -6,8 +6,6 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class SettingsError extends React.Component<{ errorMessage: OV<string> }, {}> {
|
class SettingsError extends React.Component<{ errorMessage: OV<string> }, {}> {
|
||||||
@boundMethod
|
@boundMethod
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Copyright 2023, Command Line Inc.
|
// Copyright 2023, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import * as appconst from "../../appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
function ShowWaveShellInstallPrompt(callbackFn: () => void) {
|
function ShowWaveShellInstallPrompt(callbackFn: () => void) {
|
||||||
let message: string = `
|
let message: string = `
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-status-container {
|
.wave-status-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-textfield {
|
.wave-textfield {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.checkbox-toggle {
|
.checkbox-toggle {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.wave-tooltip {
|
.wave-tooltip {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React, { Component, ReactNode } from "react";
|
import React, { Component, ReactNode } from "react";
|
||||||
import { RendererContext } from "../../../types/types";
|
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
|
|
||||||
interface ErrorBoundaryState {
|
interface ErrorBoundaryState {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.front-icon {
|
.front-icon {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { StatusIndicatorLevel } from "../../../types/types";
|
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { ReactComponent as SpinnerIndicator } from "../../assets/icons/spinner-indicator.svg";
|
import { ReactComponent as SpinnerIndicator } from "@/assets/icons/spinner-indicator.svg";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import { ReactComponent as RotateIconSvg } from "../../assets/icons/line/rotate.svg";
|
import { ReactComponent as RotateIconSvg } from "@/assets/icons/line/rotate.svg";
|
||||||
|
|
||||||
interface PositionalIconProps {
|
interface PositionalIconProps {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
@ -131,7 +131,7 @@ interface StatusIndicatorProps {
|
|||||||
/**
|
/**
|
||||||
* The level of the status indicator. This will determine the color of the status indicator.
|
* The level of the status indicator. This will determine the color of the status indicator.
|
||||||
*/
|
*/
|
||||||
level: StatusIndicatorLevel;
|
level: appconst.StatusIndicatorLevel;
|
||||||
className?: string;
|
className?: string;
|
||||||
/**
|
/**
|
||||||
* If true, a spinner will be shown around the status indicator.
|
* If true, a spinner will be shown around the status indicator.
|
||||||
@ -191,16 +191,16 @@ export class StatusIndicator extends React.Component<StatusIndicatorProps> {
|
|||||||
const { level, className, runningCommands } = this.props;
|
const { level, className, runningCommands } = this.props;
|
||||||
const spinnerVisible = this.spinnerVisible.get();
|
const spinnerVisible = this.spinnerVisible.get();
|
||||||
let statusIndicator = null;
|
let statusIndicator = null;
|
||||||
if (level != StatusIndicatorLevel.None || spinnerVisible) {
|
if (level != appconst.StatusIndicatorLevel.None || spinnerVisible) {
|
||||||
let indicatorLevelClass = null;
|
let indicatorLevelClass = null;
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case StatusIndicatorLevel.Output:
|
case appconst.StatusIndicatorLevel.Output:
|
||||||
indicatorLevelClass = "output";
|
indicatorLevelClass = "output";
|
||||||
break;
|
break;
|
||||||
case StatusIndicatorLevel.Success:
|
case appconst.StatusIndicatorLevel.Success:
|
||||||
indicatorLevelClass = "success";
|
indicatorLevelClass = "success";
|
||||||
break;
|
break;
|
||||||
case StatusIndicatorLevel.Error:
|
case appconst.StatusIndicatorLevel.Error:
|
||||||
indicatorLevelClass = "error";
|
indicatorLevelClass = "error";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.about-modal {
|
.about-modal {
|
||||||
.wave-modal-content {
|
.wave-modal-content {
|
||||||
|
@ -5,12 +5,12 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { Modal, LinkButton } from "../elements";
|
import { Modal, LinkButton } from "@/elements";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
import * as appconst from "../../appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import logo from "../../assets/waveterm-logo-with-bg.svg";
|
import logo from "@/assets/waveterm-logo-with-bg.svg";
|
||||||
import "./about.less";
|
import "./about.less";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.alert-modal {
|
.alert-modal {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
|
@ -5,8 +5,8 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { Markdown, Modal, Button, Checkbox } from "../elements";
|
import { Markdown, Modal, Button, Checkbox } from "@/elements";
|
||||||
import { GlobalModel, GlobalCommandRunner } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||||
|
|
||||||
import "./alert.less";
|
import "./alert.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.clientstop-modal {
|
.clientstop-modal {
|
||||||
.inner-content {
|
.inner-content {
|
||||||
|
@ -5,8 +5,8 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { Modal, Button } from "../elements";
|
import { Modal, Button } from "@/elements";
|
||||||
|
|
||||||
import "./clientstop.less";
|
import "./clientstop.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.crconn-modal {
|
.crconn-modal {
|
||||||
width: 452px;
|
width: 452px;
|
||||||
|
@ -6,8 +6,7 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
|
||||||
import * as T from "../../../types/types";
|
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
TextField,
|
TextField,
|
||||||
@ -17,13 +16,11 @@ import {
|
|||||||
PasswordField,
|
PasswordField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
ShowWaveShellInstallPrompt,
|
ShowWaveShellInstallPrompt,
|
||||||
} from "../elements";
|
} from "@/elements";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
|
|
||||||
import "./createremoteconn.less";
|
import "./createremoteconn.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class CreateRemoteConnModal extends React.Component<{}, {}> {
|
class CreateRemoteConnModal extends React.Component<{}, {}> {
|
||||||
tempAlias: OV<string>;
|
tempAlias: OV<string>;
|
||||||
@ -35,7 +32,7 @@ class CreateRemoteConnModal extends React.Component<{}, {}> {
|
|||||||
tempKeyFile: OV<string>;
|
tempKeyFile: OV<string>;
|
||||||
tempShellPref: OV<string>;
|
tempShellPref: OV<string>;
|
||||||
errorStr: OV<string>;
|
errorStr: OV<string>;
|
||||||
remoteEdit: T.RemoteEditType;
|
remoteEdit: RemoteEditType;
|
||||||
model: RemotesModel;
|
model: RemotesModel;
|
||||||
|
|
||||||
constructor(props: { remotesModel?: RemotesModel }) {
|
constructor(props: { remotesModel?: RemotesModel }) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.disconnected-modal {
|
.disconnected-modal {
|
||||||
.wave-modal-content {
|
.wave-modal-content {
|
||||||
|
@ -5,8 +5,8 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { Modal, Button } from "../elements";
|
import { Modal, Button } from "@/elements";
|
||||||
|
|
||||||
import "./disconnected.less";
|
import "./disconnected.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.erconn-modal {
|
.erconn-modal {
|
||||||
width: 502px;
|
width: 502px;
|
||||||
|
@ -6,15 +6,12 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
|
||||||
import * as T from "../../../types/types";
|
import { Modal, TextField, InputDecoration, Dropdown, PasswordField, Tooltip } from "@/elements";
|
||||||
import { Modal, TextField, InputDecoration, Dropdown, PasswordField, Tooltip } from "../elements";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../../util/util";
|
|
||||||
|
|
||||||
import "./editremoteconn.less";
|
import "./editremoteconn.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
const PasswordUnchangedSentinel = "--unchanged--";
|
const PasswordUnchangedSentinel = "--unchanged--";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
@ -42,11 +39,11 @@ class EditRemoteConnModal extends React.Component<{}, {}> {
|
|||||||
return this.model.selectedRemoteId.get();
|
return this.model.selectedRemoteId.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedRemote(): T.RemoteType {
|
get selectedRemote(): RemoteType {
|
||||||
return GlobalModel.getRemote(this.selectedRemoteId);
|
return GlobalModel.getRemote(this.selectedRemoteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
get remoteEdit(): T.RemoteEditType {
|
get remoteEdit(): RemoteEditType {
|
||||||
return this.model.remoteEdit.get();
|
return this.model.remoteEdit.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.line-settings-modal {
|
.line-settings-modal {
|
||||||
width: 640px;
|
width: 640px;
|
||||||
|
@ -5,16 +5,13 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel, GlobalCommandRunner } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||||
import { SettingsError, Modal, Dropdown } from "../elements";
|
import { SettingsError, Modal, Dropdown } from "@/elements";
|
||||||
import { LineType, RendererPluginType } from "../../../types/types";
|
import { PluginModel } from "@/plugins/plugins";
|
||||||
import { PluginModel } from "../../../plugins/plugins";
|
import { commandRtnHandler } from "@/util/util";
|
||||||
import { commandRtnHandler } from "../../../util/util";
|
|
||||||
|
|
||||||
import "./linesettings.less";
|
import "./linesettings.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class LineSettingsModal extends React.Component<{}, {}> {
|
class LineSettingsModal extends React.Component<{}, {}> {
|
||||||
rendererDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "lineSettings-rendererDropdownActive" });
|
rendererDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "lineSettings-rendererDropdownActive" });
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { TosModal } from "./tos";
|
import { TosModal } from "./tos";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
|
@ -13,8 +13,8 @@ import {
|
|||||||
ScreenSettingsModal,
|
ScreenSettingsModal,
|
||||||
LineSettingsModal,
|
LineSettingsModal,
|
||||||
UserInputModal,
|
UserInputModal,
|
||||||
} from "../modals";
|
} from "@/modals";
|
||||||
import * as constants from "../../appconst";
|
import * as constants from "@/app/appconst";
|
||||||
|
|
||||||
const modalsRegistry: { [key: string]: React.ComponentType } = {
|
const modalsRegistry: { [key: string]: React.ComponentType } = {
|
||||||
[constants.ABOUT]: AboutModal,
|
[constants.ABOUT]: AboutModal,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.screen-settings-modal {
|
.screen-settings-modal {
|
||||||
width: 640px;
|
width: 640px;
|
||||||
|
@ -7,20 +7,16 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If, For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, Screen } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||||
import { Toggle, InlineSettingsTextEdit, SettingsError, Modal, Dropdown, Tooltip } from "../elements";
|
import { Toggle, InlineSettingsTextEdit, SettingsError, Modal, Dropdown, Tooltip } from "@/elements";
|
||||||
import { RemoteType } from "../../../types/types";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../../util/util";
|
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
||||||
import { commandRtnHandler } from "../../../util/util";
|
import { ReactComponent as GlobeIcon } from "@/assets/icons/globe.svg";
|
||||||
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
|
import { ReactComponent as StatusCircleIcon } from "@/assets/icons/statuscircle.svg";
|
||||||
import { ReactComponent as GlobeIcon } from "../../assets/icons/globe.svg";
|
import * as appconst from "@/app/appconst";
|
||||||
import { ReactComponent as StatusCircleIcon } from "../../assets/icons/statuscircle.svg";
|
|
||||||
import * as appconst from "../../appconst";
|
|
||||||
|
|
||||||
import "./screensettings.less";
|
import "./screensettings.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
const ScreenDeleteMessage = `
|
const ScreenDeleteMessage = `
|
||||||
Are you sure you want to delete this tab?
|
Are you sure you want to delete this tab?
|
||||||
|
|
||||||
@ -98,7 +94,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { tabcolor: color }, false);
|
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { tabcolor: color }, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -119,7 +115,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenArchive(this.screenId, val);
|
let prtn = GlobalCommandRunner.screenArchive(this.screenId, val);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -137,7 +133,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenWebShare(this.screen.screenId, val);
|
let prtn = GlobalCommandRunner.screenWebShare(this.screen.screenId, val);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +166,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { name: val }, false);
|
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { name: val }, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -182,7 +178,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { sharename: val }, false);
|
let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { sharename: val }, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -209,7 +205,7 @@ class ScreenSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.screenDelete(this.screenId, false);
|
let prtn = GlobalCommandRunner.screenDelete(this.screenId, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
GlobalModel.modalsModel.popModal();
|
GlobalModel.modalsModel.popModal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.session-settings-modal {
|
.session-settings-modal {
|
||||||
width: 640px;
|
width: 640px;
|
||||||
|
@ -5,15 +5,12 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel, GlobalCommandRunner, Session } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Session } from "@/models";
|
||||||
import { Toggle, InlineSettingsTextEdit, SettingsError, Modal, Tooltip } from "../elements";
|
import { Toggle, InlineSettingsTextEdit, SettingsError, Modal, Tooltip } from "@/elements";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
import { commandRtnHandler } from "../../../util/util";
|
|
||||||
|
|
||||||
import "./sessionsettings.less";
|
import "./sessionsettings.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
const SessionDeleteMessage = `
|
const SessionDeleteMessage = `
|
||||||
Are you sure you want to delete this workspace?
|
Are you sure you want to delete this workspace?
|
||||||
|
|
||||||
@ -52,7 +49,7 @@ class SessionSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.sessionSetSettings(this.sessionId, { name: newVal }, false);
|
let prtn = GlobalCommandRunner.sessionSetSettings(this.sessionId, { name: newVal }, false);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -64,7 +61,7 @@ class SessionSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.sessionArchive(this.sessionId, val);
|
let prtn = GlobalCommandRunner.sessionArchive(this.sessionId, val);
|
||||||
commandRtnHandler(prtn, this.errorMessage);
|
util.commandRtnHandler(prtn, this.errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -76,7 +73,7 @@ class SessionSettingsModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prtn = GlobalCommandRunner.sessionDelete(this.sessionId);
|
let prtn = GlobalCommandRunner.sessionDelete(this.sessionId);
|
||||||
commandRtnHandler(prtn, this.errorMessage, () => GlobalModel.modalsModel.popModal());
|
util.commandRtnHandler(prtn, this.errorMessage, () => GlobalModel.modalsModel.popModal());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.tabswitcher-modal {
|
.tabswitcher-modal {
|
||||||
width: 452px;
|
width: 452px;
|
||||||
|
@ -5,18 +5,20 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||||
import { Modal, TextField, InputDecoration, Tooltip } from "../elements";
|
import { Modal, TextField, InputDecoration, Tooltip } from "@/elements";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
import { Screen } from "../../../models";
|
import { Screen } from "@/models";
|
||||||
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
|
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
||||||
|
|
||||||
import "./tabswitcher.less";
|
import "./tabswitcher.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
type ViewDataType = {
|
||||||
type OArr<V> = mobx.IObservableArray<V>;
|
label: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
type SwitcherDataType = {
|
type SwitcherDataType = {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
@ -27,9 +29,25 @@ type SwitcherDataType = {
|
|||||||
screenName: string;
|
screenName: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
viewData?: ViewDataType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MaxOptionsToDisplay = 100;
|
const MaxOptionsToDisplay = 100;
|
||||||
|
const additionalOptions = [
|
||||||
|
{ label: "Connections", value: "connections" },
|
||||||
|
{ label: "History", value: "history" },
|
||||||
|
{ label: "Settings", value: "clientsettings" },
|
||||||
|
].map((item, index) => ({
|
||||||
|
sessionId: `additional-${index}`,
|
||||||
|
sessionName: "",
|
||||||
|
sessionIdx: -1,
|
||||||
|
screenId: `additional-${index}`,
|
||||||
|
screenIdx: -1,
|
||||||
|
screenName: "",
|
||||||
|
icon: "",
|
||||||
|
color: "",
|
||||||
|
viewData: item,
|
||||||
|
}));
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class TabSwitcherModal extends React.Component<{}, {}> {
|
class TabSwitcherModal extends React.Component<{}, {}> {
|
||||||
@ -47,8 +65,8 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.activeSessionIdx = GlobalModel.getActiveSession().sessionIdx.get();
|
this.activeSessionIdx = GlobalModel.getActiveSession().sessionIdx.get();
|
||||||
let oSessions = GlobalModel.sessionList;
|
const oSessions = GlobalModel.sessionList;
|
||||||
let oScreens = GlobalModel.screenMap;
|
const oScreens = GlobalModel.screenMap;
|
||||||
oScreens.forEach((oScreen) => {
|
oScreens.forEach((oScreen) => {
|
||||||
if (oScreen == null) {
|
if (oScreen == null) {
|
||||||
return;
|
return;
|
||||||
@ -57,13 +75,13 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Find the matching session in the observable array
|
// Find the matching session in the observable array
|
||||||
let foundSession = oSessions.find((s) => {
|
const foundSession = oSessions.find((s) => {
|
||||||
return s.sessionId == oScreen.sessionId && !s.archived.get();
|
return s.sessionId == oScreen.sessionId && !s.archived.get();
|
||||||
});
|
});
|
||||||
if (!foundSession) {
|
if (!foundSession) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data: SwitcherDataType = {
|
const data: SwitcherDataType = {
|
||||||
sessionName: foundSession.name.get(),
|
sessionName: foundSession.name.get(),
|
||||||
sessionId: foundSession.sessionId,
|
sessionId: foundSession.sessionId,
|
||||||
sessionIdx: foundSession.sessionIdx.get(),
|
sessionIdx: foundSession.sessionIdx.get(),
|
||||||
@ -88,11 +106,11 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
let currFocusedIdx = this.focusedIdx.get();
|
const currFocusedIdx = this.focusedIdx.get();
|
||||||
|
|
||||||
// Check if selectedIdx has changed
|
// Check if selectedIdx has changed
|
||||||
if (currFocusedIdx !== this.prevFocusedIdx) {
|
if (currFocusedIdx !== this.prevFocusedIdx) {
|
||||||
let optionElement = this.optionRefs[currFocusedIdx]?.current;
|
const optionElement = this.optionRefs[currFocusedIdx]?.current;
|
||||||
|
|
||||||
if (optionElement) {
|
if (optionElement) {
|
||||||
optionElement.scrollIntoView({ block: "nearest" });
|
optionElement.scrollIntoView({ block: "nearest" });
|
||||||
@ -109,7 +127,7 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
getTabIcon(screen: Screen): string {
|
getTabIcon(screen: Screen): string {
|
||||||
let tabIcon = "default";
|
let tabIcon = "default";
|
||||||
let screenOpts = screen.opts.get();
|
const screenOpts = screen.opts.get();
|
||||||
if (screenOpts != null && !util.isBlank(screenOpts.tabicon)) {
|
if (screenOpts != null && !util.isBlank(screenOpts.tabicon)) {
|
||||||
tabIcon = screenOpts.tabicon;
|
tabIcon = screenOpts.tabicon;
|
||||||
}
|
}
|
||||||
@ -119,7 +137,7 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
getTabColor(screen: Screen): string {
|
getTabColor(screen: Screen): string {
|
||||||
let tabColor = "default";
|
let tabColor = "default";
|
||||||
let screenOpts = screen.opts.get();
|
const screenOpts = screen.opts.get();
|
||||||
if (screenOpts != null && !util.isBlank(screenOpts.tabcolor)) {
|
if (screenOpts != null && !util.isBlank(screenOpts.tabcolor)) {
|
||||||
tabColor = screenOpts.tabcolor;
|
tabColor = screenOpts.tabcolor;
|
||||||
}
|
}
|
||||||
@ -132,7 +150,7 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
this.closeModal();
|
this.closeModal();
|
||||||
} else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
|
} else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let newIndex = this.calculateNewIndex(e.key === "ArrowUp");
|
const newIndex = this.calculateNewIndex(e.key === "ArrowUp");
|
||||||
this.setFocusedIndex(newIndex);
|
this.setFocusedIndex(newIndex);
|
||||||
} else if (e.key === "Enter") {
|
} else if (e.key === "Enter") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -142,7 +160,7 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
calculateNewIndex(isUpKey) {
|
calculateNewIndex(isUpKey) {
|
||||||
let currentIndex = this.focusedIdx.get();
|
const currentIndex = this.focusedIdx.get();
|
||||||
if (isUpKey) {
|
if (isUpKey) {
|
||||||
return Math.max(currentIndex - 1, 0);
|
return Math.max(currentIndex - 1, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -165,6 +183,11 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
handleSelect(index: number): void {
|
handleSelect(index: number): void {
|
||||||
const selectedOption = this.sOptions[index];
|
const selectedOption = this.sOptions[index];
|
||||||
|
if (selectedOption.sessionIdx === -1) {
|
||||||
|
GlobalCommandRunner.switchView(selectedOption.viewData.value);
|
||||||
|
this.closeModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (selectedOption) {
|
if (selectedOption) {
|
||||||
GlobalCommandRunner.switchScreen(selectedOption.screenId, selectedOption.sessionId);
|
GlobalCommandRunner.switchScreen(selectedOption.screenId, selectedOption.sessionId);
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
@ -192,27 +215,28 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
@mobx.computed
|
@mobx.computed
|
||||||
@boundMethod
|
@boundMethod
|
||||||
filterOptions(searchInput: string): SwitcherDataType[] {
|
filterOptions(searchInput: string): SwitcherDataType[] {
|
||||||
let filteredScreens = [];
|
const searchLower = searchInput.toLowerCase();
|
||||||
|
|
||||||
for (let i = 0; i < this.options.length; i++) {
|
|
||||||
let tab = this.options[i];
|
|
||||||
let match = false;
|
|
||||||
|
|
||||||
|
let filteredScreens = this.options.filter((tab) => {
|
||||||
if (searchInput.includes("/")) {
|
if (searchInput.includes("/")) {
|
||||||
let [sessionFilter, screenFilter] = searchInput.split("/").map((s) => s.trim().toLowerCase());
|
const [sessionFilter, screenFilter] = searchInput.split("/").map((s) => s.trim().toLowerCase());
|
||||||
match =
|
return (
|
||||||
tab.sessionName.toLowerCase().includes(sessionFilter) &&
|
tab.sessionName.toLowerCase().includes(sessionFilter) &&
|
||||||
tab.screenName.toLowerCase().includes(screenFilter);
|
tab.screenName.toLowerCase().includes(screenFilter)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
match =
|
return (
|
||||||
tab.sessionName.toLowerCase().includes(searchInput) ||
|
tab.sessionName.toLowerCase().includes(searchLower) ||
|
||||||
tab.screenName.toLowerCase().includes(searchInput);
|
tab.screenName.toLowerCase().includes(searchLower)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add tab to filtered list if it matches the criteria
|
if (searchLower.length > 0) {
|
||||||
if (match) {
|
const additionalFiltered = additionalOptions.filter((item) =>
|
||||||
filteredScreens.push(tab);
|
item.viewData?.label.toLowerCase().includes(searchLower)
|
||||||
}
|
);
|
||||||
|
filteredScreens = filteredScreens.concat(additionalFiltered);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredScreens;
|
return filteredScreens;
|
||||||
@ -221,9 +245,10 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
@mobx.computed
|
@mobx.computed
|
||||||
@boundMethod
|
@boundMethod
|
||||||
sortOptions(options: SwitcherDataType[]): SwitcherDataType[] {
|
sortOptions(options: SwitcherDataType[]): SwitcherDataType[] {
|
||||||
return options.sort((a, b) => {
|
const mainOptions = options.filter((o) => o.sessionIdx !== -1);
|
||||||
let aInCurrentSession = a.sessionIdx === this.activeSessionIdx;
|
mainOptions.sort((a, b) => {
|
||||||
let bInCurrentSession = b.sessionIdx === this.activeSessionIdx;
|
const aInCurrentSession = a.sessionIdx === this.activeSessionIdx;
|
||||||
|
const bInCurrentSession = b.sessionIdx === this.activeSessionIdx;
|
||||||
|
|
||||||
// Tabs in the current session are sorted by screenIdx
|
// Tabs in the current session are sorted by screenIdx
|
||||||
if (aInCurrentSession && bInCurrentSession) {
|
if (aInCurrentSession && bInCurrentSession) {
|
||||||
@ -246,11 +271,16 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const additionalOptions = options.filter((o) => o.sessionIdx === -1);
|
||||||
|
additionalOptions.sort((a, b) => a.viewData?.label.localeCompare(b.viewData?.label));
|
||||||
|
|
||||||
|
return mainOptions.concat(additionalOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
renderIcon(option: SwitcherDataType): React.ReactNode {
|
renderIcon(option: SwitcherDataType): React.ReactNode {
|
||||||
let tabIcon = option.icon;
|
const tabIcon = option.icon;
|
||||||
if (tabIcon === "default" || tabIcon === "square") {
|
if (tabIcon === "default" || tabIcon === "square") {
|
||||||
return <SquareIcon className="left-icon" />;
|
return <SquareIcon className="left-icon" />;
|
||||||
}
|
}
|
||||||
@ -271,10 +301,15 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
})}
|
})}
|
||||||
onClick={() => this.handleSelect(index)}
|
onClick={() => this.handleSelect(index)}
|
||||||
>
|
>
|
||||||
|
<If condition={option.sessionIdx != -1}>
|
||||||
<div className={cn("icon", "color-" + option.color)}>{this.renderIcon(option)}</div>
|
<div className={cn("icon", "color-" + option.color)}>{this.renderIcon(option)}</div>
|
||||||
<div className="tabname">
|
<div className="tabname">
|
||||||
#{option.sessionName} / {option.screenName}
|
#{option.sessionName} / {option.screenName}
|
||||||
</div>
|
</div>
|
||||||
|
</If>
|
||||||
|
<If condition={option.sessionIdx == -1}>
|
||||||
|
<div className="tabname">{option.viewData?.label}</div>
|
||||||
|
</If>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -293,13 +328,13 @@ class TabSwitcherModal extends React.Component<{}, {}> {
|
|||||||
decoration={{
|
decoration={{
|
||||||
startDecoration: (
|
startDecoration: (
|
||||||
<InputDecoration position="start">
|
<InputDecoration position="start">
|
||||||
<div className="tabswitcher-search-prefix">Switch to Tab:</div>
|
<div className="tabswitcher-search-prefix">Go to:</div>
|
||||||
</InputDecoration>
|
</InputDecoration>
|
||||||
),
|
),
|
||||||
endDecoration: (
|
endDecoration: (
|
||||||
<InputDecoration>
|
<InputDecoration>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
message={`Type to filter workspaces and tabs.`}
|
message={`Type to filter workspaces, tabs and views.`}
|
||||||
icon={<i className="fa-sharp fa-regular fa-circle-question" />}
|
icon={<i className="fa-sharp fa-regular fa-circle-question" />}
|
||||||
>
|
>
|
||||||
<i className="fa-sharp fa-regular fa-circle-question" />
|
<i className="fa-sharp fa-regular fa-circle-question" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.tos-modal {
|
.tos-modal {
|
||||||
width: 640px;
|
width: 640px;
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel, GlobalCommandRunner } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||||
import { Toggle, Modal, Button } from "../elements";
|
import { Toggle, Modal, Button } from "@/elements";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
import { ClientDataType } from "../../../types/types";
|
|
||||||
|
|
||||||
import shield from "../../assets/icons/shield_check.svg";
|
import shield from "@/assets/icons/shield_check.svg";
|
||||||
import help from "../../assets/icons/help_filled.svg";
|
import help from "@/assets/icons/help_filled.svg";
|
||||||
import github from "../../assets/icons/github.svg";
|
import github from "@/assets/icons/github.svg";
|
||||||
|
|
||||||
import "./tos.less";
|
import "./tos.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.userinput-modal {
|
.userinput-modal {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { Choose, When, If } from "tsx-control-statements/components";
|
import { Choose, When, If } from "tsx-control-statements/components";
|
||||||
import { Modal, PasswordField, Markdown } from "../elements";
|
import { Modal, PasswordField, Markdown } from "@/elements";
|
||||||
import { UserInputRequest } from "../../../types/types";
|
|
||||||
|
|
||||||
import "./userinput.less";
|
import "./userinput.less";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.rconndetail-modal {
|
.rconndetail-modal {
|
||||||
width: 631px;
|
width: 631px;
|
||||||
@ -54,6 +54,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.remote-detail {
|
.remote-detail {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.settings-field {
|
.settings-field {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -91,8 +93,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.terminal-wrapper {
|
.terminal-wrapper {
|
||||||
width: 100%;
|
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
|
||||||
.terminal-connectelem {
|
.terminal-connectelem {
|
||||||
height: 163px !important; // Needed to override plugin height
|
height: 163px !important; // Needed to override plugin height
|
||||||
@ -111,7 +114,6 @@
|
|||||||
|
|
||||||
.xterm-screen {
|
.xterm-screen {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
width: 541px !important; // Needed to override plugin width
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,14 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If, For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, RemotesModel } from "@/models";
|
||||||
import * as T from "../../../types/types";
|
import { Modal, Tooltip, Button, Status } from "@/elements";
|
||||||
import { Modal, Tooltip, Button, Status } from "../elements";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../../util/util";
|
import * as textmeasure from "@/util/textmeasure";
|
||||||
import * as textmeasure from "../../../util/textmeasure";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import "./viewremoteconndetail.less";
|
import "./viewremoteconndetail.less";
|
||||||
|
|
||||||
const RemotePtyRows = 9;
|
|
||||||
const RemotePtyCols = 80;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
||||||
termRef: React.RefObject<any> = React.createRef();
|
termRef: React.RefObject<any> = React.createRef();
|
||||||
@ -29,7 +26,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mobx.computed
|
@mobx.computed
|
||||||
getSelectedRemote(): T.RemoteType {
|
getSelectedRemote(): RemoteType {
|
||||||
const selectedRemoteId = this.model.selectedRemoteId.get();
|
const selectedRemoteId = this.model.selectedRemoteId.get();
|
||||||
return GlobalModel.getRemote(selectedRemoteId);
|
return GlobalModel.getRemote(selectedRemoteId);
|
||||||
}
|
}
|
||||||
@ -60,7 +57,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getRemoteTypeStr(remote: T.RemoteType): string {
|
getRemoteTypeStr(remote: RemoteType): string {
|
||||||
if (!util.isBlank(remote.uname)) {
|
if (!util.isBlank(remote.uname)) {
|
||||||
let unameStr = remote.uname;
|
let unameStr = remote.uname;
|
||||||
unameStr = unameStr.replace("|", ", ");
|
unameStr = unameStr.replace("|", ", ");
|
||||||
@ -138,7 +135,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
this.model.setRecentConnAdded(false);
|
this.model.setRecentConnAdded(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInstallStatus(remote: T.RemoteType): any {
|
renderInstallStatus(remote: RemoteType): any {
|
||||||
let statusStr: string = null;
|
let statusStr: string = null;
|
||||||
if (remote.installstatus == "disconnected") {
|
if (remote.installstatus == "disconnected") {
|
||||||
if (remote.needsmshellupgrade) {
|
if (remote.needsmshellupgrade) {
|
||||||
@ -162,7 +159,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeaderBtns(remote: T.RemoteType): React.ReactNode {
|
renderHeaderBtns(remote: RemoteType): React.ReactNode {
|
||||||
let buttons: React.ReactNode[] = [];
|
let buttons: React.ReactNode[] = [];
|
||||||
const disconnectButton = (
|
const disconnectButton = (
|
||||||
<Button theme="secondary" onClick={() => this.disconnectRemote(remote.remoteid)}>
|
<Button theme="secondary" onClick={() => this.disconnectRemote(remote.remoteid)}>
|
||||||
@ -256,7 +253,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMessage(remote: T.RemoteType): string {
|
getMessage(remote: RemoteType): string {
|
||||||
let message = "";
|
let message = "";
|
||||||
if (remote.status == "connected") {
|
if (remote.status == "connected") {
|
||||||
message = "Connected and ready to run commands.";
|
message = "Connected and ready to run commands.";
|
||||||
@ -295,7 +292,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
let model = this.model;
|
let model = this.model;
|
||||||
let isTermFocused = this.model.remoteTermWrapFocus.get();
|
let isTermFocused = this.model.remoteTermWrapFocus.get();
|
||||||
let termFontSize = GlobalModel.termFontSize.get();
|
let termFontSize = GlobalModel.termFontSize.get();
|
||||||
let termWidth = textmeasure.termWidthFromCols(RemotePtyCols, termFontSize);
|
let termWidth = textmeasure.termWidthFromCols(appconst.RemotePtyCols, termFontSize);
|
||||||
let remoteAliasText = util.isBlank(remote.remotealias) ? "(none)" : remote.remotealias;
|
let remoteAliasText = util.isBlank(remote.remotealias) ? "(none)" : remote.remotealias;
|
||||||
let selectedRemoteStatus = this.getSelectedRemote().status;
|
let selectedRemoteStatus = this.getSelectedRemote().status;
|
||||||
|
|
||||||
@ -373,7 +370,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
ref={this.termRef}
|
ref={this.termRef}
|
||||||
data-remoteid={remote.remoteid}
|
data-remoteid={remote.remoteid}
|
||||||
style={{
|
style={{
|
||||||
height: textmeasure.termHeightFromRows(RemotePtyRows, termFontSize),
|
height: textmeasure.termHeightFromRows(appconst.RemotePtyRows, termFontSize),
|
||||||
width: termWidth,
|
width: termWidth,
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
@ -397,7 +394,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImportTooltip(remote: T.RemoteType): React.ReactElement<any, any> {
|
function getImportTooltip(remote: RemoteType): React.ReactElement<any, any> {
|
||||||
if (remote.sshconfigsrc == "sshconfig-import") {
|
if (remote.sshconfigsrc == "sshconfig-import") {
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.term-prompt {
|
.term-prompt {
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
@ -3,42 +3,17 @@
|
|||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import type {
|
|
||||||
LineType,
|
|
||||||
RemoteType,
|
|
||||||
RemotePtrType,
|
|
||||||
LineHeightChangeCallbackType,
|
|
||||||
LineContainerType,
|
|
||||||
} from "../../../types/types";
|
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { isBlank } from "../../../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import { ReactComponent as FolderIcon } from "../../assets/icons/folder.svg";
|
import { ReactComponent as FolderIcon } from "@/assets/icons/folder.svg";
|
||||||
|
|
||||||
import "./prompt.less";
|
import "./prompt.less";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
type OArr<V> = mobx.IObservableArray<V>;
|
|
||||||
type OMap<K, V> = mobx.ObservableMap<K, V>;
|
|
||||||
|
|
||||||
type RendererComponentProps = {
|
|
||||||
screen: LineContainerType;
|
|
||||||
line: LineType;
|
|
||||||
width: number;
|
|
||||||
staticRender: boolean;
|
|
||||||
visible: OV<boolean>;
|
|
||||||
onHeightChange: LineHeightChangeCallbackType;
|
|
||||||
collapsed: boolean;
|
|
||||||
};
|
|
||||||
type RendererComponentType = {
|
|
||||||
new (props: RendererComponentProps): React.Component<RendererComponentProps, {}>;
|
|
||||||
};
|
|
||||||
|
|
||||||
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)) {
|
||||||
return remoteRef;
|
return remoteRef;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.connections-view {
|
.connections-view {
|
||||||
.no-items {
|
.no-items {
|
||||||
|
@ -7,16 +7,12 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { If, For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, RemotesModel, GlobalCommandRunner } from "../../models";
|
import { GlobalModel, RemotesModel, GlobalCommandRunner } from "@/models";
|
||||||
import { Button, Status, ShowWaveShellInstallPrompt } from "../common/elements";
|
import { Button, Status, ShowWaveShellInstallPrompt } from "@/common/elements";
|
||||||
import * as T from "../../types/types";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../util/util";
|
|
||||||
import * as appconst from "../appconst";
|
|
||||||
|
|
||||||
import "./connections.less";
|
import "./connections.less";
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||||
tableRef: React.RefObject<any> = React.createRef();
|
tableRef: React.RefObject<any> = React.createRef();
|
||||||
@ -54,13 +50,13 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
|||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
getName(item: T.RemoteType) {
|
getName(item: RemoteType) {
|
||||||
const { remotealias, remotecanonicalname } = item;
|
const { remotealias, remotecanonicalname } = item;
|
||||||
return remotealias ? `${remotealias} [${remotecanonicalname}]` : remotecanonicalname;
|
return remotealias ? `${remotealias} [${remotecanonicalname}]` : remotecanonicalname;
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
getImportSymbol(item: T.RemoteType): React.ReactElement<any, any> {
|
getImportSymbol(item: RemoteType): React.ReactElement<any, any> {
|
||||||
const { sshconfigsrc } = item;
|
const { sshconfigsrc } = item;
|
||||||
if (sshconfigsrc == "sshconfig-import") {
|
if (sshconfigsrc == "sshconfig-import") {
|
||||||
return <i title="Connection Imported from SSH Config" className="fa-sharp fa-solid fa-file-import" />;
|
return <i title="Connection Imported from SSH Config" className="fa-sharp fa-solid fa-file-import" />;
|
||||||
@ -131,7 +127,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
|||||||
}
|
}
|
||||||
|
|
||||||
let items = util.sortAndFilterRemotes(GlobalModel.remotes.slice());
|
let items = util.sortAndFilterRemotes(GlobalModel.remotes.slice());
|
||||||
let item: T.RemoteType = null;
|
let item: RemoteType = null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("view connections-view")}>
|
<div className={cn("view connections-view")}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.history-view {
|
.history-view {
|
||||||
background-color: @background-session;
|
background-color: @background-session;
|
||||||
@ -14,7 +14,7 @@
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #3B3F3A;
|
border: 1px solid #3b3f3a;
|
||||||
background: rgba(213, 254, 175, 0.03);
|
background: rgba(213, 254, 175, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
fill: rgba(213, 254, 175, 0.03);
|
fill: rgba(213, 254, 175, 0.03);
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
stroke: #3B3F3A;
|
stroke: #3b3f3a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +264,7 @@
|
|||||||
margin: 0px 10px 10px 10px;
|
margin: 0px 10px 10px 10px;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
border-top: 2px solid #ccc;
|
border-top: 2px solid #ccc;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
|
||||||
tr.active-history-item {
|
tr.active-history-item {
|
||||||
td {
|
td {
|
||||||
@ -309,9 +310,8 @@
|
|||||||
tr.history-item {
|
tr.history-item {
|
||||||
padding: 0 10px 0 10px;
|
padding: 0 10px 0 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid rgba(250, 250, 250, 0.10);
|
border-bottom: 1px solid rgba(250, 250, 250, 0.1);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 40px;
|
|
||||||
color: @text-secondary;
|
color: @text-secondary;
|
||||||
|
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
|
@ -8,40 +8,30 @@ import { If, For } from "tsx-control-statements/components";
|
|||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, Cmd } from "../../models";
|
import { GlobalModel, GlobalCommandRunner, Cmd } from "@/models";
|
||||||
import { HistoryItem, RemotePtrType, LineType, CmdDataType } from "../../types/types";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import customParseFormat from "dayjs/plugin/customParseFormat";
|
import customParseFormat from "dayjs/plugin/customParseFormat";
|
||||||
import { Line } from "../line/linecomps";
|
import { Line } from "@/app/line/linecomps";
|
||||||
import { CmdStrCode } from "../common/elements";
|
import { CmdStrCode } from "@/common/elements";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../../util/keyutil";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
|
|
||||||
import { ReactComponent as FavoritesIcon } from "../assets/icons/favourites.svg";
|
import { ReactComponent as XmarkIcon } from "@/assets/icons/line/xmark.svg";
|
||||||
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
|
import { ReactComponent as AngleDownIcon } from "@/assets/icons/history/angle-down.svg";
|
||||||
import { ReactComponent as AngleDownIcon } from "../assets/icons/history/angle-down.svg";
|
import { ReactComponent as ChevronLeftIcon } from "@/assets/icons/history/chevron-left.svg";
|
||||||
import { ReactComponent as ChevronLeftIcon } from "../assets/icons/history/chevron-left.svg";
|
import { ReactComponent as ChevronRightIcon } from "@/assets/icons/history/chevron-right.svg";
|
||||||
import { ReactComponent as ChevronRightIcon } from "../assets/icons/history/chevron-right.svg";
|
import { ReactComponent as RightIcon } from "@/assets/icons/history/right.svg";
|
||||||
import { ReactComponent as RightIcon } from "../assets/icons/history/right.svg";
|
import { ReactComponent as SearchIcon } from "@/assets/icons/history/search.svg";
|
||||||
import { ReactComponent as SearchIcon } from "../assets/icons/history/search.svg";
|
import { ReactComponent as TrashIcon } from "@/assets/icons/trash.svg";
|
||||||
import { ReactComponent as SquareCheckIcon } from "../assets/icons/history/square-check.svg";
|
import { ReactComponent as CheckedCheckbox } from "@/assets/icons/checked-checkbox.svg";
|
||||||
import { ReactComponent as SquareMinusIcon } from "../assets/icons/history/square-minus.svg";
|
import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
|
||||||
import { ReactComponent as SquareIcon } from "../assets/icons/history/square.svg";
|
import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
|
||||||
import { ReactComponent as TrashIcon } from "../assets/icons/trash.svg";
|
|
||||||
import { ReactComponent as CheckedCheckbox } from "../assets/icons/checked-checkbox.svg";
|
|
||||||
import { ReactComponent as CheckIcon } from "../assets/icons/line/check.svg";
|
|
||||||
import { ReactComponent as CopyIcon } from "../assets/icons/history/copy.svg";
|
|
||||||
|
|
||||||
import "./history.less";
|
import "./history.less";
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
type OArr<V> = mobx.IObservableArray<V>;
|
|
||||||
type OMap<K, V> = mobx.ObservableMap<K, V>;
|
|
||||||
type CV<V> = mobx.IComputedValue<V>;
|
|
||||||
|
|
||||||
function isBlank(s: string) {
|
function isBlank(s: string) {
|
||||||
return s == null || s == "";
|
return s == null || s == "";
|
||||||
}
|
}
|
||||||
@ -429,8 +419,16 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
let sessionId: string = null;
|
let sessionId: string = null;
|
||||||
let remoteIds = Object.keys(rnames);
|
let remoteIds = Object.keys(rnames);
|
||||||
let remoteId: string = null;
|
let remoteId: string = null;
|
||||||
|
|
||||||
|
// TODO: something is weird with how we calculate width for views. Before, history view was not honoring tab width. This fix is copied from workspaceview.tsx, which had a similar issue.
|
||||||
|
const width = window.innerWidth - 6 - GlobalModel.mainSidebarModel.getWidth();
|
||||||
return (
|
return (
|
||||||
<div className={cn("history-view", { "is-hidden": isHidden })}>
|
<div
|
||||||
|
className={cn("history-view", "view", { "is-hidden": isHidden })}
|
||||||
|
style={{
|
||||||
|
width: `${width}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<div className="history-title">History</div>
|
<div className="history-title">History</div>
|
||||||
<div className="history-search">
|
<div className="history-search">
|
||||||
|
@ -9,48 +9,36 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { GlobalModel, GlobalCommandRunner, Cmd } from "../../models";
|
import { GlobalModel, GlobalCommandRunner, Cmd } from "@/models";
|
||||||
import { termHeightFromRows } from "../../util/textmeasure";
|
import { termHeightFromRows } from "@/util/textmeasure";
|
||||||
import type {
|
|
||||||
LineType,
|
|
||||||
RenderModeType,
|
|
||||||
RendererOpts,
|
|
||||||
RendererPluginType,
|
|
||||||
LineHeightChangeCallbackType,
|
|
||||||
RendererModelInitializeParams,
|
|
||||||
RendererModel,
|
|
||||||
LineContainerType,
|
|
||||||
} from "../../types/types";
|
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { getTermPtyData } from "../../util/modelutil";
|
import { getTermPtyData } from "@/util/modelutil";
|
||||||
|
|
||||||
import { renderCmdText } from "../common/elements";
|
import { renderCmdText } from "@/common/elements";
|
||||||
import { SimpleBlobRenderer } from "../../plugins/core/basicrenderer";
|
import { SimpleBlobRenderer } from "@/plugins/core/basicrenderer";
|
||||||
import { IncrementalRenderer } from "../../plugins/core/incrementalrenderer";
|
import { IncrementalRenderer } from "@/plugins/core/incrementalrenderer";
|
||||||
import { TerminalRenderer } from "../../plugins/terminal/terminal";
|
import { TerminalRenderer } from "@/plugins/terminal/terminal";
|
||||||
import { isBlank } from "../../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import { PluginModel } from "../../plugins/plugins";
|
import { PluginModel } from "@/plugins/plugins";
|
||||||
import { Prompt } from "../common/prompt/prompt";
|
import { Prompt } from "@/common/prompt/prompt";
|
||||||
import * as lineutil from "./lineutil";
|
import * as lineutil from "./lineutil";
|
||||||
import { ErrorBoundary } from "../../app/common/error/errorboundary";
|
import { ErrorBoundary } from "@/common/error/errorboundary";
|
||||||
import * as appconst from "../appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import { ReactComponent as CheckIcon } from "../assets/icons/line/check.svg";
|
import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
|
||||||
import { ReactComponent as CommentIcon } from "../assets/icons/line/comment.svg";
|
import { ReactComponent as CommentIcon } from "@/assets/icons/line/comment.svg";
|
||||||
import { ReactComponent as QuestionIcon } from "../assets/icons/line/question.svg";
|
import { ReactComponent as QuestionIcon } from "@/assets/icons/line/question.svg";
|
||||||
import { ReactComponent as WarningIcon } from "../assets/icons/line/triangle-exclamation.svg";
|
import { ReactComponent as WarningIcon } from "@/assets/icons/line/triangle-exclamation.svg";
|
||||||
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
|
import { ReactComponent as XmarkIcon } from "@/assets/icons/line/xmark.svg";
|
||||||
import { ReactComponent as FillIcon } from "../assets/icons/line/fill.svg";
|
import { ReactComponent as FillIcon } from "@/assets/icons/line/fill.svg";
|
||||||
import { ReactComponent as GearIcon } from "../assets/icons/line/gear.svg";
|
import { ReactComponent as GearIcon } from "@/assets/icons/line/gear.svg";
|
||||||
|
|
||||||
import { RotateIcon } from "../common/icons/icons";
|
import { RotateIcon } from "@/common/icons/icons";
|
||||||
|
|
||||||
import "./lines.less";
|
import "./lines.less";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class SmallLineAvatar extends React.Component<{ line: LineType; cmd: Cmd; onRightClick?: (e: any) => void }, {}> {
|
class SmallLineAvatar extends React.Component<{ line: LineType; cmd: Cmd; onRightClick?: (e: any) => void }, {}> {
|
||||||
render() {
|
render() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.line.line-text {
|
.line.line-text {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -11,16 +11,12 @@ import cn from "classnames";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { debounce, throttle } from "throttle-debounce";
|
import { debounce, throttle } from "throttle-debounce";
|
||||||
import * as T from "../../types/types";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../util/util";
|
|
||||||
import * as lineutil from "./lineutil";
|
import * as lineutil from "./lineutil";
|
||||||
|
|
||||||
import "./lines.less";
|
import "./lines.less";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
type OArr<V> = mobx.IObservableArray<V>;
|
|
||||||
type OMap<K, V> = mobx.ObservableMap<K, V>;
|
|
||||||
|
|
||||||
const LinesVisiblePadding = 500;
|
const LinesVisiblePadding = 500;
|
||||||
|
|
||||||
@ -29,20 +25,20 @@ type ScreenInterface = {
|
|||||||
getSelectedLine(): number;
|
getSelectedLine(): number;
|
||||||
getAnchor(): { anchorLine: number; anchorOffset: number };
|
getAnchor(): { anchorLine: number; anchorOffset: number };
|
||||||
isLineIdInSidebar(lineId: string): boolean;
|
isLineIdInSidebar(lineId: string): boolean;
|
||||||
getLineByNum(lineNum: number): T.LineType;
|
getLineByNum(lineNum: number): LineType;
|
||||||
};
|
};
|
||||||
|
|
||||||
// <Line key={line.lineid} line={line} screen={screen} width={width} visible={this.visibleMap.get(lineNumStr)} staticRender={this.staticRender.get()} onHeightChange={this.onHeightChange} overrideCollapsed={this.collapsedMap.get(lineNumStr)} topBorder={topBorder} renderMode={renderMode}/>;
|
// <Line key={line.lineid} line={line} screen={screen} width={width} visible={this.visibleMap.get(lineNumStr)} staticRender={this.staticRender.get()} onHeightChange={this.onHeightChange} overrideCollapsed={this.collapsedMap.get(lineNumStr)} topBorder={topBorder} renderMode={renderMode}/>;
|
||||||
|
|
||||||
type LineCompFactory = (props: T.LineFactoryProps) => JSX.Element;
|
type LineCompFactory = (props: LineFactoryProps) => JSX.Element;
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class LinesView extends React.Component<
|
class LinesView extends React.Component<
|
||||||
{
|
{
|
||||||
screen: ScreenInterface;
|
screen: ScreenInterface;
|
||||||
width: number;
|
width: number;
|
||||||
lines: T.LineInterface[];
|
lines: LineInterface[];
|
||||||
renderMode: T.RenderModeType;
|
renderMode: RenderModeType;
|
||||||
lineFactory: LineCompFactory;
|
lineFactory: LineCompFactory;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
@ -384,7 +380,7 @@ class LinesView extends React.Component<
|
|||||||
this.computeVisibleMap_debounced();
|
this.computeVisibleMap_debounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
hasTopBorder(lines: T.LineInterface[], idx: number): boolean {
|
hasTopBorder(lines: LineInterface[], idx: number): boolean {
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -394,7 +390,7 @@ class LinesView extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDateSepStr(
|
getDateSepStr(
|
||||||
lines: T.LineInterface[],
|
lines: LineInterface[],
|
||||||
idx: number,
|
idx: number,
|
||||||
prevStr: string,
|
prevStr: string,
|
||||||
todayStr: string,
|
todayStr: string,
|
||||||
@ -410,7 +406,7 @@ class LinesView extends React.Component<
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
findClosestLineIndex(lineNum: number): { line: T.LineInterface; index: number } {
|
findClosestLineIndex(lineNum: number): { line: LineInterface; index: number } {
|
||||||
let { lines } = this.props;
|
let { lines } = this.props;
|
||||||
if (lines.length == 0) {
|
if (lines.length == 0) {
|
||||||
throw new Error("invalid lines, cannot have 0 length in LinesView");
|
throw new Error("invalid lines, cannot have 0 length in LinesView");
|
||||||
@ -444,7 +440,7 @@ class LinesView extends React.Component<
|
|||||||
render() {
|
render() {
|
||||||
let { screen, width, lines, renderMode } = this.props;
|
let { screen, width, lines, renderMode } = this.props;
|
||||||
let selectedLine = screen.getSelectedLine(); // for re-rendering
|
let selectedLine = screen.getSelectedLine(); // for re-rendering
|
||||||
let line: T.LineInterface = null;
|
let line: LineInterface = null;
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
let key = String(lines[i].linenum);
|
let key = String(lines[i].linenum);
|
||||||
let visObs = this.visibleMap.get(key);
|
let visObs = this.visibleMap.get(key);
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { isBlank, getDateStr } from "../../util/util";
|
import { isBlank, getDateStr } from "@/util/util";
|
||||||
import { LineType, WebLine, RendererContext } from "../../types/types";
|
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
@ -4,32 +4,10 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { sprintf } from "sprintf-js";
|
|
||||||
import { boundMethod } from "autobind-decorator";
|
|
||||||
import { If, For, When, Otherwise, Choose } from "tsx-control-statements/components";
|
|
||||||
import type {
|
|
||||||
RendererModelInitializeParams,
|
|
||||||
TermOptsType,
|
|
||||||
RendererContext,
|
|
||||||
RendererOpts,
|
|
||||||
SimpleBlobRendererComponent,
|
|
||||||
RendererModelContainerApi,
|
|
||||||
RendererPluginType,
|
|
||||||
PtyDataType,
|
|
||||||
RendererModel,
|
|
||||||
RendererOptsUpdate,
|
|
||||||
LineStateType,
|
|
||||||
LineType,
|
|
||||||
TermContextUnion,
|
|
||||||
RendererContainerType,
|
|
||||||
ExtBlob,
|
|
||||||
} from "../../../types/types";
|
|
||||||
import { debounce } from "throttle-debounce";
|
|
||||||
import * as util from "../../../util/util";
|
|
||||||
import { GlobalModel } from "../../../models";
|
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
import { debounce } from "throttle-debounce";
|
||||||
type CV<V> = mobx.IComputedValue<V>;
|
import * as util from "@/util";
|
||||||
|
import { GlobalModel } from "@/models";
|
||||||
|
|
||||||
class SimpleBlobRendererModel {
|
class SimpleBlobRendererModel {
|
||||||
context: RendererContext;
|
context: RendererContext;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.plugins-view {
|
.plugins-view {
|
||||||
background-color: @background-session;
|
background-color: @background-session;
|
||||||
|
@ -5,11 +5,11 @@ import * as React from "react";
|
|||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { GlobalModel } from "../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { PluginModel } from "../../plugins/plugins";
|
import { PluginModel } from "@/plugins/plugins";
|
||||||
import { Markdown } from "../common/elements";
|
import { Markdown } from "@/common/elements";
|
||||||
|
|
||||||
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
|
import { ReactComponent as XmarkIcon } from "@/assets/icons/line/xmark.svg";
|
||||||
|
|
||||||
import "./pluginsview.less";
|
import "./pluginsview.less";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
@import "../../app/common/icons/icons.less";
|
@import "@/common/icons/icons.less";
|
||||||
|
|
||||||
.main-sidebar {
|
.main-sidebar {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -7,23 +7,22 @@ import * as mobx from "mobx";
|
|||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { ClientDataType, RemoteType } from "../../types/types";
|
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { compareLoose } from "semver";
|
import { compareLoose } from "semver";
|
||||||
|
|
||||||
import { ReactComponent as LeftChevronIcon } from "../assets/icons/chevron_left.svg";
|
import { ReactComponent as LeftChevronIcon } from "@/assets/icons/chevron_left.svg";
|
||||||
import { ReactComponent as AppsIcon } from "../assets/icons/apps.svg";
|
import { ReactComponent as AppsIcon } from "@/assets/icons/apps.svg";
|
||||||
import { ReactComponent as WorkspacesIcon } from "../assets/icons/workspaces.svg";
|
import { ReactComponent as WorkspacesIcon } from "@/assets/icons/workspaces.svg";
|
||||||
import { ReactComponent as SettingsIcon } from "../assets/icons/settings.svg";
|
import { ReactComponent as SettingsIcon } from "@/assets/icons/settings.svg";
|
||||||
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel, GlobalCommandRunner, Session } from "../../models";
|
import { GlobalModel, GlobalCommandRunner, Session } from "@/models";
|
||||||
import { isBlank, openLink } from "../../util/util";
|
import { isBlank, openLink } from "@/util/util";
|
||||||
import { ResizableSidebar } from "../common/elements";
|
import { ResizableSidebar } from "@/common/elements";
|
||||||
import * as appconst from "../appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import "./sidebar.less";
|
import "./sidebar.less";
|
||||||
import { ActionsIcon, CenteredIcon, FrontIcon, StatusIndicator } from "../common/icons/icons";
|
import { ActionsIcon, CenteredIcon, FrontIcon, StatusIndicator } from "@/common/icons/icons";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
@ -4,16 +4,13 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { isBlank } from "../../../util/util";
|
import { isBlank } from "@/util";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { Prompt } from "../../common/prompt/prompt";
|
import { For } from "tsx-control-statements/components";
|
||||||
import { TextAreaInput } from "./textareainput";
|
import { Markdown } from "@/elements";
|
||||||
import { If, For } from "tsx-control-statements/components";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
import type { OpenAICmdInfoChatMessageType } from "../../../types/types";
|
|
||||||
import { Markdown } from "../../common/elements";
|
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../../../util/keyutil";
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class AIChat extends React.Component<{}, {}> {
|
class AIChat extends React.Component<{}, {}> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.cmd-input {
|
.cmd-input {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
@ -8,16 +8,15 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { RemoteType, RemoteInstanceType, RemotePtrType } from "../../../types/types";
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel, GlobalCommandRunner, Screen } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||||
import { renderCmdText } from "../../common/elements";
|
import { renderCmdText } from "@/elements";
|
||||||
import { TextAreaInput } from "./textareainput";
|
import { TextAreaInput } from "./textareainput";
|
||||||
import { InfoMsg } from "./infomsg";
|
import { InfoMsg } from "./infomsg";
|
||||||
import { HistoryInfo } from "./historyinfo";
|
import { HistoryInfo } from "./historyinfo";
|
||||||
import { Prompt } from "../../common/prompt/prompt";
|
import { Prompt } from "@/common/prompt/prompt";
|
||||||
import { ReactComponent as ExecIcon } from "../../assets/icons/exec.svg";
|
import { ReactComponent as ExecIcon } from "@/assets/icons/exec.svg";
|
||||||
import { RotateIcon } from "../../common/icons/icons";
|
import { RotateIcon } from "@/common/icons/icons";
|
||||||
import { AIChat } from "./aichat";
|
import { AIChat } from "./aichat";
|
||||||
|
|
||||||
import "./cmdinput.less";
|
import "./cmdinput.less";
|
||||||
|
@ -9,10 +9,9 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import { If, For } from "tsx-control-statements/components";
|
import { If, For } from "tsx-control-statements/components";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import type { HistoryItem, HistoryQueryOpts } from "../../../types/types";
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { isBlank } from "../../../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ import { If, For } from "tsx-control-statements/components";
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "../../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { makeExternLink } from "../../../util/util";
|
import { makeExternLink } from "@/util/util";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
@ -4,16 +4,14 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as mobxReact from "mobx-react";
|
import * as mobxReact from "mobx-react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import type * as T from "../../../types/types";
|
import * as util from "@/util/util";
|
||||||
import * as util from "../../../util/util";
|
|
||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, Screen } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||||
import { getMonoFontSize } from "../../../util/textmeasure";
|
import { getMonoFontSize } from "@/util/textmeasure";
|
||||||
import { isModKeyPress, hasNoModifiers } from "../../../util/util";
|
import * as appconst from "@/app/appconst";
|
||||||
import * as appconst from "../../appconst";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../../../util/keyutil";
|
|
||||||
|
|
||||||
type OV<T> = mobx.IObservableValue<T>;
|
type OV<T> = mobx.IObservableValue<T>;
|
||||||
|
|
||||||
@ -51,7 +49,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
|
|||||||
historyInputRef: React.RefObject<HTMLInputElement> = React.createRef();
|
historyInputRef: React.RefObject<HTMLInputElement> = React.createRef();
|
||||||
controlRef: React.RefObject<HTMLDivElement> = React.createRef();
|
controlRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||||
lastHeight: number = 0;
|
lastHeight: number = 0;
|
||||||
lastSP: T.StrWithPos = { str: "", pos: appconst.NoStrPos };
|
lastSP: StrWithPos = { str: "", pos: appconst.NoStrPos };
|
||||||
version: OV<number> = mobx.observable.box(0); // forces render updates
|
version: OV<number> = mobx.observable.box(0); // forces render updates
|
||||||
|
|
||||||
incVersion(): void {
|
incVersion(): void {
|
||||||
@ -59,7 +57,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
|
|||||||
mobx.action(() => this.version.set(v + 1))();
|
mobx.action(() => this.version.set(v + 1))();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurSP(): T.StrWithPos {
|
getCurSP(): StrWithPos {
|
||||||
let textarea = this.mainInputRef.current;
|
let textarea = this.mainInputRef.current;
|
||||||
if (textarea == null) {
|
if (textarea == null) {
|
||||||
return this.lastSP;
|
return this.lastSP;
|
||||||
@ -169,7 +167,7 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
onKeyDown(e: any) {
|
onKeyDown(e: any) {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
if (isModKeyPress(e)) {
|
if (util.isModKeyPress(e)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let model = GlobalModel;
|
let model = GlobalModel;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
.screen-view {
|
.screen-view {
|
||||||
@ -6,7 +6,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-sidebar, .window-view {
|
.screen-sidebar,
|
||||||
|
.window-view {
|
||||||
transition: width 0.5s ease-in-out;
|
transition: width 0.5s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,21 +10,19 @@ import { If, For } from "tsx-control-statements/components";
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { debounce } from "throttle-debounce";
|
import { debounce } from "throttle-debounce";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { GlobalCommandRunner, ForwardLineContainer, GlobalModel, ScreenLines, Screen, Session } from "../../../models";
|
import { GlobalCommandRunner, ForwardLineContainer, GlobalModel, ScreenLines, Screen, Session } from "@/models";
|
||||||
import type { LineType, RenderModeType, LineFactoryProps } from "../../../types/types";
|
|
||||||
import * as T from "../../../types/types";
|
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { Button, TextField, Dropdown } from "../../common/elements";
|
import { Button, TextField, Dropdown } from "@/elements";
|
||||||
import { getRemoteStr } from "../../common/prompt/prompt";
|
import { getRemoteStr } from "@/common/prompt/prompt";
|
||||||
import { Line } from "../../line/linecomps";
|
import { Line } from "@/app/line/linecomps";
|
||||||
import { LinesView } from "../../line/linesview";
|
import { LinesView } from "@/app/line/linesview";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "@/util/util";
|
||||||
import { ReactComponent as EllipseIcon } from "../../assets/icons/ellipse.svg";
|
import { ReactComponent as EllipseIcon } from "@/assets/icons/ellipse.svg";
|
||||||
import { ReactComponent as Check12Icon } from "../../assets/icons/check12.svg";
|
import { ReactComponent as Check12Icon } from "@/assets/icons/check12.svg";
|
||||||
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
|
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
||||||
import { ReactComponent as GlobeIcon } from "../../assets/icons/globe.svg";
|
import { ReactComponent as GlobeIcon } from "@/assets/icons/globe.svg";
|
||||||
import { ReactComponent as StatusCircleIcon } from "../../assets/icons/statuscircle.svg";
|
import { ReactComponent as StatusCircleIcon } from "@/assets/icons/statuscircle.svg";
|
||||||
import * as appconst from "../../appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import "./screenview.less";
|
import "./screenview.less";
|
||||||
import "./tabs.less";
|
import "./tabs.less";
|
||||||
@ -32,8 +30,6 @@ import { MagicLayout } from "../../magiclayout";
|
|||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ScreenView extends React.Component<{ session: Session; screen: Screen }, {}> {
|
class ScreenView extends React.Component<{ session: Session; screen: Screen }, {}> {
|
||||||
rszObs: ResizeObserver;
|
rszObs: ResizeObserver;
|
||||||
@ -164,7 +160,7 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, {
|
|||||||
|
|
||||||
type SidebarLineContainerPropsType = {
|
type SidebarLineContainerPropsType = {
|
||||||
screen: Screen;
|
screen: Screen;
|
||||||
winSize: T.WindowSize;
|
winSize: WindowSize;
|
||||||
lineId: string;
|
lineId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -230,7 +226,7 @@ class SidebarLineContainer extends React.Component<SidebarLineContainerPropsType
|
|||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {}> {
|
class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {}> {
|
||||||
rszObs: ResizeObserver;
|
rszObs: ResizeObserver;
|
||||||
sidebarSize: OV<T.WindowSize> = mobx.observable.box({ height: 0, width: 0 }, { name: "sidebarSize" });
|
sidebarSize: OV<WindowSize> = mobx.observable.box({ height: 0, width: 0 }, { name: "sidebarSize" });
|
||||||
sidebarRef: React.RefObject<any> = React.createRef();
|
sidebarRef: React.RefObject<any> = React.createRef();
|
||||||
handleResize_debounced: (entries: ResizeObserverEntry[]) => void;
|
handleResize_debounced: (entries: ResizeObserverEntry[]) => void;
|
||||||
|
|
||||||
@ -288,7 +284,7 @@ class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {
|
|||||||
GlobalCommandRunner.screenSidebarOpen("500px");
|
GlobalCommandRunner.screenSidebarOpen("500px");
|
||||||
}
|
}
|
||||||
|
|
||||||
getSidebarConfig(): T.ScreenSidebarOptsType {
|
getSidebarConfig(): ScreenSidebarOptsType {
|
||||||
let { screen } = this.props;
|
let { screen } = this.props;
|
||||||
let viewOpts = screen.viewOpts.get();
|
let viewOpts = screen.viewOpts.get();
|
||||||
return viewOpts?.sidebar;
|
return viewOpts?.sidebar;
|
||||||
@ -344,7 +340,7 @@ class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {
|
|||||||
class NewTabSettings extends React.Component<{ screen: Screen }, {}> {
|
class NewTabSettings extends React.Component<{ screen: Screen }, {}> {
|
||||||
connDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "NewTabSettings-connDropdownActive" });
|
connDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "NewTabSettings-connDropdownActive" });
|
||||||
errorMessage: OV<string | null> = mobx.observable.box(null, { name: "NewTabSettings-errorMessage" });
|
errorMessage: OV<string | null> = mobx.observable.box(null, { name: "NewTabSettings-errorMessage" });
|
||||||
remotes: T.RemoteType[];
|
remotes: RemoteType[];
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -6,13 +6,13 @@ import * as mobxReact from "mobx-react";
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, Screen } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||||
import { ActionsIcon, StatusIndicator, CenteredIcon } from "../../common/icons/icons";
|
import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons";
|
||||||
import { renderCmdText } from "../../common/elements";
|
import { renderCmdText } from "@/elements";
|
||||||
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
|
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
||||||
import * as constants from "../../appconst";
|
import * as constants from "@/app/appconst";
|
||||||
import { Reorder } from "framer-motion";
|
import { Reorder } from "framer-motion";
|
||||||
import { MagicLayout } from "../../magiclayout";
|
import { MagicLayout } from "@/app/magiclayout";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ScreenTab extends React.Component<
|
class ScreenTab extends React.Component<
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@import "../../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
@import "../../../app/common/icons/icons.less";
|
@import "@/common/icons/icons.less";
|
||||||
|
|
||||||
#main .screen-tabs .screen-tab {
|
#main .screen-tabs .screen-tab {
|
||||||
border-top: 1px solid transparent;
|
border-top: 1px solid transparent;
|
||||||
|
@ -7,8 +7,8 @@ import * as mobx from "mobx";
|
|||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { For } from "tsx-control-statements/components";
|
import { For } from "tsx-control-statements/components";
|
||||||
import { GlobalModel, GlobalCommandRunner, Session, Screen } from "../../../models";
|
import { GlobalModel, GlobalCommandRunner, Session, Screen } from "@/models";
|
||||||
import { ReactComponent as AddIcon } from "../../assets/icons/add.svg";
|
import { ReactComponent as AddIcon } from "@/assets/icons/add.svg";
|
||||||
import { Reorder } from "framer-motion";
|
import { Reorder } from "framer-motion";
|
||||||
import { ScreenTab } from "./tab";
|
import { ScreenTab } from "./tab";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "@/common/themes/themes.less";
|
||||||
|
|
||||||
.session-view {
|
.session-view {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -7,18 +7,16 @@ import * as mobx from "mobx";
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "../../models";
|
import { GlobalModel } from "@/models";
|
||||||
import { CmdInput } from "./cmdinput/cmdinput";
|
import { CmdInput } from "./cmdinput/cmdinput";
|
||||||
import { ScreenView } from "./screen/screenview";
|
import { ScreenView } from "./screen/screenview";
|
||||||
import { ScreenTabs } from "./screen/tabs";
|
import { ScreenTabs } from "./screen/tabs";
|
||||||
import { ErrorBoundary } from "../../app/common/error/errorboundary";
|
import { ErrorBoundary } from "@/common/error/errorboundary";
|
||||||
import { MagicLayout } from "../magiclayout";
|
import { MagicLayout } from "../magiclayout";
|
||||||
import "./workspace.less";
|
import "./workspace.less";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
type OV<V> = mobx.IObservableValue<V>;
|
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class WorkspaceView extends React.Component<{}, {}> {
|
class WorkspaceView extends React.Component<{}, {}> {
|
||||||
render() {
|
render() {
|
||||||
|
@ -7,12 +7,12 @@ import * as fs from "fs";
|
|||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import * as child_process from "node:child_process";
|
import * as child_process from "node:child_process";
|
||||||
import { debounce } from "throttle-debounce";
|
import { debounce } from "throttle-debounce";
|
||||||
import { handleJsonFetchResponse } from "../util/util";
|
|
||||||
import * as winston from "winston";
|
import * as winston from "winston";
|
||||||
import * as util from "util";
|
|
||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
|
import * as util from "util";
|
||||||
|
import { handleJsonFetchResponse } from "@/util/util";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { checkKeyPressed, adaptFromElectronKeyEvent, setKeyUtilPlatform } from "../util/keyutil";
|
import { checkKeyPressed, adaptFromElectronKeyEvent, setKeyUtilPlatform } from "@/util/keyutil";
|
||||||
import { platform } from "os";
|
import { platform } from "os";
|
||||||
|
|
||||||
const WaveAppPathVarName = "WAVETERM_APP_PATH";
|
const WaveAppPathVarName = "WAVETERM_APP_PATH";
|
||||||
@ -40,19 +40,21 @@ let unameArch: string = process.arch;
|
|||||||
if (unameArch == "x64") {
|
if (unameArch == "x64") {
|
||||||
unameArch = "amd64";
|
unameArch = "amd64";
|
||||||
}
|
}
|
||||||
let logger;
|
let loggerTransports: winston.transport[] = [
|
||||||
|
new winston.transports.File({ filename: path.join(waveHome, "waveterm-app.log"), level: "info" }),
|
||||||
|
];
|
||||||
|
if (isDev) {
|
||||||
|
loggerTransports.push(new winston.transports.Console());
|
||||||
|
}
|
||||||
let loggerConfig = {
|
let loggerConfig = {
|
||||||
level: "info",
|
level: "info",
|
||||||
format: winston.format.combine(
|
format: winston.format.combine(
|
||||||
winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
||||||
winston.format.printf((info) => `${info.timestamp} ${info.message}`)
|
winston.format.printf((info) => `${info.timestamp} ${info.message}`)
|
||||||
),
|
),
|
||||||
transports: [new winston.transports.File({ filename: path.join(waveHome, "waveterm-app.log"), level: "info" })],
|
transports: loggerTransports,
|
||||||
};
|
};
|
||||||
if (isDev) {
|
let logger = winston.createLogger(loggerConfig);
|
||||||
loggerConfig.transports.push(new winston.transports.Console());
|
|
||||||
}
|
|
||||||
logger = winston.createLogger(loggerConfig);
|
|
||||||
function log(...msg) {
|
function log(...msg) {
|
||||||
try {
|
try {
|
||||||
logger.info(util.format(...msg));
|
logger.info(util.format(...msg));
|
||||||
@ -75,7 +77,7 @@ if (isDev) {
|
|||||||
}
|
}
|
||||||
let app = electron.app;
|
let app = electron.app;
|
||||||
app.setName(isDev ? "Wave (Dev)" : "Wave");
|
app.setName(isDev ? "Wave (Dev)" : "Wave");
|
||||||
let waveSrvProc = null;
|
let waveSrvProc: child_process.ChildProcessWithoutNullStreams | null = null;
|
||||||
let waveSrvShouldRestart = false;
|
let waveSrvShouldRestart = false;
|
||||||
|
|
||||||
electron.dialog.showErrorBox = (title, content) => {
|
electron.dialog.showErrorBox = (title, content) => {
|
||||||
@ -101,8 +103,11 @@ function checkPromptMigrate() {
|
|||||||
// don't migrate if we're running dev version or if wave home directory already exists
|
// don't migrate if we're running dev version or if wave home directory already exists
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let homeDir = process.env.HOME;
|
if (process.env.HOME == null) {
|
||||||
let promptHome = path.join(homeDir, "prompt");
|
return;
|
||||||
|
}
|
||||||
|
let homeDir: string = process.env.HOME;
|
||||||
|
let promptHome: string = path.join(homeDir, "prompt");
|
||||||
if (!fs.existsSync(promptHome) || !fs.existsSync(path.join(promptHome, "prompt.db"))) {
|
if (!fs.existsSync(promptHome) || !fs.existsSync(path.join(promptHome, "prompt.db"))) {
|
||||||
// make sure we have a valid prompt home directory (prompt.db must exist inside)
|
// make sure we have a valid prompt home directory (prompt.db must exist inside)
|
||||||
return;
|
return;
|
||||||
@ -170,7 +175,7 @@ function readAuthKey() {
|
|||||||
return authKeyStr.trim();
|
return authKeyStr.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
let menuTemplate = [
|
let menuTemplate: Electron.MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
role: "appMenu",
|
role: "appMenu",
|
||||||
submenu: [
|
submenu: [
|
||||||
@ -222,7 +227,7 @@ function getMods(input: any) {
|
|||||||
return { meta: input.meta, shift: input.shift, ctrl: input.control, alt: input.alt };
|
return { meta: input.meta, shift: input.shift, ctrl: input.control, alt: input.alt };
|
||||||
}
|
}
|
||||||
|
|
||||||
function shNavHandler(event: any, url: any) {
|
function shNavHandler(event: Electron.Event<Electron.WebContentsWillNavigateEventParams>, url: string) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (url.startsWith("https://") || url.startsWith("http://") || url.startsWith("file://")) {
|
if (url.startsWith("https://") || url.startsWith("http://") || url.startsWith("file://")) {
|
||||||
console.log("open external, shNav", url);
|
console.log("open external, shNav", url);
|
||||||
@ -232,12 +237,13 @@ function shNavHandler(event: any, url: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shFrameNavHandler(event: any, url: any) {
|
function shFrameNavHandler(event: Electron.Event<Electron.WebContentsWillFrameNavigateEventParams>) {
|
||||||
if (!event.frame || event.frame.parent == null) {
|
if (!event.frame || event.frame.parent == null) {
|
||||||
// only use this handler to process iframe events (non-iframe events go to shNavHandler)
|
// only use this handler to process iframe events (non-iframe events go to shNavHandler)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
let url = event.url;
|
||||||
console.log(`frame-navigation url=${url} frame=${event.frame.name}`);
|
console.log(`frame-navigation url=${url} frame=${event.frame.name}`);
|
||||||
if (event.frame.name == "webview") {
|
if (event.frame.name == "webview") {
|
||||||
// "webview" links always open in new window
|
// "webview" links always open in new window
|
||||||
@ -250,7 +256,7 @@ function shFrameNavHandler(event: any, url: any) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMainWindow(clientData) {
|
function createMainWindow(clientData: ClientDataType | null) {
|
||||||
let bounds = calcBounds(clientData);
|
let bounds = calcBounds(clientData);
|
||||||
setKeyUtilPlatform(platform());
|
setKeyUtilPlatform(platform());
|
||||||
let win = new electron.BrowserWindow({
|
let win = new electron.BrowserWindow({
|
||||||
@ -644,12 +650,11 @@ electron.ipcMain.on("context-editmenu", (event, { x, y }, opts) => {
|
|||||||
}
|
}
|
||||||
console.log("context-editmenu");
|
console.log("context-editmenu");
|
||||||
let menu = new electron.Menu();
|
let menu = new electron.Menu();
|
||||||
let menuItem = null;
|
|
||||||
if (opts.showCut) {
|
if (opts.showCut) {
|
||||||
menuItem = new electron.MenuItem({ label: "Cut", role: "cut" });
|
let menuItem = new electron.MenuItem({ label: "Cut", role: "cut" });
|
||||||
menu.append(menuItem);
|
menu.append(menuItem);
|
||||||
}
|
}
|
||||||
menuItem = new electron.MenuItem({ label: "Copy", role: "copy" });
|
let menuItem = new electron.MenuItem({ label: "Copy", role: "copy" });
|
||||||
menu.append(menuItem);
|
menu.append(menuItem);
|
||||||
menuItem = new electron.MenuItem({ label: "Paste", role: "paste" });
|
menuItem = new electron.MenuItem({ label: "Paste", role: "paste" });
|
||||||
menu.append(menuItem);
|
menu.append(menuItem);
|
||||||
@ -657,7 +662,7 @@ electron.ipcMain.on("context-editmenu", (event, { x, y }, opts) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function createMainWindowWrap() {
|
async function createMainWindowWrap() {
|
||||||
let clientData = null;
|
let clientData: ClientDataType | null = null;
|
||||||
try {
|
try {
|
||||||
clientData = await getClientDataPoll(1);
|
clientData = await getClientDataPoll(1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -5,7 +5,7 @@ import * as mobx from "mobx";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
import { App } from "./app/app";
|
import { App } from "@/app/app";
|
||||||
import * as DOMPurify from "dompurify";
|
import * as DOMPurify from "dompurify";
|
||||||
import { loadFonts } from "./util/util";
|
import { loadFonts } from "./util/util";
|
||||||
|
|
||||||
|
@ -4,10 +4,8 @@
|
|||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { sprintf } from "sprintf-js";
|
import { sprintf } from "sprintf-js";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { genMergeSimpleData } from "../util/util";
|
import { genMergeSimpleData } from "@/util/util";
|
||||||
import { BookmarkType } from "../types/types";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../util/keyutil";
|
|
||||||
import { OV, OArr } from "../types/types";
|
|
||||||
import { GlobalCommandRunner } from "./global";
|
import { GlobalCommandRunner } from "./global";
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
|
|
||||||
|
@ -2,20 +2,10 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { stringToBase64 } from "../util/util";
|
import { stringToBase64 } from "@/util/util";
|
||||||
import { TermWrap } from "../plugins/terminal/term";
|
import { TermWrap } from "@/plugins/terminal/term";
|
||||||
import {
|
import { cmdStatusIsRunning } from "@/app/line/lineutil";
|
||||||
RemotePtrType,
|
|
||||||
CmdDataType,
|
|
||||||
TermOptsType,
|
|
||||||
FeInputPacketType,
|
|
||||||
RendererModel,
|
|
||||||
WebCmd,
|
|
||||||
WebRemote,
|
|
||||||
} from "../types/types";
|
|
||||||
import { cmdStatusIsRunning } from "../app/line/lineutil";
|
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { OV } from "../types/types";
|
|
||||||
|
|
||||||
const InputChunkSize = 500;
|
const InputChunkSize = 500;
|
||||||
class Cmd {
|
class Cmd {
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { RendererContext, CommandRtnType, HistorySearchParams, LineStateType } from "../types/types";
|
|
||||||
import { GlobalModel } from "./global";
|
import { GlobalModel } from "./global";
|
||||||
|
|
||||||
class CommandRunner {
|
class CommandRunner {
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
static getInstance() {
|
static getInstance(): CommandRunner {
|
||||||
if (!(window as any).GlobalCommandRunner) {
|
if (!(window as any).GlobalCommandRunner) {
|
||||||
(window as any).GlobalCommandRunner = new CommandRunner();
|
(window as any).GlobalCommandRunner = new CommandRunner();
|
||||||
}
|
}
|
||||||
@ -35,6 +34,12 @@ class CommandRunner {
|
|||||||
return prtn;
|
return prtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switchView(view: string) {
|
||||||
|
mobx.action(() => {
|
||||||
|
GlobalModel.activeMainView.set(view);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
switchSession(session: string) {
|
switchSession(session: string) {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
GlobalModel.activeMainView.set("session");
|
GlobalModel.activeMainView.set("session");
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// Copyright 2023, Command Line Inc.
|
// Copyright 2023, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { TermWrap } from "../plugins/terminal/term";
|
import { TermWrap } from "@/plugins/terminal/term";
|
||||||
import * as types from "../types/types";
|
import { windowWidthToCols, windowHeightToRows } from "@/util/textmeasure";
|
||||||
import { windowWidthToCols, windowHeightToRows } from "../util/textmeasure";
|
import { MagicLayout } from "@/app/magiclayout";
|
||||||
import { MagicLayout } from "../app/magiclayout";
|
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { GlobalCommandRunner } from "./global";
|
import { GlobalCommandRunner } from "./global";
|
||||||
import { Cmd } from "./cmd";
|
import { Cmd } from "./cmd";
|
||||||
@ -12,12 +11,12 @@ import { Screen } from "./screen";
|
|||||||
|
|
||||||
class ForwardLineContainer {
|
class ForwardLineContainer {
|
||||||
globalModel: Model;
|
globalModel: Model;
|
||||||
winSize: types.WindowSize;
|
winSize: WindowSize;
|
||||||
screen: Screen;
|
screen: Screen;
|
||||||
containerType: types.LineContainerStrs;
|
containerType: LineContainerStrs;
|
||||||
lineId: string;
|
lineId: string;
|
||||||
|
|
||||||
constructor(screen: Screen, winSize: types.WindowSize, containerType: types.LineContainerStrs, lineId: string) {
|
constructor(screen: Screen, winSize: WindowSize, containerType: LineContainerStrs, lineId: string) {
|
||||||
this.globalModel = Model.getInstance();
|
this.globalModel = Model.getInstance();
|
||||||
this.screen = screen;
|
this.screen = screen;
|
||||||
this.winSize = winSize;
|
this.winSize = winSize;
|
||||||
@ -25,7 +24,7 @@ class ForwardLineContainer {
|
|||||||
this.lineId = lineId;
|
this.lineId = lineId;
|
||||||
}
|
}
|
||||||
|
|
||||||
screenSizeCallback(winSize: types.WindowSize): void {
|
screenSizeCallback(winSize: WindowSize): void {
|
||||||
this.winSize = winSize;
|
this.winSize = winSize;
|
||||||
let termWrap = this.getTermWrap(this.lineId);
|
let termWrap = this.getTermWrap(this.lineId);
|
||||||
if (termWrap != null) {
|
if (termWrap != null) {
|
||||||
@ -37,11 +36,11 @@ class ForwardLineContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContainerType(): types.LineContainerStrs {
|
getContainerType(): LineContainerStrs {
|
||||||
return this.containerType;
|
return this.containerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCmd(line: types.LineType): Cmd {
|
getCmd(line: LineType): Cmd {
|
||||||
return this.screen.getCmd(line);
|
return this.screen.getCmd(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,25 +56,25 @@ class ForwardLineContainer {
|
|||||||
this.screen.setLineFocus(lineNum, focus);
|
this.screen.setLineFocus(lineNum, focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentHeight(context: types.RendererContext, height: number): void {
|
setContentHeight(context: RendererContext, height: number): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxContentSize(): types.WindowSize {
|
getMaxContentSize(): WindowSize {
|
||||||
let rtn = { width: this.winSize.width, height: this.winSize.height };
|
let rtn = { width: this.winSize.width, height: this.winSize.height };
|
||||||
rtn.width = rtn.width - MagicLayout.ScreenMaxContentWidthBuffer;
|
rtn.width = rtn.width - MagicLayout.ScreenMaxContentWidthBuffer;
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
getIdealContentSize(): types.WindowSize {
|
getIdealContentSize(): WindowSize {
|
||||||
return this.winSize;
|
return this.winSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTerminalRenderer(elem: Element, line: types.LineType, cmd: Cmd, width: number): void {
|
loadTerminalRenderer(elem: Element, line: LineType, cmd: Cmd, width: number): void {
|
||||||
this.screen.loadTerminalRenderer(elem, line, cmd, width);
|
this.screen.loadTerminalRenderer(elem, line, cmd, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerRenderer(lineId: string, renderer: types.RendererModel): void {
|
registerRenderer(lineId: string, renderer: RendererModel): void {
|
||||||
this.screen.registerRenderer(lineId, renderer);
|
this.screen.registerRenderer(lineId, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,11 +82,11 @@ class ForwardLineContainer {
|
|||||||
this.screen.unloadRenderer(lineId);
|
this.screen.unloadRenderer(lineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getContentHeight(context: types.RendererContext): number {
|
getContentHeight(context: RendererContext): number {
|
||||||
return this.screen.getContentHeight(context);
|
return this.screen.getContentHeight(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsedRows(context: types.RendererContext, line: types.LineType, cmd: Cmd, width: number): number {
|
getUsedRows(context: RendererContext, line: LineType, cmd: Cmd, width: number): number {
|
||||||
return this.screen.getUsedRows(context, line, cmd, width);
|
return this.screen.getUsedRows(context, line, cmd, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ class ForwardLineContainer {
|
|||||||
return this.screen.getIsFocused(lineNum);
|
return this.screen.getIsFocused(lineNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderer(lineId: string): types.RendererModel {
|
getRenderer(lineId: string): RendererModel {
|
||||||
return this.screen.getRenderer(lineId);
|
return this.screen.getRenderer(lineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ class ForwardLineContainer {
|
|||||||
return this.screen.getTermWrap(lineId);
|
return this.screen.getTermWrap(lineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFocusType(): types.FocusTypeStrs {
|
getFocusType(): FocusTypeStrs {
|
||||||
return this.screen.getFocusType();
|
return this.screen.getFocusType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { CommandRunner } from "./commandrunner";
|
import { CommandRunner } from "./commandrunner";
|
||||||
|
|
||||||
const GlobalModel = Model.getInstance();
|
const GlobalModel: Model = Model.getInstance();
|
||||||
const GlobalCommandRunner = CommandRunner.getInstance();
|
const GlobalCommandRunner: CommandRunner = CommandRunner.getInstance();
|
||||||
export { GlobalModel, GlobalCommandRunner };
|
export { GlobalModel, GlobalCommandRunner };
|
||||||
|
@ -3,20 +3,11 @@
|
|||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { isBlank } from "../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import {
|
import { termWidthFromCols, termHeightFromRows } from "@/util/textmeasure";
|
||||||
LineType,
|
|
||||||
HistoryItem,
|
|
||||||
CmdDataType,
|
|
||||||
HistoryViewDataType,
|
|
||||||
HistorySearchParams,
|
|
||||||
CommandRtnType,
|
|
||||||
} from "../types/types";
|
|
||||||
import { termWidthFromCols, termHeightFromRows } from "../util/textmeasure";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import * as appconst from "../app/appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "../util/keyutil";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||||
import { OV, OArr, OMap } from "../types/types";
|
|
||||||
import { GlobalCommandRunner } from "./global";
|
import { GlobalCommandRunner } from "./global";
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { Cmd } from "./cmd";
|
import { Cmd } from "./cmd";
|
||||||
|
@ -4,19 +4,8 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { boundMethod } from "autobind-decorator";
|
import { boundMethod } from "autobind-decorator";
|
||||||
import { isBlank } from "../util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import {
|
import * as appconst from "@/app/appconst";
|
||||||
HistoryItem,
|
|
||||||
RemotePtrType,
|
|
||||||
InfoType,
|
|
||||||
HistoryInfoType,
|
|
||||||
HistoryQueryOpts,
|
|
||||||
HistoryTypeStrs,
|
|
||||||
OpenAICmdInfoChatMessageType,
|
|
||||||
} from "../types/types";
|
|
||||||
import { StrWithPos } from "../types/types";
|
|
||||||
import * as appconst from "../app/appconst";
|
|
||||||
import { OV } from "../types/types";
|
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { GlobalCommandRunner } from "./global";
|
import { GlobalCommandRunner } from "./global";
|
||||||
|
|
||||||
@ -207,7 +196,6 @@ class InputModel {
|
|||||||
this.historyQueryOpts.set(opts);
|
this.historyQueryOpts.set(opts);
|
||||||
let bestIndex = this.findBestNewIndex(oldItem);
|
let bestIndex = this.findBestNewIndex(oldItem);
|
||||||
setTimeout(() => this.setHistoryIndex(bestIndex, true), 10);
|
setTimeout(() => this.setHistoryIndex(bestIndex, true), 10);
|
||||||
return;
|
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,13 +612,17 @@ class InputModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openAIAssistantChat(): void {
|
openAIAssistantChat(): void {
|
||||||
|
mobx.action(() => {
|
||||||
this.aIChatShow.set(true);
|
this.aIChatShow.set(true);
|
||||||
this.setAIChatFocus();
|
this.setAIChatFocus();
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAIAssistantChat(): void {
|
closeAIAssistantChat(): void {
|
||||||
|
mobx.action(() => {
|
||||||
this.aIChatShow.set(false);
|
this.aIChatShow.set(false);
|
||||||
this.giveFocus();
|
this.giveFocus();
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearAIAssistantChat(): void {
|
clearAIAssistantChat(): void {
|
||||||
@ -721,14 +713,6 @@ class InputModel {
|
|||||||
setCurLine(val: string): void {
|
setCurLine(val: string): void {
|
||||||
let hidx = this.historyIndex.get();
|
let hidx = this.historyIndex.get();
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
// if (val == "\" ") {
|
|
||||||
// this.setInputMode("comment");
|
|
||||||
// val = "";
|
|
||||||
// }
|
|
||||||
// if (val == "//") {
|
|
||||||
// this.setInputMode("global");
|
|
||||||
// val = "";
|
|
||||||
// }
|
|
||||||
if (this.modHistory.length <= hidx) {
|
if (this.modHistory.length <= hidx) {
|
||||||
this.modHistory.length = hidx + 1;
|
this.modHistory.length = hidx + 1;
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { MagicLayout } from "../app/magiclayout";
|
import { MagicLayout } from "@/app/magiclayout";
|
||||||
import { OV } from "../types/types";
|
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
|
|
||||||
class MainSidebarModel {
|
class MainSidebarModel {
|
||||||
globalModel: Model = null;
|
globalModel: Model = null;
|
||||||
tempWidth: OV<number> = mobx.observable.box(null, {
|
tempWidth: OV<number> = mobx.observable.box(null, {
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { ModalStoreEntry } from "../types/types";
|
import { modalsRegistry } from "@/modals/registry";
|
||||||
import { modalsRegistry } from "../app/common/modals/registry";
|
|
||||||
import { OArr } from "../types/types";
|
|
||||||
|
|
||||||
class ModalsModel {
|
class ModalsModel {
|
||||||
store: OArr<ModalStoreEntry> = mobx.observable.array([], { name: "ModalsModel-store", deep: false });
|
store: OArr<ModalStoreEntry> = mobx.observable.array([], { name: "ModalsModel-store", deep: false });
|
||||||
|
@ -12,43 +12,12 @@ import {
|
|||||||
genMergeSimpleData,
|
genMergeSimpleData,
|
||||||
isModKeyPress,
|
isModKeyPress,
|
||||||
isBlank,
|
isBlank,
|
||||||
} from "../util/util";
|
} from "@/util/util";
|
||||||
import {
|
|
||||||
SessionDataType,
|
|
||||||
LineType,
|
|
||||||
RemoteType,
|
|
||||||
RemoteInstanceType,
|
|
||||||
CmdDataType,
|
|
||||||
FeCmdPacketType,
|
|
||||||
ScreenDataType,
|
|
||||||
PtyDataUpdateType,
|
|
||||||
ModelUpdateType,
|
|
||||||
UpdateMessage,
|
|
||||||
InfoType,
|
|
||||||
StrWithPos,
|
|
||||||
UIContextType,
|
|
||||||
ContextMenuOpts,
|
|
||||||
RendererContext,
|
|
||||||
ClientDataType,
|
|
||||||
AlertMessageType,
|
|
||||||
UserInputRequest,
|
|
||||||
UserInputResponsePacket,
|
|
||||||
ScreenLinesType,
|
|
||||||
RemoteViewType,
|
|
||||||
CommandRtnType,
|
|
||||||
LineFocusType,
|
|
||||||
CmdInputTextPacketType,
|
|
||||||
FileInfoType,
|
|
||||||
ExtFile,
|
|
||||||
HistorySearchParams,
|
|
||||||
LineStateType,
|
|
||||||
} from "../types/types";
|
|
||||||
import { WSControl } from "./ws";
|
import { WSControl } from "./ws";
|
||||||
import { cmdStatusIsRunning } from "../app/line/lineutil";
|
import { cmdStatusIsRunning } from "@/app/line/lineutil";
|
||||||
import * as appconst from "../app/appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
import { remotePtrToString, cmdPacketString } from "../util/modelutil";
|
import { remotePtrToString, cmdPacketString } from "@/util/modelutil";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, setKeyUtilPlatform } from "../util/keyutil";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, setKeyUtilPlatform } from "@/util/keyutil";
|
||||||
import { OV, OArr, OMap, CV } from "../types/types";
|
|
||||||
import { Session } from "./session";
|
import { Session } from "./session";
|
||||||
import { ScreenLines } from "./screenlines";
|
import { ScreenLines } from "./screenlines";
|
||||||
import { InputModel } from "./input";
|
import { InputModel } from "./input";
|
||||||
@ -187,7 +156,7 @@ class Model {
|
|||||||
this.isDev = getApi().getIsDev();
|
this.isDev = getApi().getIsDev();
|
||||||
this.authKey = getApi().getAuthKey();
|
this.authKey = getApi().getAuthKey();
|
||||||
this.ws = new WSControl(this.getBaseWsHostPort(), this.clientId, this.authKey, (message: any) => {
|
this.ws = new WSControl(this.getBaseWsHostPort(), this.clientId, this.authKey, (message: any) => {
|
||||||
let interactive = message?.interactive ?? false;
|
const interactive = message?.interactive ?? false;
|
||||||
this.runUpdate(message, interactive);
|
this.runUpdate(message, interactive);
|
||||||
});
|
});
|
||||||
this.ws.reconnect();
|
this.ws.reconnect();
|
||||||
@ -200,17 +169,17 @@ class Model {
|
|||||||
this.remotesModel = new RemotesModel(this);
|
this.remotesModel = new RemotesModel(this);
|
||||||
this.modalsModel = new ModalsModel();
|
this.modalsModel = new ModalsModel();
|
||||||
this.mainSidebarModel = new MainSidebarModel(this);
|
this.mainSidebarModel = new MainSidebarModel(this);
|
||||||
let isWaveSrvRunning = getApi().getWaveSrvStatus();
|
const isWaveSrvRunning = getApi().getWaveSrvStatus();
|
||||||
this.waveSrvRunning = mobx.observable.box(isWaveSrvRunning, {
|
this.waveSrvRunning = mobx.observable.box(isWaveSrvRunning, {
|
||||||
name: "model-wavesrv-running",
|
name: "model-wavesrv-running",
|
||||||
});
|
});
|
||||||
this.platform = this.getPlatform();
|
this.platform = this.getPlatform();
|
||||||
this.termFontSize = mobx.computed(() => {
|
this.termFontSize = mobx.computed(() => {
|
||||||
let cdata = this.clientData.get();
|
const cdata = this.clientData.get();
|
||||||
if (cdata == null || cdata.feopts == null || cdata.feopts.termfontsize == null) {
|
if (cdata?.feopts?.termfontsize == null) {
|
||||||
return appconst.DefaultTermFontSize;
|
return appconst.DefaultTermFontSize;
|
||||||
}
|
}
|
||||||
let fontSize = Math.ceil(cdata.feopts.termfontsize);
|
const fontSize = Math.ceil(cdata.feopts.termfontsize);
|
||||||
if (fontSize < appconst.MinFontSize) {
|
if (fontSize < appconst.MinFontSize) {
|
||||||
return appconst.MinFontSize;
|
return appconst.MinFontSize;
|
||||||
}
|
}
|
||||||
@ -239,7 +208,7 @@ class Model {
|
|||||||
setTimeout(() => this.getClientDataLoop(1), 10);
|
setTimeout(() => this.getClientDataLoop(1), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getInstance() {
|
static getInstance(): Model {
|
||||||
if (!(window as any).GlobalModel) {
|
if (!(window as any).GlobalModel) {
|
||||||
(window as any).GlobalModel = new Model();
|
(window as any).GlobalModel = new Model();
|
||||||
}
|
}
|
||||||
@ -265,11 +234,11 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
needsTos(): boolean {
|
needsTos(): boolean {
|
||||||
let cdata = this.clientData.get();
|
const cdata = this.clientData.get();
|
||||||
if (cdata == null) {
|
if (cdata == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cdata.clientopts == null || !cdata.clientopts.acceptedtos;
|
return !cdata.clientopts?.acceptedtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshClient(): void {
|
refreshClient(): void {
|
||||||
@ -288,7 +257,7 @@ class Model {
|
|||||||
|
|
||||||
refocus() {
|
refocus() {
|
||||||
// givefocus() give back focus to cmd or input
|
// givefocus() give back focus to cmd or input
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
if (screen == null) {
|
if (screen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -296,8 +265,8 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWebSharedScreens(): Screen[] {
|
getWebSharedScreens(): Screen[] {
|
||||||
let rtn: Screen[] = [];
|
const rtn: Screen[] = [];
|
||||||
for (let screen of this.screenMap.values()) {
|
for (const screen of this.screenMap.values()) {
|
||||||
if (screen.shareMode.get() == "web") {
|
if (screen.shareMode.get() == "web") {
|
||||||
rtn.push(screen);
|
rtn.push(screen);
|
||||||
}
|
}
|
||||||
@ -309,7 +278,7 @@ class Model {
|
|||||||
if (this.clientData.get() == null) {
|
if (this.clientData.get() == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let cdata = this.clientData.get();
|
const cdata = this.clientData.get();
|
||||||
if (cdata.cmdstoretype == "session") {
|
if (cdata.cmdstoretype == "session") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -318,8 +287,8 @@ class Model {
|
|||||||
|
|
||||||
showAlert(alertMessage: AlertMessageType): Promise<boolean> {
|
showAlert(alertMessage: AlertMessageType): Promise<boolean> {
|
||||||
if (alertMessage.confirmflag != null) {
|
if (alertMessage.confirmflag != null) {
|
||||||
let cdata = this.clientData.get();
|
const cdata = this.clientData.get();
|
||||||
let noConfirm = cdata.clientopts?.confirmflags?.[alertMessage.confirmflag];
|
const noConfirm = cdata.clientopts?.confirmflags?.[alertMessage.confirmflag];
|
||||||
if (noConfirm) {
|
if (noConfirm) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
@ -328,7 +297,7 @@ class Model {
|
|||||||
this.alertMessage.set(alertMessage);
|
this.alertMessage.set(alertMessage);
|
||||||
this.modalsModel.pushModal(appconst.ALERT);
|
this.modalsModel.pushModal(appconst.ALERT);
|
||||||
})();
|
})();
|
||||||
let prtn = new Promise<boolean>((resolve, reject) => {
|
const prtn = new Promise<boolean>((resolve, reject) => {
|
||||||
this.alertPromiseResolver = resolve;
|
this.alertPromiseResolver = resolve;
|
||||||
});
|
});
|
||||||
return prtn;
|
return prtn;
|
||||||
@ -405,7 +374,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
docKeyDownHandler(e: KeyboardEvent) {
|
docKeyDownHandler(e: KeyboardEvent) {
|
||||||
let waveEvent = adaptFromReactOrNativeKeyEvent(e);
|
const waveEvent = adaptFromReactOrNativeKeyEvent(e);
|
||||||
if (isModKeyPress(e)) {
|
if (isModKeyPress(e)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -447,7 +416,7 @@ class Model {
|
|||||||
if (this.clearModals()) {
|
if (this.clearModals()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let inputModel = this.inputModel;
|
const inputModel = this.inputModel;
|
||||||
inputModel.toggleInfoMsg();
|
inputModel.toggleInfoMsg();
|
||||||
if (inputModel.inputMode.get() != null) {
|
if (inputModel.inputMode.get() != null) {
|
||||||
inputModel.resetInputMode();
|
inputModel.resetInputMode();
|
||||||
@ -460,9 +429,9 @@ class Model {
|
|||||||
}
|
}
|
||||||
if (this.activeMainView.get() == "session" && checkKeyPressed(waveEvent, "Cmd:Ctrl:s")) {
|
if (this.activeMainView.get() == "session" && checkKeyPressed(waveEvent, "Cmd:Ctrl:s")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
if (activeScreen != null) {
|
if (activeScreen != null) {
|
||||||
let isSidebarOpen = activeScreen.isSidebarOpen();
|
const isSidebarOpen = activeScreen.isSidebarOpen();
|
||||||
if (isSidebarOpen) {
|
if (isSidebarOpen) {
|
||||||
GlobalCommandRunner.screenSidebarClose();
|
GlobalCommandRunner.screenSidebarClose();
|
||||||
} else {
|
} else {
|
||||||
@ -471,7 +440,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (checkKeyPressed(waveEvent, "Cmd:d")) {
|
if (checkKeyPressed(waveEvent, "Cmd:d")) {
|
||||||
let ranDelete = this.deleteActiveLine();
|
const ranDelete = this.deleteActiveLine();
|
||||||
if (ranDelete) {
|
if (ranDelete) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
@ -479,22 +448,22 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteActiveLine(): boolean {
|
deleteActiveLine(): boolean {
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
if (activeScreen == null || activeScreen.getFocusType() != "cmd") {
|
if (activeScreen == null || activeScreen.getFocusType() != "cmd") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let selectedLine = activeScreen.selectedLine.get();
|
const selectedLine = activeScreen.selectedLine.get();
|
||||||
if (selectedLine == null || selectedLine <= 0) {
|
if (selectedLine == null || selectedLine <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let line = activeScreen.getLineByNum(selectedLine);
|
const line = activeScreen.getLineByNum(selectedLine);
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let cmd = activeScreen.getCmd(line);
|
const cmd = activeScreen.getCmd(line);
|
||||||
if (cmd != null) {
|
if (cmd != null) {
|
||||||
if (cmd.isRunning()) {
|
if (cmd.isRunning()) {
|
||||||
let info: InfoType = { infomsg: "Cannot delete a running command" };
|
const info: InfoType = { infomsg: "Cannot delete a running command" };
|
||||||
this.inputModel.flashInfoMsg(info, 2000);
|
this.inputModel.flashInfoMsg(info, 2000);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -507,11 +476,11 @@ class Model {
|
|||||||
if (this.activeMainView.get() != "session") {
|
if (this.activeMainView.get() != "session") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
if (activeScreen == null) {
|
if (activeScreen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rtnp = this.showAlert({
|
const rtnp = this.showAlert({
|
||||||
message: "Are you sure you want to delete this screen?",
|
message: "Are you sure you want to delete this screen?",
|
||||||
confirm: true,
|
confirm: true,
|
||||||
});
|
});
|
||||||
@ -527,7 +496,7 @@ class Model {
|
|||||||
if (this.activeMainView.get() != "session") {
|
if (this.activeMainView.get() != "session") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
if (activeScreen == null) {
|
if (activeScreen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -536,7 +505,7 @@ class Model {
|
|||||||
GlobalCommandRunner.lineRestart("E", true);
|
GlobalCommandRunner.lineRestart("E", true);
|
||||||
} else {
|
} else {
|
||||||
// restart selected line
|
// restart selected line
|
||||||
let selectedLine = activeScreen.selectedLine.get();
|
const selectedLine = activeScreen.selectedLine.get();
|
||||||
if (selectedLine == null || selectedLine == 0) {
|
if (selectedLine == null || selectedLine == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -585,7 +554,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCurRemoteInstance(): RemoteInstanceType {
|
getCurRemoteInstance(): RemoteInstanceType {
|
||||||
let screen = this.getActiveScreen();
|
const screen = this.getActiveScreen();
|
||||||
if (screen == null) {
|
if (screen == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -603,12 +572,12 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getContentHeight(context: RendererContext): number {
|
getContentHeight(context: RendererContext): number {
|
||||||
let key = context.screenId + "/" + context.lineId;
|
const key = context.screenId + "/" + context.lineId;
|
||||||
return this.termUsedRowsCache[key];
|
return this.termUsedRowsCache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentHeight(context: RendererContext, height: number): void {
|
setContentHeight(context: RendererContext, height: number): void {
|
||||||
let key = context.screenId + "/" + context.lineId;
|
const key = context.screenId + "/" + context.lineId;
|
||||||
this.termUsedRowsCache[key] = height;
|
this.termUsedRowsCache[key] = height;
|
||||||
GlobalCommandRunner.setTermUsedRows(context, height);
|
GlobalCommandRunner.setTermUsedRows(context, height);
|
||||||
}
|
}
|
||||||
@ -622,7 +591,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUIContext(): UIContextType {
|
getUIContext(): UIContextType {
|
||||||
let rtn: UIContextType = {
|
const rtn: UIContextType = {
|
||||||
sessionid: null,
|
sessionid: null,
|
||||||
screenid: null,
|
screenid: null,
|
||||||
remote: null,
|
remote: null,
|
||||||
@ -630,10 +599,10 @@ class Model {
|
|||||||
linenum: null,
|
linenum: null,
|
||||||
build: appconst.VERSION + " " + appconst.BUILD,
|
build: appconst.VERSION + " " + appconst.BUILD,
|
||||||
};
|
};
|
||||||
let session = this.getActiveSession();
|
const session = this.getActiveSession();
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
rtn.sessionid = session.sessionId;
|
rtn.sessionid = session.sessionId;
|
||||||
let screen = session.getActiveScreen();
|
const screen = session.getActiveScreen();
|
||||||
if (screen != null) {
|
if (screen != null) {
|
||||||
rtn.screenid = screen.screenId;
|
rtn.screenid = screen.screenId;
|
||||||
rtn.remote = screen.curRemote.get();
|
rtn.remote = screen.curRemote.get();
|
||||||
@ -653,7 +622,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onLCmd(e: any, mods: KeyModsType) {
|
onLCmd(e: any, mods: KeyModsType) {
|
||||||
let screen = this.getActiveScreen();
|
const screen = this.getActiveScreen();
|
||||||
if (screen != null) {
|
if (screen != null) {
|
||||||
GlobalCommandRunner.screenSetFocus("cmd");
|
GlobalCommandRunner.screenSetFocus("cmd");
|
||||||
}
|
}
|
||||||
@ -671,11 +640,11 @@ class Model {
|
|||||||
if (this.inputModel.hasFocus()) {
|
if (this.inputModel.hasFocus()) {
|
||||||
return { cmdInputFocus: true };
|
return { cmdInputFocus: true };
|
||||||
}
|
}
|
||||||
let lineElem: any = document.activeElement.closest(".line[data-lineid]");
|
const lineElem: any = document.activeElement.closest(".line[data-lineid]");
|
||||||
if (lineElem == null) {
|
if (lineElem == null) {
|
||||||
return { cmdInputFocus: false };
|
return { cmdInputFocus: false };
|
||||||
}
|
}
|
||||||
let lineNum = parseInt(lineElem.dataset.linenum);
|
const lineNum = parseInt(lineElem.dataset.linenum);
|
||||||
return {
|
return {
|
||||||
cmdInputFocus: false,
|
cmdInputFocus: false,
|
||||||
lineid: lineElem.dataset.lineid,
|
lineid: lineElem.dataset.lineid,
|
||||||
@ -685,17 +654,17 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmdStatusUpdate(screenId: string, lineId: string, origStatus: string, newStatus: string) {
|
cmdStatusUpdate(screenId: string, lineId: string, origStatus: string, newStatus: string) {
|
||||||
let wasRunning = cmdStatusIsRunning(origStatus);
|
const wasRunning = cmdStatusIsRunning(origStatus);
|
||||||
let isRunning = cmdStatusIsRunning(newStatus);
|
const isRunning = cmdStatusIsRunning(newStatus);
|
||||||
if (wasRunning && !isRunning) {
|
if (wasRunning && !isRunning) {
|
||||||
let ptr = this.getActiveLine(screenId, lineId);
|
const ptr = this.getActiveLine(screenId, lineId);
|
||||||
if (ptr != null) {
|
if (ptr != null) {
|
||||||
let screen = ptr.screen;
|
const screen = ptr.screen;
|
||||||
let renderer = screen.getRenderer(lineId);
|
const renderer = screen.getRenderer(lineId);
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
renderer.setIsDone();
|
renderer.setIsDone();
|
||||||
}
|
}
|
||||||
let term = screen.getTermWrap(lineId);
|
const term = screen.getTermWrap(lineId);
|
||||||
if (term != null) {
|
if (term != null) {
|
||||||
term.cmdDone();
|
term.cmdDone();
|
||||||
}
|
}
|
||||||
@ -747,21 +716,25 @@ class Model {
|
|||||||
|
|
||||||
runUpdate(genUpdate: UpdateMessage, interactive: boolean) {
|
runUpdate(genUpdate: UpdateMessage, interactive: boolean) {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let oldContext = this.getUIContext();
|
const oldContext = this.getUIContext();
|
||||||
try {
|
try {
|
||||||
this.runUpdate_internal(genUpdate, oldContext, interactive);
|
this.runUpdate_internal(genUpdate, oldContext, interactive);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("error running update", e, genUpdate);
|
console.warn("error running update", e, genUpdate);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
let newContext = this.getUIContext();
|
const newContext = this.getUIContext();
|
||||||
if (oldContext.sessionid != newContext.sessionid || oldContext.screenid != newContext.screenid) {
|
if (oldContext.sessionid != newContext.sessionid || oldContext.screenid != newContext.screenid) {
|
||||||
this.inputModel.resetInput();
|
this.inputModel.resetInput();
|
||||||
if ("cmdline" in genUpdate) {
|
if (!("ptydata64" in genUpdate)) {
|
||||||
|
const reversedGenUpdate = genUpdate.slice().reverse();
|
||||||
|
const lastCmdLine = reversedGenUpdate.find((update) => "cmdline" in update);
|
||||||
|
if (lastCmdLine) {
|
||||||
// TODO a bit of a hack since this update gets applied in runUpdate_internal.
|
// TODO a bit of a hack since this update gets applied in runUpdate_internal.
|
||||||
// we then undo that update with the resetInput, and then redo it with the line below
|
// we then undo that update with the resetInput, and then redo it with the line below
|
||||||
// not sure how else to handle this for now though
|
// not sure how else to handle this for now though
|
||||||
this.inputModel.updateCmdLine(genUpdate.cmdline);
|
this.inputModel.updateCmdLine(lastCmdLine.cmdline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (remotePtrToString(oldContext.remote) != remotePtrToString(newContext.remote)) {
|
} else if (remotePtrToString(oldContext.remote) != remotePtrToString(newContext.remote)) {
|
||||||
this.inputModel.resetHistory();
|
this.inputModel.resetHistory();
|
||||||
@ -769,27 +742,10 @@ class Model {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
runUpdate_internal(genUpdate: UpdateMessage, uiContext: UIContextType, interactive: boolean) {
|
updateScreens(screens: ScreenDataType[]): void {
|
||||||
if ("ptydata64" in genUpdate) {
|
const mods = genMergeDataMap(
|
||||||
let ptyMsg: PtyDataUpdateType = genUpdate;
|
|
||||||
if (isBlank(ptyMsg.remoteid)) {
|
|
||||||
// regular update
|
|
||||||
this.updatePtyData(ptyMsg);
|
|
||||||
} else {
|
|
||||||
// remote update
|
|
||||||
let ptyData = base64ToArray(ptyMsg.ptydata64);
|
|
||||||
this.remotesModel.receiveData(ptyMsg.remoteid, ptyMsg.ptypos, ptyData);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let update: ModelUpdateType = genUpdate;
|
|
||||||
if ("screens" in update) {
|
|
||||||
if (update.connect) {
|
|
||||||
this.screenMap.clear();
|
|
||||||
}
|
|
||||||
let mods = genMergeDataMap(
|
|
||||||
this.screenMap,
|
this.screenMap,
|
||||||
update.screens,
|
screens,
|
||||||
(s: Screen) => s.screenId,
|
(s: Screen) => s.screenId,
|
||||||
(sdata: ScreenDataType) => sdata.screenid,
|
(sdata: ScreenDataType) => sdata.screenid,
|
||||||
(sdata: ScreenDataType) => new Screen(sdata, this)
|
(sdata: ScreenDataType) => new Screen(sdata, this)
|
||||||
@ -798,116 +754,177 @@ class Model {
|
|||||||
this.removeScreenLinesByScreenId(screenId);
|
this.removeScreenLinesByScreenId(screenId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("sessions" in update || "activesessionid" in update) {
|
|
||||||
if (update.connect) {
|
updateSessions(sessions: SessionDataType[]): void {
|
||||||
this.sessionList.clear();
|
|
||||||
}
|
|
||||||
let [oldActiveSessionId, oldActiveScreenId] = this.getActiveIds();
|
|
||||||
genMergeData(
|
genMergeData(
|
||||||
this.sessionList,
|
this.sessionList,
|
||||||
update.sessions,
|
sessions,
|
||||||
(s: Session) => s.sessionId,
|
(s: Session) => s.sessionId,
|
||||||
(sdata: SessionDataType) => sdata.sessionid,
|
(sdata: SessionDataType) => sdata.sessionid,
|
||||||
(sdata: SessionDataType) => new Session(sdata, this),
|
(sdata: SessionDataType) => new Session(sdata, this),
|
||||||
(s: Session) => s.sessionIdx.get()
|
(s: Session) => s.sessionIdx.get()
|
||||||
);
|
);
|
||||||
if ("activesessionid" in update) {
|
}
|
||||||
let newSessionId = update.activesessionid;
|
|
||||||
|
updateActiveSession(sessionId: string): void {
|
||||||
|
const [oldActiveSessionId, oldActiveScreenId] = this.getActiveIds();
|
||||||
|
|
||||||
|
if (sessionId != null) {
|
||||||
|
const newSessionId = sessionId;
|
||||||
if (this.activeSessionId.get() != newSessionId) {
|
if (this.activeSessionId.get() != newSessionId) {
|
||||||
this.activeSessionId.set(newSessionId);
|
this.activeSessionId.set(newSessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let [newActiveSessionId, newActiveScreenId] = this.getActiveIds();
|
const [newActiveSessionId, newActiveScreenId] = this.getActiveIds();
|
||||||
if (oldActiveSessionId != newActiveSessionId || oldActiveScreenId != newActiveScreenId) {
|
if (oldActiveSessionId != newActiveSessionId || oldActiveScreenId != newActiveScreenId) {
|
||||||
this.activeMainView.set("session");
|
this.activeMainView.set("session");
|
||||||
this.deactivateScreenLines();
|
this.deactivateScreenLines();
|
||||||
this.ws.watchScreen(newActiveSessionId, newActiveScreenId);
|
this.ws.watchScreen(newActiveSessionId, newActiveScreenId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("line" in update) {
|
|
||||||
this.addLineCmd(update.line, update.cmd, interactive);
|
updateScreenNumRunningCommands(numRunningCommandUpdates: ScreenNumRunningCommandsUpdateType[]) {
|
||||||
} else if ("cmd" in update) {
|
for (const update of numRunningCommandUpdates) {
|
||||||
this.updateCmd(update.cmd);
|
this.getScreenById_single(update.screenid)?.setNumRunningCmds(update.num);
|
||||||
}
|
|
||||||
if ("lines" in update) {
|
|
||||||
for (const line of update.lines) {
|
|
||||||
this.addLineCmd(line, null, interactive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("screenlines" in update) {
|
|
||||||
this.updateScreenLines(update.screenlines, false);
|
updateScreenStatusIndicators(screenStatusIndicators: ScreenStatusIndicatorUpdateType[]) {
|
||||||
}
|
for (const update of screenStatusIndicators) {
|
||||||
if ("remotes" in update) {
|
this.getScreenById_single(update.screenid)?.setStatusIndicator(update.status);
|
||||||
if (update.connect) {
|
|
||||||
this.remotes.clear();
|
|
||||||
}
|
|
||||||
this.updateRemotes(update.remotes);
|
|
||||||
// This code's purpose is to show view remote connection modal when a new connection is added
|
|
||||||
if (update.remotes?.length && this.remotesModel.recentConnAddedState.get()) {
|
|
||||||
this.remotesModel.openReadModal(update.remotes[0].remoteid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("mainview" in update) {
|
|
||||||
if (update.mainview == "plugins") {
|
runUpdate_internal(genUpdate: UpdateMessage, uiContext: UIContextType, interactive: boolean) {
|
||||||
this.pluginsModel.showPluginsView();
|
if ("ptydata64" in genUpdate) {
|
||||||
} else if (update.mainview == "bookmarks") {
|
const ptyMsg: PtyDataUpdateType = genUpdate;
|
||||||
this.bookmarksModel.showBookmarksView(update.bookmarks, update.selectedbookmark);
|
if (isBlank(ptyMsg.remoteid)) {
|
||||||
} else if (update.mainview == "session") {
|
// regular update
|
||||||
this.activeMainView.set("session");
|
this.updatePtyData(ptyMsg);
|
||||||
} else if (update.mainview == "history") {
|
|
||||||
this.historyViewModel.showHistoryView(update.historyviewdata);
|
|
||||||
} else {
|
} else {
|
||||||
console.log("invalid mainview in update:", update.mainview);
|
// remote update
|
||||||
|
const ptyData = base64ToArray(ptyMsg.ptydata64);
|
||||||
|
this.remotesModel.receiveData(ptyMsg.remoteid, ptyMsg.ptypos, ptyData);
|
||||||
}
|
}
|
||||||
} else if ("bookmarks" in update) {
|
return;
|
||||||
this.bookmarksModel.mergeBookmarks(update.bookmarks);
|
|
||||||
}
|
}
|
||||||
if ("clientdata" in update) {
|
let showedRemotesModal = false;
|
||||||
|
genUpdate.forEach((update) => {
|
||||||
|
if (update.connect != null) {
|
||||||
|
if (update.connect.screens != null) {
|
||||||
|
this.screenMap.clear();
|
||||||
|
this.updateScreens(update.connect.screens);
|
||||||
|
}
|
||||||
|
if (update.connect.sessions != null) {
|
||||||
|
this.sessionList.clear();
|
||||||
|
this.updateSessions(update.connect.sessions);
|
||||||
|
}
|
||||||
|
if (update.connect.remotes != null) {
|
||||||
|
this.remotes.clear();
|
||||||
|
this.updateRemotes(update.connect.remotes);
|
||||||
|
}
|
||||||
|
if (update.connect.activesessionid != null) {
|
||||||
|
this.updateActiveSession(update.connect.activesessionid);
|
||||||
|
}
|
||||||
|
if (update.connect.screennumrunningcommands != null) {
|
||||||
|
this.updateScreenNumRunningCommands(update.connect.screennumrunningcommands);
|
||||||
|
}
|
||||||
|
if (update.connect.screenstatusindicators != null) {
|
||||||
|
this.updateScreenStatusIndicators(update.connect.screenstatusindicators);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sessionListLoaded.set(true);
|
||||||
|
this.remotesLoaded.set(true);
|
||||||
|
} else if (update.screen != null) {
|
||||||
|
this.updateScreens([update.screen]);
|
||||||
|
} else if (update.session != null) {
|
||||||
|
this.updateSessions([update.session]);
|
||||||
|
} else if (update.activesessionid != null) {
|
||||||
|
this.updateActiveSession(update.activesessionid);
|
||||||
|
} else if (update.line != null) {
|
||||||
|
this.addLineCmd(update.line.line, update.line.cmd, interactive);
|
||||||
|
} else if (update.cmd != null) {
|
||||||
|
this.updateCmd(update.cmd);
|
||||||
|
} else if (update.screenlines != null) {
|
||||||
|
this.updateScreenLines(update.screenlines, false);
|
||||||
|
} else if (update.remote != null) {
|
||||||
|
this.updateRemotes([update.remote]);
|
||||||
|
// This code's purpose is to show view remote connection modal when a new connection is added
|
||||||
|
if (!showedRemotesModal && this.remotesModel.recentConnAddedState.get()) {
|
||||||
|
showedRemotesModal = true;
|
||||||
|
this.remotesModel.openReadModal(update.remote.remoteid);
|
||||||
|
}
|
||||||
|
} else if (update.mainview != null) {
|
||||||
|
switch (update.mainview.mainview) {
|
||||||
|
case "session":
|
||||||
|
this.activeMainView.set("session");
|
||||||
|
break;
|
||||||
|
case "history":
|
||||||
|
if (update.mainview.historyview != null) {
|
||||||
|
this.historyViewModel.showHistoryView(update.mainview.historyview);
|
||||||
|
} else {
|
||||||
|
console.warn("invalid historyview in update:", update.mainview);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "bookmarks":
|
||||||
|
if (update.mainview.bookmarksview != null) {
|
||||||
|
this.bookmarksModel.showBookmarksView(
|
||||||
|
update.mainview.bookmarksview?.bookmarks ?? [],
|
||||||
|
update.mainview.bookmarksview?.selectedbookmark
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn("invalid bookmarksview in update:", update.mainview);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "plugins":
|
||||||
|
this.pluginsModel.showPluginsView();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn("invalid mainview in update:", update.mainview);
|
||||||
|
}
|
||||||
|
} else if (update.bookmarks != null) {
|
||||||
|
if (update.bookmarks.bookmarks != null) {
|
||||||
|
this.bookmarksModel.mergeBookmarks(update.bookmarks.bookmarks);
|
||||||
|
}
|
||||||
|
} else if (update.clientdata != null) {
|
||||||
this.clientData.set(update.clientdata);
|
this.clientData.set(update.clientdata);
|
||||||
}
|
} else if (update.cmdline != null) {
|
||||||
if (interactive && "info" in update) {
|
this.inputModel.updateCmdLine(update.cmdline);
|
||||||
let info: InfoType = update.info;
|
} else if (update.openaicmdinfochat != null) {
|
||||||
|
this.inputModel.setOpenAICmdInfoChat(update.openaicmdinfochat);
|
||||||
|
} else if (update.screenstatusindicator != null) {
|
||||||
|
this.updateScreenStatusIndicators([update.screenstatusindicator]);
|
||||||
|
} else if (update.screennumrunningcommands != null) {
|
||||||
|
this.updateScreenNumRunningCommands([update.screennumrunningcommands]);
|
||||||
|
} else if (update.userinputrequest != null) {
|
||||||
|
let userInputRequest: UserInputRequest = update.userinputrequest;
|
||||||
|
this.modalsModel.pushModal(appconst.USER_INPUT, userInputRequest);
|
||||||
|
} else if (interactive) {
|
||||||
|
if (update.info != null) {
|
||||||
|
const info: InfoType = update.info;
|
||||||
this.inputModel.flashInfoMsg(info, info.timeoutms);
|
this.inputModel.flashInfoMsg(info, info.timeoutms);
|
||||||
}
|
} else if (update.remoteview != null) {
|
||||||
if (interactive && "remoteview" in update) {
|
const rview: RemoteViewType = update.remoteview;
|
||||||
let rview: RemoteViewType = update.remoteview;
|
|
||||||
if (rview.remoteedit != null) {
|
if (rview.remoteedit != null) {
|
||||||
this.remotesModel.openEditModal({ ...rview.remoteedit });
|
this.remotesModel.openEditModal({ ...rview.remoteedit });
|
||||||
}
|
}
|
||||||
}
|
} else if (update.alertmessage != null) {
|
||||||
if (interactive && "alertmessage" in update) {
|
const alertMessage: AlertMessageType = update.alertmessage;
|
||||||
let alertMessage: AlertMessageType = update.alertmessage;
|
|
||||||
this.showAlert(alertMessage);
|
this.showAlert(alertMessage);
|
||||||
}
|
} else if (update.history != null) {
|
||||||
if ("cmdline" in update) {
|
if (
|
||||||
this.inputModel.updateCmdLine(update.cmdline);
|
uiContext.sessionid == update.history.sessionid &&
|
||||||
}
|
uiContext.screenid == update.history.screenid
|
||||||
if (interactive && "history" in update) {
|
) {
|
||||||
if (uiContext.sessionid == update.history.sessionid && uiContext.screenid == update.history.screenid) {
|
|
||||||
this.inputModel.setHistoryInfo(update.history);
|
this.inputModel.setHistoryInfo(update.history);
|
||||||
}
|
}
|
||||||
|
} else if (this.isDev) {
|
||||||
|
console.log("did not match update", update);
|
||||||
}
|
}
|
||||||
if ("connect" in update) {
|
} else if (this.isDev) {
|
||||||
this.sessionListLoaded.set(true);
|
console.log("did not match update", update);
|
||||||
this.remotesLoaded.set(true);
|
|
||||||
}
|
|
||||||
if ("openaicmdinfochat" in update) {
|
|
||||||
this.inputModel.setOpenAICmdInfoChat(update.openaicmdinfochat);
|
|
||||||
}
|
|
||||||
if ("screenstatusindicators" in update) {
|
|
||||||
for (const indicator of update.screenstatusindicators) {
|
|
||||||
this.getScreenById_single(indicator.screenid)?.setStatusIndicator(indicator.status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ("screennumrunningcommands" in update) {
|
|
||||||
for (const snc of update.screennumrunningcommands) {
|
|
||||||
this.getScreenById_single(snc.screenid)?.setNumRunningCmds(snc.num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ("userinputrequest" in update) {
|
|
||||||
let userInputRequest: UserInputRequest = update.userinputrequest;
|
|
||||||
this.modalsModel.pushModal(appconst.USER_INPUT, userInputRequest);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRemotes(remotes: RemoteType[]): void {
|
updateRemotes(remotes: RemoteType[]): void {
|
||||||
@ -919,7 +936,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSessionNames(): Record<string, string> {
|
getSessionNames(): Record<string, string> {
|
||||||
let rtn: Record<string, string> = {};
|
const rtn: Record<string, string> = {};
|
||||||
for (const session of this.sessionList) {
|
for (const session of this.sessionList) {
|
||||||
rtn[session.sessionId] = session.name.get();
|
rtn[session.sessionId] = session.name.get();
|
||||||
}
|
}
|
||||||
@ -927,8 +944,8 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getScreenNames(): Record<string, string> {
|
getScreenNames(): Record<string, string> {
|
||||||
let rtn: Record<string, string> = {};
|
const rtn: Record<string, string> = {};
|
||||||
for (let screen of this.screenMap.values()) {
|
for (const screen of this.screenMap.values()) {
|
||||||
rtn[screen.screenId] = screen.name.get();
|
rtn[screen.screenId] = screen.name.get();
|
||||||
}
|
}
|
||||||
return rtn;
|
return rtn;
|
||||||
@ -958,13 +975,13 @@ class Model {
|
|||||||
|
|
||||||
updateScreenLines(slines: ScreenLinesType, load: boolean) {
|
updateScreenLines(slines: ScreenLinesType, load: boolean) {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let existingWin = this.screenLines.get(slines.screenid);
|
const existingWin = this.screenLines.get(slines.screenid);
|
||||||
if (existingWin == null) {
|
if (existingWin == null) {
|
||||||
if (!load) {
|
if (!load) {
|
||||||
console.log("cannot update screen-lines that does not exist", slines.screenid);
|
console.log("cannot update screen-lines that does not exist", slines.screenid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let newWindow = new ScreenLines(slines.screenid);
|
const newWindow = new ScreenLines(slines.screenid);
|
||||||
this.screenLines.set(slines.screenid, newWindow);
|
this.screenLines.set(slines.screenid, newWindow);
|
||||||
newWindow.updateData(slines, load);
|
newWindow.updateData(slines, load);
|
||||||
} else {
|
} else {
|
||||||
@ -989,8 +1006,8 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSessionScreens(sessionId: string): Screen[] {
|
getSessionScreens(sessionId: string): Screen[] {
|
||||||
let rtn: Screen[] = [];
|
const rtn: Screen[] = [];
|
||||||
for (let screen of this.screenMap.values()) {
|
for (const screen of this.screenMap.values()) {
|
||||||
if (screen.sessionId == sessionId) {
|
if (screen.sessionId == sessionId) {
|
||||||
rtn.push(screen);
|
rtn.push(screen);
|
||||||
}
|
}
|
||||||
@ -999,7 +1016,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getScreenLinesForActiveScreen(): ScreenLines {
|
getScreenLinesForActiveScreen(): ScreenLines {
|
||||||
let screen = this.getActiveScreen();
|
const screen = this.getActiveScreen();
|
||||||
if (screen == null) {
|
if (screen == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1007,7 +1024,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getActiveScreen(): Screen {
|
getActiveScreen(): Screen {
|
||||||
let session = this.getActiveSession();
|
const session = this.getActiveSession();
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1018,11 +1035,11 @@ class Model {
|
|||||||
if (cmd == null || !cmd.restarted) {
|
if (cmd == null || !cmd.restarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let screen = this.screenMap.get(cmd.screenid);
|
const screen = this.screenMap.get(cmd.screenid);
|
||||||
if (screen == null) {
|
if (screen == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let termWrap = screen.getTermWrap(cmd.lineid);
|
const termWrap = screen.getTermWrap(cmd.lineid);
|
||||||
if (termWrap == null) {
|
if (termWrap == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1030,7 +1047,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addLineCmd(line: LineType, cmd: CmdDataType, interactive: boolean) {
|
addLineCmd(line: LineType, cmd: CmdDataType, interactive: boolean) {
|
||||||
let slines = this.getScreenLinesById(line.screenid);
|
const slines = this.getScreenLinesById(line.screenid);
|
||||||
if (slines == null) {
|
if (slines == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1039,7 +1056,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateCmd(cmd: CmdDataType) {
|
updateCmd(cmd: CmdDataType) {
|
||||||
let slines = this.screenLines.get(cmd.screenid);
|
const slines = this.screenLines.get(cmd.screenid);
|
||||||
if (slines != null) {
|
if (slines != null) {
|
||||||
slines.updateCmd(cmd);
|
slines.updateCmd(cmd);
|
||||||
}
|
}
|
||||||
@ -1050,12 +1067,12 @@ class Model {
|
|||||||
if (update == null || "ptydata64" in update) {
|
if (update == null || "ptydata64" in update) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return update.info != null || update.history != null;
|
return update.some((u) => u.info != null || u.history != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getClientDataLoop(loopNum: number): void {
|
getClientDataLoop(loopNum: number): void {
|
||||||
this.getClientData();
|
this.getClientData();
|
||||||
let clientStop = this.getHasClientStop();
|
const clientStop = this.getHasClientStop();
|
||||||
if (this.clientData.get() != null && !clientStop) {
|
if (this.clientData.get() != null && !clientStop) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1073,13 +1090,13 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getClientData(): void {
|
getClientData(): void {
|
||||||
let url = new URL(this.getBaseHostPort() + "/api/get-client-data");
|
const url = new URL(this.getBaseHostPort() + "/api/get-client-data");
|
||||||
let fetchHeaders = this.getFetchHeaders();
|
const fetchHeaders = this.getFetchHeaders();
|
||||||
fetch(url, { method: "post", body: null, headers: fetchHeaders })
|
fetch(url, { method: "post", body: null, headers: fetchHeaders })
|
||||||
.then((resp) => handleJsonFetchResponse(url, resp))
|
.then((resp) => handleJsonFetchResponse(url, resp))
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let clientData: ClientDataType = data.data;
|
const clientData: ClientDataType = data.data;
|
||||||
this.clientData.set(clientData);
|
this.clientData.set(clientData);
|
||||||
})();
|
})();
|
||||||
})
|
})
|
||||||
@ -1096,10 +1113,10 @@ class Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// adding cmdStr for debugging only (easily filter run-command calls in the network tab of debugger)
|
// adding cmdStr for debugging only (easily filter run-command calls in the network tab of debugger)
|
||||||
let cmdStr = cmdPk.metacmd + (cmdPk.metasubcmd ? ":" + cmdPk.metasubcmd : "");
|
const cmdStr = cmdPk.metacmd + (cmdPk.metasubcmd ? ":" + cmdPk.metasubcmd : "");
|
||||||
let url = new URL(this.getBaseHostPort() + "/api/run-command?cmd=" + cmdStr);
|
const url = new URL(this.getBaseHostPort() + "/api/run-command?cmd=" + cmdStr);
|
||||||
let fetchHeaders = this.getFetchHeaders();
|
const fetchHeaders = this.getFetchHeaders();
|
||||||
let prtn = fetch(url, {
|
const prtn = fetch(url, {
|
||||||
method: "post",
|
method: "post",
|
||||||
body: JSON.stringify(cmdPk),
|
body: JSON.stringify(cmdPk),
|
||||||
headers: fetchHeaders,
|
headers: fetchHeaders,
|
||||||
@ -1107,7 +1124,7 @@ class Model {
|
|||||||
.then((resp) => handleJsonFetchResponse(url, resp))
|
.then((resp) => handleJsonFetchResponse(url, resp))
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
mobx.action(() => {
|
mobx.action(() => {
|
||||||
let update = data.data;
|
const update = data.data;
|
||||||
if (update != null) {
|
if (update != null) {
|
||||||
this.runUpdate(update, interactive);
|
this.runUpdate(update, interactive);
|
||||||
}
|
}
|
||||||
@ -1135,7 +1152,7 @@ class Model {
|
|||||||
kwargs: Record<string, string>,
|
kwargs: Record<string, string>,
|
||||||
interactive: boolean
|
interactive: boolean
|
||||||
): Promise<CommandRtnType> {
|
): Promise<CommandRtnType> {
|
||||||
let pk: FeCmdPacketType = {
|
const pk: FeCmdPacketType = {
|
||||||
type: "fecmd",
|
type: "fecmd",
|
||||||
metacmd: metaCmd,
|
metacmd: metaCmd,
|
||||||
metasubcmd: metaSubCmd,
|
metasubcmd: metaSubCmd,
|
||||||
@ -1157,9 +1174,9 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitChatInfoCommand(chatMsg: string, curLineStr: string, clear: boolean): Promise<CommandRtnType> {
|
submitChatInfoCommand(chatMsg: string, curLineStr: string, clear: boolean): Promise<CommandRtnType> {
|
||||||
let commandStr = "/chat " + chatMsg;
|
const commandStr = "/chat " + chatMsg;
|
||||||
let interactive = false;
|
const interactive = false;
|
||||||
let pk: FeCmdPacketType = {
|
const pk: FeCmdPacketType = {
|
||||||
type: "fecmd",
|
type: "fecmd",
|
||||||
metacmd: "eval",
|
metacmd: "eval",
|
||||||
args: [commandStr],
|
args: [commandStr],
|
||||||
@ -1179,7 +1196,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitRawCommand(cmdStr: string, addToHistory: boolean, interactive: boolean): Promise<CommandRtnType> {
|
submitRawCommand(cmdStr: string, addToHistory: boolean, interactive: boolean): Promise<CommandRtnType> {
|
||||||
let pk: FeCmdPacketType = {
|
const pk: FeCmdPacketType = {
|
||||||
type: "fecmd",
|
type: "fecmd",
|
||||||
metacmd: "eval",
|
metacmd: "eval",
|
||||||
args: [cmdStr],
|
args: [cmdStr],
|
||||||
@ -1196,16 +1213,16 @@ class Model {
|
|||||||
|
|
||||||
// returns [sessionId, screenId]
|
// returns [sessionId, screenId]
|
||||||
getActiveIds(): [string, string] {
|
getActiveIds(): [string, string] {
|
||||||
let activeSession = this.getActiveSession();
|
const activeSession = this.getActiveSession();
|
||||||
let activeScreen = this.getActiveScreen();
|
const activeScreen = this.getActiveScreen();
|
||||||
return [activeSession?.sessionId, activeScreen?.screenId];
|
return [activeSession?.sessionId, activeScreen?.screenId];
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadScreenLinesAsync(newWin: ScreenLines) {
|
_loadScreenLinesAsync(newWin: ScreenLines) {
|
||||||
this.screenLines.set(newWin.screenId, newWin);
|
this.screenLines.set(newWin.screenId, newWin);
|
||||||
let usp = new URLSearchParams({ screenid: newWin.screenId });
|
const usp = new URLSearchParams({ screenid: newWin.screenId });
|
||||||
let url = new URL(this.getBaseHostPort() + "/api/get-screen-lines?" + usp.toString());
|
const url = new URL(this.getBaseHostPort() + "/api/get-screen-lines?" + usp.toString());
|
||||||
let fetchHeaders = this.getFetchHeaders();
|
const fetchHeaders = this.getFetchHeaders();
|
||||||
fetch(url, { headers: fetchHeaders })
|
fetch(url, { headers: fetchHeaders })
|
||||||
.then((resp) => handleJsonFetchResponse(url, resp))
|
.then((resp) => handleJsonFetchResponse(url, resp))
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@ -1213,7 +1230,7 @@ class Model {
|
|||||||
console.log("null screen-lines returned from get-screen-lines");
|
console.log("null screen-lines returned from get-screen-lines");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let slines: ScreenLinesType = data.data;
|
const slines: ScreenLinesType = data.data;
|
||||||
this.updateScreenLines(slines, true);
|
this.updateScreenLines(slines, true);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -1222,7 +1239,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadScreenLines(screenId: string): ScreenLines {
|
loadScreenLines(screenId: string): ScreenLines {
|
||||||
let newWin = new ScreenLines(screenId);
|
const newWin = new ScreenLines(screenId);
|
||||||
setTimeout(() => this._loadScreenLinesAsync(newWin), 0);
|
setTimeout(() => this._loadScreenLinesAsync(newWin), 0);
|
||||||
return newWin;
|
return newWin;
|
||||||
}
|
}
|
||||||
@ -1235,7 +1252,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRemoteNames(): Record<string, string> {
|
getRemoteNames(): Record<string, string> {
|
||||||
let rtn: Record<string, string> = {};
|
const rtn: Record<string, string> = {};
|
||||||
for (const remote of this.remotes) {
|
for (const remote of this.remotes) {
|
||||||
if (!isBlank(remote.remotealias)) {
|
if (!isBlank(remote.remotealias)) {
|
||||||
rtn[remote.remoteid] = remote.remotealias;
|
rtn[remote.remoteid] = remote.remotealias;
|
||||||
@ -1260,7 +1277,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCmdByScreenLine(screenId: string, lineId: string): Cmd {
|
getCmdByScreenLine(screenId: string, lineId: string): Cmd {
|
||||||
let slines = this.getScreenLinesById(screenId);
|
const slines = this.getScreenLinesById(screenId);
|
||||||
if (slines == null) {
|
if (slines == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1268,14 +1285,14 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getActiveLine(screenId: string, lineid: string): SWLinePtr {
|
getActiveLine(screenId: string, lineid: string): SWLinePtr {
|
||||||
let slines = this.screenLines.get(screenId);
|
const slines = this.screenLines.get(screenId);
|
||||||
if (slines == null) {
|
if (slines == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!slines.loaded.get()) {
|
if (!slines.loaded.get()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let cmd = slines.getCmd(lineid);
|
const cmd = slines.getCmd(lineid);
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1289,12 +1306,12 @@ class Model {
|
|||||||
if (line == null) {
|
if (line == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let screen = this.getScreenById_single(slines.screenId);
|
const screen = this.getScreenById_single(slines.screenId);
|
||||||
return { line: line, slines: slines, screen: screen };
|
return { line: line, slines: slines, screen: screen };
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePtyData(ptyMsg: PtyDataUpdateType): void {
|
updatePtyData(ptyMsg: PtyDataUpdateType): void {
|
||||||
let linePtr = this.getActiveLine(ptyMsg.screenid, ptyMsg.lineid);
|
const linePtr = this.getActiveLine(ptyMsg.screenid, ptyMsg.lineid);
|
||||||
if (linePtr != null) {
|
if (linePtr != null) {
|
||||||
linePtr.screen.updatePtyData(ptyMsg);
|
linePtr.screen.updatePtyData(ptyMsg);
|
||||||
}
|
}
|
||||||
@ -1320,7 +1337,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendCmdInputText(screenId: string, sp: StrWithPos) {
|
sendCmdInputText(screenId: string, sp: StrWithPos) {
|
||||||
let pk: CmdInputTextPacketType = {
|
const pk: CmdInputTextPacketType = {
|
||||||
type: "cmdinputtext",
|
type: "cmdinputtext",
|
||||||
seqnum: this.getNextPacketSeqNum(),
|
seqnum: this.getNextPacketSeqNum(),
|
||||||
screenid: screenId,
|
screenid: screenId,
|
||||||
@ -1334,7 +1351,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveRemoteIdToRef(remoteId: string) {
|
resolveRemoteIdToRef(remoteId: string) {
|
||||||
let remote = this.getRemote(remoteId);
|
const remote = this.getRemote(remoteId);
|
||||||
if (remote == null) {
|
if (remote == null) {
|
||||||
return "[unknown]";
|
return "[unknown]";
|
||||||
}
|
}
|
||||||
@ -1345,7 +1362,7 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveRemoteIdToFullRef(remoteId: string) {
|
resolveRemoteIdToFullRef(remoteId: string) {
|
||||||
let remote = this.getRemote(remoteId);
|
const remote = this.getRemote(remoteId);
|
||||||
if (remote == null) {
|
if (remote == null) {
|
||||||
return "[unknown]";
|
return "[unknown]";
|
||||||
}
|
}
|
||||||
@ -1356,17 +1373,17 @@ class Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readRemoteFile(screenId: string, lineId: string, path: string): Promise<ExtFile> {
|
readRemoteFile(screenId: string, lineId: string, path: string): Promise<ExtFile> {
|
||||||
let urlParams = {
|
const urlParams = {
|
||||||
screenid: screenId,
|
screenid: screenId,
|
||||||
lineid: lineId,
|
lineid: lineId,
|
||||||
path: path,
|
path: path,
|
||||||
};
|
};
|
||||||
let usp = new URLSearchParams(urlParams);
|
const usp = new URLSearchParams(urlParams);
|
||||||
let url = new URL(this.getBaseHostPort() + "/api/read-file?" + usp.toString());
|
const url = new URL(this.getBaseHostPort() + "/api/read-file?" + usp.toString());
|
||||||
let fetchHeaders = this.getFetchHeaders();
|
const fetchHeaders = this.getFetchHeaders();
|
||||||
let fileInfo: FileInfoType = null;
|
let fileInfo: FileInfoType = null;
|
||||||
let badResponseStr: string = null;
|
let badResponseStr: string = null;
|
||||||
let prtn = fetch(url, { method: "get", headers: fetchHeaders })
|
const prtn = fetch(url, { method: "get", headers: fetchHeaders })
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
badResponseStr = sprintf(
|
badResponseStr = sprintf(
|
||||||
@ -1381,14 +1398,14 @@ class Model {
|
|||||||
})
|
})
|
||||||
.then((blobOrText: any) => {
|
.then((blobOrText: any) => {
|
||||||
if (blobOrText instanceof Blob) {
|
if (blobOrText instanceof Blob) {
|
||||||
let blob: Blob = blobOrText;
|
const blob: Blob = blobOrText;
|
||||||
let file = new File([blob], fileInfo.name, { type: blob.type, lastModified: fileInfo.modts });
|
const file = new File([blob], fileInfo.name, { type: blob.type, lastModified: fileInfo.modts });
|
||||||
let isWriteable = (fileInfo.perm & 0o222) > 0; // checks for unix permission "w" bits
|
const isWriteable = (fileInfo.perm & 0o222) > 0; // checks for unix permission "w" bits
|
||||||
(file as any).readOnly = !isWriteable;
|
(file as any).readOnly = !isWriteable;
|
||||||
(file as any).notFound = !!fileInfo.notfound;
|
(file as any).notFound = !!fileInfo.notfound;
|
||||||
return file as ExtFile;
|
return file as ExtFile;
|
||||||
} else {
|
} else {
|
||||||
let textError: string = blobOrText;
|
const textError: string = blobOrText;
|
||||||
if (textError == null || textError.length == 0) {
|
if (textError == null || textError.length == 0) {
|
||||||
throw new Error(badResponseStr);
|
throw new Error(badResponseStr);
|
||||||
}
|
}
|
||||||
@ -1398,7 +1415,7 @@ class Model {
|
|||||||
return prtn;
|
return prtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeRemoteFile(
|
async writeRemoteFile(
|
||||||
screenId: string,
|
screenId: string,
|
||||||
lineId: string,
|
lineId: string,
|
||||||
path: string,
|
path: string,
|
||||||
@ -1406,24 +1423,21 @@ class Model {
|
|||||||
opts?: { useTemp?: boolean }
|
opts?: { useTemp?: boolean }
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
let params = {
|
const params = {
|
||||||
screenid: screenId,
|
screenid: screenId,
|
||||||
lineid: lineId,
|
lineid: lineId,
|
||||||
path: path,
|
path: path,
|
||||||
usetemp: !!opts.useTemp,
|
usetemp: !!opts.useTemp,
|
||||||
};
|
};
|
||||||
let formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("params", JSON.stringify(params));
|
formData.append("params", JSON.stringify(params));
|
||||||
let blob = new Blob([data], { type: "application/octet-stream" });
|
const blob = new Blob([data], { type: "application/octet-stream" });
|
||||||
formData.append("data", blob);
|
formData.append("data", blob);
|
||||||
let url = new URL(this.getBaseHostPort() + "/api/write-file");
|
const url = new URL(this.getBaseHostPort() + "/api/write-file");
|
||||||
let fetchHeaders = this.getFetchHeaders();
|
const fetchHeaders = this.getFetchHeaders();
|
||||||
let prtn = fetch(url, { method: "post", headers: fetchHeaders, body: formData });
|
const prtn = fetch(url, { method: "post", headers: fetchHeaders, body: formData });
|
||||||
return prtn
|
const resp = await prtn;
|
||||||
.then((resp) => handleJsonFetchResponse(url, resp))
|
const _ = await handleJsonFetchResponse(url, resp);
|
||||||
.then((_) => {
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ import {
|
|||||||
genMergeSimpleData,
|
genMergeSimpleData,
|
||||||
boundInt,
|
boundInt,
|
||||||
isModKeyPress,
|
isModKeyPress,
|
||||||
} from "../util/util";
|
} from "@/util/util";
|
||||||
import { TermWrap } from "../plugins/terminal/term";
|
import { TermWrap } from "@/plugins/terminal/term";
|
||||||
import { PluginModel } from "../plugins/plugins";
|
import { PluginModel } from "@/plugins/plugins";
|
||||||
import {
|
import {
|
||||||
SessionDataType,
|
SessionDataType,
|
||||||
LineType,
|
LineType,
|
||||||
@ -76,15 +76,15 @@ import {
|
|||||||
windowHeightToRows,
|
windowHeightToRows,
|
||||||
termWidthFromCols,
|
termWidthFromCols,
|
||||||
termHeightFromRows,
|
termHeightFromRows,
|
||||||
} from "../util/textmeasure";
|
} from "@/util/textmeasure";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import customParseFormat from "dayjs/plugin/customParseFormat";
|
import customParseFormat from "dayjs/plugin/customParseFormat";
|
||||||
import { getRendererContext, cmdStatusIsRunning } from "../app/line/lineutil";
|
import { getRendererContext, cmdStatusIsRunning } from "@/app/line/lineutil";
|
||||||
import { MagicLayout } from "../app/magiclayout";
|
import { MagicLayout } from "@/app/magiclayout";
|
||||||
import { modalsRegistry } from "../app/common/modals/registry";
|
import { modalsRegistry } from "@/modals/registry";
|
||||||
import * as appconst from "../app/appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, setKeyUtilPlatform } from "../util/keyutil";
|
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent, setKeyUtilPlatform } from "@/util/keyutil";
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
@ -2,10 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import { PluginModel } from "../plugins/plugins";
|
import { PluginModel } from "@/plugins/plugins";
|
||||||
import { RendererPluginType } from "../types/types";
|
|
||||||
import { OV } from "../types/types";
|
|
||||||
import { GlobalCommandRunner } from "./global";
|
|
||||||
import { Model } from "./model";
|
import { Model } from "./model";
|
||||||
|
|
||||||
class PluginsModel {
|
class PluginsModel {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user