This commit is contained in:
Rizky 2023-10-24 17:09:24 +07:00
parent 4bc08ebc29
commit db347a728b
11 changed files with 189 additions and 14 deletions

View File

@ -23,7 +23,13 @@ export const SyncActions = {
load: async (id: string) => ({}) as ESite | void, load: async (id: string) => ({}) as ESite | void,
}, },
comp: { comp: {
new: async (arg: { group_id: string; item: IItem }) => {}, new: async (arg: {
group_id: string;
page_id?: string;
comp_id?: string;
item_id: string;
item: IItem;
}) => {},
list: () => ({}) as Record<string, Exclude<component, "content_tree">>, list: () => ({}) as Record<string, Exclude<component, "content_tree">>,
group: async (id_site: string) => group: async (id_site: string) =>
({}) as Record<string, { id: string; name: string; comps: string[] }>, ({}) as Record<string, { id: string; name: string; comps: string[] }>,

View File

@ -1,9 +1,106 @@
import { TypedArray } from "yjs-types";
import { MContent } from "../../../../web/src/utils/types/general";
import { IItem, MItem } from "../../../../web/src/utils/types/item";
import { SAction } from "../actions"; import { SAction } from "../actions";
import { docs } from "../entity/docs";
import { SyncConnection } from "../type"; import { SyncConnection } from "../type";
import { syncronize } from "y-pojo";
import {
FMComponent,
FNComponent,
} from "../../../../web/src/utils/types/meta-fn";
import { MText } from "../../../../web/src/utils/types/text";
export const comp_new: SAction["comp"]["new"] = async function ( export const comp_new: SAction["comp"]["new"] = async function (
this: SyncConnection, this: SyncConnection,
arg arg
) { ) {
console.log(arg); const { group_id, item, item_id, page_id, comp_id } = arg;
const comp = await createComp(item, group_id);
const walk = (mitem: MItem | MText) => {
if (mitem.get("id") === item_id) {
const map = new Y.Map() as FMComponent;
syncronize(
map as any,
{
id: comp.id,
ref_ids: {},
props: {},
} as FNComponent
);
mitem.set("component", map);
mitem.set("childs", new Y.Array());
}
const childs = mitem.get("childs") as TypedArray<MItem | MText>;
if (childs) walkArray(childs);
};
const walkArray = (mitems: TypedArray<MItem | MText>) => {
mitems.forEach((item: MItem) => {
const mcomp = item.get("component");
if (mcomp && item.get("type") === "item") {
mcomp.get("props")?.forEach((e) => {
if (e.get("meta")?.get("type") === "content-element") {
const content = e.get("content") as MItem;
if (content) {
walk(content);
}
}
});
}
walk(item);
});
};
if (page_id) {
const doc = docs.page[page_id].doc;
doc.transact(() => {
const root = doc.getMap("map").get("root");
if (root) {
root.get("childs")?.forEach((e) => {
walk(e);
});
}
}, "server: comp_new");
} else if (comp_id) {
const doc = docs.comp[comp_id].doc;
doc.transact(() => {
const root = doc.getMap("map").get("item");
if (root) {
root.get("childs")?.forEach((e) => {
walk(e);
});
}
}, "server: comp_new");
}
};
const createComp = async (item: any, group_id: string) => {
const comp = await db.component.create({
data: {
name: item.name,
content_tree: {},
component_group: {
connect: {
id: group_id,
},
},
},
});
if (comp) {
item.component = {
id: comp.id,
props: {},
ref_ids: {},
};
await db.component.update({
where: { id: comp.id },
data: { content_tree: item },
});
comp.content_tree = item;
}
return comp;
}; };

View File

@ -52,8 +52,6 @@ export const syncHandler: WebSocketHandler<WSData> = {
await loadDefaultSite(user_id); await loadDefaultSite(user_id);
} }
console.log(conf);
conn.conf = new Proxy(conf, { conn.conf = new Proxy(conf, {
get(_, p) { get(_, p) {
const conf = user.conf.get(user_id); const conf = user.conf.get(user_id);

View File

@ -88,6 +88,7 @@ export const EDGlobal = {
}, },
ui: { ui: {
tree: { tree: {
item_loading: [] as string[],
search: "", search: "",
search_mode: { search_mode: {
Name: true, Name: true,

View File

@ -22,7 +22,9 @@ export const edInitSync = (p: PG) => {
page_id: params.page_id, page_id: params.page_id,
events: { events: {
connected() { connected() {
if (w.offline) console.log("connected"); if (w.offline) {
console.log("reconnected, syncing...");
}
w.offline = false; w.offline = false;
p.render(); p.render();
}, },

View File

@ -93,7 +93,7 @@ const walkLoad = async (p: PG, mitem: MItem, loaded: Set<string>) => {
const pcomp = p.comp.list[id]; const pcomp = p.comp.list[id];
if (pcomp) { if (pcomp) {
const pitem = pcomp.doc.getMap("map").get("item"); const pitem = pcomp.doc.getMap("map").get("root");
if (pitem && !loaded.has(id)) { if (pitem && !loaded.has(id)) {
await walkLoad(p, pitem, loaded); await walkLoad(p, pitem, loaded);
} }
@ -137,6 +137,12 @@ const walkMap = (
let override_id = ""; let override_id = "";
const id = mitem.get("id"); const id = mitem.get("id");
let skip_tree = arg.skip_add_tree;
let skip_tree_child = skip_tree;
if (id && p.ui.tree.item_loading.includes(id)) {
skip_tree_child = true;
}
if (parent_comp && id) { if (parent_comp && id) {
const fcomp = parent_comp.mitem.get("component"); const fcomp = parent_comp.mitem.get("component");
if (fcomp) { if (fcomp) {
@ -159,7 +165,7 @@ const walkMap = (
const item_comp = item.component; const item_comp = item.component;
const mitem_comp = mitem.get("component"); const mitem_comp = mitem.get("component");
const metaNotFound = () => { const metaNotFound = () => {
if (!arg.skip_add_tree) { if (!skip_tree) {
p.page.tree.push({ p.page.tree.push({
id: item.id, id: item.id,
parent: parent_item.id, parent: parent_item.id,
@ -174,14 +180,17 @@ const walkMap = (
} }
const ref_comp = p.comp.list[item_comp.id]; const ref_comp = p.comp.list[item_comp.id];
if (ref_comp && mitem_comp) { if (ref_comp && mitem_comp) {
const mcomp = ref_comp.doc.getMap("map").get("item"); const mcomp = ref_comp.doc.getMap("map").get("root");
if (mcomp) { if (mcomp) {
let ref_ids: Record<string, string> = item_comp.ref_ids; let ref_ids: Record<string, string> = item_comp.ref_ids;
if (!ref_ids) { if (!ref_ids) {
mitem_comp.set("ref_ids", new Y.Map() as any); mitem_comp.set("ref_ids", new Y.Map() as any);
ref_ids = {}; ref_ids = {};
} }
mapItem(mcomp, item); mapItem(mcomp, item);
const meta: EdMeta = { const meta: EdMeta = {
@ -191,7 +200,7 @@ const walkMap = (
parent_comp, parent_comp,
}; };
p.page.meta[item.id] = meta; p.page.meta[item.id] = meta;
if (!arg.skip_add_tree) { if (!skip_tree) {
p.page.tree.push({ p.page.tree.push({
id: item.id, id: item.id,
parent: parent_item.id, parent: parent_item.id,
@ -221,6 +230,7 @@ const walkMap = (
parent_item: { id: item.id, mitem: mitem as MItem }, parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: { mitem: mitem as MItem, mcomp }, parent_comp: { mitem: mitem as MItem, mcomp },
portal: arg.portal, portal: arg.portal,
skip_add_tree: skip_tree_child,
}); });
} }
} }
@ -263,7 +273,7 @@ const walkMap = (
p.page.meta[item.id] = meta; p.page.meta[item.id] = meta;
if (!arg.skip_add_tree) { if (!skip_tree) {
p.page.tree.push({ p.page.tree.push({
id: item.id, id: item.id,
parent: parent_item.id, parent: parent_item.id,
@ -279,6 +289,7 @@ const walkMap = (
parent_item: { id: item.id, mitem: mitem as MItem }, parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: arg.parent_comp, parent_comp: arg.parent_comp,
portal: arg.portal, portal: arg.portal,
skip_add_tree: skip_tree_child,
}); });
} }
}; };

View File

@ -1,8 +1,35 @@
import { syncronize } from "y-pojo";
import { IItem } from "../../../../../../../utils/types/item"; import { IItem } from "../../../../../../../utils/types/item";
import { PG } from "../../../../../logic/ed-global"; import { PG } from "../../../../../logic/ed-global";
import { treeRebuild } from "../../../../../logic/tree/build";
import { fillID } from "../../../../../../editor/tools/fill-id";
export const edActionDetach = (p: PG, item: IItem) => { export const edActionDetach = (p: PG, item: IItem) => {
const mitem = p.page.meta[item.id].mitem; const mitem = p.page.meta[item.id].mitem;
if (mitem) { if (mitem) {
const compid = mitem.get("component")?.get("id");
if (compid) {
let comp = p.comp.list[compid].doc
.getMap("map")
.get("root")
?.toJSON() as IItem;
if (comp) {
fillID(comp);
comp.id = item.id;
delete comp.component;
mitem.doc?.transact(() => {
mitem.parent.forEach((e, k) => {
if (e == mitem) {
mitem.parent.delete(k);
const nmap = new Y.Map();
syncronize(nmap, comp);
mitem.parent.insert(k, [nmap]);
}
});
});
}
treeRebuild(p);
}
} }
}; };

View File

@ -1,5 +1,6 @@
import { IItem } from "../../../../../../../utils/types/item"; import { IItem } from "../../../../../../../utils/types/item";
import { PG } from "../../../../../logic/ed-global"; import { PG, active } from "../../../../../logic/ed-global";
import { treeRebuild } from "../../../../../logic/tree/build";
export const edActionNewComp = ( export const edActionNewComp = (
p: PG, p: PG,
@ -11,7 +12,30 @@ export const edActionNewComp = (
p.ui.popup.comp_group = { p.ui.popup.comp_group = {
mouse_event: e, mouse_event: e,
async on_pick(group_id) { async on_pick(group_id) {
await p.sync.comp.new({ group_id, item }); const item = mitem.toJSON() as IItem;
let item_id = active.item_id;
p.ui.tree.item_loading.push(item_id);
await treeRebuild(p);
if (p.comp.cur.id) {
await p.sync.comp.new({
group_id,
item,
comp_id: p.comp.cur.id,
item_id: active.item_id,
});
} else {
await p.sync.comp.new({
group_id,
item,
page_id: p.page.cur.id,
item_id: active.item_id,
});
}
p.ui.tree.item_loading = p.ui.tree.item_loading.filter(
(e) => e !== item_id
);
p.render();
}, },
}; };
p.render(); p.render();

View File

@ -5,6 +5,7 @@ import { EdTreeAction } from "./item/action";
import { EdTreeCtxMenu } from "./item/ctx-menu"; import { EdTreeCtxMenu } from "./item/ctx-menu";
import { EdTreeIndent } from "./item/indent"; import { EdTreeIndent } from "./item/indent";
import { EdTreeName } from "./item/name"; import { EdTreeName } from "./item/name";
import { Loading } from "../../../../../utils/ui/loading";
export const nodeRender: NodeRender<EdMeta> = (node, prm) => { export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
const p = useGlobal(EDGlobal, "EDITOR"); const p = useGlobal(EDGlobal, "EDITOR");
@ -15,6 +16,14 @@ export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
const item = node.data?.item; const item = node.data?.item;
const isComponent = item.type === "item" && item.component?.id; const isComponent = item.type === "item" && item.component?.id;
if (p.ui.tree.item_loading.includes(item.id)) {
return (
<div className={"relative border-b flex items-stretch min-h-[26px]"}>
<Loading backdrop={false} />
</div>
);
}
return ( return (
<div <div
className={cx( className={cx(

View File

@ -15,7 +15,7 @@ import { w } from "../types/general";
import { initIDB } from "./idb"; import { initIDB } from "./idb";
const packr = new Packr({ structuredClone: true }); const packr = new Packr({ structuredClone: true });
const WS_DEBUG = false; const WS_DEBUG = true;
const conf = { const conf = {
ws: null as null | WebSocket, ws: null as null | WebSocket,

View File

@ -15,4 +15,4 @@ export type MRoot = TypedMap<{
}>; }>;
export type DPage = TypedDoc<{ map: TypedMap<{ id: string; root: MRoot }> }>; export type DPage = TypedDoc<{ map: TypedMap<{ id: string; root: MRoot }> }>;
export type DComp = TypedDoc<{ map: TypedMap<{ id: string; item: MItem }> }>; export type DComp = TypedDoc<{ map: TypedMap<{ id: string; root: MItem }> }>;