fix double model creation

This commit is contained in:
sawka 2024-08-22 16:25:53 -07:00
parent 9237208e49
commit 43138f754c
7 changed files with 31 additions and 9 deletions

View File

@ -6,7 +6,15 @@ import { PlotView } from "@/app/view/plotview/plotview";
import { PreviewModel, PreviewView, makePreviewModel } from "@/app/view/preview/preview";
import { ErrorBoundary } from "@/element/errorboundary";
import { CenteredDiv } from "@/element/quickelems";
import { atoms, counterInc, registerViewModel, setBlockFocus, unregisterViewModel, useBlockAtom } from "@/store/global";
import {
atoms,
counterInc,
getViewModel,
registerViewModel,
setBlockFocus,
unregisterViewModel,
useBlockAtom,
} from "@/store/global";
import * as WOS from "@/store/wos";
import * as util from "@/util/util";
import { CpuPlotView, CpuPlotViewModel, makeCpuPlotViewModel } from "@/view/cpuplot/cpuplot";
@ -44,7 +52,7 @@ function makeViewModel(blockId: string, blockView: string): ViewModel {
if (blockView === "cpuplot") {
return makeCpuPlotViewModel(blockId);
}
return makeDefaultViewModel(blockId);
return makeDefaultViewModel(blockId, blockView);
}
function getViewElem(blockId: string, blockView: string, viewModel: ViewModel): JSX.Element {
@ -75,9 +83,10 @@ function getViewElem(blockId: string, blockView: string, viewModel: ViewModel):
return <CenteredDiv>Invalid View "{blockView}"</CenteredDiv>;
}
function makeDefaultViewModel(blockId: string): ViewModel {
function makeDefaultViewModel(blockId: string, viewType: string): ViewModel {
const blockDataAtom = WOS.getWaveObjectAtom<Block>(WOS.makeORef("block", blockId));
let viewModel: ViewModel = {
viewType: viewType,
viewIcon: jotai.atom((get) => {
const blockData = get(blockDataAtom);
return blockViewToIcon(blockData?.meta?.view);
@ -211,10 +220,11 @@ const Block = React.memo((props: BlockProps) => {
counterInc("render-Block");
counterInc("render-Block-" + props.blockId.substring(0, 8));
const [blockData, loading] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", props.blockId));
const viewModel = makeViewModel(props.blockId, blockData?.meta?.view);
React.useEffect(() => {
let viewModel = getViewModel(props.blockId);
if (viewModel == null || viewModel.viewType != blockData?.meta?.view) {
viewModel = makeViewModel(props.blockId, blockData?.meta?.view);
registerViewModel(props.blockId, viewModel);
}, [blockData?.meta?.view]);
}
React.useEffect(() => {
return () => {
unregisterViewModel(props.blockId);

View File

@ -19,6 +19,7 @@ type Point = {
};
class CpuPlotViewModel {
viewType: string;
blockAtom: jotai.Atom<Block>;
termMode: jotai.Atom<string>;
htmlElemFocusRef: React.RefObject<HTMLInputElement>;
@ -32,6 +33,7 @@ class CpuPlotViewModel {
incrementCount: jotai.WritableAtom<unknown, [], Promise<void>>;
constructor(blockId: string) {
this.viewType = "cpuplot";
this.blockId = blockId;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);
this.width = 100;
@ -39,7 +41,8 @@ class CpuPlotViewModel {
this.addDataAtom = jotai.atom(null, (get, set, point) => {
// not efficient but should be okay for a demo?
const data = get(this.dataAtom);
set(this.dataAtom, [...data.slice(1), point]);
const newData = [...data.slice(1), point];
set(this.dataAtom, newData);
});
this.viewIcon = jotai.atom((get) => {
@ -89,8 +92,8 @@ function CpuPlotView({ model }: { model: CpuPlotViewModel; blockId: string }) {
);
try {
for await (const datum of dataGen) {
const ts = datum.ts;
addPlotData({ time: ts / 1000, value: datum.values?.["cpu"] });
const data = { time: datum.ts / 1000, value: datum.values?.["cpu"] };
addPlotData(data);
}
} catch (e) {
console.log(e);

View File

@ -35,6 +35,7 @@ function isTextFile(mimeType: string): boolean {
}
export class PreviewModel implements ViewModel {
viewType: string;
blockId: string;
blockAtom: jotai.Atom<Block>;
viewIcon: jotai.Atom<string | HeaderIconButton>;
@ -64,6 +65,7 @@ export class PreviewModel implements ViewModel {
}
constructor(blockId: string) {
this.viewType = "preview";
this.blockId = blockId;
this.showHiddenFiles = jotai.atom(true);
this.refreshVersion = jotai.atom(0);

View File

@ -108,6 +108,7 @@ function setBlockFocus(blockId: string) {
}
class TermViewModel {
viewType: string;
termRef: React.RefObject<TermWrap>;
blockAtom: jotai.Atom<Block>;
termMode: jotai.Atom<string>;
@ -119,6 +120,7 @@ class TermViewModel {
blockBg: jotai.Atom<MetaType>;
constructor(blockId: string) {
this.viewType = "term";
this.blockId = blockId;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);
this.termMode = jotai.atom((get) => {

View File

@ -39,6 +39,7 @@ function promptToMsg(prompt: OpenAIPromptMessageType): ChatMessageType {
}
export class WaveAiModel implements ViewModel {
viewType: string;
blockId: string;
blockAtom: jotai.Atom<Block>;
viewIcon?: jotai.Atom<string | HeaderIconButton>;
@ -53,6 +54,7 @@ export class WaveAiModel implements ViewModel {
textAreaRef: React.RefObject<HTMLTextAreaElement>;
constructor(blockId: string) {
this.viewType = "waveai";
this.blockId = blockId;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);
this.viewIcon = jotai.atom((get) => {

View File

@ -13,6 +13,7 @@ import { checkKeyPressed } from "@/util/keyutil";
import "./webview.less";
export class WebViewModel implements ViewModel {
viewType: string;
blockId: string;
blockAtom: jotai.Atom<Block>;
viewIcon: jotai.Atom<string | HeaderIconButton>;
@ -32,6 +33,7 @@ export class WebViewModel implements ViewModel {
recentUrls: { [key: string]: number };
constructor(blockId: string) {
this.viewType = "web";
this.blockId = blockId;
this.blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);

View File

@ -183,6 +183,7 @@ declare global {
};
interface ViewModel {
viewType: string;
viewIcon?: jotai.Atom<string | HeaderIconButton>;
viewName?: jotai.Atom<string>;
viewText?: jotai.Atom<string | HeaderElem[]>;