From 87505023a0371a09cfd2b2e3bff298008c06204c Mon Sep 17 00:00:00 2001 From: jpirnay Date: Tue, 14 Apr 2026 13:00:18 +0200 Subject: [PATCH] Add file drop support --- src/network/html/FilesPage.html | 97 +++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/network/html/FilesPage.html b/src/network/html/FilesPage.html index 96795d17..7b95966e 100644 --- a/src/network/html/FilesPage.html +++ b/src/network/html/FilesPage.html @@ -167,6 +167,36 @@ background-color: #c0392b; } + /* Drag & drop overlay */ + .drop-overlay { + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(52, 152, 219, 0.15); + border: 4px dashed #3498db; + z-index: 300; + justify-content: center; + align-items: center; + pointer-events: none; + } + + .drop-overlay.active { + display: flex; + } + + .drop-overlay-message { + background: var(--card-bg); + color: #3498db; + padding: 24px 40px; + border-radius: 12px; + font-size: 1.4em; + font-weight: bold; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25); + } + /* Upload modal */ .modal-overlay { display: none; @@ -1760,6 +1790,11 @@ + +
+
📥 Drop files to upload to
+
+
@@ -3078,8 +3113,70 @@ this.value = qualitySlider.value; }; } + + setupPageDragAndDrop(); }); + function setupPageDragAndDrop() { + const overlay = document.getElementById('dropOverlay'); + const pathSpan = document.getElementById('dropOverlayPath'); + let dragDepth = 0; + + const hasFiles = (e) => { + if (!e.dataTransfer) return false; + const types = e.dataTransfer.types; + if (!types) return false; + for (let i = 0; i < types.length; i++) { + if (types[i] === 'Files') return true; + } + return false; + }; + + const canAcceptDrop = () => { + if (isUploadInProgress) return false; + if (document.getElementById('uploadModal').classList.contains('open')) return false; + return true; + }; + + window.addEventListener('dragenter', (e) => { + if (!hasFiles(e) || !canAcceptDrop()) return; + e.preventDefault(); + dragDepth++; + pathSpan.textContent = currentPath === '/' ? '/ 🏠' : currentPath; + overlay.classList.add('active'); + }); + + window.addEventListener('dragover', (e) => { + if (!hasFiles(e) || !canAcceptDrop()) return; + e.preventDefault(); + e.dataTransfer.dropEffect = 'copy'; + }); + + window.addEventListener('dragleave', (e) => { + if (!hasFiles(e)) return; + dragDepth = Math.max(0, dragDepth - 1); + if (dragDepth === 0) overlay.classList.remove('active'); + }); + + window.addEventListener('drop', (e) => { + if (!hasFiles(e)) return; + e.preventDefault(); + dragDepth = 0; + overlay.classList.remove('active'); + if (!canAcceptDrop()) return; + const files = e.dataTransfer.files; + if (!files || files.length === 0) return; + + const dt = new DataTransfer(); + for (let i = 0; i < files.length; i++) dt.items.add(files[i]); + + openUploadModal(); + const fileInput = document.getElementById('fileInput'); + fileInput.files = dt.files; + validateFile(); + }); + } + function openFolderModal() { document.getElementById('folderPathDisplay').textContent = currentPath === '/' ? '/ 🏠' : currentPath; document.getElementById('folderModal').classList.add('open');