mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 09:22:12 +00:00
drop anywhere in folder
This commit is contained in:
1 parent
a5c1f6ad33
commit
8fd47d8b18
2 files changed
+20
-7
No files matched your search
@@ -23,6 +23,7 @@
|
|||||||
editableName,
|
editableName,
|
||||||
explorerSelection,
|
explorerSelection,
|
||||||
isWithin,
|
isWithin,
|
||||||
|
parentOf,
|
||||||
renaming,
|
renaming,
|
||||||
} from './state.svelte';
|
} from './state.svelte';
|
||||||
|
|
||||||
@@ -206,28 +207,34 @@
|
|||||||
dragging.target = undefined;
|
dragging.target = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The folder where what is dropped on the row goes: the folder of a file, among its files. */
|
||||||
|
let dropFolder = $derived(kind === 'file' ? parentOf(path) : path);
|
||||||
|
|
||||||
function ondragover(event: DragEvent) {
|
function ondragover(event: DragEvent) {
|
||||||
if (kind === 'file' || dragging.paths.length === 0) return;
|
if (dragging.paths.length === 0) return;
|
||||||
// not into itself
|
// not into itself, nor where it is already
|
||||||
if (dragging.paths.some((dragged) => isWithin(path, dragged))) return;
|
if (dragging.paths.some((dragged) => isWithin(dropFolder, dragged))) return;
|
||||||
|
if (dragging.paths.every((dragged) => parentOf(dragged) === dropFolder)) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.dropEffect = 'move';
|
event.dataTransfer.dropEffect = 'move';
|
||||||
}
|
}
|
||||||
dragging.target = path;
|
// the row of the folder shows it
|
||||||
|
dragging.target = dropFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ondragleave(event: DragEvent) {
|
function ondragleave(event: DragEvent) {
|
||||||
if (dragging.target === path && !row?.contains(event.relatedTarget as Node | null)) {
|
// to another row, which tells where it would go (it was entered first)
|
||||||
|
const to = event.relatedTarget as Element | null;
|
||||||
|
if (to?.closest?.('[data-explorer-path]')) return;
|
||||||
dragging.target = undefined;
|
dragging.target = undefined;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function ondrop(event: DragEvent) {
|
async function ondrop(event: DragEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const paths = dragging.paths;
|
const paths = dragging.paths;
|
||||||
ondragend();
|
ondragend();
|
||||||
if (paths.length > 0 && !(await engine.movePaths(paths, path))) {
|
if (paths.length > 0 && !(await engine.movePaths(paths, dropFolder))) {
|
||||||
showError();
|
showError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ function isSeparator(char: string | undefined) {
|
|||||||
return char === '/' || char === '\\';
|
return char === '/' || char === '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The folder that holds `path`. */
|
||||||
|
export function parentOf(path: string): string {
|
||||||
|
const index = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
||||||
|
return index > 0 ? path.slice(0, index) : path;
|
||||||
|
}
|
||||||
|
|
||||||
/** Whether `path` is `folder` or something in it. */
|
/** Whether `path` is `folder` or something in it. */
|
||||||
export function isWithin(path: string, folder: string): boolean {
|
export function isWithin(path: string, folder: string): boolean {
|
||||||
return path === folder || (path.startsWith(folder) && isSeparator(path[folder.length]));
|
return path === folder || (path.startsWith(folder) && isSeparator(path[folder.length]));
|
||||||
|
|||||||
Reference in new issue
Block a user