diff --git a/src/app/common/modals/modals.tsx b/src/app/common/modals/modals.tsx index 7604e5e4..e8cb8e1a 100644 --- a/src/app/common/modals/modals.tsx +++ b/src/app/common/modals/modals.tsx @@ -11,7 +11,19 @@ import dayjs from "dayjs"; import localizedFormat from "dayjs/plugin/localizedFormat"; import { GlobalModel, GlobalCommandRunner, RemotesModel } from "../../../model/model"; import * as T from "../../../types/types"; -import { Markdown, Toggle, Modal, TextField, NumberField, InputDecoration, Dropdown, PasswordField, Tooltip, Button, Status } from "../common"; +import { + Markdown, + Toggle, + Modal, + TextField, + NumberField, + InputDecoration, + Dropdown, + PasswordField, + Tooltip, + Button, + Status, +} from "../common"; import * as util from "../../../util/util"; import * as textmeasure from "../../../util/textmeasure"; import { ClientDataType } from "../../../types/types"; @@ -37,18 +49,18 @@ const PasswordUnchangedSentinel = "--unchanged--"; @mobxReact.observer class ModalsProvider extends React.Component { - renderModals() { - const modals = GlobalModel.modalsModel.activeModals; - + render() { + let store = GlobalModel.modalsModel.store.slice(); if (GlobalModel.needsTos()) { return ; } - - return modals.map((ModalComponent, index) => ); - } - - render() { - return <>{this.renderModals()}; + let rtn: JSX.Element[] = []; + for (let i = 0; i < store.length; i++) { + let entry = store[i]; + let Comp = entry.component; + rtn.push(); + } + return <>{rtn}; } } @@ -277,7 +289,11 @@ class TosModal extends React.Component<{}, {}> {
- + Help
@@ -286,7 +302,11 @@ class TosModal extends React.Component<{}, {}> { Get help, submit feature requests, report bugs, or just chat with fellow terminal enthusiasts.
- + Join the Wave Discord Channel
@@ -846,7 +866,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> { @boundMethod openEditModal(): void { - GlobalModel.remotesModel.openEditModal(); + GlobalModel.remotesModel.startEditAuth(); } @boundMethod @@ -959,7 +979,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> { ); if (remote.local) { - installNowButton = <>; + installNowButton = <>; updateAuthButton = <>; cancelInstallButton = <>; } @@ -1115,74 +1135,47 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> { @mobxReact.observer class EditRemoteConnModal extends React.Component<{}, {}> { - internalTempAlias: OV; - internalTempKeyFile: OV; - internalTempPassword: OV; + tempAlias: OV; + tempKeyFile: OV; + tempPassword: OV; + tempConnectMode: OV; + tempAuthMode: OV; model: RemotesModel; constructor(props: { remotesModel?: RemotesModel }) { super(props); this.model = GlobalModel.remotesModel; - this.internalTempAlias = mobx.observable.box(null, { name: "EditRemoteSettings-internalTempAlias" }); - this.internalTempKeyFile = mobx.observable.box(null, { name: "EditRemoteSettings-internalTempKeyFile" }); - this.internalTempPassword = mobx.observable.box(null, { name: "EditRemoteSettings-internalTempPassword" }); + this.tempAlias = mobx.observable.box(null, { name: "EditRemoteSettings-tempAlias" }); + this.tempAuthMode = mobx.observable.box(null, { name: "EditRemoteSettings-tempAuthMode" }); + this.tempKeyFile = mobx.observable.box(null, { name: "EditRemoteSettings-tempKeyFile" }); + this.tempPassword = mobx.observable.box(null, { name: "EditRemoteSettings-tempPassword" }); + this.tempConnectMode = mobx.observable.box(null, { name: "EditRemoteSettings-tempConnectMode" }); } - @mobx.computed get selectedRemoteId() { return this.model.selectedRemoteId.get(); } - @mobx.computed get selectedRemote(): T.RemoteType { return GlobalModel.getRemote(this.selectedRemoteId); } - @mobx.computed get remoteEdit(): T.RemoteEditType { return this.model.remoteEdit.get(); } - @mobx.computed get isAuthEditMode(): boolean { return this.model.isAuthEditMode(); } - @mobx.computed - get tempAuthMode(): mobx.IObservableValue { - return mobx.observable.box(this.selectedRemote?.authtype, { - name: "EditRemoteConnModal-authMode", - }); - } - - @mobx.computed - get tempConnectMode(): mobx.IObservableValue { - return mobx.observable.box(this.selectedRemote?.connectmode, { - name: "EditRemoteConnModal-connectMode", - }); - } - - @mobx.computed - get tempAlias(): mobx.IObservableValue { - return mobx.observable.box(this.internalTempAlias.get() || this.selectedRemote.remotealias, { - name: "EditRemoteConnModal-alias", - }); - } - - @mobx.computed - get tempKeyFile(): mobx.IObservableValue { - return mobx.observable.box(this.internalTempKeyFile.get() || this.remoteEdit?.keystr, { - name: "EditRemoteConnModal-keystr", - }); - } - - @mobx.computed - get tempPassword(): mobx.IObservableValue { - const oldPassword = this.remoteEdit?.haspassword ? PasswordUnchangedSentinel : ""; - const newPassword = this.internalTempPassword.get() || oldPassword; - return mobx.observable.box(newPassword, { - name: "EditRemoteConnModal-password", - }); + componentDidMount(): void { + mobx.action(() => { + this.tempAlias.set(this.selectedRemote?.remotealias); + this.tempKeyFile.set(this.remoteEdit?.keystr); + this.tempPassword.set(this.remoteEdit?.haspassword ? PasswordUnchangedSentinel : ""); + this.tempConnectMode.set(this.selectedRemote?.connectmode); + this.tempAuthMode.set(this.selectedRemote?.authtype); + })(); } componentDidUpdate() { @@ -1194,21 +1187,35 @@ class EditRemoteConnModal extends React.Component<{}, {}> { @boundMethod handleChangeKeyFile(value: string): void { mobx.action(() => { - this.internalTempKeyFile.set(value); + this.tempKeyFile.set(value); })(); } @boundMethod handleChangePassword(value: string): void { mobx.action(() => { - this.internalTempPassword.set(value); + this.tempPassword.set(value); })(); } @boundMethod handleChangeAlias(value: string): void { mobx.action(() => { - this.internalTempAlias.set(value); + this.tempAlias.set(value); + })(); + } + + @boundMethod + handleChangeAuthMode(value: string): void { + mobx.action(() => { + this.tempAuthMode.set(value); + })(); + } + + @boundMethod + handleChangeConnectMode(value: string): void { + mobx.action(() => { + this.tempConnectMode.set(value); })(); } @@ -1238,10 +1245,13 @@ class EditRemoteConnModal extends React.Component<{}, {}> { submitRemote(): void { let authMode = this.tempAuthMode.get(); let kwargs: Record = {}; - if (!util.isStrEq(this.tempKeyFile.get(), this.remoteEdit?.keystr)) { - if (authMode == "key" || authMode == "key+password") { + if (authMode == "key" || authMode == "key+password") { + let keyStrEq = util.isStrEq(this.tempKeyFile.get(), this.remoteEdit?.keystr); + if (!keyStrEq) { kwargs["key"] = this.tempKeyFile.get(); - } else { + } + } else { + if (!util.isBlank(this.tempKeyFile.get())) { kwargs["key"] = ""; } } @@ -1291,11 +1301,9 @@ class EditRemoteConnModal extends React.Component<{}, {}> { render() { let authMode = this.tempAuthMode.get(); - if (this.remoteEdit === null || !this.isAuthEditMode) { return null; } - return ( @@ -1333,9 +1341,7 @@ class EditRemoteConnModal extends React.Component<{}, {}> { { value: "key+password", label: "key+password" }, ]} value={this.tempAuthMode.get()} - onChange={(val: string) => { - this.tempAuthMode.set(val); - }} + onChange={this.handleChangeAuthMode} decoration={{ endDecoration: ( @@ -1406,9 +1412,7 @@ class EditRemoteConnModal extends React.Component<{}, {}> { { value: "manual", label: "manual" }, ]} value={this.tempConnectMode.get()} - onChange={(val: string) => { - this.tempConnectMode.set(val); - }} + onChange={this.handleChangeConnectMode} />
diff --git a/src/model/model.ts b/src/model/model.ts index 11282b8a..93b629e8 100644 --- a/src/model/model.ts +++ b/src/model/model.ts @@ -4,6 +4,7 @@ import type React from "react"; import * as mobx from "mobx"; import { sprintf } from "sprintf-js"; +import { v4 as uuidv4 } from "uuid"; import { boundMethod } from "autobind-decorator"; import { debounce } from "throttle-debounce"; import { @@ -1892,7 +1893,7 @@ class ForwardLineContainer { } 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; return rtn; } @@ -2946,16 +2947,11 @@ class RemotesModel { } openEditModal(redit?: RemoteEditType): void { - if (redit == null) { - this.startEditAuth(); + mobx.action(() => { + this.selectedRemoteId.set(redit?.remoteid); + this.remoteEdit.set(redit); GlobalModel.modalsModel.pushModal(appconst.EDIT_REMOTE); - } else { - mobx.action(() => { - this.selectedRemoteId.set(redit?.remoteid); - this.remoteEdit.set(redit); - GlobalModel.modalsModel.pushModal(appconst.EDIT_REMOTE); - })(); - } + })(); } selectRemote(remoteId: string): void { @@ -3081,28 +3077,22 @@ class RemotesModel { } class ModalsModel { - store: Array<{ id: string; component: React.ComponentType }> = []; - - constructor() { - mobx.makeAutoObservable(this); - } + store: OArr = mobx.observable.array([], { name: "ModalsModel-store" }); pushModal(modalId: string) { const modalFactory = modalsRegistry[modalId]; if (modalFactory && !this.store.some((modal) => modal.id === modalId)) { - this.store.push({ id: modalId, component: modalFactory }); + mobx.action(() => { + this.store.push({ id: modalId, component: modalFactory, uniqueKey: uuidv4() }); + })(); } } popModal() { - this.store.pop(); - } - - get activeModals() { - return this.store.slice().map((modal) => { - return modal.component; - }); + mobx.action(() => { + this.store.pop(); + })(); } } diff --git a/src/types/types.ts b/src/types/types.ts index fa693ee3..bff3c85c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -660,6 +660,12 @@ type ExtFile = File & { notFound: boolean; }; +type ModalStoreEntry = { + id: string; + component: React.ComponentType; + uniqueKey: string; +}; + export type { SessionDataType, LineStateType, @@ -734,4 +740,5 @@ export type { ExtBlob, ExtFile, LineContainerStrs, + ModalStoreEntry, };