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;