From 67b0e50afb09eccac7a2c35a63da177f7c0f6218 Mon Sep 17 00:00:00 2001 From: Rizky Date: Sun, 19 Nov 2023 20:04:02 +0700 Subject: [PATCH] wip fix render --- app/web/src/nova/ed/logic/ed-global.ts | 2 + app/web/src/nova/ed/logic/tree/build.tsx | 12 +++-- app/web/src/nova/ed/panel/header/left/api.tsx | 27 +++++------- app/web/src/nova/ed/panel/header/left/js.tsx | 21 ++++----- app/web/src/nova/ed/panel/header/top-btn.tsx | 3 ++ app/web/src/nova/ed/panel/main/main.tsx | 27 +++++++++++- .../src/nova/ed/panel/main/pane-resize.tsx | 6 +-- .../src/nova/ed/panel/tree/node/item/name.tsx | 6 +++ .../src/nova/ed/panel/tree/node/render.tsx | 9 +++- app/web/src/nova/view/logic/global.ts | 16 ++++++- app/web/src/nova/view/logic/init.ts | 2 +- app/web/src/nova/view/logic/load-code.ts | 8 ++-- app/web/src/nova/view/render/entry.tsx | 4 +- app/web/src/nova/view/render/meta.tsx | 11 ----- .../src/nova/view/render/meta/children.tsx | 21 +++++++++ app/web/src/nova/view/render/meta/elprop.tsx | 0 app/web/src/nova/view/render/meta/meta.tsx | 26 +++++++++++ app/web/src/nova/view/render/meta/render.tsx | 44 +++++++++++++++++++ app/web/src/nova/view/render/meta/script.tsx | 13 ++++++ app/web/src/nova/view/render/section.tsx | 6 --- app/web/src/nova/view/view.tsx | 37 +++++++++++----- 21 files changed, 226 insertions(+), 75 deletions(-) delete mode 100644 app/web/src/nova/view/render/meta.tsx create mode 100644 app/web/src/nova/view/render/meta/children.tsx create mode 100644 app/web/src/nova/view/render/meta/elprop.tsx create mode 100644 app/web/src/nova/view/render/meta/meta.tsx create mode 100644 app/web/src/nova/view/render/meta/render.tsx create mode 100644 app/web/src/nova/view/render/meta/script.tsx delete mode 100644 app/web/src/nova/view/render/section.tsx diff --git a/app/web/src/nova/ed/logic/ed-global.ts b/app/web/src/nova/ed/logic/ed-global.ts index c224974c..f4a474cd 100644 --- a/app/web/src/nova/ed/logic/ed-global.ts +++ b/app/web/src/nova/ed/logic/ed-global.ts @@ -36,6 +36,7 @@ const EmptyComp = { const target = { active_id: false as any }; export const active = { + hover_id: "", get item_id() { if (target.active_id === false) { target.active_id = localStorage.getItem("prasi-active-id") || ""; @@ -63,6 +64,7 @@ export type EdMeta = { }; export const EDGlobal = { + mode: "" as "desktop" | "mobile", user: { id: "", username: "", client_id: "" }, clients: {} as Record, status: "init" as diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index 2bacb07c..db248b00 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -1,7 +1,7 @@ import { createId } from "@paralleldrive/cuid2"; import { decompress } from "wasm-gzip"; import { syncronize } from "y-pojo"; -import { TypedMap } from "yjs-types"; +import { TypedArray, TypedMap } from "yjs-types"; import { MContent } from "../../../../utils/types/general"; import { IItem, MItem } from "../../../../utils/types/item"; import { @@ -10,7 +10,7 @@ import { FNCompDef, FNComponent, } from "../../../../utils/types/meta-fn"; -import { DComp, IRoot } from "../../../../utils/types/root"; +import { DComp } from "../../../../utils/types/root"; import { MSection } from "../../../../utils/types/section"; import { EdMeta, PG } from "../ed-global"; @@ -28,7 +28,6 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { const loaded = new Set(); await Promise.all( sections.map((e) => { - p.page.entry.push(e.get("id")); return walkLoad(p, e, loaded); }) ); @@ -66,6 +65,7 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { p.page.building = false; p.render(); + p.page.render(); } }; @@ -80,7 +80,11 @@ const mapItem = (mitem: MContent, item: any) => { } item[k] = val; } else { - item[k] = []; + if (!item[k]) item[k] = []; + const childs = e as unknown as TypedArray<{}>; + childs.forEach((c) => { + item[k].push({ id: c.get("id") }); + }); } }); }; diff --git a/app/web/src/nova/ed/panel/header/left/api.tsx b/app/web/src/nova/ed/panel/header/left/api.tsx index 64167fc0..e0fa8d3b 100644 --- a/app/web/src/nova/ed/panel/header/left/api.tsx +++ b/app/web/src/nova/ed/panel/header/left/api.tsx @@ -5,25 +5,20 @@ export const EdApi = () => { return ( } placement="right" > -
-
API
-
+
+ + `, + }} + >
); }; diff --git a/app/web/src/nova/ed/panel/header/left/js.tsx b/app/web/src/nova/ed/panel/header/left/js.tsx index 78d7a405..339c2c4a 100644 --- a/app/web/src/nova/ed/panel/header/left/js.tsx +++ b/app/web/src/nova/ed/panel/header/left/js.tsx @@ -7,24 +7,19 @@ export const EdSiteJS = () => { return ( { p.ui.popup.code.open = true; p.render(); }} > - - - +
`, + }} + >
); }; diff --git a/app/web/src/nova/ed/panel/header/top-btn.tsx b/app/web/src/nova/ed/panel/header/top-btn.tsx index 0bf4afcf..da1fba5b 100644 --- a/app/web/src/nova/ed/panel/header/top-btn.tsx +++ b/app/web/src/nova/ed/panel/header/top-btn.tsx @@ -6,6 +6,7 @@ import { useLocal } from "web-utils"; export const TopBtn = ({ children, className, + innerClassName, disabled, underlight, onClick, @@ -15,6 +16,7 @@ export const TopBtn = ({ }: { children: ReactNode; className?: string; + innerClassName?: string; disabled?: boolean; underlight?: string; onClick?: React.MouseEventHandler; @@ -76,6 +78,7 @@ export const TopBtn = ({ local.open = open; local.render(); }} + className={innerClassName} placement={placement} > {result} diff --git a/app/web/src/nova/ed/panel/main/main.tsx b/app/web/src/nova/ed/panel/main/main.tsx index de1eac95..09af635e 100644 --- a/app/web/src/nova/ed/panel/main/main.tsx +++ b/app/web/src/nova/ed/panel/main/main.tsx @@ -1,7 +1,7 @@ import { useGlobal } from "web-utils"; import { Loading } from "../../../../utils/ui/loading"; import { View } from "../../../view/view"; -import { EDGlobal } from "../../logic/ed-global"; +import { EDGlobal, active } from "../../logic/ed-global"; import { loadComponent } from "../../logic/tree/build"; export const EdMain = () => { @@ -11,6 +11,7 @@ export const EdMain = () => { {!!p.page.building && } {!p.page.building && ( { bind={({ render }) => { p.page.render = render; }} + hidden={(item) => { + if (item.hidden) return true; + return false; + }} + hover={{ + get(item) { + return active.hover_id === item.id; + }, + set(id) { + active.hover_id = id; + p.render(); + p.page.render(); + }, + }} + active={{ + get(item) { + return active.item_id === item.id; + }, + set(id) { + active.item_id = id; + p.render(); + p.page.render(); + }, + }} /> )} diff --git a/app/web/src/nova/ed/panel/main/pane-resize.tsx b/app/web/src/nova/ed/panel/main/pane-resize.tsx index 1718a0c7..51a79b26 100644 --- a/app/web/src/nova/ed/panel/main/pane-resize.tsx +++ b/app/web/src/nova/ed/panel/main/pane-resize.tsx @@ -46,7 +46,7 @@ const EdPaneResize = (arg: { <> {local.dragging && (
{ local.inzone = true; }} @@ -67,8 +67,8 @@ const EdPaneResize = (arg: {
{ arg.onResize(local.default); diff --git a/app/web/src/nova/ed/panel/tree/node/item/name.tsx b/app/web/src/nova/ed/panel/tree/node/item/name.tsx index 3e1e069d..8f3d788f 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/name.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/name.tsx @@ -37,6 +37,12 @@ export const EdTreeName = ({ onFocus={(e) => { e.currentTarget.select(); }} + onBlur={() => { + item.name = local.rename; + mitem.set("name", item.name); + p.ui.tree.rename_id = ""; + p.render(); + }} onKeyDown={(e) => { e.stopPropagation(); if (e.key === "Enter" || e.key === "Escape") { 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 516ef05b..77316f87 100644 --- a/app/web/src/nova/ed/panel/tree/node/render.tsx +++ b/app/web/src/nova/ed/panel/tree/node/render.tsx @@ -42,7 +42,8 @@ export const nodeRender: NodeRender = (node, prm) => { `, active.item_id === item.id ? ["bg-blue-100"] - : ["hover:bg-blue-50", isComponent && `bg-purple-50`] + : [isComponent && `bg-purple-50`], + active.hover_id === item.id && "bg-blue-50" )} onKeyDown={(e) => { p.ui.prevent_indent_hook = true; @@ -237,6 +238,12 @@ export const nodeRender: NodeRender = (node, prm) => { active.item_id = item.id; p.ui.tree.search = ""; p.render(); + p.page.render(); + }} + onMouseOver={() => { + active.hover_id = item.id; + p.render(); + p.page.render(); }} >
diff --git a/app/web/src/nova/view/logic/global.ts b/app/web/src/nova/view/logic/global.ts index 3d59c223..4c5e3400 100644 --- a/app/web/src/nova/view/logic/global.ts +++ b/app/web/src/nova/view/logic/global.ts @@ -1,12 +1,26 @@ import { ReactElement } from "react"; +import { IContent } from "../../../utils/types/general"; +import { IItem } from "../../../utils/types/item"; +import { ISection } from "../../../utils/types/section"; +import { IText } from "../../../utils/types/text"; import { EdMeta } from "../../ed/logic/ed-global"; export const ViewGlobal = { - mode: "init" as "init" | "load-code" | "loading-code" | "ready" | "rebuild", + mode: "" as "desktop" | "mobile", + status: "init" as "init" | "load-code" | "loading-code" | "ready" | "rebuild", current: { site_id: "", page_id: "" }, meta: {} as Record, entry: [] as string[], bodyCache: null as null | ReactElement, + view: { + hidden: undefined as undefined | ((item: IContent) => boolean), + active: undefined as + | undefined + | { get: (item: IContent) => boolean; set: (id: string) => void }, + hover: undefined as + | undefined + | { get: (item: IContent) => boolean; set: (id: string) => void }, + }, }; export type VG = typeof ViewGlobal & { render: () => void }; diff --git a/app/web/src/nova/view/logic/init.ts b/app/web/src/nova/view/logic/init.ts index b0be3a9f..2e15f55e 100644 --- a/app/web/src/nova/view/logic/init.ts +++ b/app/web/src/nova/view/logic/init.ts @@ -7,7 +7,7 @@ export const vInit = ( ) => { const { load, site_id, page_id } = arg; - v.mode = "load-code"; + v.status = "load-code"; v.current.site_id = site_id; v.current.page_id = page_id; diff --git a/app/web/src/nova/view/logic/load-code.ts b/app/web/src/nova/view/logic/load-code.ts index 554f430a..0cf2647a 100644 --- a/app/web/src/nova/view/logic/load-code.ts +++ b/app/web/src/nova/view/logic/load-code.ts @@ -9,12 +9,12 @@ const codeMap = { export const vLoadCode = async (v: VG, forceLoad?: boolean) => { if (forceLoad) { codeLoaded.clear(); - v.mode = "load-code"; + v.status = "load-code"; v.render(); } - if (v.mode === "load-code") { - v.mode = "loading-code"; + if (v.status === "load-code") { + v.status = "loading-code"; const { site_id, page_id } = v.current; const w = window as any; @@ -78,7 +78,7 @@ export const vLoadCode = async (v: VG, forceLoad?: boolean) => { await Promise.all(promises); - v.mode = "rebuild"; + v.status = "rebuild"; v.render(); } }; diff --git a/app/web/src/nova/view/render/entry.tsx b/app/web/src/nova/view/render/entry.tsx index bd3cd109..ec38dae9 100644 --- a/app/web/src/nova/view/render/entry.tsx +++ b/app/web/src/nova/view/render/entry.tsx @@ -1,6 +1,6 @@ import { useGlobal } from "web-utils"; import { ViewGlobal } from "../logic/global"; -import { VSection } from "./section"; +import { ViewMeta } from "./meta/meta"; export const VEntry = () => { const v = useGlobal(ViewGlobal, "VIEW"); @@ -8,7 +8,7 @@ export const VEntry = () => { return ( <> {v.entry.map((section_id) => { - return ; + return ; })} ); diff --git a/app/web/src/nova/view/render/meta.tsx b/app/web/src/nova/view/render/meta.tsx deleted file mode 100644 index 89d42426..00000000 --- a/app/web/src/nova/view/render/meta.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { FC } from "react"; -import { useGlobal } from "web-utils"; -import { ViewGlobal } from "../logic/global"; - -export const ViewMeta: FC<{ id: string }> = ({ id }) => { - const v = useGlobal(ViewGlobal, "VIEW"); - - const meta = v.meta[id]; - const item = meta.item; - return
; -}; diff --git a/app/web/src/nova/view/render/meta/children.tsx b/app/web/src/nova/view/render/meta/children.tsx new file mode 100644 index 00000000..d059998c --- /dev/null +++ b/app/web/src/nova/view/render/meta/children.tsx @@ -0,0 +1,21 @@ +import { FC, ReactNode } from "react"; +import { IItem } from "../../../../utils/types/item"; +import { IText } from "../../../../utils/types/text"; +import { ISection } from "../../../../utils/types/section"; +import { ViewMeta } from "./meta"; + +export const ViewMetaChildren: FC<{ item: IItem | IText | ISection }> = ({ + item, +}) => { + const children: ReactNode[] = []; + + if (item.type !== "text") { + for (const child of item.childs) { + children.push(); + } + } else { + return ; + } + + return <>{children}; +}; diff --git a/app/web/src/nova/view/render/meta/elprop.tsx b/app/web/src/nova/view/render/meta/elprop.tsx new file mode 100644 index 00000000..e69de29b diff --git a/app/web/src/nova/view/render/meta/meta.tsx b/app/web/src/nova/view/render/meta/meta.tsx new file mode 100644 index 00000000..5d3d7eaf --- /dev/null +++ b/app/web/src/nova/view/render/meta/meta.tsx @@ -0,0 +1,26 @@ +import { FC } from "react"; +import { useGlobal } from "web-utils"; +import { ViewGlobal } from "../../logic/global"; +import { ViewMetaRender } from "./render"; +import { ViewMetaScript } from "./script"; + +export const ViewMeta: FC<{ id: string }> = ({ id }) => { + const v = useGlobal(ViewGlobal, "VIEW"); + + const meta = v.meta[id]; + const item = meta.item; + + if (item.hidden && v.view.hidden) { + if (v.view.hidden(item)) { + return null; + } + } + + if (item.adv) { + if (item.adv.js) { + return ; + } + } + + return ; +}; diff --git a/app/web/src/nova/view/render/meta/render.tsx b/app/web/src/nova/view/render/meta/render.tsx new file mode 100644 index 00000000..5d4c9b99 --- /dev/null +++ b/app/web/src/nova/view/render/meta/render.tsx @@ -0,0 +1,44 @@ +import { FC } from "react"; +import { IContent } from "../../../../utils/types/general"; +import { VG } from "../../logic/global"; +import { ViewMetaChildren } from "./children"; +import { produceCSS } from "../../../../utils/css/gen"; + +export const ViewMetaRender: FC<{ item: IContent; v: VG; props?: any }> = ({ + item, + v, + props, +}) => { + const className = produceCSS(item, { + mode: v.mode, + hover: v.view.hover ? v.view.hover.get(item) : undefined, + active: v.view.active ? v.view.active.get(item) : undefined, + }); + + return ( +
{ + e.stopPropagation(); + e.preventDefault(); + v.view.hover?.set(item.id); + } + : props?.onPointerOver + } + onClick={ + v.view.active + ? (e) => { + e.stopPropagation(); + e.preventDefault(); + v.view.active?.set(item.id); + } + : props?.onClick + } + > + +
+ ); +}; diff --git a/app/web/src/nova/view/render/meta/script.tsx b/app/web/src/nova/view/render/meta/script.tsx new file mode 100644 index 00000000..edf5248c --- /dev/null +++ b/app/web/src/nova/view/render/meta/script.tsx @@ -0,0 +1,13 @@ +import { FC } from "react"; +import { IItem } from "../../../../utils/types/item"; +import { ISection } from "../../../../utils/types/section"; +import { IText } from "../../../../utils/types/text"; +import { VG } from "../../logic/global"; +import { ViewMetaRender } from "./render"; + +export const ViewMetaScript: FC<{ + v: VG; + item: IItem | IText | ISection; +}> = ({ item, v }) => { + return ; +}; diff --git a/app/web/src/nova/view/render/section.tsx b/app/web/src/nova/view/render/section.tsx deleted file mode 100644 index eb97916a..00000000 --- a/app/web/src/nova/view/render/section.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { FC } from "react"; -import { ViewMeta } from "./meta"; - -export const VSection: FC<{ id: string }> = ({ id }) => { - return ; -}; diff --git a/app/web/src/nova/view/view.tsx b/app/web/src/nova/view/view.tsx index e03ba5b1..2b744bd0 100644 --- a/app/web/src/nova/view/view.tsx +++ b/app/web/src/nova/view/view.tsx @@ -1,51 +1,64 @@ import { FC } from "react"; import { useGlobal } from "web-utils"; import { Loading } from "../../utils/ui/loading"; -import { ViewGlobal } from "./logic/global"; +import { VG, ViewGlobal } from "./logic/global"; import { vInit } from "./logic/init"; import { vLoadCode } from "./logic/load-code"; import { VLoad, VLoadComponent } from "./logic/types"; import { VEntry } from "./render/entry"; +import { IContent } from "../../utils/types/general"; export const View: FC<{ load: VLoad; component: VLoadComponent; site_id: string; page_id: string; + mode: "desktop" | "mobile"; bind?: (arg: { render: () => void }) => void; -}> = ({ load, site_id, page_id, bind: onLoad }) => { + hidden?: (item: IContent) => boolean; + hover?: { get: (item: IContent) => boolean; set: (id: string) => void }; + active?: { get: (item: IContent) => boolean; set: (id: string) => void }; +}> = ({ load, site_id, page_id, bind, hover, active, hidden }) => { const v = useGlobal(ViewGlobal, "VIEW"); + if (hidden) v.view.hidden = hidden; + if (hover) v.view.hover = hover; + if (active) v.view.active = active; + if (v.current.page_id !== page_id || v.current.site_id !== site_id) { - v.mode = "init"; + v.status = "init"; } - if (onLoad) { - onLoad({ + if (bind) { + bind({ render() { - v.mode = "rebuild"; + v.status = "rebuild"; v.render(); }, }); } - if (v.mode === "init") { + if (v.status === "init") { vInit(v, { load, page_id, site_id }); - if (v.mode === "init") { + if (v.status === "init") { return ; } } - if (v.mode === "load-code" || v.mode === "loading-code") { + if (v.status === "load-code" || v.status === "loading-code") { vLoadCode(v); - if (v.mode === "load-code" || v.mode === "loading-code") { + if (v.status === "load-code" || v.status === "loading-code") { return ; } } - if (v.mode === "rebuild") { + if (v.status === "rebuild") { + if (load.mode === "tree_meta") { + v.meta = load.meta; + v.entry = load.entry; + } v.bodyCache = ; - v.mode = "ready"; + v.status = "ready"; } return
{v.bodyCache}
;