fix(mobile): Symbol-Tap auf dem Handy zuverlässig – TouchBackend schluckte onClick (v1.5.2)
Ursache: react-dnd TouchBackend (delayTouchStart:150) unterdrückt auf Touch- Geräten den onClick der Drag-Quelle → Tap-to-place löste auf dem Handy nie aus, und echtes Touch-Drag über die MapLibre-Karte ist ohnehin unzuverlässig. - DraggableSymbol erkennt Taps jetzt über echte Touch-Events (onTouchStart/End): kurzer, ortsfester Tipp (<12px, <600ms) = Auswahl → Karte antippen platziert - preventDefault verhindert Doppel-Auslösung durch den synthetischen Klick - onClick bleibt für Desktop/Maus erhalten Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { useDrag } from 'react-dnd'
|
||||
import { getEmptyImage } from 'react-dnd-html5-backend'
|
||||
import { Input } from '@/components/ui/input'
|
||||
@@ -76,10 +76,34 @@ function DraggableSymbol({ symbol, canEdit, onSelect }: {
|
||||
preview(getEmptyImage(), { captureDraggingState: true })
|
||||
}, [preview])
|
||||
|
||||
// Touch-Tap eigenständig erkennen: der TouchBackend (react-dnd) schluckt auf
|
||||
// dem Handy den onClick der Drag-Quelle. Ohne diesen Handler würde Tap-to-place
|
||||
// auf Mobil gar nicht auslösen. Ein kurzer Tipp ohne Bewegung = Auswahl.
|
||||
const touchStartRef = useRef<{ x: number; y: number; t: number } | null>(null)
|
||||
|
||||
const handleTouchStart = (e: React.TouchEvent) => {
|
||||
const t = e.touches[0]
|
||||
touchStartRef.current = { x: t.clientX, y: t.clientY, t: Date.now() }
|
||||
}
|
||||
const handleTouchEnd = (e: React.TouchEvent) => {
|
||||
const start = touchStartRef.current
|
||||
touchStartRef.current = null
|
||||
if (!start || !canEdit || !onSelect) return
|
||||
const t = e.changedTouches[0]
|
||||
const moved = Math.hypot(t.clientX - start.x, t.clientY - start.y)
|
||||
// Kurzer, ortsfester Tipp → als Auswahl werten (kein Drag)
|
||||
if (moved < 12 && Date.now() - start.t < 600) {
|
||||
e.preventDefault() // verhindert den synthetischen Klick (kein Doppel-Auslösen)
|
||||
onSelect(symbol)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={drag as unknown as React.LegacyRef<HTMLDivElement>}
|
||||
onClick={() => { if (canEdit && onSelect) onSelect(symbol) }}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
className={`
|
||||
flex flex-col items-center gap-1 p-1.5 md:p-2 lg:p-2.5 rounded-lg border-2 transition-all
|
||||
border-transparent hover:border-border hover:bg-accent
|
||||
|
||||
Reference in New Issue
Block a user