From 668476948ea601404eb51dca80f4f9f4c69c7114 Mon Sep 17 00:00:00 2001 From: Pepe Ziberi Date: Sun, 19 Jul 2026 18:59:54 +0200 Subject: [PATCH] =?UTF-8?q?fix(mobile):=20Symbol-Tap=20auf=20dem=20Handy?= =?UTF-8?q?=20zuverl=C3=A4ssig=20=E2=80=93=20TouchBackend=20schluckte=20on?= =?UTF-8?q?Click=20(v1.5.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- package.json | 2 +- src/components/layout/right-sidebar.tsx | 26 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 832ca57..a79a959 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lageplan", - "version": "1.5.1", + "version": "1.5.2", "description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation", "private": true, "scripts": { diff --git a/src/components/layout/right-sidebar.tsx b/src/components/layout/right-sidebar.tsx index a99e642..c67b6e4 100644 --- a/src/components/layout/right-sidebar.tsx +++ b/src/components/layout/right-sidebar.tsx @@ -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 (
} 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