wip fix
This commit is contained in:
parent
199490b6a9
commit
a7feb63345
|
|
@ -18,5 +18,17 @@ export const getMetaById = (p: PG, id: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getActiveMeta = (p: PG) => {
|
export const getActiveMeta = (p: PG) => {
|
||||||
return getMetaById(p, active.item_id);
|
const meta = getMetaById(p, active.item_id);
|
||||||
|
if (meta) return meta;
|
||||||
|
|
||||||
|
if (active.comp_id) {
|
||||||
|
const comp = p.comp.list[active.comp_id];
|
||||||
|
if (comp) {
|
||||||
|
const first = comp.tree.find((e) => e.parent === "root");
|
||||||
|
if (first && first.data?.item) return first.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const first = p.page.tree.find((e) => e.parent === "root");
|
||||||
|
if (first && first.data?.item) return first.data;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { loadComponent } from "../../../logic/comp/load";
|
||||||
import { EDGlobal, active } from "../../../logic/ed-global";
|
import { EDGlobal, active } from "../../../logic/ed-global";
|
||||||
import { fillID } from "../../../logic/tree/fill-id";
|
import { fillID } from "../../../logic/tree/fill-id";
|
||||||
import { TopBtn } from "../top-btn";
|
import { TopBtn } from "../top-btn";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export const EdCompPicker = () => {
|
export const EdCompPicker = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
@ -36,7 +37,9 @@ export const EdCompPicker = () => {
|
||||||
let active_meta = getActiveMeta(p);
|
let active_meta = getActiveMeta(p);
|
||||||
if (!active_meta) {
|
if (!active_meta) {
|
||||||
alert("Please select an item/section to add component!");
|
alert("Please select an item/section to add component!");
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (active_meta) {
|
||||||
let item = active_meta.item as IContent;
|
let item = active_meta.item as IContent;
|
||||||
if (
|
if (
|
||||||
item.type === "item" &&
|
item.type === "item" &&
|
||||||
|
|
@ -68,9 +71,9 @@ export const EdCompPicker = () => {
|
||||||
p.render();
|
p.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// activatePopup();
|
activatePopup();
|
||||||
// }, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TopBtn
|
<TopBtn
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,10 @@ export const EdPopComp = () => {
|
||||||
className={cx(
|
className={cx(
|
||||||
"absolute inset-0",
|
"absolute inset-0",
|
||||||
css`
|
css`
|
||||||
|
> .container {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
> .tree-root > .listitem:first-child > div {
|
> .tree-root > .listitem:first-child > div {
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +220,6 @@ export const EdPopComp = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<EdCompPreview />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,10 @@ import { useGlobal } from "web-utils";
|
||||||
import { produceCSS } from "../../../../../utils/css/gen";
|
import { produceCSS } from "../../../../../utils/css/gen";
|
||||||
import { IItem } from "../../../../../utils/types/item";
|
import { IItem } from "../../../../../utils/types/item";
|
||||||
import { IText } from "../../../../../utils/types/text";
|
import { IText } from "../../../../../utils/types/text";
|
||||||
|
import { loadComponent } from "../../../logic/comp/load";
|
||||||
import { EDGlobal, PG, active } from "../../../logic/ed-global";
|
import { EDGlobal, PG, active } from "../../../logic/ed-global";
|
||||||
import { EdCompPreviewTree } from "./comp-preview-tree";
|
import { EdCompPreviewTree } from "./comp-preview-tree";
|
||||||
import { compPicker, reloadCompPicker } from "./comp-reload";
|
import { compPicker, reloadCompPicker } from "./comp-reload";
|
||||||
import { loadComponent } from "../../../logic/comp/load";
|
|
||||||
import { NodeModel } from "@minoru/react-dnd-treeview";
|
|
||||||
import { CompItem } from "./comp-tree";
|
|
||||||
|
|
||||||
export const EdCompPreview = () => {
|
export const EdCompPreview = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { useGlobal, useLocal } from "web-utils";
|
||||||
import { EDGlobal, active } from "../../../logic/ed-global";
|
import { EDGlobal, active } from "../../../logic/ed-global";
|
||||||
import { compPicker, reloadCompPicker } from "./comp-reload";
|
import { compPicker, reloadCompPicker } from "./comp-reload";
|
||||||
import { treeRebuild } from "../../../logic/tree/build";
|
import { treeRebuild } from "../../../logic/tree/build";
|
||||||
|
import tc from "tinycolor2";
|
||||||
export type CompItem = {
|
export type CompItem = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -21,10 +21,64 @@ export const edPageTreeRender: NodeRender<CompItem> = (
|
||||||
|
|
||||||
const isTrashed = !!compPicker.trash.find((e) => e.id === item.id);
|
const isTrashed = !!compPicker.trash.find((e) => e.id === item.id);
|
||||||
|
|
||||||
|
const addComponent = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||||
|
if (isTrashed) {
|
||||||
|
p.ui.popup.comp.preview_id = item.id;
|
||||||
|
p.ui.popup.comp_group = {
|
||||||
|
mouse_event: e,
|
||||||
|
async on_pick(group_id) {
|
||||||
|
await _db.component.update({
|
||||||
|
where: { id: item.id },
|
||||||
|
data: { id_component_group: group_id },
|
||||||
|
});
|
||||||
|
await reloadCompPicker(p);
|
||||||
|
treeRebuild(p);
|
||||||
|
p.render();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
p.render();
|
||||||
|
} else {
|
||||||
|
if (p.ui.popup.comp.open) {
|
||||||
|
p.ui.popup.comp.open(item.id);
|
||||||
|
}
|
||||||
|
p.ui.popup.comp.open = null;
|
||||||
|
active.item_id = compPicker.active_id;
|
||||||
|
compPicker.active_id = "";
|
||||||
|
treeRebuild(p);
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const delComponent = async (comp_id: string) => {
|
||||||
|
if (isTrashed) {
|
||||||
|
if (confirm("Permanently delete this component?")) {
|
||||||
|
await _db.component.delete({
|
||||||
|
where: { id: p.ui.popup.comp.preview_id },
|
||||||
|
});
|
||||||
|
const idx = compPicker.tree.findIndex((e) => e.id === comp_id) + 1;
|
||||||
|
|
||||||
|
if (idx >= 0 && compPicker.tree[idx])
|
||||||
|
p.ui.popup.comp.preview_id = compPicker.tree[idx].id as any;
|
||||||
|
|
||||||
|
compPicker.tree = compPicker.tree.filter((e) => e.id !== comp_id);
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (confirm("Move component to trash?")) {
|
||||||
|
await _db.component.update({
|
||||||
|
where: { id: comp_id },
|
||||||
|
data: { id_component_group: compPicker.trash_id },
|
||||||
|
});
|
||||||
|
await reloadCompPicker(p);
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"flex hover:bg-blue-50 cursor-pointer",
|
"flex flex-col hover:bg-blue-50 cursor-pointer",
|
||||||
css`
|
css`
|
||||||
.btn {
|
.btn {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
@ -34,25 +88,32 @@ export const edPageTreeRender: NodeRender<CompItem> = (
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
item.id === p.page.cur.id && `bg-blue-50`,
|
item.id === p.page.cur.id && `bg-blue-50`,
|
||||||
item.type === "component" && "m-1 border flex-1",
|
item.type === "component" && "ml-1 mr-2 mb-3 border flex-1",
|
||||||
item.type === "folder" && "border-t py-[2px] items-center",
|
item.type === "component" &&
|
||||||
|
css`
|
||||||
|
min-width: 190px;
|
||||||
|
`,
|
||||||
|
item.type === "folder" && "border-t py-[2px] ",
|
||||||
item.id === p.ui.popup.comp.preview_id &&
|
item.id === p.ui.popup.comp.preview_id &&
|
||||||
css`
|
css`
|
||||||
border: 1px solid blue !important;
|
border: 1px solid blue !important;
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
onClick={() => {
|
onClick={(e) => {
|
||||||
if (item.type === "folder") {
|
if (item.type === "folder") {
|
||||||
onToggle();
|
onToggle();
|
||||||
} else {
|
} else {
|
||||||
if (p.ui.popup.comp.preview_id !== item.id) {
|
addComponent(e);
|
||||||
p.ui.popup.comp.preview_id = item.id;
|
|
||||||
} else {
|
|
||||||
p.ui.popup.comp.preview_id = "";
|
|
||||||
}
|
|
||||||
p.render();
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
{item.type === "component" && <Pic name={item.name} />}
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"flex",
|
||||||
|
item.type === "component" && "items-stretch",
|
||||||
|
item.type === "folder" && "items-center"
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{item.id === p.page.cur.id && (
|
{item.id === p.page.cur.id && (
|
||||||
<div className="absolute left-0 top-0 bottom-0 bg-blue-500 w-1"></div>
|
<div className="absolute left-0 top-0 bottom-0 bg-blue-500 w-1"></div>
|
||||||
|
|
@ -134,46 +195,37 @@ export const edPageTreeRender: NodeRender<CompItem> = (
|
||||||
)}
|
)}
|
||||||
onClick={async (e) => {
|
onClick={async (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
delComponent(item.id);
|
||||||
if (isTrashed) {
|
|
||||||
p.ui.popup.comp.preview_id = item.id;
|
|
||||||
p.ui.popup.comp_group = {
|
|
||||||
mouse_event: e,
|
|
||||||
async on_pick(group_id) {
|
|
||||||
await _db.component.update({
|
|
||||||
where: { id: item.id },
|
|
||||||
data: { id_component_group: group_id },
|
|
||||||
});
|
|
||||||
await reloadCompPicker(p);
|
|
||||||
treeRebuild(p);
|
|
||||||
p.render();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
p.render();
|
|
||||||
} else {
|
|
||||||
if (p.ui.popup.comp.open) {
|
|
||||||
p.ui.popup.comp.open(item.id);
|
|
||||||
}
|
|
||||||
p.ui.popup.comp.open = null;
|
|
||||||
active.item_id = compPicker.active_id;
|
|
||||||
compPicker.active_id = "";
|
|
||||||
treeRebuild(p);
|
|
||||||
p.render();
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="normal">
|
<div className="normal">
|
||||||
<PlayIcon />
|
<DeleteIcon />
|
||||||
</div>
|
</div>
|
||||||
<div className="over hidden">
|
<div className="over hidden text-red-600">
|
||||||
{isTrashed ? <ResetIcon /> : <CheckIcon />}
|
<DeleteIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colorize = (str: string) => {
|
||||||
|
let hash = 0;
|
||||||
|
if (str.length === 0) return "";
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||||
|
hash = hash & hash;
|
||||||
|
}
|
||||||
|
var color = "#";
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
var value = (hash >> (i * 8)) & 255;
|
||||||
|
color += ("00" + value.toString(16)).substr(-2);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
};
|
||||||
|
|
||||||
const Name: FC<{ name: ReactNode }> = ({ name }) => {
|
const Name: FC<{ name: ReactNode }> = ({ name }) => {
|
||||||
if (typeof name !== "string") return name;
|
if (typeof name !== "string") return name;
|
||||||
if (name === "__TRASH__") return "Trash";
|
if (name === "__TRASH__") return "Trash";
|
||||||
|
|
@ -192,6 +244,26 @@ const Name: FC<{ name: ReactNode }> = ({ name }) => {
|
||||||
return <div>{name}</div>;
|
return <div>{name}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Pic: FC<{ name: string }> = ({ name }) => {
|
||||||
|
const bg = colorize(name);
|
||||||
|
const fg = tc(bg);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"capitalize text-center flex items-center justify-center",
|
||||||
|
css`
|
||||||
|
height: 50px;
|
||||||
|
background-color: ${bg};
|
||||||
|
opacity: 0.8;
|
||||||
|
color: ${fg.isDark() ? "white" : "black"};
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{name.split("_").join(" ")}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const CheckIcon = () => (
|
const CheckIcon = () => (
|
||||||
<div
|
<div
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ export const EdStyleAll = () => {
|
||||||
? p.comp.list[active.comp_id].meta[active.item_id]
|
? p.comp.list[active.comp_id].meta[active.item_id]
|
||||||
: p.page.meta[active.item_id];
|
: p.page.meta[active.item_id];
|
||||||
|
|
||||||
let item = meta.item;
|
let item = meta?.item;
|
||||||
let is_inherit = false;
|
let is_inherit = false;
|
||||||
if (item.component?.id) {
|
if (item?.component?.id) {
|
||||||
const comp = p.comp.list[item.component.id].doc
|
const comp = p.comp.list[item.component.id].doc
|
||||||
.getMap("map")
|
.getMap("map")
|
||||||
.get("root")
|
.get("root")
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { InspectTreeResult } from "fs-jetpack/types";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { watch } from "fs";
|
import { watch } from "fs";
|
||||||
import { CORS_HEADERS } from "./serve-api";
|
import { CORS_HEADERS } from "./serve-api";
|
||||||
|
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
|
|
||||||
|
|
@ -26,8 +25,30 @@ const cache = {
|
||||||
>,
|
>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const serveStatic = {
|
export const serveStatic: any = {
|
||||||
init: async () => {
|
async init() {
|
||||||
|
await this.walk();
|
||||||
|
if (g.mode === "dev") {
|
||||||
|
watch(dir.path(`app/static`), async (_, filename) => {
|
||||||
|
if (filename) {
|
||||||
|
const path = join("static", filename);
|
||||||
|
try {
|
||||||
|
const file = Bun.file(dir.path(`app/${path}`));
|
||||||
|
if (await file.exists()) {
|
||||||
|
cache.static[`/${filename}`] = {
|
||||||
|
type: mime.getType(path) || "application/octet-stream",
|
||||||
|
compression: g.mode === "prod" ? "br" : "",
|
||||||
|
content: await file.arrayBuffer(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
cache.static = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
walk: async () => {
|
||||||
const list = await inspectTreeAsync(dir.path(`app/${web.path}`));
|
const list = await inspectTreeAsync(dir.path(`app/${web.path}`));
|
||||||
const walk = async (
|
const walk = async (
|
||||||
list: InspectTreeResult,
|
list: InspectTreeResult,
|
||||||
|
|
@ -52,31 +73,11 @@ export const serveStatic = {
|
||||||
if (list) {
|
if (list) {
|
||||||
await walk(list);
|
await walk(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g.mode === "dev") {
|
|
||||||
watch(dir.path(`app/static`), async (_, filename) => {
|
|
||||||
if (filename) {
|
|
||||||
const path = join("static", filename);
|
|
||||||
try {
|
|
||||||
const file = Bun.file(dir.path(`app/${path}`));
|
|
||||||
if (await file.exists()) {
|
|
||||||
cache.static[`/${filename}`] = {
|
|
||||||
type: mime.getType(path) || "application/octet-stream",
|
|
||||||
compression: g.mode === "prod" ? "br" : "",
|
|
||||||
content: await file.arrayBuffer(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
|
||||||
cache.static = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
exists: (url: URL) => {
|
exists: (url: URL) => {
|
||||||
return !!cache.static[url.pathname];
|
return !!cache.static[url.pathname];
|
||||||
},
|
},
|
||||||
serve: (url: URL) => {
|
async serve(url: URL) {
|
||||||
let file = cache.static[url.pathname];
|
let file = cache.static[url.pathname];
|
||||||
if (file) {
|
if (file) {
|
||||||
return new Response(file.content, {
|
return new Response(file.content, {
|
||||||
|
|
@ -88,6 +89,10 @@ export const serveStatic = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g.mode === 'dev' && url.pathname.endsWith('.js')) {
|
||||||
|
await this.walk();
|
||||||
|
}
|
||||||
|
|
||||||
file = cache.static["/index.html"];
|
file = cache.static["/index.html"];
|
||||||
if (file) {
|
if (file) {
|
||||||
return new Response(file.content, {
|
return new Response(file.content, {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue