Skip to content

Commit

Permalink
Merge pull request #2466 from reecebrowne/bug/fix-multitool-drag
Browse files Browse the repository at this point in the history
Fix drag and drop bugs and clean up UI
  • Loading branch information
Frooodle authored Dec 17, 2024
2 parents 8053035 + db3a8a8 commit 720705e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 95 deletions.
29 changes: 19 additions & 10 deletions src/main/resources/static/css/dragdrop.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,9 @@
}

.drag-manager_dragging {
width: 0px;
visibility: hidden;
opacity: 0.2;
}

.drag-manager_draghover {
width: 375px !important;
}

.drag-manager_draghover .insert-file-button-container {
display: none !important;
Expand All @@ -46,26 +42,29 @@
}

html[dir="ltr"] .drag-manager_draghover img {
left: calc(50% + 62.5px) !important;
left: 80% !important;
}

html[dir="rtl"] .drag-manager_draghover img {
left: 125px;
left: 25px;
}

.drag-manager_dragging-container .hide-on-drag {
display: none !important;
}

.drag-manager_endpoint {
width: 80px;
height: 100%;
width: 150px;
height: 250px;
background-color: #ffffff10;
transition: width 0.1s;
animation: end-drop-expand 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
margin-left:16px;
border-radius: 8px;

}

