From 3ea11499cbd033dbfcde9ada16d4eb58c892400e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:46:26 +0000 Subject: [PATCH 1/2] Initial plan From 9bdc545da9ed27124d6a03531bf3dc4ee89f792a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:51:08 +0000 Subject: [PATCH 2/2] Fix Wishlist touch interactions not working on iOS (iPhone) The touchstart handler was immediately entering drag mode and the touchmove handler unconditionally called preventDefault(), which suppressed synthetic click events on iOS/Safari for child elements (checkbox, edit button, View Listing link). Fix: only activate drag mode when touch moves beyond a 10px threshold, only call preventDefault() when drag mode is active, and skip drag logic in touchend when no drag was initiated. touchstart is now passive:true since we no longer call preventDefault() there. Co-authored-by: JoeProgrammer88 <7156063+JoeProgrammer88@users.noreply.github.com> Agent-Logs-Url: https://github.com/SpeakingInBits/TaskManagerWeb/sessions/e94c6188-f1fa-4385-ad79-c8a2282534f0 --- src/app.ts | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/app.ts b/src/app.ts index 83951e3..9796c0f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1923,13 +1923,27 @@ class TaskManager { // Touch events for mobile drag and drop support let touchDragOverItem: HTMLElement | null = null; - el.addEventListener('touchstart', () => { - this.dragSrcWishId = el.dataset.wishId!; - el.classList.add('dragging'); - }, { passive: false }); + let touchDragActive = false; + let touchStartX = 0; + let touchStartY = 0; + const DRAG_THRESHOLD = 10; + el.addEventListener('touchstart', (e) => { + const touch = e.touches[0]; + touchStartX = touch.clientX; + touchStartY = touch.clientY; + touchDragActive = false; + }, { passive: true }); el.addEventListener('touchmove', (e) => { - e.preventDefault(); const touch = e.touches[0]; + const dx = touch.clientX - touchStartX; + const dy = touch.clientY - touchStartY; + if (!touchDragActive && (dx * dx + dy * dy) > DRAG_THRESHOLD * DRAG_THRESHOLD) { + touchDragActive = true; + this.dragSrcWishId = el.dataset.wishId!; + el.classList.add('dragging'); + } + if (!touchDragActive) return; + e.preventDefault(); // Temporarily hide the dragged element so elementFromPoint finds the element underneath el.style.visibility = 'hidden'; const target = document.elementFromPoint(touch.clientX, touch.clientY); @@ -1942,6 +1956,10 @@ class TaskManager { } }, { passive: false }); el.addEventListener('touchend', (e) => { + if (!touchDragActive) { + touchDragOverItem = null; + return; + } el.classList.remove('dragging'); touchDragOverItem?.classList.remove('drag-over'); const touch = e.changedTouches[0]; @@ -1951,6 +1969,7 @@ class TaskManager { const targetItem = target?.closest('.wish-item'); const targetId = targetItem?.dataset.wishId; touchDragOverItem = null; + touchDragActive = false; if (this.dragSrcWishId && targetId && this.dragSrcWishId !== targetId) { const allItems = storage.getWishItems(); const srcIdx = allItems.findIndex(i => i.id === this.dragSrcWishId);