From 43138f754c4046a01fc892a3b9563c4c0bd6bcc7 Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 22 Aug 2024 16:25:53 -0700 Subject: [PATCH] fix double model creation --- frontend/app/block/block.tsx | 22 ++++++++++++++++------ frontend/app/view/cpuplot/cpuplot.tsx | 9 ++++++--- frontend/app/view/preview/preview.tsx | 2 ++ frontend/app/view/term/term.tsx | 2 ++ frontend/app/view/waveai/waveai.tsx | 2 ++ frontend/app/view/webview/webview.tsx | 2 ++ frontend/types/custom.d.ts | 1 + 7 files changed, 31 insertions(+), 9 deletions(-) diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx index 913d173fd..96f7d29df 100644 --- a/frontend/app/block/block.tsx +++ b/frontend/app/block/block.tsx @@ -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 Invalid View "{blockView}"; } -function makeDefaultViewModel(blockId: string): ViewModel { +function makeDefaultViewModel(blockId: string, viewType: string): ViewModel { const blockDataAtom = WOS.getWaveObjectAtom(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(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); diff --git a/frontend/app/view/cpuplot/cpuplot.tsx b/frontend/app/view/cpuplot/cpuplot.tsx index f52c540c2..d9322012d 100644 --- a/frontend/app/view/cpuplot/cpuplot.tsx +++ b/frontend/app/view/cpuplot/cpuplot.tsx @@ -19,6 +19,7 @@ type Point = { }; class CpuPlotViewModel { + viewType: string; blockAtom: jotai.Atom; termMode: jotai.Atom; htmlElemFocusRef: React.RefObject; @@ -32,6 +33,7 @@ class CpuPlotViewModel { incrementCount: jotai.WritableAtom>; constructor(blockId: string) { + this.viewType = "cpuplot"; this.blockId = blockId; this.blockAtom = WOS.getWaveObjectAtom(`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); diff --git a/frontend/app/view/preview/preview.tsx b/frontend/app/view/preview/preview.tsx index 11a19b87f..6510b5c72 100644 --- a/frontend/app/view/preview/preview.tsx +++ b/frontend/app/view/preview/preview.tsx @@ -35,6 +35,7 @@ function isTextFile(mimeType: string): boolean { } export class PreviewModel implements ViewModel { + viewType: string; blockId: string; blockAtom: jotai.Atom; viewIcon: jotai.Atom; @@ -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); diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index a8d55e52b..b39806810 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -108,6 +108,7 @@ function setBlockFocus(blockId: string) { } class TermViewModel { + viewType: string; termRef: React.RefObject; blockAtom: jotai.Atom; termMode: jotai.Atom; @@ -119,6 +120,7 @@ class TermViewModel { blockBg: jotai.Atom; constructor(blockId: string) { + this.viewType = "term"; this.blockId = blockId; this.blockAtom = WOS.getWaveObjectAtom(`block:${blockId}`); this.termMode = jotai.atom((get) => { diff --git a/frontend/app/view/waveai/waveai.tsx b/frontend/app/view/waveai/waveai.tsx index 1915c7d29..bbbd9f700 100644 --- a/frontend/app/view/waveai/waveai.tsx +++ b/frontend/app/view/waveai/waveai.tsx @@ -39,6 +39,7 @@ function promptToMsg(prompt: OpenAIPromptMessageType): ChatMessageType { } export class WaveAiModel implements ViewModel { + viewType: string; blockId: string; blockAtom: jotai.Atom; viewIcon?: jotai.Atom; @@ -53,6 +54,7 @@ export class WaveAiModel implements ViewModel { textAreaRef: React.RefObject; constructor(blockId: string) { + this.viewType = "waveai"; this.blockId = blockId; this.blockAtom = WOS.getWaveObjectAtom(`block:${blockId}`); this.viewIcon = jotai.atom((get) => { diff --git a/frontend/app/view/webview/webview.tsx b/frontend/app/view/webview/webview.tsx index 630fefdd9..faac9910d 100644 --- a/frontend/app/view/webview/webview.tsx +++ b/frontend/app/view/webview/webview.tsx @@ -13,6 +13,7 @@ import { checkKeyPressed } from "@/util/keyutil"; import "./webview.less"; export class WebViewModel implements ViewModel { + viewType: string; blockId: string; blockAtom: jotai.Atom; viewIcon: jotai.Atom; @@ -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:${blockId}`); diff --git a/frontend/types/custom.d.ts b/frontend/types/custom.d.ts index 2299c10b8..bd6612c26 100644 --- a/frontend/types/custom.d.ts +++ b/frontend/types/custom.d.ts @@ -183,6 +183,7 @@ declare global { }; interface ViewModel { + viewType: string; viewIcon?: jotai.Atom; viewName?: jotai.Atom; viewText?: jotai.Atom;