wip fix
This commit is contained in:
parent
86ef473710
commit
db45f936fc
File diff suppressed because one or more lines are too long
|
|
@ -15,6 +15,7 @@
|
||||||
"@monaco-editor/react": "^4.6.0",
|
"@monaco-editor/react": "^4.6.0",
|
||||||
"@paralleldrive/cuid2": "2.2.2",
|
"@paralleldrive/cuid2": "2.2.2",
|
||||||
"react-contenteditable": "^3.3.7",
|
"react-contenteditable": "^3.3.7",
|
||||||
|
"react-dropzone": "14.2.3",
|
||||||
"@parcel/packager-wasm": "^2.10.3",
|
"@parcel/packager-wasm": "^2.10.3",
|
||||||
"@parcel/service-worker": "^2.10.3",
|
"@parcel/service-worker": "^2.10.3",
|
||||||
"recast": "^0.23.4",
|
"recast": "^0.23.4",
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,19 @@ export const apiProxy = (api_url: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api_ref) {
|
if (api_ref) {
|
||||||
|
if (actionName === "_raw") {
|
||||||
|
const url = `${base_url}${rest.join("")}`;
|
||||||
|
|
||||||
|
const result = await fetchSendApi(url, rest);
|
||||||
|
resolve(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!api_ref.apiEntry) api_ref.apiEntry = {};
|
if (!api_ref.apiEntry) api_ref.apiEntry = {};
|
||||||
if (api_ref.apiEntry && !api_ref.apiEntry[actionName]) {
|
if (api_ref.apiEntry && !api_ref.apiEntry[actionName]) {
|
||||||
reject(
|
reject(
|
||||||
`API ${actionName.toString()} not found, existing API: \n - ${Object.keys(
|
`API ${actionName.toString()} not found, existing API: \n - ${Object.keys(
|
||||||
api_ref || {}
|
api_ref.apiEntry || {}
|
||||||
).join("\n - ")}`
|
).join("\n - ")}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ export const Root: FC<{}> = ({}) => {
|
||||||
prasiContext.render = local.render;
|
prasiContext.render = local.render;
|
||||||
|
|
||||||
const Provider = GlobalContext.Provider as FC<{ value: any; children: any }>;
|
const Provider = GlobalContext.Provider as FC<{ value: any; children: any }>;
|
||||||
|
|
||||||
const found = local.router.lookup(location.pathname);
|
const found = local.router.lookup(location.pathname);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { EdPopScript } from "./panel/popup/script/pop-script";
|
||||||
import { EdPopSite } from "./panel/popup/site/site-popup";
|
import { EdPopSite } from "./panel/popup/site/site-popup";
|
||||||
import { EdPageHistoryMain } from "./panel/main/main-history";
|
import { EdPageHistoryMain } from "./panel/main/main-history";
|
||||||
import { jscript } from "../../utils/script/jscript";
|
import { jscript } from "../../utils/script/jscript";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export const EdBase = () => {
|
export const EdBase = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { useGlobal } from "web-utils";
|
||||||
import { ResponsiveToggle } from "./panel/header/right/responsive-toggle";
|
import { ResponsiveToggle } from "./panel/header/right/responsive-toggle";
|
||||||
import { EdCompEditable } from "./panel/header/mid/comp-editable";
|
import { EdCompEditable } from "./panel/header/mid/comp-editable";
|
||||||
import { MobileQRButton } from "./panel/side/style/tools/mobile-qr";
|
import { MobileQRButton } from "./panel/side/style/tools/mobile-qr";
|
||||||
|
import { EdFileBrowser } from "./panel/file/file-browser";
|
||||||
|
|
||||||
export const EdMid: FC<{}> = () => {
|
export const EdMid: FC<{}> = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITORF");
|
const p = useGlobal(EDGlobal, "EDITORF");
|
||||||
|
|
@ -37,6 +38,7 @@ export const EdMid: FC<{}> = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-stretch flex-1 justify-end">
|
<div className="flex items-stretch flex-1 justify-end">
|
||||||
|
<EdFileBrowser />
|
||||||
{p.site.responsive !== "desktop-only" && <MobileQRButton />}
|
{p.site.responsive !== "desktop-only" && <MobileQRButton />}
|
||||||
<label className=" text-slate-400 flex items-center pr-1">
|
<label className=" text-slate-400 flex items-center pr-1">
|
||||||
<div className=" px-1"> Zoom</div>
|
<div className=" px-1"> Zoom</div>
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ export const EDGlobal = {
|
||||||
open: {} as Record<string, string[]>,
|
open: {} as Record<string, string[]>,
|
||||||
},
|
},
|
||||||
popup: {
|
popup: {
|
||||||
file: { enabled: false },
|
file: { enabled: false, open: true },
|
||||||
code: {
|
code: {
|
||||||
init: false,
|
init: false,
|
||||||
open: false,
|
open: false,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
import { useCallback, useEffect } from "react";
|
||||||
|
import { useDropzone } from "react-dropzone";
|
||||||
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
|
import { apiProxy } from "../../../../base/load/api/api-proxy";
|
||||||
|
import { Modal } from "../../../../utils/ui/modal";
|
||||||
|
import { EDGlobal } from "../../logic/ed-global";
|
||||||
|
import { EdFileTree } from "./file-tree";
|
||||||
|
import { FEntry } from "./type";
|
||||||
|
|
||||||
|
export const EdFileBrowser = () => {
|
||||||
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const local = useLocal({
|
||||||
|
entry: {} as Record<string, FEntry[]>,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!p.script.api && p.site.config?.api_url) {
|
||||||
|
p.script.api = apiProxy(p.site.config.api_url);
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
p.script.api._raw(`/_file/?dir`).then((e: FEntry[]) => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
local.entry = { "/": e };
|
||||||
|
p.ui.popup.file.enabled = true;
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onDrop = useCallback((acceptedFiles: any[]) => {
|
||||||
|
console.log(acceptedFiles);
|
||||||
|
}, []);
|
||||||
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||||
|
onDrop,
|
||||||
|
noClick: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!p.ui.popup.file.enabled) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="items-center flex px-2 cursor-pointer border border-transparent hover:bg-slate-200 transition-all hover:border-black"
|
||||||
|
onClick={() => {
|
||||||
|
p.ui.popup.file.open = true;
|
||||||
|
p.render();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="12"
|
||||||
|
height="12"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M20 10a1 1 0 001-1V6a1 1 0 00-1-1h-2.5a1 1 0 01-.8-.4l-.9-1.2A1 1 0 0015 3h-2a1 1 0 00-1 1v5a1 1 0 001 1zM20 21a1 1 0 001-1v-3a1 1 0 00-1-1h-2.9a1 1 0 01-.88-.55l-.42-.85a1 1 0 00-.92-.6H13a1 1 0 00-1 1v5a1 1 0 001 1zM3 5a2 2 0 002 2h3"></path>
|
||||||
|
<path d="M3 3v13a2 2 0 002 2h3"></path>
|
||||||
|
</svg>{" "}
|
||||||
|
<div className="pl-1">Files</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
fade={false}
|
||||||
|
open={p.ui.popup.file.open}
|
||||||
|
onOpenChange={(open) => {
|
||||||
|
if (!open) {
|
||||||
|
p.ui.popup.file.open = false;
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
{...getRootProps()}
|
||||||
|
className={cx(
|
||||||
|
"bg-white select-none fixed inset-[50px] flex",
|
||||||
|
css`
|
||||||
|
outline: none;
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<input {...getInputProps()} />
|
||||||
|
{isDragActive && (
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center flex-col bg-blue-50 border-4 border-blue-500">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
className="lucide lucide-upload"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"></path>
|
||||||
|
<path d="M17 8L12 3 7 8"></path>
|
||||||
|
<path d="M12 3L12 15"></path>
|
||||||
|
</svg>
|
||||||
|
<div>Drag Here to Upload</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="flex flex-1 items-stretch">
|
||||||
|
<div className="flex min-w-[200px] border-r">
|
||||||
|
<EdFileTree entry={local.entry} />
|
||||||
|
</div>
|
||||||
|
<div>Moko</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
import {
|
||||||
|
MultiBackend,
|
||||||
|
NodeModel,
|
||||||
|
Tree as DNDTree,
|
||||||
|
getBackendOptions,
|
||||||
|
} from "@minoru/react-dnd-treeview";
|
||||||
|
import { DndProvider } from "react-dnd";
|
||||||
|
import { FEntry } from "./type";
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
const Tree = DNDTree<FEntry>;
|
||||||
|
|
||||||
|
export const EdFileTree: FC<{ entry: Record<string, FEntry[]> }> = ({
|
||||||
|
entry,
|
||||||
|
}) => {
|
||||||
|
const tree: NodeModel<FEntry>[] = [];
|
||||||
|
for (const [path, entries] of Object.entries(entry)) {
|
||||||
|
const arr = path.split("/");
|
||||||
|
const name = arr.pop() || "/";
|
||||||
|
tree.push({ id: path, text: name, parent: arr.join("/") });
|
||||||
|
for (const e of entries) {
|
||||||
|
if (e.type === "dir") {
|
||||||
|
tree.push({
|
||||||
|
id: (path === "/" ? "" : path) + "/" + e.name,
|
||||||
|
text: e.name,
|
||||||
|
parent: path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DndProvider backend={MultiBackend} options={getBackendOptions()}>
|
||||||
|
<Tree
|
||||||
|
tree={tree}
|
||||||
|
dragPreviewRender={() => <></>}
|
||||||
|
rootId=""
|
||||||
|
initialOpen={true}
|
||||||
|
onDrop={async (newTree, opt) => {}}
|
||||||
|
render={(node, { depth, isOpen, onToggle, hasChild }) => (
|
||||||
|
<div
|
||||||
|
className={cx(css`
|
||||||
|
padding-left: ${(depth * 10) + 10}px;
|
||||||
|
`)}
|
||||||
|
>
|
||||||
|
{node.text}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
></Tree>
|
||||||
|
</DndProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export type FEntry = {
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
type: "dir" | "file";
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue