diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx index 8ddabc7d0..ac8125b8c 100644 --- a/frontend/app/block/block.tsx +++ b/frontend/app/block/block.tsx @@ -13,7 +13,7 @@ import * as WOS from "@/store/wos"; import * as util from "@/util/util"; import { PlotView } from "@/view/plotview"; import { PreviewView, makePreviewModel } from "@/view/preview"; -import { TerminalView } from "@/view/term/term"; +import { TerminalView, makeTerminalModel } from "@/view/term/term"; import { WaveAi } from "@/view/waveai"; import { WebView, makeWebViewModel } from "@/view/webview"; import clsx from "clsx"; @@ -499,7 +499,9 @@ function getViewElemAndModel( let viewElem: JSX.Element = null; let viewModel: ViewModel = null; if (blockView === "term") { - viewElem = ; + const termViewModel = makeTerminalModel(blockId); + viewElem = ; + viewModel = termViewModel; } else if (blockView === "preview") { const previewModel = makePreviewModel(blockId); viewElem = ; diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index e483cd8e2..5ecf24bfd 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -125,14 +125,53 @@ function setBlockFocus(blockId: string) { WOS.setObjectValue(winData, globalStore.set, true); } -const TerminalView = ({ blockId }: { blockId: string }) => { +class TermViewModel { + termRef: React.RefObject; + blockAtom: jotai.Atom; + termMode: jotai.Atom; + htmlElemFocusRef: React.RefObject; + blockId: string; + + constructor(blockId: string) { + this.blockId = blockId; + this.blockAtom = WOS.getWaveObjectAtom(`block:${blockId}`); + this.termMode = jotai.atom((get) => { + const blockData = get(this.blockAtom); + return blockData?.meta?.["term:mode"] ?? "term"; + }); + } + + giveFocus(): boolean { + let termMode = globalStore.get(this.termMode); + if (termMode == "term") { + if (this.termRef?.current?.terminal) { + this.termRef.current.terminal.focus(); + return true; + } + } else { + if (this.htmlElemFocusRef?.current) { + this.htmlElemFocusRef.current.focus(); + return true; + } + } + return false; + } +} + +function makeTerminalModel(blockId: string): TermViewModel { + return new TermViewModel(blockId); +} + +const TerminalView = ({ blockId, model }: { blockId: string; model: TermViewModel }) => { const connectElemRef = React.useRef(null); const termRef = React.useRef(null); + model.termRef = termRef; const shellProcStatusRef = React.useRef(null); const blockIconOverrideAtom = useBlockAtom(blockId, "blockicon:override", () => { return jotai.atom(null); }) as jotai.PrimitiveAtom; const htmlElemFocusRef = React.useRef(null); + model.htmlElemFocusRef = htmlElemFocusRef; const [blockData] = WOS.useWaveObjectValue(WOS.makeORef("block", blockId)); const isFocusedAtom = useBlockAtom(blockId, "isFocused", () => { return jotai.atom((get) => { @@ -311,4 +350,4 @@ const TerminalView = ({ blockId }: { blockId: string }) => { ); }; -export { TerminalView }; +export { TerminalView, makeTerminalModel };