feat(mobile): Handy-Optimierung – Tap-to-place, Bottom-Nav, kompakte Banner (v1.4.12)
- Tap-to-place: Symbol antippen → auf Karte tippen platziert es (Alternative zu Drag&Drop, mobil-tauglich); schwebender Hinweis mit Abbrechen - Mobile Bottom-Navigation: Karte / Journal(Auswertung) / Symbole ohne Menü erreichbar - FAB entfernt; Karten-Steuerung (Zoom/Standort/Massstab) hebt sich mobil über die Bottom-Nav - Touch-Ziele in der Werkzeugleiste auf 44px vergrössert - "Einsatz/Übung beenden" jetzt auch im Mobile-Overflow-Menü - Banner (Übung/Offline/E-Mail/Live) mobil kompakt: kleinere Höhe, gekürzte Texte, truncate - Einsatz-beenden-Bestätigung als In-App-Dialog statt Browser-confirm() Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,9 @@ interface MapViewProps {
|
||||
mapRef?: React.MutableRefObject<maplibregl.Map | null>
|
||||
onDrawModeChange?: (mode: DrawMode) => void
|
||||
undoDrawPointRef?: React.MutableRefObject<(() => boolean) | null>
|
||||
/** Tap-to-place: wenn gesetzt, platziert der nächste Karten-Tipp dieses Symbol (Mobil-freundlich). */
|
||||
pendingSymbol?: { iconId: string; imageUrl?: string } | null
|
||||
onSymbolPlaced?: () => void
|
||||
}
|
||||
|
||||
export function MapView({
|
||||
@@ -100,6 +103,8 @@ export function MapView({
|
||||
mapRef: externalMapRef,
|
||||
onDrawModeChange,
|
||||
undoDrawPointRef,
|
||||
pendingSymbol,
|
||||
onSymbolPlaced,
|
||||
}: MapViewProps) {
|
||||
const mapContainer = useRef<HTMLDivElement | null>(null)
|
||||
const map = useRef<maplibregl.Map | null>(null)
|
||||
@@ -165,6 +170,8 @@ export function MapView({
|
||||
const onSymbolDropRef = useRef(onSymbolDrop)
|
||||
const onTextPlaceRef = useRef(onTextPlace)
|
||||
const onDrawModeChangeRef = useRef(onDrawModeChange)
|
||||
const pendingSymbolRef = useRef(pendingSymbol)
|
||||
const onSymbolPlacedRef = useRef(onSymbolPlaced)
|
||||
|
||||
// Lock/unlock map panning based on draw mode
|
||||
// Apple-style: touchZoomRotate (two-finger pinch/zoom) ALWAYS enabled
|
||||
@@ -191,6 +198,8 @@ export function MapView({
|
||||
useEffect(() => { onSymbolDropRef.current = onSymbolDrop }, [onSymbolDrop])
|
||||
useEffect(() => { onTextPlaceRef.current = onTextPlace }, [onTextPlace])
|
||||
useEffect(() => { onDrawModeChangeRef.current = onDrawModeChange }, [onDrawModeChange])
|
||||
useEffect(() => { pendingSymbolRef.current = pendingSymbol }, [pendingSymbol])
|
||||
useEffect(() => { onSymbolPlacedRef.current = onSymbolPlaced }, [onSymbolPlaced])
|
||||
|
||||
// Expose undo-draw-point function to parent via ref
|
||||
useEffect(() => {
|
||||
@@ -891,6 +900,15 @@ export function MapView({
|
||||
const width = selectedWidthRef.current
|
||||
const coords: [number, number] = [e.lngLat.lng, e.lngLat.lat]
|
||||
|
||||
// Tap-to-place: ein zuvor angetipptes Symbol wird hier platziert (Mobil-freundlich,
|
||||
// Alternative zum Drag&Drop). Hat Vorrang vor allen Zeichen-Modi.
|
||||
if (pendingSymbolRef.current) {
|
||||
const p = pendingSymbolRef.current
|
||||
onSymbolDropRef.current(p.iconId, coords, p.imageUrl)
|
||||
onSymbolPlacedRef.current?.()
|
||||
return
|
||||
}
|
||||
|
||||
if (mode === 'select') {
|
||||
// Detect click near a line/polygon for vertex editing
|
||||
const pixel = e.point
|
||||
|
||||
Reference in New Issue
Block a user