From 9e39b7d0fd215db1360a81f83c1e440fab8e16bb Mon Sep 17 00:00:00 2001 From: Rizky Date: Sat, 9 Dec 2023 11:17:28 +0700 Subject: [PATCH] wip fix --- app/web/src/nova/ed/logic/ed-global.ts | 3 +- app/web/src/nova/ed/logic/tree/build.tsx | 52 +++--- .../src/nova/ed/logic/tree/sync-walk-comp.tsx | 59 +++---- app/web/src/nova/ed/logic/tree/sync-walk.tsx | 33 ++-- app/web/src/nova/ed/panel/main/main.tsx | 153 +++--------------- .../src/nova/ed/panel/popup/script/monaco.tsx | 125 +++++++------- .../src/nova/ed/panel/popup/script/scope.tsx | 8 +- .../src/nova/ed/panel/side/prop-instance.tsx | 2 +- .../ed/panel/side/prop-instance/prop-text.tsx | 16 +- .../src/nova/ed/panel/side/prop-master.tsx | 2 +- .../src/nova/ed/panel/tree/node/render.tsx | 6 +- app/web/src/nova/view/logic/load-code-old.ts | 5 +- app/web/src/utils/script/mount.tsx | 1 + 13 files changed, 170 insertions(+), 295 deletions(-) diff --git a/app/web/src/nova/ed/logic/ed-global.ts b/app/web/src/nova/ed/logic/ed-global.ts index 52c2295a..f57ece88 100644 --- a/app/web/src/nova/ed/logic/ed-global.ts +++ b/app/web/src/nova/ed/logic/ed-global.ts @@ -119,7 +119,8 @@ export type EdMeta = { mitem?: MItem; }; parent_mcomp?: { - mitem: MItem; + minstance: MItem; + meta: EdMeta; mcomp: MItem; }; el?: ReactElement; diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index b706f8c1..1f6852e1 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -45,32 +45,34 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { }); } - sections.map((e) => { - if (p.page.root_id === "root") { - p.page.entry.push(e.get("id")); - } - syncWalkMap( - { - note: "tree-rebuild layout", - comps: p.comp.list, - item_loading: p.ui.tree.item_loading, - meta: p.page.meta, - scope: p.page.scope, - }, - { - is_layout: true, - mitem: e, - parent_item: { id: p.page.root_id }, - tree_root_id: p.page.root_id, - skip_add_tree: true, - portal, - each(meta) { - if (meta.item.name === "content") { - p.page.root_id = meta.item.id; - } - }, + ldoc.doc.transact(() => { + sections.map((e) => { + if (p.page.root_id === "root") { + p.page.entry.push(e.get("id")); } - ); + syncWalkMap( + { + note: "tree-rebuild layout", + comps: p.comp.list, + item_loading: p.ui.tree.item_loading, + meta: p.page.meta, + scope: p.page.scope, + }, + { + is_layout: true, + mitem: e, + parent_item: { id: p.page.root_id }, + tree_root_id: p.page.root_id, + skip_add_tree: true, + portal, + each(meta) { + if (meta.item.name === "content") { + p.page.root_id = meta.item.id; + } + }, + } + ); + }); }); for (const [k, portal_out] of Object.entries(portal.out)) { diff --git a/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx b/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx index e5af6ed1..d1c2f23e 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx @@ -87,37 +87,38 @@ const walkCompTree = async (p: PG, mitem: MItem, comp_id: string) => { out: {} as Record, }; syncWalkLoad(p, mitem, (id) => loadComponent(p, id)); + mitem.doc?.transact(() => { + syncWalkMap( + { + note: "walk-comp", + comps: p.comp.list, + item_loading: p.ui.tree.item_loading, + meta, + tree, + component_not_found(id) { + setTimeout(() => { + if (loadcomp.pending.has(id) || p.comp.list[id]) { + waitUntil(() => !loadcomp.pending.has(id)).then(async () => { + walkCompTree(p, mitem, comp_id); - syncWalkMap( - { - note: "walk-comp", - comps: p.comp.list, - item_loading: p.ui.tree.item_loading, - meta, - tree, - component_not_found(id) { - setTimeout(() => { - if (loadcomp.pending.has(id) || p.comp.list[id]) { - waitUntil(() => !loadcomp.pending.has(id)).then(async () => { - walkCompTree(p, mitem, comp_id); - - const { tree, meta } = await walkCompTree(p, mitem, comp_id); - p.comp.list[comp_id].tree = tree; - p.comp.list[comp_id].meta = meta; - p.render(); - }); - } - }, 100); + const { tree, meta } = await walkCompTree(p, mitem, comp_id); + p.comp.list[comp_id].tree = tree; + p.comp.list[comp_id].meta = meta; + p.render(); + }); + } + }, 100); + }, }, - }, - { - mitem, - is_layout: false, - parent_item: { id: "root" }, - portal, - tree_root_id: "root", - } - ); + { + mitem, + is_layout: false, + parent_item: { id: "root" }, + portal, + tree_root_id: "root", + } + ); + }); return { tree, meta }; }; diff --git a/app/web/src/nova/ed/logic/tree/sync-walk.tsx b/app/web/src/nova/ed/logic/tree/sync-walk.tsx index 2b2defba..58feb0eb 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -81,7 +81,7 @@ export const syncWalkMap = ( each?: (meta: EdMeta) => void; } ) => { - const { mitem, parent_item, parent_mcomp } = arg; + const { mitem, parent_item } = arg; if (typeof mitem.get !== "function") { return; } @@ -98,8 +98,8 @@ export const syncWalkMap = ( } let mapped = false; - if (parent_mcomp && id) { - const fcomp = parent_mcomp.mitem.get("component"); + if (arg.parent_mcomp && id) { + const fcomp = arg.parent_mcomp.minstance.get("component"); if (fcomp) { const ref_ids = fcomp.get("ref_ids"); @@ -162,14 +162,20 @@ export const syncWalkMap = ( if (ref_comp && mitem_comp) { const mcomp = ref_comp.doc.getMap("map").get("root"); - if (mcomp) { - let ref_ids: Record = item_comp.ref_ids; - if (!ref_ids) { - mitem_comp.set("ref_ids", new Y.Map() as any); - ref_ids = {}; - } + const minstance = arg.parent_mcomp + ? arg.parent_mcomp.minstance + : (mitem as MItem); + let mref_ids = minstance.get("component")?.get("ref_ids"); + + if (!mref_ids) { + minstance.get("component")?.set("ref_ids", new Y.Map() as any); + mref_ids = minstance.get("component")?.get("ref_ids"); + } + + if (mcomp) { const old_id = item.id; + const ref_ids = mref_ids?.toJSON() || {}; mapItem(mcomp, item, ref_ids); item.id = old_id; @@ -177,10 +183,11 @@ export const syncWalkMap = ( item, mitem: mitem as MItem, parent_item, - parent_mcomp: parent_mcomp, + parent_mcomp: arg.parent_mcomp, indexed_scope: {}, is_layout: arg.is_layout, }; + if (item.name.startsWith("⬅")) { arg.portal.in[item.name] = meta; } @@ -232,7 +239,7 @@ export const syncWalkMap = ( tree_root_id: arg.tree_root_id, mitem: mcontent, jsx_prop_name: k, - parent_mcomp: arg.parent_mcomp, + parent_mcomp: { minstance, meta, mcomp }, parent_item: { id: item.id, mitem: mitem as MItem }, portal: arg.portal, skip_add_tree: skip_tree_child, @@ -254,7 +261,7 @@ export const syncWalkMap = ( tree_root_id: arg.tree_root_id, mitem: e, parent_item: { id: item.id, mitem: mitem as MItem }, - parent_mcomp: { mitem: mitem as MItem, mcomp }, + parent_mcomp: { minstance, meta, mcomp }, skip_add_tree: true, portal: arg.portal, each: arg.each, @@ -274,7 +281,7 @@ export const syncWalkMap = ( jsx_prop_name: arg.jsx_prop_name, mitem: mitem as MItem, parent_item, - parent_mcomp: parent_mcomp, + parent_mcomp: arg.parent_mcomp, indexed_scope: {}, }; diff --git a/app/web/src/nova/ed/panel/main/main.tsx b/app/web/src/nova/ed/panel/main/main.tsx index 6742d4ae..481876c4 100644 --- a/app/web/src/nova/ed/panel/main/main.tsx +++ b/app/web/src/nova/ed/panel/main/main.tsx @@ -1,11 +1,11 @@ -import { useGlobal, useLocal } from "web-utils"; +import { useEffect } from "react"; +import { useGlobal } from "web-utils"; import { Loading } from "../../../../utils/ui/loading"; import { View } from "../../../view/view"; -import { EDGlobal, active } from "../../logic/ed-global"; +import { EDGlobal, EdMeta, active } from "../../logic/ed-global"; import { getMetaById } from "../../logic/tree/build"; import { loadComponent } from "../../logic/tree/sync-walk"; import { code } from "../popup/code/code"; -import { useEffect } from "react"; export const EdMain = () => { const p = useGlobal(EDGlobal, "EDITOR"); @@ -49,60 +49,12 @@ export const EdMain = () => { }} hover={{ get(meta) { - const item = meta.item; - - if (active.comp_id) { - const p = meta.parent_mcomp; - if (p) { - if ( - p.mitem.get("id") !== active.instance.item_id || - p.mcomp.get("component")?.get("id") !== active.comp_id - ) - return false; - } - } - - if ( - item.originalId === active.hover_id || - item.id === active.hover_id - ) - return true; - - return false; + return active.hover_id === meta.item.id; }, set(meta) { - if (meta.parent_mcomp) { - const id = meta.parent_mcomp.mitem.get("id"); - if (active.instance.item_id !== id) { - const original_id = - meta.parent_mcomp.mitem.get("originalId"); - - if (active.comp_id && original_id) { - active.hover_id = original_id; - } else if (id) { - active.hover_id = id; - } - - p.render(); - p.page.render(); - focus(); - - return; - } - } - - if (active.comp_id) { - const parent = meta.parent_mcomp; - if (parent) { - const mcomp = parent.mcomp; - if (mcomp.get("component")?.get("id") === active.comp_id) { - active.hover_id = meta.item.originalId || meta.item.id; - } - } else { - active.hover_id = meta.item.id; - } - } else { - active.hover_id = meta.item.id; + const outer = getOuterItem(meta); + if (outer) { + active.hover_id = outer.id; } p.render(); @@ -111,86 +63,12 @@ export const EdMain = () => { }} active={{ get(meta) { - const item = meta.item; - - if (active.comp_id) { - const p = meta.parent_mcomp; - if (p) { - if ( - p.mitem.get("id") !== active.instance.item_id || - p.mcomp.get("component")?.get("id") !== active.comp_id - ) - return false; - } - } - - if ( - item.originalId === active.item_id || - item.id === active.item_id - ) - return true; - - return false; + return active.item_id === meta.item.id; }, set(meta) { - if (meta.parent_mcomp) { - const id = meta.parent_mcomp.mitem.get("id"); - if (active.instance.item_id !== id) { - const original_id = - meta.parent_mcomp.mitem.get("originalId"); - - let active_id = ""; - if (active.comp_id && original_id) { - active_id = original_id; - } else if (id) { - active_id = id; - } - - if (active_id) { - if (active.item_id !== active_id) { - active.item_id = active_id; - } else { - const comp_id = meta.parent_mcomp.mcomp - .get("component") - ?.get("id"); - if (comp_id) { - active.instance.item_id = active_id; - active.instance.comp_id = active.comp_id; - - active.comp_id = comp_id || ""; - const root = p.comp.list[comp_id].tree.find( - (e) => e.parent === "root" - ); - if (root && typeof root.id === "string") { - active.item_id = root.id || ""; - } - } - } - } - - p.render(); - p.page.render(); - focus(); - - return; - } - } - - if (active.comp_id) { - const parent = meta.parent_mcomp; - if (parent) { - const mcomp = parent.mcomp; - if (mcomp.get("component")?.get("id") === active.comp_id) { - active.item_id = meta.item.originalId || meta.item.id; - } - } else { - active.comp_id = ""; - active.item_id = meta.item.id; - active.instance.item_id = ""; - active.instance.comp_id = ""; - } - } else { - active.item_id = meta.item.id; + const outer = getOuterItem(meta); + if (outer) { + active.item_id = outer.id; } p.render(); @@ -274,6 +152,15 @@ export const EdMain = () => { ); }; +const getOuterItem = (meta: EdMeta) => { + let cur: undefined | EdMeta = meta; + while (cur.parent_mcomp) { + cur = cur.parent_mcomp.meta; + } + + return cur.item; +}; + function setEndOfContenteditable(div: any) { let range: any, sel: any; if (document.createRange) { diff --git a/app/web/src/nova/ed/panel/popup/script/monaco.tsx b/app/web/src/nova/ed/panel/popup/script/monaco.tsx index da381345..e325c1f7 100644 --- a/app/web/src/nova/ed/panel/popup/script/monaco.tsx +++ b/app/web/src/nova/ed/panel/popup/script/monaco.tsx @@ -23,6 +23,8 @@ export const ScriptMonaco = () => { editor: null as null | MonacoEditor, monaco: null as null | Monaco, changeTimeout: 0 as any, + init: false, + value: "", historyOpen: false, idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"), }); @@ -45,33 +47,57 @@ export const ScriptMonaco = () => { }, []); useEffect(() => { - if (local.monaco && local.editor) { - local.monaco.editor.getModels().forEach((model) => { - const uri = model.uri.toString(); - if ( - uri.startsWith("inmemory://model") || - uri.startsWith("ts:comp-") || - uri.startsWith("ts:page-") - ) { - model.dispose(); - } - }); + (async () => { + const editor = local.editor; + const monaco = local.monaco; + if (monaco && editor) { + if (!local.init) { + if (p.ui.popup.script.mode === "js") { + monaco.editor.getModels().forEach((model) => { + model.dispose(); + }); + monaco.editor.getModels().forEach((model) => { + if (model.uri.toString().startsWith("inmemory://model")) { + model.dispose(); + } + }); - let model = local.monaco.editor.createModel( - val, - "typescript", - local.monaco.Uri.parse( - `ts:${ - active.comp_id ? `comp-${active.comp_id}` : `page-${p.page.cur.id}` - }-${active.item_id}.tsx` - ) - ); - local.editor.setModel(model); - declareScope(p, local.editor, local.monaco).then(() => { - local.render(); - }); - } - }, [active.item_id, val]); + let model = monaco.editor.createModel( + val, + "typescript", + monaco.Uri.parse( + `ts:${ + active.comp_id + ? `comp-${active.comp_id}` + : `page-${p.page.cur.id}` + }-${active.item_id}.tsx` + ) + ); + editor.setModel(model); + await jsMount(editor, monaco, p); + await monacoTypings( + { + site_dts: p.site_dts, + script: { + siteTypes: {}, + }, + site: p.site.config, + }, + monaco, + { types: {}, values: {} } + ); + declareScope(p, editor, monaco).then(() => { + local.render(); + }); + } + + local.init = true; + local.value = val; + local.render(); + } + } + })(); + }, [active.item_id, local.monaco, local.editor]); if (!meta) return null; @@ -121,9 +147,9 @@ export const ScriptMonaco = () => { } else if ( item.type === "item" && item.component?.id && - meta.parent_mcomp?.mitem + meta.parent_mcomp?.meta.mitem ) { - mitem = meta.parent_mcomp?.mitem; + mitem = meta.parent_mcomp?.meta.mitem; if (!mitem) { active.item_id = ""; @@ -170,11 +196,8 @@ async () => { } } - if (!meta) return null; - return ( { language={ { css: "scss", js: "typescript", html: "html" }[p.ui.popup.script.mode] } + value={local.value} onChange={(val) => { + local.value = val || ""; + local.render(); clearTimeout(scriptEdit.timeout); scriptEdit.timeout = setTimeout(() => { const meta = getMetaById(p, active.item_id); @@ -222,46 +248,13 @@ async () => { }, 1000); }} onMount={async (editor, monaco) => { + local.monaco = monaco; local.editor = editor; + local.render(); editor.focus(); setTimeout(() => { editor.focus(); }, 300); - - const value = editor.getValue(); - if (p.ui.popup.script.mode === "js") { - monaco.editor.getModels().forEach((model) => { - if (model.uri.toString().startsWith("inmemory://model")) { - model.dispose(); - } - }); - - let model = monaco.editor.createModel( - value, - "typescript", - monaco.Uri.parse( - `ts:${ - active.comp_id - ? `comp-${active.comp_id}` - : `page-${p.page.cur.id}` - }-${active.item_id}.tsx` - ) - ); - editor.setModel(model); - await jsMount(editor, monaco, p); - await monacoTypings( - { - site_dts: p.site_dts, - script: { - siteTypes: {}, - }, - site: p.site.config, - }, - monaco, - { types: {}, values: {} } - ); - await declareScope(p, editor, monaco); - } }} /> ); diff --git a/app/web/src/nova/ed/panel/popup/script/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope.tsx index 9c780b41..4eec377d 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope.tsx @@ -20,11 +20,6 @@ export const declareScope = async ( if (!s) return; s.p.push(active_id); - monaco.editor.getModels().forEach((model) => { - if (model.uri.toString().startsWith("ts:scope~")) { - model.dispose(); - } - }); const existing: Record = {}; @@ -143,7 +138,8 @@ const spreadScope = ( if (!item) { if (meta) { if (meta.parent_mcomp) { - comp_id = meta.parent_mcomp.mitem.get("component")?.get("id") || ""; + comp_id = + meta.parent_mcomp.meta.mitem?.get("component")?.get("id") || ""; if (comp_id) { const scope = p.comp.list[comp_id].scope; item = scope[meta.item.originalId || meta.item.id]; diff --git a/app/web/src/nova/ed/panel/side/prop-instance.tsx b/app/web/src/nova/ed/panel/side/prop-instance.tsx index 856e9b65..64c54beb 100644 --- a/app/web/src/nova/ed/panel/side/prop-instance.tsx +++ b/app/web/src/nova/ed/panel/side/prop-instance.tsx @@ -95,7 +95,7 @@ export const EdSidePropInstance: FC<{ meta: EdMeta }> = ({ meta }) => { -
+
{local.rightClickEvent && ( { - if (val) { - try { - eval(`local.value = ${valBuilt}`); - } catch (e) {} - } else { - local.value = ""; - } - local.render(); - }, [val, valBuilt]); - return (
diff --git a/app/web/src/nova/ed/panel/side/prop-master.tsx b/app/web/src/nova/ed/panel/side/prop-master.tsx index 8f683476..aec736cd 100644 --- a/app/web/src/nova/ed/panel/side/prop-master.tsx +++ b/app/web/src/nova/ed/panel/side/prop-master.tsx @@ -92,7 +92,7 @@ export const EdSidePropComp: FC<{ meta: EdMeta }> = ({ meta }) => { Back to Instance
-
+
(propRef.el = ref)} diff --git a/app/web/src/nova/ed/panel/tree/node/render.tsx b/app/web/src/nova/ed/panel/tree/node/render.tsx index f00bc2c8..5b512b22 100644 --- a/app/web/src/nova/ed/panel/tree/node/render.tsx +++ b/app/web/src/nova/ed/panel/tree/node/render.tsx @@ -33,11 +33,11 @@ export const nodeRender: NodeRender = (node, prm) => { const meta = getMetaById(p, node.data?.parent_item.id); if (meta) { if (meta.propvis) { - jsxPropVisCache[node.data.item.id] = meta.propvis; + jsxPropVisCache[meta.item.id] = meta.propvis; if (meta.propvis[node.data.jsx_prop_name] === false) return <>; } else { - if (jsxPropVisCache[node.data.item.id]) { - meta.propvis = jsxPropVisCache[node.data.item.id]; + if (jsxPropVisCache[meta.item.id]) { + meta.propvis = jsxPropVisCache[meta.item.id]; if (meta.propvis) { if (meta.propvis[node.data.jsx_prop_name] === false) return <>; } diff --git a/app/web/src/nova/view/logic/load-code-old.ts b/app/web/src/nova/view/logic/load-code-old.ts index f411b851..44a1cfe2 100644 --- a/app/web/src/nova/view/logic/load-code-old.ts +++ b/app/web/src/nova/view/logic/load-code-old.ts @@ -1,6 +1,6 @@ import importModule from "../../../render/editor/tools/dynamic-import"; import { devLoader } from "../../../render/live/dev-loader"; -import { createAPI, createDB } from "../../../utils/script/init-api"; +import { createAPI, createDB, initApi } from "../../../utils/script/init-api"; import { VG } from "./global"; export const oldLoadCode = async (v: VG) => { @@ -21,11 +21,12 @@ export const oldLoadCode = async (v: VG) => { } } + await initApi(site.config); await importModule(loader.npm(p, "site", site.id)); if (site.js_compiled) { const config = site.config as any; const exec = (fn: string, scopes: any) => { - if (config.api_url) { + if (config.api_url && !scopes["api"]) { scopes["api"] = createAPI(config.api_url); scopes["db"] = createDB(config.api_url); } diff --git a/app/web/src/utils/script/mount.tsx b/app/web/src/utils/script/mount.tsx index 86df05d2..c63cbb76 100644 --- a/app/web/src/utils/script/mount.tsx +++ b/app/web/src/utils/script/mount.tsx @@ -39,6 +39,7 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => { if (p) { p.ui.popup.script.mode === "js"; const cpath = r.path.substring(`scope~`.length).split("__"); + const [comp_id, prev_comp_id, prev_item_id] = cpath[0].split("~"); if (cpath[1]) { const path = cpath[1].split("~");