document.addEventListener('DOMContentLoaded', () => { // Handle all bootstrap popover inits const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]') const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl)) const masonryContainer = document.querySelector('[data-masonry]'); if ( ! masonryContainer ) { return; } const masonryInstance = new Masonry(masonryContainer, { columnHeight: '.accordion', percentPosition: true }); const updateMasonryLayout = () => masonryInstance.layout(); masonryContainer.addEventListener('hidden.bs.collapse', updateMasonryLayout); masonryContainer.addEventListener('shown.bs.collapse', updateMasonryLayout); const observer = new MutationObserver(() => { updateMasonryLayout(); }); // Observe all cards for changes in the DOM document.querySelectorAll('.card').forEach((card) => { observer.observe(card, { childList: true, subtree: true }); }); // Initialize all toggle functions toggleVisibility('editModeSwitch', 'edit-mode'); toggleVisibility('showArchivedSwitch', 'link-archived'); toggleVisibility('showHiddenSwitch', 'link-hidden'); toggleVisibility('archiveButtonSwitch', 'btn-archive'); toggleVisibility('visibilityButtonSwitch', 'btn-hideshow'); toggleVisibility('privacyButtonSwitch', 'btn-publish'); toggleVisibility('addButtonSwitch', 'btn-addlink'); toggleVisibility('shareButtonSwitch', 'btn-share'); toggleVisibility('dashShowArchivedSwitch', 'link-archived'); toggleVisibility('dashShowHiddenSwitch', 'link-hidden'); toggleVisibility('dashAddButtonSwitch', 'btn-addlink'); toggleVisibility('dashShareButtonSwitch', 'btn-share'); }); // Function to handle showing or hiding elements based on the checkbox state function toggleVisibility(switchId, className) { const switchElement = document.getElementById(switchId); const elementsToToggle = document.querySelectorAll(`.${className}`); if ( ! switchElement ) { return; } // Listen for changes to the checkbox switchElement.addEventListener('change', () => { if (switchElement.checked) { elementsToToggle.forEach(element => { element.style.display = ''; // Show the element (default display) }); } else { elementsToToggle.forEach(element => { element.style.display = 'none'; // Hide the element }); } }); // Trigger the toggle initially to set the correct visibility on page load switchElement.dispatchEvent(new Event('change')); } document.addEventListener('DOMContentLoaded', function () { const bookmarkSort = document.getElementById('bookmarkSort'); if ( ! bookmarkSort ) { return; } let draggingElement = null; let placeholder = null; let initialX = 0; let initialY = 0; let offsetX = 0; let offsetY = 0; // Function to handle the drag start const handleDragStart = (e, element) => { draggingElement = element; // Create a placeholder to maintain layout placeholder = document.createElement('div'); placeholder.style.height = `${draggingElement.offsetHeight}px`; placeholder.style.marginBottom = getComputedStyle(draggingElement).marginBottom; placeholder.classList.add('placeholder'); draggingElement.parentNode.insertBefore(placeholder, draggingElement); const rect = element.getBoundingClientRect(); initialX = e.clientX; initialY = e.clientY; offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; // Prevent the element from moving in the normal flow element.classList.add('dragging'); element.style.position = 'absolute'; draggingElement.style.width = `${rect.width}px`; // Preserve width draggingElement.style.height = `${rect.height}px`; // Preserve height element.style.zIndex = 1000; // Bring the element on top of others element.style.left = `${rect.left}px`; element.style.top = `${rect.top}px`; e.preventDefault(); }; // Function to handle dragging movement const handleDragMove = (e) => { if (draggingElement) { const dx = e.clientX - initialX + offsetX; const dy = e.clientY - initialY + offsetY; draggingElement.style.left = `${dx}px`; draggingElement.style.top = `${dy}px`; } }; // Function to handle the drag end const handleDragEnd = () => { if (draggingElement) { const rect = draggingElement.getBoundingClientRect(); // Reset the position styles of the dragged element draggingElement.style.position = ''; draggingElement.style.zIndex = ''; // Reset z-index draggingElement.style.left = ''; draggingElement.style.top = ''; draggingElement.classList.remove('dragging'); // Re-insert the element back into the DOM properly const closestElement = getClosestElement(rect.left, rect.top); console.error(closestElement.id); if (closestElement) { bookmarkSort.insertBefore(draggingElement, closestElement); console.log( 'insertBefore' ); } else { bookmarkSort.appendChild(draggingElement); console.log( 'append' ); } // Reorder the elements after the drag ends reorderElements(); draggingElement = null; } }; // Function to reorder the elements inside the container const reorderElements = () => { const elements = Array.from(bookmarkSort.children); const sortedIds = elements.map(element => element.id); console.log('New order:', sortedIds); }; // Function to handle the drop event const handleDrop = (e) => { e.preventDefault(); }; // Helper function to find the closest element based on mouse position const getClosestElement = (x, y) => { const elements = Array.from(bookmarkSort.children).filter( (el) => el !== placeholder && el !== draggingElement ); let closest = null; let closestDistance = Number.POSITIVE_INFINITY; elements.forEach((child) => { const rect = child.getBoundingClientRect(); const distance = Math.abs(rect.top - y); if (distance < closestDistance) { closestDistance = distance; closest = child; } }); return closest; }; // Attach event listeners to all .card-header elements for dragging Array.from(document.querySelectorAll('.mover-arrow')).forEach(cardHeader => { cardHeader.addEventListener('mousedown', (e) => handleDragStart(e, cardHeader.closest('.bookmark-card'))); }); // Handle the dragging process document.addEventListener('mousemove', handleDragMove); document.addEventListener('mouseup', handleDragEnd); bookmarkSort.addEventListener('dragover', handleDrop); // Listen for the drop event to update the order });