feature: added ability to drag and drop files/folders
Refactored drop function Bug: Moving root directory throws an error
mellbacon committed
May 24, 2023 at 14:35 UTC
c50f570ae7d463da9c1328ca8a1fa8223c0bb16a
2 files changed
+34
-19
src/lib/FileTree/FileTreeList.svelte
+33
-18
@@ -10,6 +10,7 @@
10
import Directory from "../../util/icons/Directory.svelte";
11
import {filetree} from "../FileTree.svelte";
12
import ContextMenu from "../utility/ContextMenu.svelte";
13
+ import { moveFile } from "../File";
14
15
export let root = false;
16
export let isroot = false;
@@ -61,39 +62,53 @@
62
}
63
64
function dragstart(e) {
64
- let data = {element: `filetree-node-${id}`, id:id, type: "parent"};
65
+ let data = {element: `filetree-node-${id}`, id:id, type: "directory"};
66
e.dataTransfer.setData("text/plain", JSON.stringify(data));
67
}
68
68
- function drop(e) {
69
+ async function drop(e) {
70
let data = JSON.parse(e.dataTransfer.getData("text/plain"))
71
let el = document.getElementById(data.element);
72
let from = el.parentElement;
72
- let to = e.target.parentElement.parentElement;
73
-
74
- let fromid = from.getAttribute("data-id");
75
- let toid = to.getAttribute("data-id");
76
-
73
+ let to = dropTarget.parentElement.parentElement;
74
+ if (dropTarget.hasAttribute("data-nodetype")) {
75
+ if (dropTarget.nextElementSibling) {
76
+ to = dropTarget.nextElementSibling;
77
+ }
78
+ else {
79
+ to = dropTarget;
80
+ }
81
+ }
82
+
83
+ const fromid = from.getAttribute("data-id");
84
+ const toid = to.getAttribute("data-id");
85
const element = findNode(parseInt(data.id));
86
const fromlist = findNode(parseInt(fromid));
87
const tolist = findNode(parseInt(toid));
88
+
89
+ if (fromlist.path === tolist.path) return;
90
81
- fromlist.children.splice(fromlist.children.indexOf(element), 1);
82
- tolist.children = [...tolist.children, element];
83
-
84
- from.removeChild(el);
85
- to.appendChild(el);
91
+ await moveFile(fromlist.path, tolist.path, element.path, data.type);
92
87
- filetree.set($filetree);
88
-
89
- e.target.parentElement.classList.remove("hover");
93
+ e.target.classList.remove("hover");
94
}
95
96
+ let dropTarget = null;
97
function dragenter(e) {
93
- e.target.parentElement.classList.add("hover");
98
+ switch (e.target.nodeName) {
99
+ case "svg": case "SPAN":
100
+ dropTarget = e.target.parentElement;
101
+ break;
102
+ case "path":
103
+ dropTarget = e.target.parentElement.parentElement;
104
+ break;
105
+ default:
106
+ dropTarget = e.target;
107
+ }
108
+ e.target.classList.add("hover");
109
}
110
function dragleave(e) {
96
- e.target.parentElement.classList.remove("hover");
111
+ e.target.classList.remove("hover");
112
}
113
114
const toggleExpansion = (event) => {
@@ -136,7 +151,7 @@
151
{:else}
152
<li id={`filetree-node-${id}`} bind:this={ref} class="treenode" class:root={isroot} on:dragenter|stopPropagation={dragenter} on:dragleave|stopPropagation={dragleave} on:dragend|stopPropagation={dragleave} title={path}>
153
<!-- svelte-ignore a11y-click-events-have-key-events -->
139
- <div bind:this={refLabel} class:selected class="tree-label" on:click={toggleExpansion} draggable={true} on:dragstart={dragstart} on:mouseup={(e) => {
154
+ <div bind:this={refLabel} data-id={id} class:selected class="tree-label" data-nodetype="directory" on:click={toggleExpansion} on:dragover|preventDefault on:drop|stopPropagation={drop} draggable={true} on:dragstart={dragstart} on:mouseup={(e) => {
155
if (e.button === 2) {
156
contextmenu = true;
157
}
src/lib/FileTree/FileTreeNode.svelte
+1
-1
@@ -42,7 +42,7 @@
42
]
43
44
function dragstart(e) {
45
- let data = {element: `filetree-node-${id}`, id:id, type: "node"};
45
+ let data = {element: `filetree-node-${id}`, id:id, type: "file"};
46
e.dataTransfer.setData("text/plain", JSON.stringify(data));
47
}
48