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
+21
-8
No files matched your search
@@ -23,6 +23,7 @@
|
||||
editableName,
|
||||
explorerSelection,
|
||||
isWithin,
|
||||
parentOf,
|
||||
renaming,
|
||||
} from './state.svelte';
|
||||
|
||||
@@ -206,28 +207,34 @@
|
||||
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) {
|
||||
if (kind === 'file' || dragging.paths.length === 0) return;
|
||||
// not into itself
|
||||
if (dragging.paths.some((dragged) => isWithin(path, dragged))) return;
|
||||
if (dragging.paths.length === 0) return;
|
||||
// not into itself, nor where it is already
|
||||
if (dragging.paths.some((dragged) => isWithin(dropFolder, dragged))) return;
|
||||
if (dragging.paths.every((dragged) => parentOf(dragged) === dropFolder)) return;
|
||||
event.preventDefault();
|
||||
if (event.dataTransfer) {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
dragging.target = path;
|
||||
// the row of the folder shows it
|
||||
dragging.target = dropFolder;
|
||||
}
|
||||
|
||||
function ondragleave(event: DragEvent) {
|
||||
if (dragging.target === path && !row?.contains(event.relatedTarget as Node | null)) {
|
||||
dragging.target = undefined;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
async function ondrop(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
const paths = dragging.paths;
|
||||
ondragend();
|
||||
if (paths.length > 0 && !(await engine.movePaths(paths, path))) {
|
||||
if (paths.length > 0 && !(await engine.movePaths(paths, dropFolder))) {
|
||||
showError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ function isSeparator(char: string | undefined) {
|
||||
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. */
|
||||
export function isWithin(path: string, folder: string): boolean {
|
||||
return path === folder || (path.startsWith(folder) && isSeparator(path[folder.length]));
|
||||
|
||||
Reference in new issue
Block a user