From d2454542313f2043669f3540c2a5959eef675cb5 Mon Sep 17 00:00:00 2001 From: megaproxy Date: Mon, 14 Jul 2025 17:14:53 +0100 Subject: [PATCH] Fix drag-and-drop functionality in team builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- webserver.py | 107 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/webserver.py b/webserver.py index 4f5015d..87006a3 100644 --- a/webserver.py +++ b/webserver.py @@ -2176,11 +2176,16 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): background: var(--bg-tertiary); border-radius: 12px; padding: 15px; - cursor: move; + cursor: grab; transition: all 0.3s ease; border: 2px solid transparent; position: relative; box-shadow: 0 2px 8px rgba(0,0,0,0.2); + user-select: none; + }} + + .pet-card:active {{ + cursor: grabbing; }} .pet-card:hover {{ @@ -2498,24 +2503,35 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): currentTeam[petId] = isActive; }}); - // Enhanced drag and drop functionality - document.querySelectorAll('.pet-card').forEach(card => {{ - card.addEventListener('dragstart', handleDragStart); - card.addEventListener('dragend', handleDragEnd); - }}); - - document.querySelectorAll('.drop-zone, .pets-container').forEach(zone => {{ - zone.addEventListener('dragover', handleDragOver); - zone.addEventListener('drop', handleDrop); - zone.addEventListener('dragenter', handleDragEnter); - zone.addEventListener('dragleave', handleDragLeave); - }}); + // Enhanced drag and drop functionality - Fixed version + function initializeDragAndDrop() {{ + // Attach events to pet cards + document.querySelectorAll('.pet-card').forEach(card => {{ + card.draggable = true; + card.addEventListener('dragstart', handleDragStart); + card.addEventListener('dragend', handleDragEnd); + }}); + + // Attach events to drop zones and containers + const dropTargets = ['#active-container', '#storage-container', '#active-drop', '#storage-drop']; + dropTargets.forEach(selector => {{ + const element = document.querySelector(selector); + if (element) {{ + element.addEventListener('dragover', handleDragOver); + element.addEventListener('drop', handleDrop); + element.addEventListener('dragenter', handleDragEnter); + element.addEventListener('dragleave', handleDragLeave); + }} + }}); + }} function handleDragStart(e) {{ draggedElement = this; this.classList.add('dragging'); e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.setData('text/html', this.outerHTML); + e.dataTransfer.setData('text/plain', this.dataset.petId); + + console.log('Drag started for pet:', this.dataset.petId); // Add visual feedback setTimeout(() => {{ @@ -2531,6 +2547,8 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): document.querySelectorAll('.drop-zone, .pets-container').forEach(zone => {{ zone.classList.remove('drag-over'); }}); + + console.log('Drag ended'); }} function handleDragOver(e) {{ @@ -2540,41 +2558,55 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): function handleDragEnter(e) {{ e.preventDefault(); - if (e.target.classList.contains('drop-zone') || e.target.classList.contains('pets-container')) {{ - e.target.classList.add('drag-over'); + const target = e.currentTarget; + if (target.classList.contains('drop-zone') || target.classList.contains('pets-container')) {{ + target.classList.add('drag-over'); }} }} function handleDragLeave(e) {{ - if (e.target.classList.contains('drop-zone') || e.target.classList.contains('pets-container')) {{ - // Only remove if we're actually leaving the element - if (!e.target.contains(e.relatedTarget)) {{ - e.target.classList.remove('drag-over'); - }} + const target = e.currentTarget; + // Only remove if we're leaving the current target and not entering a child + if (!target.contains(e.relatedTarget)) {{ + target.classList.remove('drag-over'); }} }} function handleDrop(e) {{ e.preventDefault(); - if (!draggedElement) return; + console.log('Drop event triggered'); - const petId = draggedElement.dataset.petId; - let newActiveStatus; - let targetContainer; - - // Determine target based on drop zone or container - if (e.target.id === 'active-drop' || e.target.closest('#active-container')) {{ - newActiveStatus = true; - targetContainer = document.getElementById('active-container'); - moveToActive(draggedElement); - }} else if (e.target.id === 'storage-drop' || e.target.closest('#storage-container')) {{ - newActiveStatus = false; - targetContainer = document.getElementById('storage-container'); - moveToStorage(draggedElement); + if (!draggedElement) {{ + console.log('No dragged element'); + return; }} - if (newActiveStatus !== undefined && newActiveStatus !== currentTeam[petId]) {{ + const petId = draggedElement.dataset.petId; + const currentIsActive = currentTeam[petId]; + let newActiveStatus = null; + + // Determine target section based on the drop target + const dropTarget = e.currentTarget; + console.log('Drop target:', dropTarget.id); + + if (dropTarget.id === 'active-container' || dropTarget.id === 'active-drop') {{ + newActiveStatus = true; + console.log('Moving to active team'); + }} else if (dropTarget.id === 'storage-container' || dropTarget.id === 'storage-drop') {{ + newActiveStatus = false; + console.log('Moving to storage'); + }} + + // Only move if there's a change + if (newActiveStatus !== null && newActiveStatus !== currentIsActive) {{ currentTeam[petId] = newActiveStatus; + + if (newActiveStatus) {{ + moveToActive(draggedElement); + }} else {{ + moveToStorage(draggedElement); + }} + updateSaveButton(); updateDropZoneVisibility(); @@ -2583,6 +2615,8 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): setTimeout(() => {{ draggedElement.style.transform = ''; }}, 200); + + console.log('Pet moved successfully'); }} // Clear all drag states @@ -2726,6 +2760,7 @@ class PetBotRequestHandler(BaseHTTPRequestHandler): }}); // Initialize interface + initializeDragAndDrop(); updateSaveButton(); updateDropZoneVisibility();