show all files in explore
This commit is contained in:
1 parent
fa5644fda7
commit
9e71989ff5
3 files changed
+216
-187
No files matched your search
+207
-180
@@ -2,6 +2,7 @@ import { FileTreeType, useWorkspace } from "@/contexts/workspace-context";
|
|||||||
import { NodeDef, getNodeType } from "@/misc/b3type";
|
import { NodeDef, getNodeType } from "@/misc/b3type";
|
||||||
import * as b3util from "@/misc/b3util";
|
import * as b3util from "@/misc/b3util";
|
||||||
import { modal } from "@/misc/hooks";
|
import { modal } from "@/misc/hooks";
|
||||||
|
import i18n from "@/misc/i18n";
|
||||||
import { Hotkey, isHotkeyPressed, isMacos, useHotkeys } from "@/misc/keys";
|
import { Hotkey, isHotkeyPressed, isMacos, useHotkeys } from "@/misc/keys";
|
||||||
import Path from "@/misc/path";
|
import Path from "@/misc/path";
|
||||||
import { DownOutlined } from "@ant-design/icons";
|
import { DownOutlined } from "@ant-design/icons";
|
||||||
@@ -115,6 +116,160 @@ const renameFile = (oldPath: string, newPath: string) => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// file context menu
|
||||||
|
const createFileContextMenu = (node: FileTreeType) => {
|
||||||
|
const isTreeFile = b3util.isTreeFile(node.path);
|
||||||
|
const MenuItem: FC<FlexProps> = (itemProps) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
gap="50px"
|
||||||
|
style={{ minWidth: "200px", justifyContent: "space-between", alignItems: "center" }}
|
||||||
|
{...itemProps}
|
||||||
|
></Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const arr: MenuProps["items"] = [
|
||||||
|
{
|
||||||
|
disabled: !isTreeFile,
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("open")}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "open",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disabled: !isTreeFile,
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("copy")}</div>
|
||||||
|
<div>{isMacos ? "⌘ C" : "Ctrl+C"}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "copy",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disabled: !isTreeFile,
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("duplicate")}</div>
|
||||||
|
<div>{isMacos ? "⌘ D" : "Ctrl+D"}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "duplicate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{isMacos ? i18n.t("revealFileOnMac") : i18n.t("revealFileOnWindows")}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "revealFile",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("rename")}</div>
|
||||||
|
{isMacos && <IoMdReturnLeft />}
|
||||||
|
{!isMacos && <div>F2</div>}
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "rename",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("delete")}</div>
|
||||||
|
{isMacos && (
|
||||||
|
<Space size={6}>
|
||||||
|
<FiCommand />
|
||||||
|
<FiDelete />
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "delete",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// folder context menu
|
||||||
|
const createFolderContextMenu = (copiedPath: string) => {
|
||||||
|
const MenuItem: FC<FlexProps> = (itemProps) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
gap="50px"
|
||||||
|
style={{ minWidth: "200px", justifyContent: "space-between", alignItems: "center" }}
|
||||||
|
{...itemProps}
|
||||||
|
></Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const arr: MenuProps["items"] = [
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("newFile")}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "newFile",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("newFolder")}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "newFolder",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{isMacos ? i18n.t("revealFileOnMac") : i18n.t("revealFileOnWindows")}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "revealFile",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disabled: !copiedPath,
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("paste")}</div>
|
||||||
|
<div>{isMacos ? "⌘ V" : "Ctrl+V"}</div>
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "paste",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("rename")}</div>
|
||||||
|
{isMacos && <IoMdReturnLeft />}
|
||||||
|
{!isMacos && <div>F2</div>}
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "rename",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<MenuItem>
|
||||||
|
<div>{i18n.t("delete")}</div>
|
||||||
|
{isMacos && (
|
||||||
|
<Space size={6}>
|
||||||
|
<FiCommand />
|
||||||
|
<FiDelete />
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
),
|
||||||
|
key: "delete",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
|
|
||||||
export const Explorer: FC = () => {
|
export const Explorer: FC = () => {
|
||||||
const workspace = {
|
const workspace = {
|
||||||
close: useWorkspace((state) => state.close),
|
close: useWorkspace((state) => state.close),
|
||||||
@@ -237,8 +392,7 @@ export const Explorer: FC = () => {
|
|||||||
const node = findFile(selectedKeys[0], workspace.fileTree!);
|
const node = findFile(selectedKeys[0], workspace.fileTree!);
|
||||||
if (isHotkeyPressed(Hotkey.F2) || (isMacos && isHotkeyPressed(Hotkey.Enter))) {
|
if (isHotkeyPressed(Hotkey.F2) || (isMacos && isHotkeyPressed(Hotkey.Enter))) {
|
||||||
if (node && node !== workspace.fileTree) {
|
if (node && node !== workspace.fileTree) {
|
||||||
node.editing = true;
|
dispatch("rename", node);
|
||||||
setNewName("");
|
|
||||||
}
|
}
|
||||||
} else if (isHotkeyPressed(Hotkey.Delete) || isHotkeyPressed(Hotkey.MacDelete)) {
|
} else if (isHotkeyPressed(Hotkey.Delete) || isHotkeyPressed(Hotkey.MacDelete)) {
|
||||||
if (node && node !== workspace.fileTree) {
|
if (node && node !== workspace.fileTree) {
|
||||||
@@ -283,12 +437,12 @@ export const Explorer: FC = () => {
|
|||||||
node.title = Path.basename(node.path);
|
node.title = Path.basename(node.path);
|
||||||
fs.mkdirSync(node.path);
|
fs.mkdirSync(node.path);
|
||||||
} else if (node.path.endsWith("/.json")) {
|
} else if (node.path.endsWith("/.json")) {
|
||||||
node.path = Path.dirname(node.path) + "/" + newName.replace(/[^\w. _-]+/g, "") + ".json";
|
node.path = Path.dirname(node.path) + "/" + newName.replace(/[^\w. _-]+/g, "");
|
||||||
node.title = Path.basename(node.path);
|
node.title = Path.basename(node.path);
|
||||||
fs.writeFileSync(node.path, JSON.stringify(b3util.createNewTree(node.title), null, 2));
|
fs.writeFileSync(node.path, JSON.stringify(b3util.createNewTree(node.title), null, 2));
|
||||||
workspace.open(node.path);
|
workspace.open(node.path);
|
||||||
} else {
|
} else {
|
||||||
const newpath = Path.dirname(node.path) + "/" + newName + Path.extname(node.path);
|
const newpath = Path.dirname(node.path) + "/" + newName;
|
||||||
if (renameFile(node.path, newpath)) {
|
if (renameFile(node.path, newpath)) {
|
||||||
setSelectedKeys([newpath]);
|
setSelectedKeys([newpath]);
|
||||||
}
|
}
|
||||||
@@ -300,7 +454,9 @@ export const Explorer: FC = () => {
|
|||||||
const dispatch = (event: MenuEvent, node: FileTreeType, dest?: FileTreeType) => {
|
const dispatch = (event: MenuEvent, node: FileTreeType, dest?: FileTreeType) => {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case "open": {
|
case "open": {
|
||||||
workspace.open(node.path);
|
if (b3util.isTreeFile(node.path)) {
|
||||||
|
workspace.open(node.path);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "newFolder": {
|
case "newFolder": {
|
||||||
@@ -320,7 +476,7 @@ export const Explorer: FC = () => {
|
|||||||
case "newFile": {
|
case "newFile": {
|
||||||
const folderNode: FileTreeType = {
|
const folderNode: FileTreeType = {
|
||||||
path: node.path + "/.json",
|
path: node.path + "/.json",
|
||||||
title: "",
|
title: ".json",
|
||||||
isLeaf: true,
|
isLeaf: true,
|
||||||
editing: true,
|
editing: true,
|
||||||
};
|
};
|
||||||
@@ -385,17 +541,21 @@ export const Explorer: FC = () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "copy": {
|
case "copy": {
|
||||||
setCopyFile(node.path);
|
if (b3util.isTreeFile(node.path)) {
|
||||||
|
setCopyFile(node.path);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "duplicate": {
|
case "duplicate": {
|
||||||
for (let i = 1; ; i++) {
|
if (b3util.isTreeFile(node.path)) {
|
||||||
const dupName = Path.basenameWithoutExt(node.path) + " " + i + ".json";
|
for (let i = 1; ; i++) {
|
||||||
const dupPath = Path.dirname(node.path) + "/" + dupName;
|
const dupName = Path.basenameWithoutExt(node.path) + " " + i + ".json";
|
||||||
if (!fs.existsSync(dupPath)) {
|
const dupPath = Path.dirname(node.path) + "/" + dupName;
|
||||||
fs.copyFileSync(node.path, dupPath);
|
if (!fs.existsSync(dupPath)) {
|
||||||
setSelectedKeys([dupPath]);
|
fs.copyFileSync(node.path, dupPath);
|
||||||
break;
|
setSelectedKeys([dupPath]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -491,12 +651,16 @@ export const Explorer: FC = () => {
|
|||||||
}
|
}
|
||||||
case "move": {
|
case "move": {
|
||||||
try {
|
try {
|
||||||
const newPath = dest!.path + "/" + Path.basename(node.path);
|
const destDir = dest?.children ? dest.path : Path.dirname(dest!.path);
|
||||||
|
if (destDir === Path.dirname(node.path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newPath = destDir + "/" + Path.basename(node.path);
|
||||||
const doMove = () => {
|
const doMove = () => {
|
||||||
fs.renameSync(node.path, newPath);
|
fs.renameSync(node.path, newPath);
|
||||||
for (const editor of workspace.editors) {
|
for (const editor of workspace.editors) {
|
||||||
if (editor.path.startsWith(node.path)) {
|
if (editor.path.startsWith(node.path)) {
|
||||||
editor.dispatch("rename", dest!.path + "/" + Path.basename(editor.path));
|
editor.dispatch("rename", destDir + "/" + Path.basename(editor.path));
|
||||||
}
|
}
|
||||||
console.log("editor move", editor.path === newPath, editor.path, newPath);
|
console.log("editor move", editor.path === newPath, editor.path, newPath);
|
||||||
if (editor.path.startsWith(newPath)) {
|
if (editor.path.startsWith(newPath)) {
|
||||||
@@ -554,161 +718,15 @@ export const Explorer: FC = () => {
|
|||||||
ipcRenderer.invoke("showItemInFolder", node.path);
|
ipcRenderer.invoke("showItemInFolder", node.path);
|
||||||
break;
|
break;
|
||||||
case "rename": {
|
case "rename": {
|
||||||
node.editing = true;
|
if (b3util.isTreeFile(node.path)) {
|
||||||
setNewName("");
|
node.editing = true;
|
||||||
|
setNewName("");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// context menu
|
|
||||||
const fileContextMenu = useMemo(() => {
|
|
||||||
const MenuItem: FC<FlexProps> = (itemProps) => {
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
gap="50px"
|
|
||||||
style={{ minWidth: "200px", justifyContent: "space-between", alignItems: "center" }}
|
|
||||||
{...itemProps}
|
|
||||||
></Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const arr: MenuProps["items"] = [
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("open")}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "open",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("copy")}</div>
|
|
||||||
<div>{isMacos ? "⌘ C" : "Ctrl+C"}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "copy",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("duplicate")}</div>
|
|
||||||
<div>{isMacos ? "⌘ D" : "Ctrl+D"}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "duplicate",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{isMacos ? t("revealFileOnMac") : t("revealFileOnWindows")}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "revealFile",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("rename")}</div>
|
|
||||||
{isMacos && <IoMdReturnLeft />}
|
|
||||||
{!isMacos && <div>F2</div>}
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "rename",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("delete")}</div>
|
|
||||||
{isMacos && (
|
|
||||||
<Space size={6}>
|
|
||||||
<FiCommand />
|
|
||||||
<FiDelete />
|
|
||||||
</Space>
|
|
||||||
)}
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "delete",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return arr;
|
|
||||||
}, [t]);
|
|
||||||
|
|
||||||
const directoryContextMenu = useMemo(() => {
|
|
||||||
const MenuItem: FC<FlexProps> = (itemProps) => {
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
gap="50px"
|
|
||||||
style={{ minWidth: "200px", justifyContent: "space-between", alignItems: "center" }}
|
|
||||||
{...itemProps}
|
|
||||||
></Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const arr: MenuProps["items"] = [
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("newFile")}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "newFile",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("newFolder")}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "newFolder",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{isMacos ? t("revealFileOnMac") : t("revealFileOnWindows")}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "revealFile",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div style={{ color: copyFile ? "inherit" : "gray" }}>{t("paste")}</div>
|
|
||||||
<div style={{ color: copyFile ? "inherit" : "gray" }}>{isMacos ? "⌘ V" : "Ctrl+V"}</div>
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "paste",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("rename")}</div>
|
|
||||||
{isMacos && <IoMdReturnLeft />}
|
|
||||||
{!isMacos && <div>F2</div>}
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "rename",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: (
|
|
||||||
<MenuItem>
|
|
||||||
<div>{t("delete")}</div>
|
|
||||||
{isMacos && (
|
|
||||||
<Space size={6}>
|
|
||||||
<FiCommand />
|
|
||||||
<FiDelete />
|
|
||||||
</Space>
|
|
||||||
)}
|
|
||||||
</MenuItem>
|
|
||||||
),
|
|
||||||
key: "delete",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return arr;
|
|
||||||
}, [t, copyFile]);
|
|
||||||
|
|
||||||
const onClick = (info: MenuInfo) => {
|
const onClick = (info: MenuInfo) => {
|
||||||
const node = findFile(selectedKeys[0], workspace.fileTree!) ?? workspace.fileTree;
|
const node = findFile(selectedKeys[0], workspace.fileTree!) ?? workspace.fileTree;
|
||||||
if (node) {
|
if (node) {
|
||||||
@@ -728,7 +746,7 @@ export const Explorer: FC = () => {
|
|||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
style={{ height: "100%" }}
|
style={{ height: "100%" }}
|
||||||
onContextMenuCapture={() => {
|
onContextMenuCapture={() => {
|
||||||
setContextMenu(directoryContextMenu);
|
setContextMenu(createFolderContextMenu(copyFile));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ padding: "12px 24px" }}>
|
<div style={{ padding: "12px 24px" }}>
|
||||||
@@ -750,34 +768,36 @@ export const Explorer: FC = () => {
|
|||||||
}}
|
}}
|
||||||
onRightClick={(info) => {
|
onRightClick={(info) => {
|
||||||
if (info.node.isLeaf) {
|
if (info.node.isLeaf) {
|
||||||
setContextMenu(fileContextMenu);
|
setContextMenu(createFileContextMenu(info.node));
|
||||||
}
|
}
|
||||||
setSelectedKeys([info.node.path]);
|
setSelectedKeys([info.node.path]);
|
||||||
}}
|
}}
|
||||||
onSelect={(_, info) => {
|
onSelect={(_, info) => {
|
||||||
const node = info.selectedNodes.at(0);
|
const node = info.selectedNodes.at(0);
|
||||||
if (node) {
|
if (node) {
|
||||||
if (!node.children) {
|
dispatch("open", node);
|
||||||
workspace.open(node.path);
|
|
||||||
}
|
|
||||||
setSelectedKeys([node.path]);
|
setSelectedKeys([node.path]);
|
||||||
}
|
}
|
||||||
if (node && !node.children) {
|
|
||||||
workspace.open(node.path);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
onDrop={(info) => {
|
onDrop={(info) => {
|
||||||
dispatch("move", info.dragNode, info.node);
|
dispatch("move", info.dragNode, info.node);
|
||||||
}}
|
}}
|
||||||
titleRender={(node) => {
|
titleRender={(node) => {
|
||||||
|
const value = Path.basename(node.title);
|
||||||
if (node.editing) {
|
if (node.editing) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "inline-flex" }}>
|
<div style={{ display: "inline-flex" }}>
|
||||||
<Input
|
<Input
|
||||||
defaultValue={Path.basenameWithoutExt(node.title)}
|
defaultValue={value}
|
||||||
autoFocus
|
autoFocus
|
||||||
style={{ padding: "0px 0px", borderRadius: "2px" }}
|
style={{ padding: "0px 0px", borderRadius: "2px" }}
|
||||||
onFocus={(e) => e.target.select()}
|
onFocus={(e) => {
|
||||||
|
if (value.startsWith(".")) {
|
||||||
|
e.target.setSelectionRange(0, 0);
|
||||||
|
} else {
|
||||||
|
e.target.setSelectionRange(0, value.lastIndexOf("."));
|
||||||
|
}
|
||||||
|
}}
|
||||||
onChange={(e) => setNewName(e.target.value)}
|
onChange={(e) => setNewName(e.target.value)}
|
||||||
onPressEnter={() => {
|
onPressEnter={() => {
|
||||||
if (newName) {
|
if (newName) {
|
||||||
@@ -817,14 +837,21 @@ export const Explorer: FC = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
allowDrop={(options) => {
|
|
||||||
return !options.dropNode.isLeaf;
|
|
||||||
}}
|
|
||||||
onDragStart={(e) => {
|
onDragStart={(e) => {
|
||||||
e.event.dataTransfer.setData("explore-file", e.node.path);
|
e.event.dataTransfer.setData("explore-file", e.node.path);
|
||||||
}}
|
}}
|
||||||
defaultExpandedKeys={[workspace.fileTree.path]}
|
defaultExpandedKeys={[workspace.fileTree.path]}
|
||||||
draggable={newName !== null ? false : { icon: false }}
|
draggable={
|
||||||
|
newName !== null
|
||||||
|
? false
|
||||||
|
: {
|
||||||
|
icon: false,
|
||||||
|
nodeDraggable: (node) => {
|
||||||
|
const fileNode = node as unknown as FileTreeType;
|
||||||
|
return !!fileNode.children || b3util.isTreeFile(fileNode.path);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
expandedKeys={expandedKeys}
|
expandedKeys={expandedKeys}
|
||||||
switcherIcon={<DownOutlined />}
|
switcherIcon={<DownOutlined />}
|
||||||
selectedKeys={selectedKeys}
|
selectedKeys={selectedKeys}
|
||||||
|
|||||||
@@ -161,14 +161,12 @@ export type WorkspaceStore = {
|
|||||||
|
|
||||||
const loadFileTree = (workdir: string, filename: string) => {
|
const loadFileTree = (workdir: string, filename: string) => {
|
||||||
const fullpath = fs.realpathSync(`${workdir}/${filename}`);
|
const fullpath = fs.realpathSync(`${workdir}/${filename}`);
|
||||||
if (!fs.existsSync(fullpath)) {
|
|
||||||
|
if (!fs.existsSync(fullpath) || filename.endsWith(".DS_Store")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stat = fs.statSync(fullpath);
|
const stat = fs.statSync(fullpath);
|
||||||
if (!(stat.isDirectory() || fullpath.endsWith(".json"))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data: FileTreeType = {
|
const data: FileTreeType = {
|
||||||
path: fullpath.replaceAll(Path.sep, "/"),
|
path: fullpath.replaceAll(Path.sep, "/"),
|
||||||
@@ -492,7 +490,7 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
|||||||
let updated = false;
|
let updated = false;
|
||||||
allFiles.forEach((file) => (file.exists = false));
|
allFiles.forEach((file) => (file.exists = false));
|
||||||
const collect = (fileNode?: FileTreeType) => {
|
const collect = (fileNode?: FileTreeType) => {
|
||||||
if (fileNode?.isLeaf) {
|
if (fileNode?.isLeaf && b3util.isTreeFile(fileNode.path)) {
|
||||||
const path = workspace.relative(fileNode.path);
|
const path = workspace.relative(fileNode.path);
|
||||||
let fileMeta = allFiles.get(path);
|
let fileMeta = allFiles.get(path);
|
||||||
if (!fileMeta) {
|
if (!fileMeta) {
|
||||||
|
|||||||
+6
-2
@@ -364,9 +364,9 @@ export const createFileData = (data: TreeGraphData, includeSubtree?: boolean) =>
|
|||||||
return nodeData;
|
return nodeData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createNewTree = (filename: string) => {
|
export const createNewTree = (path: string) => {
|
||||||
const tree: TreeModel = {
|
const tree: TreeModel = {
|
||||||
name: Path.basenameWithoutExt(filename),
|
name: Path.basenameWithoutExt(path),
|
||||||
root: {
|
root: {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: "Sequence",
|
name: "Sequence",
|
||||||
@@ -375,6 +375,10 @@ export const createNewTree = (filename: string) => {
|
|||||||
return tree;
|
return tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isTreeFile = (path: string) => {
|
||||||
|
return path.toLocaleLowerCase().endsWith(".json");
|
||||||
|
};
|
||||||
|
|
||||||
const isAsciiChar = (c: number) => {
|
const isAsciiChar = (c: number) => {
|
||||||
return (c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f);
|
return (c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user