mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-17 20:51:55 +01:00
fe now rendering workspace/tab from db. got useWaveObject working. need to work on updates
This commit is contained in:
parent
95ce1cc86d
commit
6d3f76cb74
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as jotai from "jotai";
|
import * as jotai from "jotai";
|
||||||
import { atoms, blockDataMap, removeBlockFromTab } from "@/store/global";
|
import { atoms, blockDataMap } from "@/store/global";
|
||||||
|
|
||||||
import { TerminalView } from "@/app/view/term";
|
import { TerminalView } from "@/app/view/term";
|
||||||
import { PreviewView } from "@/app/view/preview";
|
import { PreviewView } from "@/app/view/preview";
|
||||||
@ -17,7 +17,7 @@ const Block = ({ tabId, blockId }: { tabId: string; blockId: string }) => {
|
|||||||
const [dims, setDims] = React.useState({ width: 0, height: 0 });
|
const [dims, setDims] = React.useState({ width: 0, height: 0 });
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
removeBlockFromTab(tabId, blockId);
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
@ -15,28 +15,40 @@ import * as wstore from "@/gopkg/wstore";
|
|||||||
import { Call as $Call } from "@wailsio/runtime";
|
import { Call as $Call } from "@wailsio/runtime";
|
||||||
|
|
||||||
const globalStore = jotai.createStore();
|
const globalStore = jotai.createStore();
|
||||||
|
|
||||||
const tabId1 = uuidv4();
|
|
||||||
|
|
||||||
const tabArr: wstore.Tab[] = [new wstore.Tab({ name: "Tab 1", tabid: tabId1, blockids: [] })];
|
|
||||||
const blockDataMap = new Map<string, jotai.Atom<wstore.Block>>();
|
const blockDataMap = new Map<string, jotai.Atom<wstore.Block>>();
|
||||||
const blockAtomCache = new Map<string, Map<string, jotai.Atom<any>>>();
|
|
||||||
|
|
||||||
const atoms = {
|
const atoms = {
|
||||||
activeTabId: jotai.atom<string>(tabId1),
|
|
||||||
tabsAtom: jotai.atom<wstore.Tab[]>(tabArr),
|
|
||||||
blockDataMap: blockDataMap,
|
blockDataMap: blockDataMap,
|
||||||
clientAtom: jotai.atom(null) as jotai.PrimitiveAtom<wstore.Client>,
|
clientAtom: jotai.atom(null) as jotai.PrimitiveAtom<wstore.Client>,
|
||||||
|
|
||||||
// initialized in wave.ts (will not be null inside of application)
|
// initialized in wave.ts (will not be null inside of application)
|
||||||
windowId: jotai.atom<string>(null) as jotai.PrimitiveAtom<string>,
|
windowId: jotai.atom<string>(null) as jotai.PrimitiveAtom<string>,
|
||||||
windowData: jotai.atom<wstore.Window>(null) as jotai.PrimitiveAtom<wstore.Window>,
|
windowData: jotai.atom<WaveWindow>(null) as jotai.PrimitiveAtom<WaveWindow>,
|
||||||
};
|
};
|
||||||
|
|
||||||
type SubjectWithRef<T> = rxjs.Subject<T> & { refCount: number; release: () => void };
|
type SubjectWithRef<T> = rxjs.Subject<T> & { refCount: number; release: () => void };
|
||||||
|
|
||||||
const blockSubjects = new Map<string, SubjectWithRef<any>>();
|
const blockSubjects = new Map<string, SubjectWithRef<any>>();
|
||||||
|
|
||||||
|
function isBlank(str: string): boolean {
|
||||||
|
return str == null || str == "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeORef(otype: string, oid: string): string {
|
||||||
|
if (isBlank(otype) || isBlank(oid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return `${otype}:${oid}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitORef(oref: string): [string, string] {
|
||||||
|
let parts = oref.split(":");
|
||||||
|
if (parts.length != 2) {
|
||||||
|
throw new Error("invalid oref");
|
||||||
|
}
|
||||||
|
return [parts[0], parts[1]];
|
||||||
|
}
|
||||||
|
|
||||||
function getBlockSubject(blockId: string): SubjectWithRef<any> {
|
function getBlockSubject(blockId: string): SubjectWithRef<any> {
|
||||||
let subject = blockSubjects.get(blockId);
|
let subject = blockSubjects.get(blockId);
|
||||||
if (subject == null) {
|
if (subject == null) {
|
||||||
@ -69,20 +81,6 @@ Events.On("block:ptydata", (event: any) => {
|
|||||||
subject.next(data);
|
subject.next(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
function addBlockIdToTab(tabId: string, blockId: string) {
|
|
||||||
let tabArr = globalStore.get(atoms.tabsAtom);
|
|
||||||
const newTabArr = produce(tabArr, (draft) => {
|
|
||||||
const tab = draft.find((tab) => tab.tabid == tabId);
|
|
||||||
tab.blockids.push(blockId);
|
|
||||||
});
|
|
||||||
globalStore.set(atoms.tabsAtom, newTabArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeBlock(blockId: string) {
|
|
||||||
blockDataMap.delete(blockId);
|
|
||||||
blockAtomCache.delete(blockId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function useBlockAtom<T>(blockId: string, name: string, makeFn: () => jotai.Atom<T>): jotai.Atom<T> {
|
function useBlockAtom<T>(blockId: string, name: string, makeFn: () => jotai.Atom<T>): jotai.Atom<T> {
|
||||||
let blockCache = blockAtomCache.get(blockId);
|
let blockCache = blockAtomCache.get(blockId);
|
||||||
if (blockCache == null) {
|
if (blockCache == null) {
|
||||||
@ -97,18 +95,7 @@ function useBlockAtom<T>(blockId: string, name: string, makeFn: () => jotai.Atom
|
|||||||
return atom as jotai.Atom<T>;
|
return atom as jotai.Atom<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeBlockFromTab(tabId: string, blockId: string) {
|
function GetObject<T>(oref: string): Promise<T> {
|
||||||
let tabArr = globalStore.get(atoms.tabsAtom);
|
|
||||||
const newTabArr = produce(tabArr, (draft) => {
|
|
||||||
const tab = draft.find((tab) => tab.tabid == tabId);
|
|
||||||
tab.blockids = tab.blockids.filter((id) => id !== blockId);
|
|
||||||
});
|
|
||||||
globalStore.set(atoms.tabsAtom, newTabArr);
|
|
||||||
removeBlock(blockId);
|
|
||||||
BlockService.CloseBlock(blockId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetObject(oref: string): Promise<any> {
|
|
||||||
let prtn = $Call.ByName(
|
let prtn = $Call.ByName(
|
||||||
"github.com/wavetermdev/thenextwave/pkg/service/objectservice.ObjectService.GetObject",
|
"github.com/wavetermdev/thenextwave/pkg/service/objectservice.ObjectService.GetObject",
|
||||||
oref
|
oref
|
||||||
@ -116,84 +103,85 @@ function GetObject(oref: string): Promise<any> {
|
|||||||
return prtn;
|
return prtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
type WaveObjectHookData = {
|
function GetClientObject(): Promise<Client> {
|
||||||
oref: string;
|
let prtn = $Call.ByName(
|
||||||
};
|
"github.com/wavetermdev/thenextwave/pkg/service/objectservice.ObjectService.GetClientObject"
|
||||||
|
);
|
||||||
|
return prtn;
|
||||||
|
}
|
||||||
|
|
||||||
type WaveObjectValue<T> = {
|
type WaveObjectValue<T> = {
|
||||||
pendingPromise: Promise<any>;
|
pendingPromise: Promise<any>;
|
||||||
value: T;
|
dataAtom: jotai.PrimitiveAtom<{ value: T; loading: boolean }>;
|
||||||
loading: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const waveObjectValueCache = new Map<string, WaveObjectValue<any>>();
|
const waveObjectValueCache = new Map<string, WaveObjectValue<any>>();
|
||||||
let waveObjectAtomCache = new WeakMap<WaveObjectHookData, jotai.Atom<any>>();
|
|
||||||
|
|
||||||
function clearWaveObjectCache() {
|
function clearWaveObjectCache() {
|
||||||
waveObjectValueCache.clear();
|
waveObjectValueCache.clear();
|
||||||
waveObjectAtomCache = new WeakMap<WaveObjectHookData, jotai.Atom<any>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWaveObjectAtom<T>(oref: string): jotai.Atom<[T, boolean]> {
|
function createWaveValueObject<T>(oref: string): WaveObjectValue<T> {
|
||||||
let cacheVal: WaveObjectValue<T> = waveObjectValueCache.get(oref);
|
const wov = { pendingPromise: null, dataAtom: null };
|
||||||
if (cacheVal == null) {
|
wov.dataAtom = jotai.atom({ value: null, loading: true });
|
||||||
cacheVal = { pendingPromise: null, value: null, loading: true };
|
let startTs = Date.now();
|
||||||
cacheVal.pendingPromise = GetObject(oref).then((val) => {
|
let localPromise = GetObject<T>(oref);
|
||||||
cacheVal.value = val;
|
wov.pendingPromise = localPromise;
|
||||||
cacheVal.loading = false;
|
localPromise.then((val) => {
|
||||||
cacheVal.pendingPromise = null;
|
if (wov.pendingPromise != localPromise) {
|
||||||
});
|
return;
|
||||||
waveObjectValueCache.set(oref, cacheVal);
|
|
||||||
}
|
|
||||||
return jotai.atom(
|
|
||||||
(get) => {
|
|
||||||
return [cacheVal.value, cacheVal.loading];
|
|
||||||
},
|
|
||||||
(get, set, newVal: T) => {
|
|
||||||
cacheVal.value = newVal;
|
|
||||||
}
|
}
|
||||||
);
|
const [otype, oid] = splitORef(oref);
|
||||||
|
if (val != null) {
|
||||||
|
if (val["otype"] != otype) {
|
||||||
|
throw new Error("GetObject returned wrong type");
|
||||||
|
}
|
||||||
|
if (val["oid"] != oid) {
|
||||||
|
throw new Error("GetObject returned wrong id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wov.pendingPromise = null;
|
||||||
|
globalStore.set(wov.dataAtom, { value: val, loading: false });
|
||||||
|
console.log("GetObject resolved", oref, val, Date.now() - startTs + "ms");
|
||||||
|
});
|
||||||
|
return wov;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useWaveObjectValue<T>(oref: string): [T, boolean] {
|
function useWaveObjectValue<T>(oref: string): [T, boolean] {
|
||||||
const objRef = React.useRef<WaveObjectHookData>(null);
|
console.log("useWaveObjectValue", oref);
|
||||||
if (objRef.current == null) {
|
let wov = waveObjectValueCache.get(oref);
|
||||||
objRef.current = { oref: oref };
|
if (wov == null) {
|
||||||
|
console.log("creating new wov", oref);
|
||||||
|
wov = createWaveValueObject(oref);
|
||||||
|
waveObjectValueCache.set(oref, wov);
|
||||||
}
|
}
|
||||||
const objHookData = objRef.current;
|
const atomVal = jotai.useAtomValue(wov.dataAtom);
|
||||||
let objAtom = waveObjectAtomCache.get(objHookData);
|
return [atomVal.value, atomVal.loading];
|
||||||
if (objAtom == null) {
|
|
||||||
objAtom = createWaveObjectAtom(oref);
|
|
||||||
waveObjectAtomCache.set(objHookData, objAtom);
|
|
||||||
}
|
|
||||||
const atomVal = jotai.useAtomValue(objAtom);
|
|
||||||
return [atomVal[0], atomVal[1]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function useWaveObject<T>(oref: string): [T, boolean, (T) => void] {
|
function useWaveObject<T>(oref: string): [T, boolean, (T) => void] {
|
||||||
const objRef = React.useRef<WaveObjectHookData>(null);
|
console.log("useWaveObject", oref);
|
||||||
if (objRef.current == null) {
|
let wov = waveObjectValueCache.get(oref);
|
||||||
objRef.current = { oref: oref };
|
if (wov == null) {
|
||||||
|
wov = createWaveValueObject(oref);
|
||||||
|
waveObjectValueCache.set(oref, wov);
|
||||||
}
|
}
|
||||||
const objHookData = objRef.current;
|
const [atomVal, setAtomVal] = jotai.useAtom(wov.dataAtom);
|
||||||
let objAtom = waveObjectAtomCache.get(objHookData);
|
const simpleSet = (val: T) => {
|
||||||
if (objAtom == null) {
|
setAtomVal({ value: val, loading: false });
|
||||||
objAtom = createWaveObjectAtom(oref);
|
};
|
||||||
waveObjectAtomCache.set(objHookData, objAtom);
|
return [atomVal.value, atomVal.loading, simpleSet];
|
||||||
}
|
|
||||||
const [atomVal, setAtomVal] = jotai.useAtom(objAtom);
|
|
||||||
return [atomVal[0], atomVal[1], setAtomVal];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
globalStore,
|
globalStore,
|
||||||
|
makeORef,
|
||||||
atoms,
|
atoms,
|
||||||
getBlockSubject,
|
getBlockSubject,
|
||||||
addBlockIdToTab,
|
|
||||||
blockDataMap,
|
blockDataMap,
|
||||||
useBlockAtom,
|
useBlockAtom,
|
||||||
removeBlockFromTab,
|
|
||||||
GetObject,
|
GetObject,
|
||||||
|
GetClientObject,
|
||||||
useWaveObject,
|
useWaveObject,
|
||||||
useWaveObjectValue,
|
useWaveObjectValue,
|
||||||
clearWaveObjectCache,
|
clearWaveObjectCache,
|
||||||
|
@ -5,12 +5,16 @@ import * as React from "react";
|
|||||||
import * as jotai from "jotai";
|
import * as jotai from "jotai";
|
||||||
import { Block } from "@/app/block/block";
|
import { Block } from "@/app/block/block";
|
||||||
import { atoms } from "@/store/global";
|
import { atoms } from "@/store/global";
|
||||||
|
import * as gdata from "@/store/global";
|
||||||
|
|
||||||
import "./tab.less";
|
import "./tab.less";
|
||||||
|
import { CenteredLoadingDiv } from "../element/quickelems";
|
||||||
|
|
||||||
const TabContent = ({ tabId }: { tabId: string }) => {
|
const TabContent = ({ tabId }: { tabId: string }) => {
|
||||||
const tabs = jotai.useAtomValue(atoms.tabsAtom);
|
const [tabData, tabLoading] = gdata.useWaveObjectValue<Tab>(gdata.makeORef("tab", tabId));
|
||||||
const tabData = tabs.find((tab) => tab.tabid === tabId);
|
if (tabLoading) {
|
||||||
|
return <CenteredLoadingDiv />;
|
||||||
|
}
|
||||||
if (!tabData) {
|
if (!tabData) {
|
||||||
return <div className="tabcontent">Tab not found</div>;
|
return <div className="tabcontent">Tab not found</div>;
|
||||||
}
|
}
|
||||||
|
@ -5,32 +5,40 @@ import * as React from "react";
|
|||||||
import * as jotai from "jotai";
|
import * as jotai from "jotai";
|
||||||
import { TabContent } from "@/app/tab/tab";
|
import { TabContent } from "@/app/tab/tab";
|
||||||
import { clsx } from "clsx";
|
import { clsx } from "clsx";
|
||||||
import { atoms, addBlockIdToTab, blockDataMap } from "@/store/global";
|
import { atoms, blockDataMap } from "@/store/global";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { BlockService } from "@/bindings/blockservice";
|
import { BlockService } from "@/bindings/blockservice";
|
||||||
import { ClientService } from "@/bindings/clientservice";
|
import { ClientService } from "@/bindings/clientservice";
|
||||||
import { Workspace } from "@/gopkg/wstore";
|
import { Workspace } from "@/gopkg/wstore";
|
||||||
import * as wstore from "@/gopkg/wstore";
|
import * as wstore from "@/gopkg/wstore";
|
||||||
import * as jotaiUtil from "jotai/utils";
|
import * as jotaiUtil from "jotai/utils";
|
||||||
|
import * as gdata from "@/store/global";
|
||||||
|
|
||||||
import "./workspace.less";
|
import "./workspace.less";
|
||||||
import { CenteredLoadingDiv, CenteredDiv } from "../element/quickelems";
|
import { CenteredLoadingDiv, CenteredDiv } from "../element/quickelems";
|
||||||
|
|
||||||
function Tab({ tab }: { tab: wstore.Tab }) {
|
function Tab({ tabId }: { tabId: string }) {
|
||||||
const [activeTab, setActiveTab] = jotai.useAtom(atoms.activeTabId);
|
const windowData = jotai.useAtomValue(atoms.windowData);
|
||||||
|
const [tabData, tabLoading] = gdata.useWaveObjectValue<Tab>(gdata.makeORef("tab", tabId));
|
||||||
|
|
||||||
|
function setActiveTab(tabId: string) {
|
||||||
|
if (tabId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx("tab", { active: activeTab === tab.tabid })} onClick={() => setActiveTab(tab.tabid)}>
|
<div
|
||||||
{tab.name}
|
className={clsx("tab", { active: tabData != null && windowData.activetabid === tabData.oid })}
|
||||||
|
onClick={() => setActiveTab(tabData?.oid)}
|
||||||
|
>
|
||||||
|
{tabData?.name ?? "..."}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabBar() {
|
function TabBar({ workspace, waveWindow }: { workspace: Workspace; waveWindow: WaveWindow }) {
|
||||||
const [tabData, setTabData] = jotai.useAtom(atoms.tabsAtom);
|
|
||||||
const [activeTab, setActiveTab] = jotai.useAtom(atoms.activeTabId);
|
|
||||||
const tabs = jotai.useAtomValue(atoms.tabsAtom);
|
|
||||||
const client = jotai.useAtomValue(atoms.clientAtom);
|
|
||||||
|
|
||||||
function handleAddTab() {
|
function handleAddTab() {
|
||||||
const newTabId = uuidv4();
|
const newTabId = uuidv4();
|
||||||
const newTabName = "Tab " + (tabData.length + 1);
|
const newTabName = "Tab " + (tabData.length + 1);
|
||||||
@ -38,10 +46,11 @@ function TabBar() {
|
|||||||
setActiveTab(newTabId);
|
setActiveTab(newTabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tabIds = workspace?.tabids ?? [];
|
||||||
return (
|
return (
|
||||||
<div className="tab-bar">
|
<div className="tab-bar">
|
||||||
{tabs.map((tab, idx) => {
|
{tabIds.map((tabid, idx) => {
|
||||||
return <Tab key={idx} tab={tab} />;
|
return <Tab key={idx} tabId={tabid} />;
|
||||||
})}
|
})}
|
||||||
<div className="tab-add" onClick={() => handleAddTab()}>
|
<div className="tab-add" onClick={() => handleAddTab()}>
|
||||||
<i className="fa fa-solid fa-plus fa-fw" />
|
<i className="fa fa-solid fa-plus fa-fw" />
|
||||||
@ -51,7 +60,8 @@ function TabBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Widgets() {
|
function Widgets() {
|
||||||
const activeTabId = jotai.useAtomValue(atoms.activeTabId);
|
const windowData = jotai.useAtomValue(atoms.windowData);
|
||||||
|
const activeTabId = windowData.activetabid;
|
||||||
|
|
||||||
async function createBlock(blockDef: wstore.BlockDef) {
|
async function createBlock(blockDef: wstore.BlockDef) {
|
||||||
const rtOpts: wstore.RuntimeOpts = new wstore.RuntimeOpts({ termsize: { rows: 25, cols: 80 } });
|
const rtOpts: wstore.RuntimeOpts = new wstore.RuntimeOpts({ termsize: { rows: 25, cols: 80 } });
|
||||||
@ -113,27 +123,15 @@ function Widgets() {
|
|||||||
|
|
||||||
function WorkspaceElem() {
|
function WorkspaceElem() {
|
||||||
const windowData = jotai.useAtomValue(atoms.windowData);
|
const windowData = jotai.useAtomValue(atoms.windowData);
|
||||||
const activeTabId = jotai.useAtomValue(atoms.activeTabId);
|
const workspaceId = windowData?.workspaceid;
|
||||||
const workspaceId = windowData.workspaceid;
|
const activeTabId = windowData?.activetabid;
|
||||||
const wsAtom = React.useMemo(() => {
|
const [ws, wsLoading] = gdata.useWaveObjectValue<Workspace>(gdata.makeORef("workspace", workspaceId));
|
||||||
return jotaiUtil.loadable(
|
if (wsLoading) {
|
||||||
jotai.atom(async (get) => {
|
|
||||||
const ws = await ClientService.GetWorkspace(workspaceId);
|
|
||||||
return ws;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}, [workspaceId]);
|
|
||||||
const wsLoadable = jotai.useAtomValue(wsAtom);
|
|
||||||
if (wsLoadable.state === "loading") {
|
|
||||||
return <CenteredLoadingDiv />;
|
return <CenteredLoadingDiv />;
|
||||||
}
|
}
|
||||||
if (wsLoadable.state === "hasError") {
|
|
||||||
return <CenteredDiv>Error: {wsLoadable.error?.toString()}</CenteredDiv>;
|
|
||||||
}
|
|
||||||
const ws: Workspace = wsLoadable.data;
|
|
||||||
return (
|
return (
|
||||||
<div className="workspace">
|
<div className="workspace">
|
||||||
<TabBar />
|
<TabBar workspace={ws} waveWindow={windowData} />
|
||||||
<div className="workspace-tabcontent">
|
<div className="workspace-tabcontent">
|
||||||
<TabContent key={workspaceId} tabId={activeTabId} />
|
<TabContent key={workspaceId} tabId={activeTabId} />
|
||||||
<Widgets />
|
<Widgets />
|
||||||
|
2
frontend/types/custom.d.ts
vendored
2
frontend/types/custom.d.ts
vendored
@ -81,7 +81,7 @@ declare global {
|
|||||||
oid: string;
|
oid: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Window = {
|
type WaveWindow = {
|
||||||
otype: string;
|
otype: string;
|
||||||
oid: string;
|
oid: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
@ -7,7 +7,7 @@ import { App } from "./app/app";
|
|||||||
import { loadFonts } from "./util/fontutil";
|
import { loadFonts } from "./util/fontutil";
|
||||||
import { ClientService } from "@/bindings/clientservice";
|
import { ClientService } from "@/bindings/clientservice";
|
||||||
import { Client } from "@/gopkg/wstore";
|
import { Client } from "@/gopkg/wstore";
|
||||||
import { globalStore, atoms } from "@/store/global";
|
import { globalStore, atoms, GetClientObject, GetObject, makeORef } from "@/store/global";
|
||||||
import * as wailsRuntime from "@wailsio/runtime";
|
import * as wailsRuntime from "@wailsio/runtime";
|
||||||
import * as wstore from "@/gopkg/wstore";
|
import * as wstore from "@/gopkg/wstore";
|
||||||
import { immerable } from "immer";
|
import { immerable } from "immer";
|
||||||
@ -30,9 +30,9 @@ wstore.WinSize.prototype[immerable] = true;
|
|||||||
loadFonts();
|
loadFonts();
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
const client = await ClientService.GetClientData();
|
const client = await GetClientObject();
|
||||||
globalStore.set(atoms.clientAtom, client);
|
globalStore.set(atoms.clientAtom, client);
|
||||||
const window = await ClientService.GetWindow(windowId);
|
const window = await GetObject<WaveWindow>(makeORef("window", windowId));
|
||||||
globalStore.set(atoms.windowData, window);
|
globalStore.set(atoms.windowData, window);
|
||||||
let reactElem = React.createElement(App, null, null);
|
let reactElem = React.createElement(App, null, null);
|
||||||
let elem = document.getElementById("main");
|
let elem = document.getElementById("main");
|
||||||
|
@ -25,6 +25,16 @@ func parseORef(oref string) (*waveobj.ORef, error) {
|
|||||||
return &waveobj.ORef{OType: fields[0], OID: fields[1]}, nil
|
return &waveobj.ORef{OType: fields[0], OID: fields[1]}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *ObjectService) GetClientObject() (any, error) {
|
||||||
|
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
|
||||||
|
defer cancelFn()
|
||||||
|
client, err := wstore.DBGetSingleton[*wstore.Client](ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting client: %w", err)
|
||||||
|
}
|
||||||
|
return waveobj.ToJsonMap(client)
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *ObjectService) GetObject(orefStr string) (any, error) {
|
func (svc *ObjectService) GetObject(orefStr string) (any, error) {
|
||||||
oref, err := parseORef(orefStr)
|
oref, err := parseORef(orefStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -36,7 +46,7 @@ func (svc *ObjectService) GetObject(orefStr string) (any, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error getting object: %w", err)
|
return nil, fmt.Errorf("error getting object: %w", err)
|
||||||
}
|
}
|
||||||
return obj, nil
|
return waveobj.ToJsonMap(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ObjectService) GetObjects(orefStrArr []string) (any, error) {
|
func (svc *ObjectService) GetObjects(orefStrArr []string) (any, error) {
|
||||||
|
@ -124,7 +124,7 @@ func SetVersion(waveObj WaveObj, version int) {
|
|||||||
reflect.ValueOf(waveObj).Elem().FieldByIndex(desc.VersionField.Index).SetInt(int64(version))
|
reflect.ValueOf(waveObj).Elem().FieldByIndex(desc.VersionField.Index).SetInt(int64(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToJson(w WaveObj) ([]byte, error) {
|
func ToJsonMap(w WaveObj) (map[string]any, error) {
|
||||||
m := make(map[string]any)
|
m := make(map[string]any)
|
||||||
dconfig := &mapstructure.DecoderConfig{
|
dconfig := &mapstructure.DecoderConfig{
|
||||||
Result: &m,
|
Result: &m,
|
||||||
@ -139,6 +139,16 @@ func ToJson(w WaveObj) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m[OTypeKeyName] = w.GetOType()
|
m[OTypeKeyName] = w.GetOType()
|
||||||
|
m[OIDKeyName] = GetOID(w)
|
||||||
|
m[VersionKeyName] = GetVersion(w)
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToJson(w WaveObj) ([]byte, error) {
|
||||||
|
m, err := ToJsonMap(w)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return json.Marshal(m)
|
return json.Marshal(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,10 +263,18 @@ func typeToTSType(t reflect.Type) (string, []reflect.Type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tsRenameMap = map[string]string{
|
||||||
|
"Window": "WaveWindow",
|
||||||
|
}
|
||||||
|
|
||||||
func generateTSTypeInternal(rtype reflect.Type) (string, []reflect.Type) {
|
func generateTSTypeInternal(rtype reflect.Type) (string, []reflect.Type) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
waveObjType := reflect.TypeOf((*WaveObj)(nil)).Elem()
|
waveObjType := reflect.TypeOf((*WaveObj)(nil)).Elem()
|
||||||
buf.WriteString(fmt.Sprintf("type %s = {\n", rtype.Name()))
|
tsTypeName := rtype.Name()
|
||||||
|
if tsRename, ok := tsRenameMap[tsTypeName]; ok {
|
||||||
|
tsTypeName = tsRename
|
||||||
|
}
|
||||||
|
buf.WriteString(fmt.Sprintf("type %s = {\n", tsTypeName))
|
||||||
var isWaveObj bool
|
var isWaveObj bool
|
||||||
if rtype.Implements(waveObjType) || reflect.PointerTo(rtype).Implements(waveObjType) {
|
if rtype.Implements(waveObjType) || reflect.PointerTo(rtype).Implements(waveObjType) {
|
||||||
isWaveObj = true
|
isWaveObj = true
|
||||||
|
@ -209,8 +209,8 @@ func EnsureInitialData() error {
|
|||||||
return fmt.Errorf("error inserting workspace: %w", err)
|
return fmt.Errorf("error inserting workspace: %w", err)
|
||||||
}
|
}
|
||||||
tab := &Tab{
|
tab := &Tab{
|
||||||
OID: uuid.New().String(),
|
OID: tabId,
|
||||||
Name: "Tab 1",
|
Name: "Tab-1",
|
||||||
BlockIds: []string{},
|
BlockIds: []string{},
|
||||||
}
|
}
|
||||||
err = DBInsert(ctx, tab)
|
err = DBInsert(ctx, tab)
|
||||||
|
Loading…
Reference in New Issue
Block a user