.drag-manager_endpoint svg {
Expand All @@ -74,7 +73,8 @@ html[dir="rtl"] .drag-manager_draghover img {
}

.drag-manager_endpoint.drag-manager_draghover {
width: 150px !important;
width: 180px !important;
border: 2px solid darkgreen;
}

@keyframes end-drop-expand {
Expand All @@ -85,3 +85,12 @@ html[dir="rtl"] .drag-manager_draghover img {
width: 80px;
}
}
.moved-element img {
border: 8px solid #198754;
border-radius: 3px;
transition: border 0.5s ease-out;
}

.moved-element.remove img{
border: 8px solid transparent;
}
135 changes: 91 additions & 44 deletions src/main/resources/static/js/multitool/DragDropManager.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
class DragDropManager {
constructor(id, wrapperId) {
this.dragContainer = document.getElementById(id);
this.pageDirection = document.documentElement.getAttribute("dir");
this.pageDirection = document.documentElement.getAttribute('dir');
this.wrapper = document.getElementById(wrapperId);
this.pageDragging = false;
this.hoveredEl = undefined;
this.draggedImageEl = undefined;
this.draggedEl = undefined;
this.selectedPageElements = []; // Store selected pages for multi-page mode
this.elementTimeouts = new Map();

// Add CSS dynamically
const styleElement = document.createElement("link");
styleElement.rel = "stylesheet";
styleElement.href = "css/dragdrop.css";
const styleElement = document.createElement('link');
styleElement.rel = 'stylesheet';
styleElement.href = 'css/dragdrop.css';
document.head.appendChild(styleElement);

// Create the endpoint element
const div = document.createElement("div");
div.classList.add("drag-manager_endpoint");
const div = document.createElement('div');
div.classList.add('page-container');
div.classList.add('drag-manager_endpoint');
div.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
<path d="M8.5 6.5a.5.5 0 0 0-1 0v3.793L6.354 9.146a.5.5 0 1 0-.708.708l2 2a.5.5 0 0 0 .708 0l2-2a.5.5 0 0 0-.708-.708L8.5 10.293V6.5z"/>
<path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z"/>
Expand All @@ -35,59 +37,63 @@ class DragDropManager {
startDraggingPage(div) {
if (window.selectPage) {
// Multi-page drag logic
this.selectedPageElements = window.selectedPages.map((index) => {
const pageEl = document.getElementById(`page-container-${index}`);
if (pageEl) {
pageEl.initialTransform = pageEl.style.transform || "translate(0px, 0px)";
}
return pageEl;
}).filter(Boolean);
this.selectedPageElements = window.selectedPages
.map((index) => {
const pageEl = document.getElementById(`page-container-${index}`);
if (pageEl) {
pageEl.initialTransform = pageEl.style.transform || 'translate(0px, 0px)';
pageEl.classList.add('drag-manager_dragging');
}
return pageEl;
})
.filter(Boolean);

if (this.selectedPageElements.length === 0) return;

this.pageDragging = true;
this.draggedImageEl = document.createElement("div");
this.draggedImageEl.classList.add("multidrag");
this.draggedImageEl = document.createElement('div');
this.draggedImageEl.classList.add('multidrag');
this.draggedImageEl.textContent = `${this.selectedPageElements.length} ${window.translations.dragDropMessage}`;
this.draggedImageEl.style.visibility = "hidden";
this.draggedImageEl.style.visibility = 'hidden';

this.dragContainer.appendChild(this.draggedImageEl);
} else {
// Single-page drag logic
this.pageDragging = true;
this.draggedEl = div;
const img = div.querySelector("img");
div.classList.add("drag-manager_dragging");

const imgEl = document.createElement("img");
imgEl.classList.add("dragged-img");
const img = div.querySelector('img');
div.classList.add('drag-manager_dragging');
div.classList.remove('moved-element', 'remove');
const imgEl = document.createElement('img');
imgEl.classList.add('dragged-img');
imgEl.src = img.src;
imgEl.style.visibility = "hidden";
imgEl.style.transform = `rotate(${img.style.rotate === "" ? "0deg" : img.style.rotate}) translate(-50%, -50%)`;
imgEl.style.visibility = 'hidden';
imgEl.style.transform = `rotate(${img.style.rotate === '' ? '0deg' : img.style.rotate}) translate(-50%, -50%)`;
this.draggedImageEl = imgEl;
this.dragContainer.appendChild(imgEl);
}

// Common setup for both modes
window.addEventListener("mouseup", this.stopDraggingPage);
window.addEventListener("mousemove", this.onDragEl);
this.wrapper.classList.add("drag-manager_dragging-container");
window.addEventListener('mouseup', this.stopDraggingPage);
window.addEventListener('mousemove', this.onDragEl);
this.wrapper.classList.add('drag-manager_dragging-container');
this.wrapper.appendChild(this.endInsertionElement);
}

onDragEl(mouseEvent) {
const { clientX, clientY } = mouseEvent;
const {clientX, clientY} = mouseEvent;
if (this.draggedImageEl) {
this.draggedImageEl.style.visibility = "visible";
this.draggedImageEl.style.visibility = 'visible';
this.draggedImageEl.style.left = `${clientX}px`;
this.draggedImageEl.style.top = `${clientY}px`;
}
}

stopDraggingPage() {
window.removeEventListener("mousemove", this.onDragEl);
this.wrapper.classList.remove("drag-manager_dragging-container");
window.removeEventListener('mousemove', this.onDragEl);
this.wrapper.classList.remove('drag-manager_dragging-container');
this.wrapper.removeChild(this.endInsertionElement);
window.removeEventListener("mouseup", this.stopDraggingPage);
window.removeEventListener('mouseup', this.stopDraggingPage);

if (this.draggedImageEl) {
this.dragContainer.removeChild(this.draggedImageEl);
Expand All @@ -96,38 +102,79 @@ class DragDropManager {

if (window.selectPage) {
// Multi-page drop logic
if (!this.hoveredEl) {
if (
!this.hoveredEl ||
!this.hoveredEl.classList.contains('page-container') ||
this.selectedPageElements.includes(this.hoveredEl)
) {
this.selectedPageElements.forEach((pageEl) => {
pageEl.style.transform = pageEl.initialTransform || "translate(0px, 0px)";
pageEl.classList.remove("drag-manager_dragging");
pageEl.style.transform = pageEl.initialTransform || 'translate(0px, 0px)';
pageEl.classList.remove('drag-manager_dragging');
});
} else {
this.selectedPageElements.forEach((pageEl) => {
pageEl.classList.remove("drag-manager_dragging");
pageEl.classList.remove('drag-manager_dragging');

if (this.hoveredEl === this.endInsertionElement) {
this.movePageTo(pageEl);
} else {
this.movePageTo(pageEl, this.hoveredEl);
}

// Handle timeout for the current element
this.handleTimeoutForElement(pageEl);
});
}
this.selectedPageElements = [];
window.resetPages()
window.resetPages();
} else {
// Single-page drop logic
if (!this.hoveredEl) return;
this.draggedEl.classList.remove("drag-manager_dragging");
if (
!this.hoveredEl ||
!this.hoveredEl.classList.contains('page-container') ||
this.hoveredEl === this.draggedEl
) {
this.draggedEl.style.transform = this.draggedEl.initialTransform || 'translate(0px, 0px)';
this.draggedEl.classList.remove('drag-manager_dragging');
return;
}

this.draggedEl.classList.remove('drag-manager_dragging');

if (this.hoveredEl === this.endInsertionElement) {
this.movePageTo(this.draggedEl);
} else {
this.movePageTo(this.draggedEl, this.hoveredEl);
}

// Handle timeout for the current element
this.handleTimeoutForElement(this.draggedEl);
}

this.pageDragging = false;
}

setActions({ movePageTo }) {
// Helper function to manage independent timeouts
handleTimeoutForElement(element) {
// Clear existing timeout if present
if (this.elementTimeouts.has(element)) {
clearTimeout(this.elementTimeouts.get(element));
}

// Add the moved-element class and set a new timeout
element.classList.remove('remove');
element.classList.add('moved-element');

const timeoutId = setTimeout(() => {
element.classList.add('remove');
this.elementTimeouts.delete(element); // Cleanup the timeout map
}, 2000);

// Store the timeout ID for this element
this.elementTimeouts.set(element, timeoutId);
}

setActions({movePageTo}) {
this.movePageTo = movePageTo;
}

Expand All @@ -140,18 +187,18 @@ class DragDropManager {
const onMouseEnter = () => {
if (this.pageDragging) {
this.hoveredEl = div;
div.classList.add("drag-manager_draghover");
div.classList.add('drag-manager_draghover');
}
};

const onMouseLeave = () => {
this.hoveredEl = undefined;
div.classList.remove("drag-manager_draghover");
div.classList.remove('drag-manager_draghover');
};

div.addEventListener("dragstart", onDragStart);
div.addEventListener("mouseenter", onMouseEnter);
div.addEventListener("mouseleave", onMouseLeave);
div.addEventListener('dragstart', onDragStart);
div.addEventListener('mouseenter', onMouseEnter);
div.addEventListener('mouseleave', onMouseLeave);

return div;
}
Expand Down
Loading

0 comments on commit 720705e

Please sign in to comment.