fix
This commit is contained in:
parent
4be4bdc160
commit
8f5c20beeb
|
|
@ -5,38 +5,32 @@ export const SyncActionDefinition = {
|
|||
"load": "2"
|
||||
},
|
||||
"comp": {
|
||||
"undo": "3",
|
||||
"redo": "4",
|
||||
"list": "5",
|
||||
"group": "6",
|
||||
"load": "7"
|
||||
"list": "3",
|
||||
"group": "4",
|
||||
"load": "5"
|
||||
},
|
||||
"page": {
|
||||
"undo": "8",
|
||||
"redo": "9",
|
||||
"list": "10",
|
||||
"load": "11"
|
||||
"list": "6",
|
||||
"load": "7"
|
||||
},
|
||||
"yjs": {
|
||||
"sv_local": "12",
|
||||
"diff_local": "13",
|
||||
"sv_remote": "14"
|
||||
"um": "8",
|
||||
"sv_local": "9",
|
||||
"diff_local": "10",
|
||||
"sv_remote": "11"
|
||||
}
|
||||
};
|
||||
export const SyncActionPaths = {
|
||||
"0": "site.list",
|
||||
"1": "site.group",
|
||||
"2": "site.load",
|
||||
"3": "comp.undo",
|
||||
"4": "comp.redo",
|
||||
"5": "comp.list",
|
||||
"6": "comp.group",
|
||||
"7": "comp.load",
|
||||
"8": "page.undo",
|
||||
"9": "page.redo",
|
||||
"10": "page.list",
|
||||
"11": "page.load",
|
||||
"12": "yjs.sv_local",
|
||||
"13": "yjs.diff_local",
|
||||
"14": "yjs.sv_remote"
|
||||
"3": "comp.list",
|
||||
"4": "comp.group",
|
||||
"5": "comp.load",
|
||||
"6": "page.list",
|
||||
"7": "page.load",
|
||||
"8": "yjs.um",
|
||||
"9": "yjs.sv_local",
|
||||
"10": "yjs.diff_local",
|
||||
"11": "yjs.sv_remote"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,29 +22,33 @@ export const SyncActions = {
|
|||
load: async (id: string) => ({}) as ESite | void,
|
||||
},
|
||||
comp: {
|
||||
undo: async (id_comp: string) => {},
|
||||
redo: async (id_comp: string) => {},
|
||||
list: () => ({}) as Record<string, Exclude<component, "content_tree">>,
|
||||
group: () => ({}) as Record<string, string[]>,
|
||||
load: async (id: string) => ({}) as EComp | void,
|
||||
},
|
||||
page: {
|
||||
undo: async (id_page: string) => {},
|
||||
redo: async (id_page: string) => {},
|
||||
list: (id_site: string) =>
|
||||
({}) as Record<string, Exclude<page, "content_tree">>,
|
||||
load: async (id: string) => ({}) as EPage | void,
|
||||
},
|
||||
yjs: {
|
||||
sv_local: async (mode: "page" | "comp", id: string, bin: Uint8Array) =>
|
||||
({}) as { diff: Uint8Array; sv: Uint8Array } | void,
|
||||
um: async (
|
||||
mode: "page" | "comp" | "site",
|
||||
action: "undo" | "redo",
|
||||
id: string
|
||||
) => {},
|
||||
sv_local: async (
|
||||
mode: "page" | "comp" | "site",
|
||||
id: string,
|
||||
bin: Uint8Array
|
||||
) => ({}) as { diff: Uint8Array; sv: Uint8Array } | void,
|
||||
diff_local: async (
|
||||
mode: "page" | "comp",
|
||||
mode: "page" | "comp" | "site",
|
||||
id: string,
|
||||
bin: Uint8Array
|
||||
) => {},
|
||||
sv_remote: async (
|
||||
mode: "page" | "comp",
|
||||
mode: "page" | "comp" | "site",
|
||||
id: string,
|
||||
sv: Uint8Array,
|
||||
diff: Uint8Array
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
import { SyncConnection } from "../type";
|
||||
|
||||
export const comp_redo = async function (this: SyncConnection, id: string) {};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import { SyncConnection } from "../type";
|
||||
|
||||
export const comp_undo = async function (this: SyncConnection, id: string) {};
|
||||
|
|
@ -2,10 +2,7 @@ export * from "./site_load";
|
|||
export * from "./site_group";
|
||||
export * from "./page_load";
|
||||
export * from "./comp_load";
|
||||
export * from "./page_undo";
|
||||
export * from "./page_redo";
|
||||
export * from "./comp_undo";
|
||||
export * from "./comp_redo";
|
||||
export * from "./yjs_um";
|
||||
export * from "./yjs_sv_local";
|
||||
export * from "./yjs_diff_local";
|
||||
export * from "./yjs_sv_remote";
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { syncronize } from "y-pojo";
|
||||
import { SAction } from "../actions";
|
||||
import { conns } from "../entity/conn";
|
||||
import { Y, docs } from "../entity/docs";
|
||||
import { snapshot } from "../entity/snapshot";
|
||||
import { user } from "../entity/user";
|
||||
import { gzipAsync } from "../entity/zlib";
|
||||
import { SyncConnection, SyncType } from "../type";
|
||||
import { conns } from "../entity/conn";
|
||||
import { sendWS } from "../sync-handler";
|
||||
import { SyncConnection, SyncType } from "../type";
|
||||
|
||||
export const page_load: SAction["page"]["load"] = async function (
|
||||
this: SyncConnection,
|
||||
|
|
@ -17,27 +17,34 @@ export const page_load: SAction["page"]["load"] = async function (
|
|||
|
||||
if (this.conf) this.conf.page_id = id;
|
||||
|
||||
const createUndoManager = (root: Y.Map<any>) => {
|
||||
const um = new Y.UndoManager(root, { ignoreRemoteMapChanges: false });
|
||||
const createUndoManager = async (root: Y.Map<any>) => {
|
||||
const um = new Y.UndoManager(root, {
|
||||
ignoreRemoteMapChanges: true,
|
||||
});
|
||||
|
||||
return um;
|
||||
};
|
||||
|
||||
const attachOnUpdate = (doc: Y.Doc, um: Y.UndoManager) => {
|
||||
const attachOnUpdate = async (doc: Y.Doc, um: Y.UndoManager) => {
|
||||
snapshot.set("page", id, "id_doc", um.doc.clientID);
|
||||
|
||||
doc.on("update", async (update: Uint8Array, origin: any) => {
|
||||
if (origin === um) {
|
||||
} else {
|
||||
const sv_local = await gzipAsync(update);
|
||||
user.active.findAll({ page_id: id }).map((e) => {
|
||||
const bin = Y.encodeStateAsUpdate(doc);
|
||||
snapshot.set("page", id, "bin", bin);
|
||||
|
||||
const sv_local = await gzipAsync(update);
|
||||
user.active.findAll({ page_id: id }).map((e) => {
|
||||
if (origin !== um) {
|
||||
if (e.client_id === origin) return;
|
||||
const ws = conns.get(e.client_id)?.ws;
|
||||
if (ws)
|
||||
sendWS(ws, {
|
||||
type: SyncType.Event,
|
||||
event: "remote_svlocal",
|
||||
data: { type: "page", sv_local, id },
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const ws = conns.get(e.client_id)?.ws;
|
||||
if (ws)
|
||||
sendWS(ws, {
|
||||
type: SyncType.Event,
|
||||
event: "remote_svlocal",
|
||||
data: { type: "page", sv_local, id },
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -52,7 +59,7 @@ export const page_load: SAction["page"]["load"] = async function (
|
|||
let root = doc.getMap("map");
|
||||
syncronize(root, { id, root: page.content_tree });
|
||||
|
||||
const um = createUndoManager(root);
|
||||
const um = await createUndoManager(root);
|
||||
docs.page[id] = {
|
||||
doc: doc as any,
|
||||
id,
|
||||
|
|
@ -60,7 +67,7 @@ export const page_load: SAction["page"]["load"] = async function (
|
|||
};
|
||||
|
||||
const bin = Y.encodeStateAsUpdate(doc);
|
||||
attachOnUpdate(doc, um);
|
||||
await attachOnUpdate(doc, um);
|
||||
|
||||
snapshot.update({
|
||||
bin,
|
||||
|
|
@ -69,6 +76,7 @@ export const page_load: SAction["page"]["load"] = async function (
|
|||
name: page.name,
|
||||
ts: Date.now(),
|
||||
url: page.url,
|
||||
id_doc: doc.clientID,
|
||||
id_site: page.id_site,
|
||||
});
|
||||
|
||||
|
|
@ -89,11 +97,12 @@ export const page_load: SAction["page"]["load"] = async function (
|
|||
}
|
||||
} else if (snap && !ydoc) {
|
||||
const doc = new Y.Doc();
|
||||
snapshot.set("page", id, "id_doc", doc.clientID);
|
||||
Y.applyUpdate(doc, snap.bin);
|
||||
let root = doc.getMap("map");
|
||||
|
||||
const um = createUndoManager(root);
|
||||
attachOnUpdate(doc, um);
|
||||
const um = await createUndoManager(root);
|
||||
await attachOnUpdate(doc, um);
|
||||
|
||||
docs.page[id] = {
|
||||
doc: doc as any,
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
import { docs } from "../entity/docs";
|
||||
import { SyncConnection } from "../type";
|
||||
|
||||
export const page_redo = async function (this: SyncConnection, id: string) {
|
||||
if (!docs.page[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const um = docs.page[id].um;
|
||||
if (um.canRedo()) {
|
||||
console.log("redoing");
|
||||
um.redo();
|
||||
}
|
||||
};
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
import { docs } from "../entity/docs";
|
||||
import { SyncConnection } from "../type";
|
||||
|
||||
export const page_undo = async function (this: SyncConnection, id: string) {
|
||||
if (!docs.page[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const um = docs.page[id].um;
|
||||
if (um.canUndo()) {
|
||||
console.log("undoing");
|
||||
|
||||
um.undo();
|
||||
}
|
||||
};
|
||||
|
|
@ -19,7 +19,4 @@ export const yjs_diff_local: SAction["yjs"]["diff_local"] = async function (
|
|||
const um = docs[mode][id].um;
|
||||
um.addTrackedOrigin(this.client_id);
|
||||
Y.applyUpdate(doc, diff, this.client_id);
|
||||
|
||||
const save = Y.encodeStateAsUpdate(doc);
|
||||
snapshot.set(mode, id, "bin", save);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
import { SAction } from "../actions";
|
||||
import { docs } from "../entity/docs";
|
||||
import { SyncConnection } from "../type";
|
||||
|
||||
export const yjs_um: SAction["yjs"]["um"] = async function (
|
||||
this: SyncConnection,
|
||||
mode,
|
||||
action,
|
||||
id
|
||||
) {
|
||||
if (!docs[mode][id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const um = docs[mode][id].um;
|
||||
if (action === "redo") {
|
||||
if (um.canRedo()) {
|
||||
um.redo();
|
||||
}
|
||||
} else {
|
||||
if (um.undoStack.length > 1) {
|
||||
if (um.canUndo()) {
|
||||
um.undo();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -5,6 +5,14 @@ import { DPage } from "../../../../web/src/utils/types/root";
|
|||
export * as Y from "yjs";
|
||||
|
||||
export const docs = {
|
||||
site: {} as Record<
|
||||
string,
|
||||
{
|
||||
id: string;
|
||||
doc: DPage;
|
||||
um: Y.UndoManager;
|
||||
}
|
||||
>,
|
||||
page: {} as Record<
|
||||
string,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ import { RootDatabase, open } from "lmdb";
|
|||
import { g } from "utils/global";
|
||||
|
||||
const emptySnapshot = {
|
||||
type: "" as "" | "comp" | "page",
|
||||
type: "" as "" | "comp" | "page" | "site",
|
||||
id: "",
|
||||
bin: new Uint8Array(),
|
||||
id_doc: 0,
|
||||
name: "",
|
||||
ts: Date.now(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
import { NodeModel } from "@minoru/react-dnd-treeview";
|
||||
import { ReactElement } from "react";
|
||||
import { clientStartSync } from "../../../utils/sync/ws-client";
|
||||
import { IContent, MContent } from "../../../utils/types/general";
|
||||
import { IItem, MItem } from "../../../utils/types/item";
|
||||
import { DComp, DPage, IRoot } from "../../../utils/types/root";
|
||||
import { ISection } from "../../../utils/types/section";
|
||||
import { IText, MText } from "../../../utils/types/text";
|
||||
import { ReactElement } from "react";
|
||||
|
||||
const EmptySite = {
|
||||
id: "",
|
||||
name: "",
|
||||
domain: "",
|
||||
js: "",
|
||||
js_compiled: "",
|
||||
config: { api_url: "" },
|
||||
snapshot: null as null | Uint8Array,
|
||||
|
||||
// js: "",
|
||||
// js_compiled: "",
|
||||
};
|
||||
export type ESite = typeof EmptySite;
|
||||
export type EPage = typeof EmptyPage;
|
||||
|
|
@ -95,7 +96,14 @@ export const EDGlobal = {
|
|||
open: {} as Record<string, string[]>,
|
||||
},
|
||||
popup: {
|
||||
comp: null as null | ((comp_id: string) => void | Promise<void>),
|
||||
comp: null as null | true | ((comp_id: string) => void | Promise<void>),
|
||||
compGroup: null as
|
||||
| null
|
||||
| true
|
||||
| {
|
||||
event: React.MouseEvent<HTMLElement, MouseEvent>;
|
||||
pick: (group_id: string) => void | Promise<void>;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ export const edUndoManager = async (p: PG) => {
|
|||
!evt.shiftKey
|
||||
) {
|
||||
if (p.comp.cur.id) {
|
||||
p.sync.comp.redo(p.comp.cur.id);
|
||||
p.sync.yjs.um("comp", "redo", p.comp.cur.id);
|
||||
} else {
|
||||
p.sync.page.redo(p.page.cur.id);
|
||||
p.sync.yjs.um("page", "redo", p.page.cur.id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -32,11 +32,10 @@ export const edUndoManager = async (p: PG) => {
|
|||
evt.shiftKey
|
||||
) {
|
||||
if (p.comp.cur.id) {
|
||||
p.sync.comp.redo(p.comp.cur.id);
|
||||
p.sync.yjs.um("comp", "redo", p.comp.cur.id);
|
||||
} else {
|
||||
p.sync.page.redo(p.page.cur.id);
|
||||
p.sync.yjs.um("page", "redo", p.page.cur.id);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -46,9 +45,9 @@ export const edUndoManager = async (p: PG) => {
|
|||
!evt.shiftKey
|
||||
) {
|
||||
if (p.comp.cur.id) {
|
||||
p.sync.comp.undo(p.comp.cur.id);
|
||||
p.sync.yjs.um("comp", "undo", p.comp.cur.id);
|
||||
} else {
|
||||
p.sync.page.undo(p.page.cur.id);
|
||||
p.sync.yjs.um("page", "undo", p.page.cur.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,22 @@
|
|||
import { IContent } from "../../../../../../../utils/types/general";
|
||||
import { syncronize } from "y-pojo";
|
||||
import { IContent, MContent } from "../../../../../../../utils/types/general";
|
||||
import { fillID } from "../../../../../../editor/tools/fill-id";
|
||||
import { PG } from "../../../../../logic/ed-global";
|
||||
import { treeRebuild } from "../../../../../logic/tree/build";
|
||||
|
||||
export const edActionClone = (p: PG, item: IContent) => {
|
||||
const mitem = p.page.meta[item.id].mitem;
|
||||
if (mitem) {
|
||||
mitem.doc?.transact(() => {
|
||||
mitem.parent.forEach((e: MContent, idx) => {
|
||||
if (e.get("id") === mitem.get("id")) {
|
||||
const json = e.toJSON() as IContent;
|
||||
const map = new Y.Map();
|
||||
syncronize(map, fillID(json));
|
||||
mitem.parent.insert(idx, [map]);
|
||||
}
|
||||
});
|
||||
});
|
||||
treeRebuild(p, { note: "clone" });
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export const EdTreeCtxMenu = ({
|
|||
onClick={() => edActionDetach(p, item)}
|
||||
/>
|
||||
)}
|
||||
{type === "item" && comp?.id && (
|
||||
{type === "item" && !comp?.id && (
|
||||
<MenuItem
|
||||
label="Create Component"
|
||||
onClick={() => edActionNewComp(p, item)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue