wip fix layout live change
This commit is contained in:
parent
7eada6fde4
commit
a296b35eff
|
|
@ -1,5 +1,4 @@
|
||||||
import { IScopeComp } from "../../../../web/src/nova/ed/logic/ed-global";
|
import { IScopeComp } from "../../../../web/src/nova/ed/logic/ed-global";
|
||||||
import { MItem } from "../../../../web/src/utils/types/item";
|
|
||||||
import { DComp } from "../../../../web/src/utils/types/root";
|
import { DComp } from "../../../../web/src/utils/types/root";
|
||||||
import { SAction } from "../actions";
|
import { SAction } from "../actions";
|
||||||
import { loadComponent } from "../editor/load-component";
|
import { loadComponent } from "../editor/load-component";
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,14 @@ export const site_load: SAction["site"]["load"] = async function (
|
||||||
|
|
||||||
activity.site.room(site.id).join({ ws: this.ws });
|
activity.site.room(site.id).join({ ws: this.ws });
|
||||||
|
|
||||||
let layout = undefined;
|
const layout = await db.page.findFirst({
|
||||||
const _layout = await db.page.findFirst({
|
|
||||||
where: {
|
where: {
|
||||||
id_site: id,
|
id_site: id,
|
||||||
is_deleted: false,
|
is_deleted: false,
|
||||||
is_default_layout: true,
|
is_default_layout: true,
|
||||||
},
|
},
|
||||||
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (_layout) layout = _layout.content_tree as IRoot;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: site.id,
|
id: site.id,
|
||||||
|
|
@ -38,7 +37,7 @@ export const site_load: SAction["site"]["load"] = async function (
|
||||||
domain: site.domain,
|
domain: site.domain,
|
||||||
js: site.js || "",
|
js: site.js || "",
|
||||||
js_compiled: site.js_compiled || "",
|
js_compiled: site.js_compiled || "",
|
||||||
layout,
|
layout: { id: layout?.id || "" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { SAction } from "../../../../../srv/ws/sync/actions";
|
||||||
import { parseJs } from "../../../../../srv/ws/sync/editor/parser/parse-js";
|
import { parseJs } from "../../../../../srv/ws/sync/editor/parser/parse-js";
|
||||||
import { clientStartSync } from "../../../utils/sync/ws-client";
|
import { clientStartSync } from "../../../utils/sync/ws-client";
|
||||||
import { IItem, MItem } from "../../../utils/types/item";
|
import { IItem, MItem } from "../../../utils/types/item";
|
||||||
import { DComp, DPage, IRoot } from "../../../utils/types/root";
|
import { DComp, DPage } from "../../../utils/types/root";
|
||||||
import { ISection } from "../../../utils/types/section";
|
import { ISection } from "../../../utils/types/section";
|
||||||
import { IText, MText } from "../../../utils/types/text";
|
import { IText, MText } from "../../../utils/types/text";
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const EmptySite = {
|
||||||
config: { api_url: "" },
|
config: { api_url: "" },
|
||||||
js: "",
|
js: "",
|
||||||
js_compiled: "",
|
js_compiled: "",
|
||||||
layout: undefined as undefined | IRoot,
|
layout: { snapshot: null as null | Uint8Array, id: "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ESite = typeof EmptySite;
|
export type ESite = typeof EmptySite;
|
||||||
|
|
@ -114,8 +114,14 @@ export const EDGlobal = {
|
||||||
page: {
|
page: {
|
||||||
cur: EmptyPage,
|
cur: EmptyPage,
|
||||||
doc: null as null | DPage,
|
doc: null as null | DPage,
|
||||||
doc_on_update: async (bin: Uint8Array, origin: any) => {},
|
list: {} as Record<
|
||||||
list: {} as Record<string, { page: EPage; doc: DPage }>,
|
string,
|
||||||
|
{
|
||||||
|
page: EPage;
|
||||||
|
doc: DPage;
|
||||||
|
on_update?: (bin: Uint8Array, origin: any) => Promise<void>;
|
||||||
|
}
|
||||||
|
>,
|
||||||
building: false,
|
building: false,
|
||||||
meta: {} as Record<string, EdMeta>,
|
meta: {} as Record<string, EdMeta>,
|
||||||
entry: [] as string[],
|
entry: [] as string[],
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { IItem } from "../../../utils/types/item";
|
||||||
import { DComp } from "../../../utils/types/root";
|
import { DComp } from "../../../utils/types/root";
|
||||||
import { PG } from "./ed-global";
|
import { PG } from "./ed-global";
|
||||||
import { treeRebuild } from "./tree/build";
|
import { treeRebuild } from "./tree/build";
|
||||||
|
import { loadSite } from "./ed-site";
|
||||||
|
|
||||||
export const edRoute = async (p: PG) => {
|
export const edRoute = async (p: PG) => {
|
||||||
if (p.status === "ready" || p.status === "init") {
|
if (p.status === "ready" || p.status === "init") {
|
||||||
|
|
@ -15,7 +16,7 @@ export const edRoute = async (p: PG) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.site = site;
|
await loadSite(p, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -23,22 +24,23 @@ export const edRoute = async (p: PG) => {
|
||||||
!p.page.cur.snapshot ||
|
!p.page.cur.snapshot ||
|
||||||
!p.page.list[p.page.cur.id]
|
!p.page.list[p.page.cur.id]
|
||||||
) {
|
) {
|
||||||
if (p.page.list[params.page_id] && p.page.doc) {
|
const page = p.page.list[params.page_id];
|
||||||
p.page.doc.off("update", p.page.doc_on_update);
|
if (page && p.page.doc && page.on_update) {
|
||||||
|
p.page.doc.off("update", page.on_update);
|
||||||
|
|
||||||
const cur = p.page.list[params.page_id];
|
const cur = p.page.list[params.page_id];
|
||||||
p.page.cur = cur.page;
|
p.page.cur = cur.page;
|
||||||
p.page.doc = cur.doc;
|
p.page.doc = cur.doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
await reloadPage(p);
|
await reloadPage(p, params.page_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const reloadPage = async (p: PG) => {
|
export const reloadPage = async (p: PG, page_id: string) => {
|
||||||
p.status = "loading";
|
p.status = "loading";
|
||||||
const remotePage = await p.sync.page.load(params.page_id);
|
const remotePage = await p.sync.page.load(page_id);
|
||||||
|
|
||||||
if (!remotePage) {
|
if (!remotePage) {
|
||||||
p.status = "page-not-found";
|
p.status = "page-not-found";
|
||||||
|
|
@ -66,7 +68,17 @@ export const reloadPage = async (p: PG) => {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
Y.applyUpdate(doc, decompress(remotePage.snapshot));
|
Y.applyUpdate(doc, decompress(remotePage.snapshot));
|
||||||
|
|
||||||
p.page.doc_on_update = async (bin: Uint8Array, origin: any) => {
|
let page = p.page.list[remotePage.id];
|
||||||
|
if (!page) {
|
||||||
|
p.page.list[remotePage.id] = {} as any;
|
||||||
|
page = p.page.list[remotePage.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page.on_update && page.doc) {
|
||||||
|
page.doc.off("update", page.on_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
page.on_update = async (bin: Uint8Array, origin: any) => {
|
||||||
if (origin === "sv_remote" || origin === "local") return;
|
if (origin === "sv_remote" || origin === "local") return;
|
||||||
|
|
||||||
const res = await p.sync.yjs.sv_local(
|
const res = await p.sync.yjs.sv_local(
|
||||||
|
|
@ -93,14 +105,12 @@ export const reloadPage = async (p: PG) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
doc.on("update", p.page.doc_on_update);
|
doc.on("update", page.on_update);
|
||||||
|
|
||||||
p.page.doc = doc as any;
|
p.page.doc = doc as any;
|
||||||
if (p.page.doc) {
|
if (p.page.doc) {
|
||||||
p.page.list[remotePage.id] = {
|
page.page = p.page.cur;
|
||||||
page: p.page.cur,
|
page.doc = p.page.doc;
|
||||||
doc: p.page.doc,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.page.doc) {
|
if (p.page.doc) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { ESite, PG } from "./ed-global";
|
||||||
|
import { reloadPage } from "./ed-route";
|
||||||
|
|
||||||
|
export const loadSite = async (p: PG, site: ESite) => {
|
||||||
|
const old_layout_id = p.site.layout.id;
|
||||||
|
const layout_changed = p.site.layout.id !== site.layout.id;
|
||||||
|
p.site = site;
|
||||||
|
if (layout_changed) {
|
||||||
|
const old_layout = p.page.list[old_layout_id];
|
||||||
|
|
||||||
|
if (old_layout && old_layout.on_update) {
|
||||||
|
old_layout.doc.off("update", old_layout.on_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (site.layout.id) {
|
||||||
|
await reloadPage(p, site.layout.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -8,6 +8,7 @@ import { EmptySite, PG } from "./ed-global";
|
||||||
import { treeRebuild } from "./tree/build";
|
import { treeRebuild } from "./tree/build";
|
||||||
import { evalCJS } from "../../view/logic/load-code";
|
import { evalCJS } from "../../view/logic/load-code";
|
||||||
import { reloadPage } from "./ed-route";
|
import { reloadPage } from "./ed-route";
|
||||||
|
import { loadSite } from "./ed-site";
|
||||||
|
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
|
|
||||||
|
|
@ -28,9 +29,9 @@ export const edInitSync = (p: PG) => {
|
||||||
p.site = deepClone(EmptySite);
|
p.site = deepClone(EmptySite);
|
||||||
p.site.id = "--loading--";
|
p.site.id = "--loading--";
|
||||||
p.ui.popup.code.init = false;
|
p.ui.popup.code.init = false;
|
||||||
p.sync.site.load(params.site_id).then((site) => {
|
p.sync.site.load(params.site_id).then(async (site) => {
|
||||||
if (site) {
|
if (site) {
|
||||||
p.site = site;
|
await loadSite(p, site);
|
||||||
p.render();
|
p.render();
|
||||||
} else {
|
} else {
|
||||||
alert("Site not found. redirecting...");
|
alert("Site not found. redirecting...");
|
||||||
|
|
@ -124,7 +125,7 @@ export const edInitSync = (p: PG) => {
|
||||||
},
|
},
|
||||||
async editor_start(e) {
|
async editor_start(e) {
|
||||||
if (p.ui.syncing) {
|
if (p.ui.syncing) {
|
||||||
await reloadPage(p);
|
await reloadPage(p, params.page_id);
|
||||||
if (p.page.doc) {
|
if (p.page.doc) {
|
||||||
p.page.doc.transact(() => {
|
p.page.doc.transact(() => {
|
||||||
p.page.doc?.getMap("map").set("ts", Date.now());
|
p.page.doc?.getMap("map").set("ts", Date.now());
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
|
||||||
const loaded = new Set<string>();
|
const loaded = new Set<string>();
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
sections.map((e) => {
|
sections.map((e) => {
|
||||||
return syncWalkLoad(p, e, loaded);
|
return syncWalkLoad(p, e, loaded, (id) => {
|
||||||
|
return loadComponent(p, id);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -32,36 +34,61 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
|
||||||
|
|
||||||
let root_id = "root";
|
let root_id = "root";
|
||||||
if (p.site.layout) {
|
if (p.site.layout) {
|
||||||
const loaded = new Set<string>();
|
const ldoc = p.page.list[p.site.layout.id];
|
||||||
await Promise.all(
|
if (ldoc) {
|
||||||
p.site.layout.childs.map((e) =>
|
const lroot = ldoc.doc.getMap("map").get("root");
|
||||||
walkLoad(p.comp, e, loaded, (id) => loadComponent(p, id))
|
if (lroot) {
|
||||||
)
|
const sections = lroot.get("childs");
|
||||||
);
|
if (sections) {
|
||||||
p.site.layout.childs.map((e) => {
|
const loaded = new Set<string>();
|
||||||
p.page.entry.push(e.id);
|
await Promise.all(
|
||||||
walkMap(
|
sections.map((e) => {
|
||||||
{ meta: p.page.meta, comps: p.comp.map },
|
return syncWalkLoad(p, e, loaded, (id) => {
|
||||||
{
|
return loadComponent(p, id);
|
||||||
isLayout: true,
|
});
|
||||||
item: e,
|
})
|
||||||
parent_item: { id: "root" },
|
);
|
||||||
portal,
|
|
||||||
each(meta) {
|
|
||||||
if (meta.item.name === "content") {
|
|
||||||
root_id = meta.item.id;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// if root_id is root, it means content is not found.
|
sections.map((e) => {
|
||||||
// if content is not found, do not use layout.
|
if (root_id === "root") {
|
||||||
if (root_id === "root") {
|
p.page.entry.push(e.get("id"));
|
||||||
p.page.entry = [];
|
}
|
||||||
p.page.tree = [];
|
syncWalkMap(p, {
|
||||||
p.page.meta = {};
|
isLayout: false,
|
||||||
|
mitem: e,
|
||||||
|
parent_item: { id: root_id },
|
||||||
|
tree_root_id: root_id,
|
||||||
|
portal,
|
||||||
|
each(meta) {
|
||||||
|
if (meta.item.name === "content") {
|
||||||
|
root_id = meta.item.id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [k, portal_out] of Object.entries(portal.out)) {
|
||||||
|
const name = k.replace(/⮕/gi, "").trim();
|
||||||
|
const portal_in = portal.in[`⬅${name}`];
|
||||||
|
if (portal_in) {
|
||||||
|
for (const key of Object.keys(portal_in)) {
|
||||||
|
delete (portal_in as any)[key];
|
||||||
|
}
|
||||||
|
for (const [k, v] of Object.entries(portal_out)) {
|
||||||
|
(portal_in as any)[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if root_id is root, it means content is not found.
|
||||||
|
// if content is not found, do not use layout.
|
||||||
|
if (root_id === "root") {
|
||||||
|
p.page.entry = [];
|
||||||
|
p.page.tree = [];
|
||||||
|
p.page.meta = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ import {
|
||||||
export const syncWalkLoad = async (
|
export const syncWalkLoad = async (
|
||||||
p: PG,
|
p: PG,
|
||||||
mitem: MItem,
|
mitem: MItem,
|
||||||
loaded: Set<string>
|
loaded: Set<string>,
|
||||||
|
loadComponent: (id: string) => Promise<boolean>
|
||||||
) => {
|
) => {
|
||||||
const mcomp = mitem.get("component");
|
const mcomp = mitem.get("component");
|
||||||
if (mcomp) {
|
if (mcomp) {
|
||||||
|
|
@ -26,14 +27,14 @@ export const syncWalkLoad = async (
|
||||||
const isFirstLoaded = !loaded.has(id);
|
const isFirstLoaded = !loaded.has(id);
|
||||||
loaded.add(id);
|
loaded.add(id);
|
||||||
if (!p.comp.list[id]) {
|
if (!p.comp.list[id]) {
|
||||||
await loadComponent(p, comp.id);
|
await loadComponent(comp.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pcomp = p.comp.list[id];
|
const pcomp = p.comp.list[id];
|
||||||
if (pcomp) {
|
if (pcomp) {
|
||||||
const pitem = pcomp.doc.getMap("map").get("root");
|
const pitem = pcomp.doc.getMap("map").get("root");
|
||||||
if (pitem && isFirstLoaded) {
|
if (pitem && isFirstLoaded) {
|
||||||
await syncWalkLoad(p, pitem, loaded);
|
await syncWalkLoad(p, pitem, loaded, loadComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +45,7 @@ export const syncWalkLoad = async (
|
||||||
if (mprop) {
|
if (mprop) {
|
||||||
const mcontent = ensurePropContent(mprop, propName);
|
const mcontent = ensurePropContent(mprop, propName);
|
||||||
if (mcontent) {
|
if (mcontent) {
|
||||||
await syncWalkLoad(p, mcontent, loaded);
|
await syncWalkLoad(p, mcontent, loaded, loadComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +53,7 @@ export const syncWalkLoad = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const e of mitem.get("childs")?.map((e) => e) || []) {
|
for (const e of mitem.get("childs")?.map((e) => e) || []) {
|
||||||
await syncWalkLoad(p, e, loaded);
|
await syncWalkLoad(p, e, loaded, loadComponent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -69,6 +70,7 @@ export const syncWalkMap = (
|
||||||
parent_mcomp?: EdMeta["parent_mcomp"];
|
parent_mcomp?: EdMeta["parent_mcomp"];
|
||||||
skip_add_tree?: boolean;
|
skip_add_tree?: boolean;
|
||||||
tree_root_id: string;
|
tree_root_id: string;
|
||||||
|
each?: (meta: EdMeta) => void;
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
const { mitem, parent_item, parent_mcomp } = arg;
|
const { mitem, parent_item, parent_mcomp } = arg;
|
||||||
|
|
@ -153,6 +155,8 @@ export const syncWalkMap = (
|
||||||
if (item.name.startsWith("⮕")) {
|
if (item.name.startsWith("⮕")) {
|
||||||
arg.portal.out[item.name] = meta;
|
arg.portal.out[item.name] = meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg.each) arg.each(meta);
|
||||||
p.page.meta[item.id] = meta;
|
p.page.meta[item.id] = meta;
|
||||||
|
|
||||||
if (!skip_tree) {
|
if (!skip_tree) {
|
||||||
|
|
@ -231,6 +235,8 @@ export const syncWalkMap = (
|
||||||
if (item.name.startsWith("⮕")) {
|
if (item.name.startsWith("⮕")) {
|
||||||
arg.portal.out[item.name] = meta;
|
arg.portal.out[item.name] = meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg.each) arg.each(meta);
|
||||||
p.page.meta[item.id] = meta;
|
p.page.meta[item.id] = meta;
|
||||||
|
|
||||||
if (!skip_tree) {
|
if (!skip_tree) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue