From 992d7038e5763fed5e31e38ceef880525a94dcad Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Mon, 10 Nov 2025 22:39:29 +0100 Subject: [PATCH] restore drag preview --- .../documents/useDocumentDragHandlers.js | 86 ++++++++++++++++--- frontend/src/styles/documents/viewer.css | 13 ++- 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/frontend/src/hooks/documents/useDocumentDragHandlers.js b/frontend/src/hooks/documents/useDocumentDragHandlers.js index 3a09fee..9662e89 100644 --- a/frontend/src/hooks/documents/useDocumentDragHandlers.js +++ b/frontend/src/hooks/documents/useDocumentDragHandlers.js @@ -53,24 +53,90 @@ const useDocumentDragHandlers = ({ const wrapper = document.createElement('div'); wrapper.className = 'document-drag-preview'; - wrapper.style.width = `${canvasSize}px`; - wrapper.style.height = `${canvasSize}px`; + wrapper.style.setProperty('--drag-preview-size', `${canvasSize}px`); visibleItems.forEach((item, index) => { - const slot = document.createElement('div'); - slot.className = 'document-drag-preview__item'; - slot.style.setProperty('--index', String(index)); - slot.style.width = `${size}px`; - slot.style.height = `${size}px`; + const layer = document.createElement('div'); + layer.className = 'document-drag-preview__item'; + layer.style.setProperty('--index', String(index)); + const rotationMagnitude = Math.random() * 8 + 2; + const rotation = (index % 2 === 0 ? 1 : -1) * rotationMagnitude; + layer.style.setProperty('--rotation-deg', `${rotation}deg`); if (item.type === 'document') { - slot.textContent = item.payload?.title || 'Document'; + const doc = item.payload; + const rowEl = doc?.id + ? document.getElementById(`document-row-${doc.id}`) + || document.getElementById(`document-card-${doc.id}`) + : null; + const wrapperEl = rowEl?.querySelector('.document-thumbnail-wrapper'); + const thumbnailEl = rowEl?.querySelector('.document-thumbnail'); + const placeholderEl = rowEl?.querySelector('.thumb-placeholder'); + const aspectAttr = wrapperEl?.dataset?.thumbnailAspect; + const aspectRatio = aspectAttr ? parseFloat(aspectAttr) : null; + + let thumbWidth = size; + let thumbHeight = size; + if (Number.isFinite(aspectRatio) && aspectRatio > 0) { + if (aspectRatio >= 1) { + thumbWidth = size; + thumbHeight = Math.max(size / aspectRatio, size * 0.5); + } else { + thumbHeight = size; + thumbWidth = Math.max(size * aspectRatio, size * 0.5); + } + } + layer.style.width = `${Math.round(thumbWidth)}px`; + layer.style.height = `${Math.round(thumbHeight)}px`; + + const thumbSrc = thumbnailEl?.currentSrc || thumbnailEl?.src || null; + if (thumbSrc) { + layer.classList.add('document-drag-preview__item--image'); + layer.style.backgroundImage = `url("${thumbSrc}")`; + } else if (placeholderEl instanceof HTMLElement) { + const clone = placeholderEl.cloneNode(true); + clone.style.pointerEvents = 'none'; + layer.appendChild(clone); + } else { + layer.textContent = doc?.title || 'Document'; + } } else { - slot.textContent = 'Folder'; + const folderId = item.payload; + const rowEl = folderId ? document.getElementById(`folder-row-${folderId}`) : null; + const iconEl = rowEl?.querySelector('.thumb-icon'); + layer.style.width = `${size}px`; + layer.style.height = `${size}px`; + + let content = null; + if (iconEl instanceof HTMLElement) { + content = iconEl.cloneNode(true); + content.classList.add('document-drag-preview__folder-thumb'); + const svg = content.querySelector('svg'); + if (svg) { + svg.setAttribute('width', '48'); + svg.setAttribute('height', '48'); + } + } + + if (!content) { + content = document.createElement('div'); + content.className = 'document-drag-preview__folder-placeholder'; + content.textContent = 'Folder'; + } + + layer.appendChild(content); } - wrapper.appendChild(slot); + + wrapper.appendChild(layer); }); + if (totalCount > 1) { + const badge = document.createElement('div'); + badge.className = 'document-drag-preview__count'; + badge.textContent = `${totalCount}`; + wrapper.appendChild(badge); + } + document.body.appendChild(wrapper); dragPreviewRef.current = wrapper; return wrapper; diff --git a/frontend/src/styles/documents/viewer.css b/frontend/src/styles/documents/viewer.css index 74af8df..c73de23 100644 --- a/frontend/src/styles/documents/viewer.css +++ b/frontend/src/styles/documents/viewer.css @@ -17,7 +17,7 @@ z-index: 9999; } -.document-drag-preview__thumb { +.document-drag-preview__item { position: absolute; top: 50%; left: 50%; @@ -38,23 +38,23 @@ transform-origin: center; } -.document-drag-preview__thumb--image { +.document-drag-preview__item--image { background-color: #000; background-repeat: no-repeat; background-size: contain; background-position: center; } -.document-drag-preview__thumb .document-thumbnail, -.document-drag-preview__thumb img { +.document-drag-preview__item .document-thumbnail, +.document-drag-preview__item img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } -.document-drag-preview__thumb .thumb-placeholder, -.document-drag-preview__thumb .thumb-placeholder * { +.document-drag-preview__item .thumb-placeholder, +.document-drag-preview__item .thumb-placeholder * { width: 100%; height: 100%; display: flex; @@ -332,4 +332,3 @@ width: 1rem; height: 1rem; } -