more focus fixes -- write a viewmodel for terminal

This commit is contained in:
sawka 2024-07-22 17:08:18 -07:00
parent baf7961cea
commit ee51f2de12
2 changed files with 45 additions and 4 deletions

View File

@ -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 = <TerminalView key={blockId} blockId={blockId} />;
const termViewModel = makeTerminalModel(blockId);
viewElem = <TerminalView key={blockId} blockId={blockId} model={termViewModel} />;
viewModel = termViewModel;
} else if (blockView === "preview") {
const previewModel = makePreviewModel(blockId);
viewElem = <PreviewView key={blockId} blockId={blockId} model={previewModel} />;

View File

@ -125,14 +125,53 @@ function setBlockFocus(blockId: string) {
WOS.setObjectValue(winData, globalStore.set, true);
}
const TerminalView = ({ blockId }: { blockId: string }) => {
class TermViewModel {
termRef: React.RefObject<TermWrap>;
blockAtom: jotai.Atom<Block>;
termMode: jotai.Atom<string>;
htmlElemFocusRef: React.RefObject<HTMLInputElement>;
blockId: string;
constructor(blockId: string) {
this.blockId = blockId;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`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<HTMLDivElement>(null);
const termRef = React.useRef<TermWrap>(null);
model.termRef = termRef;
const shellProcStatusRef = React.useRef<string>(null);
const blockIconOverrideAtom = useBlockAtom<string>(blockId, "blockicon:override", () => {
return jotai.atom<string>(null);
}) as jotai.PrimitiveAtom<string>;
const htmlElemFocusRef = React.useRef<HTMLInputElement>(null);
model.htmlElemFocusRef = htmlElemFocusRef;
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
const isFocusedAtom = useBlockAtom<boolean>(blockId, "isFocused", () => {
return jotai.atom((get) => {
@ -311,4 +350,4 @@ const TerminalView = ({ blockId }: { blockId: string }) => {
);
};
export { TerminalView };
export { TerminalView, makeTerminalModel };