mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	Fix drag and drop bugs and clean up UI
This commit is contained in:
		
							parent
							
								
									0a6b6453b2
								
							
						
					
					
						commit
						9b6dcdcd06
					
				@ -29,13 +29,9 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.drag-manager_dragging {
 | 
			
		||||
  width: 0px;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0.5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.drag-manager_draghover {
 | 
			
		||||
  width: 375px !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.drag-manager_draghover .insert-file-button-container {
 | 
			
		||||
  display: none !important;
 | 
			
		||||
@ -46,11 +42,11 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
@ -58,14 +54,17 @@ html[dir="rtl"] .drag-manager_draghover img {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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 {
 | 
			
		||||
@ -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 {
 | 
			
		||||
@ -85,3 +85,12 @@ html[dir="rtl"] .drag-manager_draghover img {
 | 
			
		||||
    width: 80px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.moved-element {
 | 
			
		||||
  background-color: darkgreen;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  transition: background-color  0.5s ease-out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.moved-element.remove {
 | 
			
		||||
  background-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
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;
 | 
			
		||||
@ -10,14 +10,15 @@ class DragDropManager {
 | 
			
		||||
    this.selectedPageElements = []; // Store selected pages for multi-page mode
 | 
			
		||||
 | 
			
		||||
    // 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"/>
 | 
			
		||||
@ -35,59 +36,62 @@ 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)';
 | 
			
		||||
          }
 | 
			
		||||
          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);
 | 
			
		||||
@ -96,38 +100,56 @@ class DragDropManager {
 | 
			
		||||
 | 
			
		||||
    if (window.selectPage) {
 | 
			
		||||
      // Multi-page drop logic
 | 
			
		||||
      if (!this.hoveredEl) {
 | 
			
		||||
      if (!this.hoveredEl || !this.hoveredEl.classList.contains('page-container')) {
 | 
			
		||||
        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');
 | 
			
		||||
          this.pageDragging = false;
 | 
			
		||||
          return;
 | 
			
		||||
        });
 | 
			
		||||
      } 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);
 | 
			
		||||
          }
 | 
			
		||||
          pageEl.classList.remove('moved-element', 'remove');
 | 
			
		||||
          pageEl.classList.add('moved-element');
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            pageEl.classList.add('remove');
 | 
			
		||||
          }, 2000);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      this.selectedPageElements = [];
 | 
			
		||||
      window.resetPages()
 | 
			
		||||
      window.resetPages();
 | 
			
		||||
    } else {
 | 
			
		||||
      // Single-page drop logic
 | 
			
		||||
      if (!this.hoveredEl || !this.hoveredEl.classList.contains('page-container')) {
 | 
			
		||||
        this.draggedEl.style.transform = this.draggedEl.initialTransform || 'translate(0px, 0px)';
 | 
			
		||||
        this.draggedEl.classList.remove('drag-manager_dragging');
 | 
			
		||||
        this.pageDragging = false;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (!this.hoveredEl) return;
 | 
			
		||||
      this.draggedEl.classList.remove("drag-manager_dragging");
 | 
			
		||||
      this.draggedEl.classList.remove('drag-manager_dragging');
 | 
			
		||||
      if (this.hoveredEl === this.endInsertionElement) {
 | 
			
		||||
        this.movePageTo(this.draggedEl);
 | 
			
		||||
      } else {
 | 
			
		||||
        this.movePageTo(this.draggedEl, this.hoveredEl);
 | 
			
		||||
      }
 | 
			
		||||
      this.draggedEl.classList.remove('moved-element', 'remove');
 | 
			
		||||
      this.draggedEl.classList.add('moved-element');
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        this.draggedEl.classList.add('remove');
 | 
			
		||||
      }, 2000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.pageDragging = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setActions({ movePageTo }) {
 | 
			
		||||
  setActions({movePageTo}) {
 | 
			
		||||
    this.movePageTo = movePageTo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -140,18 +162,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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,7 @@
 | 
			
		||||
import { Command } from "./command.js";
 | 
			
		||||
import {Command} from './command.js';
 | 
			
		||||
 | 
			
		||||
export class AbstractMovePageCommand extends Command {
 | 
			
		||||
  constructor(
 | 
			
		||||
    startElement,
 | 
			
		||||
    endElement,
 | 
			
		||||
    pagesContainer,
 | 
			
		||||
    pagesContainerWrapper,
 | 
			
		||||
    scrollTo = false
 | 
			
		||||
  ) {
 | 
			
		||||
  constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) {
 | 
			
		||||
    super();
 | 
			
		||||
 | 
			
		||||
    this.pagesContainer = pagesContainer;
 | 
			
		||||
@ -25,7 +19,7 @@ export class AbstractMovePageCommand extends Command {
 | 
			
		||||
 | 
			
		||||
  execute() {
 | 
			
		||||
    // Check & remove page number elements here too if they exist because Firefox doesn't fire the relevant event on page move.
 | 
			
		||||
    const pageNumberElement = this.startElement.querySelector(".page-number");
 | 
			
		||||
    const pageNumberElement = this.startElement.querySelector('.page-number');
 | 
			
		||||
    if (pageNumberElement) {
 | 
			
		||||
      this.startElement.removeChild(pageNumberElement);
 | 
			
		||||
    }
 | 
			
		||||
@ -38,11 +32,8 @@ export class AbstractMovePageCommand extends Command {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.scrollTo) {
 | 
			
		||||
      const { width } = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector =
 | 
			
		||||
        this.endIndex !== -1 && this.startIndex > this.endIndex
 | 
			
		||||
          ? 0 - width
 | 
			
		||||
          : width;
 | 
			
		||||
      const {width} = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector = this.endIndex !== -1 && this.startIndex > this.endIndex ? 0 - width : width;
 | 
			
		||||
 | 
			
		||||
      this.pagesContainerWrapper.scroll({
 | 
			
		||||
        left: this.pagesContainerWrapper.scrollLeft + vector,
 | 
			
		||||
@ -52,7 +43,6 @@ export class AbstractMovePageCommand extends Command {
 | 
			
		||||
 | 
			
		||||
  undo() {
 | 
			
		||||
    // Requires overriding in child classes
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  redo() {
 | 
			
		||||
@ -61,28 +51,19 @@ export class AbstractMovePageCommand extends Command {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class MovePageUpCommand extends AbstractMovePageCommand {
 | 
			
		||||
  constructor(
 | 
			
		||||
    startElement,
 | 
			
		||||
    endElement,
 | 
			
		||||
    pagesContainer,
 | 
			
		||||
    pagesContainerWrapper,
 | 
			
		||||
    scrollTo = false
 | 
			
		||||
  ) {
 | 
			
		||||
  constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) {
 | 
			
		||||
    super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  undo() {
 | 
			
		||||
    if (this.endElement) {
 | 
			
		||||
      this.pagesContainer.removeChild(this.endElement);
 | 
			
		||||
      this.startElement.insertAdjacentElement("beforebegin", this.endElement);
 | 
			
		||||
      this.startElement.insertAdjacentElement('beforebegin', this.endElement);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.scrollTo) {
 | 
			
		||||
      const { width } = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector =
 | 
			
		||||
        this.endIndex === -1 || this.startIndex <= this.endIndex
 | 
			
		||||
          ? 0 - width
 | 
			
		||||
          : width;
 | 
			
		||||
      const {width} = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector = this.endIndex === -1 || this.startIndex <= this.endIndex ? 0 - width : width;
 | 
			
		||||
 | 
			
		||||
      this.pagesContainerWrapper.scroll({
 | 
			
		||||
        left: this.pagesContainerWrapper.scrollLeft - vector,
 | 
			
		||||
@ -96,13 +77,7 @@ export class MovePageUpCommand extends AbstractMovePageCommand {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class MovePageDownCommand extends AbstractMovePageCommand {
 | 
			
		||||
  constructor(
 | 
			
		||||
    startElement,
 | 
			
		||||
    endElement,
 | 
			
		||||
    pagesContainer,
 | 
			
		||||
    pagesContainerWrapper,
 | 
			
		||||
    scrollTo = false
 | 
			
		||||
  ) {
 | 
			
		||||
  constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) {
 | 
			
		||||
    super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -111,15 +86,12 @@ export class MovePageDownCommand extends AbstractMovePageCommand {
 | 
			
		||||
 | 
			
		||||
    if (this.startElement) {
 | 
			
		||||
      this.pagesContainer.removeChild(this.startElement);
 | 
			
		||||
      previousElement.insertAdjacentElement("beforebegin", this.startElement);
 | 
			
		||||
      previousElement.insertAdjacentElement('beforebegin', this.startElement);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.scrollTo) {
 | 
			
		||||
      const { width } = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector =
 | 
			
		||||
        this.endIndex === -1 || this.startIndex <= this.endIndex
 | 
			
		||||
          ? 0 - width
 | 
			
		||||
          : width;
 | 
			
		||||
      const {width} = this.startElement.getBoundingClientRect();
 | 
			
		||||
      const vector = this.endIndex === -1 || this.startIndex <= this.endIndex ? 0 - width : width;
 | 
			
		||||
 | 
			
		||||
      this.pagesContainerWrapper.scroll({
 | 
			
		||||
        left: this.pagesContainerWrapper.scrollLeft - vector,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user