diff --git a/src/main.tsx b/src/main.tsx index 9922f0c8..ba0d766f 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -9,7 +9,7 @@ import dayjs from "dayjs"; import {If, For, When, Otherwise, Choose} from "tsx-control-statements/components"; import cn from "classnames"; import {TermWrap} from "./term"; -import type {SessionDataType, LineType, CmdDataType, RemoteType, RemoteStateType, RemoteInstanceType, RemotePtrType, HistoryItem, HistoryQueryOpts, RemoteEditType, FeStateType, ContextMenuOpts} from "./types"; +import type {SessionDataType, LineType, CmdDataType, RemoteType, RemoteStateType, RemoteInstanceType, RemotePtrType, HistoryItem, HistoryQueryOpts, RemoteEditType, FeStateType, ContextMenuOpts, BookmarkType} from "./types"; import localizedFormat from 'dayjs/plugin/localizedFormat'; import {GlobalModel, GlobalCommandRunner, Session, Cmd, Window, Screen, ScreenWindow, riToRPtr, windowWidthToCols, windowHeightToRows, termHeightFromRows, termWidthFromCols} from "./model"; import {isModKeyPress} from "./util"; @@ -2751,7 +2751,7 @@ class SessionView extends React.Component<{}, {}> { if (cmdInputHeight == 0) { cmdInputHeight = 110; } - let isHidden = GlobalModel.historyViewActive.get(); + let isHidden = (GlobalModel.activeMainView.get() != "session"); return (
@@ -2766,17 +2766,7 @@ class SessionView extends React.Component<{}, {}> { @mobxReact.observer class HistoryView extends React.Component<{}, {}> { render() { - let model = GlobalModel; - let session = model.getActiveSession(); - if (session == null) { - return
(no active session)
; - } - let activeScreen = session.getActiveScreen(); - let cmdInputHeight = model.inputModel.cmdInputHeight.get(); - if (cmdInputHeight == 0) { - cmdInputHeight = 110; - } - let isHidden = !GlobalModel.historyViewActive.get(); + let isHidden = (GlobalModel.activeMainView.get() != "history"); return (
HISTORY
@@ -2785,6 +2775,26 @@ class HistoryView extends React.Component<{}, {}> { } } +@mobxReact.observer +class BookmarksView extends React.Component<{}, {}> { + render() { + let isHidden = (GlobalModel.activeMainView.get() != "bookmarks"); + let bookmarks = GlobalModel.bookmarksModel.bookmarks; + let idx : number = 0; + let bookmark : BookmarkType = null; + return ( +
+
BOOKMARKS
+
+ +
bookmark {idx} -- {JSON.stringify(bookmark)}
+
+
+
+ ); + } +} + function getConnVal(r : RemoteType) : number { if (r.status == "connected") { return 1; @@ -2868,15 +2878,18 @@ class MainSideBar extends React.Component<{}, {}> { @boundMethod handleHistoryClick() : void { - mobx.action(() => { - let isActive = GlobalModel.historyViewActive.get(); - GlobalModel.historyViewActive.set(!isActive); - })(); + console.log("history click"); } @boundMethod handleBookmarksClick() : void { - console.log("click bookmarks"); + if (GlobalModel.activeMainView.get() == "bookmarks") { + mobx.action(() => { + GlobalModel.activeMainView.set("session"); + })(); + return; + } + GlobalCommandRunner.bookmarksView(); } render() { @@ -2906,6 +2919,7 @@ class MainSideBar extends React.Component<{}, {}> { } } let isCollapsed = this.collapsed.get(); + let mainView = GlobalModel.activeMainView.get(); return (

@@ -2927,7 +2941,7 @@ class MainSideBar extends React.Component<{}, {}> { -
  • this.handleSessionClick(session.sessionId)}> +
  • this.handleSessionClick(session.sessionId)}> {idx+1}  @@ -2947,17 +2961,17 @@ class MainSideBar extends React.Component<{}, {}> {
  • this.handleNewSharedSession()}> New Session
  • focus={sw.focusType.get()}
    - sline={sw.selectedLine.get()}
    - termfocus={sw.termLineNumFocus.get()}
    + sline={sw.selectedLine.get()}
    + termfocus={sw.termLineNumFocus.get()}

    @@ -3137,6 +3151,7 @@ class Main extends React.Component<{}, {}> { +

    diff --git a/src/model.ts b/src/model.ts index 10f7fa4f..7d61f907 100644 --- a/src/model.ts +++ b/src/model.ts @@ -5,7 +5,7 @@ import {debounce} from "throttle-debounce"; import {handleJsonFetchResponse, base64ToArray, genMergeData, genMergeSimpleData, boundInt, isModKeyPress} from "./util"; import {TermWrap} from "./term"; import {v4 as uuidv4} from "uuid"; -import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, RemotePtrType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, UIContextType, HistoryInfoType, HistoryQueryOpts, FeInputPacketType, TermWinSize, RemoteInputPacketType, FeStateType, ContextMenuOpts, RendererContext, RendererModel, PtyDataType} from "./types"; +import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, RemoteInstanceType, RemotePtrType, CmdDataType, FeCmdPacketType, TermOptsType, RemoteStateType, ScreenDataType, ScreenWindowType, ScreenOptsType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, UIContextType, HistoryInfoType, HistoryQueryOpts, FeInputPacketType, TermWinSize, RemoteInputPacketType, FeStateType, ContextMenuOpts, RendererContext, RendererModel, PtyDataType, BookmarksViewType, BookmarkType} from "./types"; import {WSControl} from "./ws"; import {ImageRendererModel} from "./imagerenderer"; @@ -1583,6 +1583,10 @@ type LineFocusType = { cmdid? : string, }; +class BookmarksModel { + bookmarks : OArr = mobx.observable.array([], {name: "Bookmarks"}); +} + class Model { clientId : string; activeSessionId : OV = mobx.observable.box(null, {name: "activeSessionId"}); @@ -1592,14 +1596,16 @@ class Model { remotes : OArr = mobx.observable.array([], {name: "remotes", deep: false}); remotesLoaded : OV = mobx.observable.box(false, {name: "remotesLoaded"}); windows : OMap = mobx.observable.map({}, {name: "windows", deep: false}); // key = "sessionid/windowid" - inputModel : InputModel; termUsedRowsCache : Record = {}; debugCmds : number = 0; debugSW : OV = mobx.observable.box(false); localServerRunning : OV; authKey : string; isDev : boolean; - historyViewActive : OV = mobx.observable.box(false, {name: "historyViewActive"}); + activeMainView : OV<"session" | "history" | "bookmarks"> = mobx.observable.box("session", {name: "activeMainView"}); + + inputModel : InputModel; + bookmarksModel : BookmarksModel; constructor() { this.clientId = getApi().getId(); @@ -1608,6 +1614,7 @@ class Model { this.ws = new WSControl(this.getBaseWsHostPort(), this.clientId, this.authKey, (message : any) => this.runUpdate(message, false)); this.ws.reconnect(); this.inputModel = new InputModel(); + this.bookmarksModel = new BookmarksModel(); let isLocalServerRunning = getApi().getLocalServerStatus(); this.localServerRunning = mobx.observable.box(isLocalServerRunning, {name: "model-local-server-running"}); getApi().onTCmd(this.onTCmd.bind(this)); @@ -1911,6 +1918,9 @@ class Model { } this.updateRemotes(update.remotes); } + if ("bookmarksview" in update) { + this.showBookmarksView(update.bookmarksview); + } if (interactive && "info" in update) { let info : InfoType = update.info; this.inputModel.flashInfoMsg(info, info.timeoutms); @@ -1930,6 +1940,13 @@ class Model { // console.log("run-update>", Date.now(), interactive, update); } + showBookmarksView(bmview : BookmarksViewType) : void { + mobx.action(() => { + this.activeMainView.set("bookmarks"); + this.bookmarksModel.bookmarks.replace(bmview.bookmarks || []); + })(); + } + updateRemotes(remotes : RemoteType[]) : void { genMergeSimpleData(this.remotes, remotes, (r) => r.remoteid, null); } @@ -2118,6 +2135,9 @@ class Model { } _activateSession(sessionId : string) { + mobx.action(() => { + this.activeMainView.set("session"); + })(); let oldActiveSession = this.getActiveSession(); if (oldActiveSession != null && oldActiveSession.sessionId == sessionId) { return; @@ -2130,6 +2150,9 @@ class Model { } _activateScreen(sessionId : string, screenId : string, oldActiveScreen? : Screen) { + mobx.action(() => { + this.activeMainView.set("session"); + })(); if (!oldActiveScreen) { oldActiveScreen = this.getActiveScreen(); } @@ -2425,6 +2448,10 @@ class CommandRunner { linePin(lineId : string, val : boolean) { GlobalModel.submitCommand("line", "pin", [lineId, (val ? "1" : "0")], {"nohist": "1"}, true); } + + bookmarksView() { + GlobalModel.submitCommand("bookmarks", "show", null, {"nohist": "1"}, true); + } }; function cmdPacketString(pk : FeCmdPacketType) : string { diff --git a/src/sh2.less b/src/sh2.less index 181891e9..224d3136 100644 --- a/src/sh2.less +++ b/src/sh2.less @@ -51,7 +51,7 @@ html, body, #main { background-color: black; height: 100%; - .session-view, .history-view { + .session-view, .history-view, .bookmarks-view { flex-grow: 1; display: flex; flex-direction: column; @@ -117,6 +117,14 @@ html, body, #main { } } +.bookmarks-view { + .bookmarks-title { + margin: 10px 0 10px 15px; + .mono-font(1.5rem); + color: @term-bright-white; + } +} + .screen-tabs { height: 30px; display: flex; diff --git a/src/types.ts b/src/types.ts index b10a578a..8cef8b4b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -282,6 +282,22 @@ type ModelUpdateType = { history? : HistoryInfoType, interactive : boolean, connect? : boolean, + bookmarksview? : BookmarksViewType, +}; + +type BookmarksViewType = { + bookmarks: BookmarkType[], +}; + +type BookmarkType = { + bookmarkid : string, + createdts : number, + cmdstr : string, + alias : string, + tags : string[], + description : string, + cmds : string[], + orderidx : number, }; type HistoryInfoType = { @@ -366,4 +382,4 @@ type PtyDataType = { data : Uint8Array, }; -export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel, PtyDataType}; +export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType, FeStateType, ContextMenuOpts, RendererContext, WindowSize, RendererModel, PtyDataType, BookmarksViewType, BookmarkType};