fix(sync): Editier-Lock-Versionierung + Zeichnen-Race + Mess-Race (v1.6.4)
- handleStopEditing speichert jetzt MIT baseVersion und aktualisiert featuresVersionRef aus der Antwort (409 → Server-Stand übernehmen). Verhindert Fehl-Konflikte/Konflikt-Schleifen beim erneuten Bearbeiten nach dem Freigeben. - Lock-Ablehnung (zwei zeichnen bei freier Karte gleichzeitig): der abgelehnte Client lädt den echten Sperr-Halter nach → Karte wird lokal read-only, keine weiteren nicht-speicherbaren Änderungen mehr. - Mess-Höhenabfrage: Generation-Zähler bricht veraltete asynchrone Abfragen ab (Neue Messung/Verlassen) → keine falschen Höhen-/Druckwerte der alten Messung. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -126,6 +126,9 @@ export function MapView({
|
||||
const markerCleanupsRef = useRef<(() => void)[]>([])
|
||||
const measureMarkersRef = useRef<maplibregl.Marker[]>([])
|
||||
const measureCoordsRef = useRef<number[][]>([])
|
||||
// Generation-Zähler: bricht veraltete (asynchrone) Höhen-Abfragen ab, wenn
|
||||
// zwischenzeitlich eine neue Messung gestartet/geleert wurde.
|
||||
const measureGenRef = useRef(0)
|
||||
const [isMapLoaded, setIsMapLoaded] = useState(false)
|
||||
const [activeBaseLayer, setActiveBaseLayer] = useState<'osm' | 'satellite' | 'swisstopo'>('osm')
|
||||
const [layerDropdownOpen, setLayerDropdownOpen] = useState(false)
|
||||
@@ -454,6 +457,8 @@ export function MapView({
|
||||
const fetchElevationsAndUpdate = useCallback(async () => {
|
||||
const coords = measureCoordsRef.current
|
||||
if (coords.length < 2 || !map.current) return
|
||||
// Diese Abfrage gehört zur aktuellen Messung; wird sie überholt, verwerfen wir das Ergebnis.
|
||||
const gen = measureGenRef.current
|
||||
|
||||
// Interpolate extra points along the line (every ~30m) for better elevation accuracy
|
||||
const sampledCoords: number[][] = [coords[0]]
|
||||
@@ -560,6 +565,10 @@ export function MapView({
|
||||
} catch { /* ignore */ }
|
||||
if (hoseTypes.length === 0) hoseTypes = FALLBACK_HOSE_TYPES
|
||||
|
||||
// Überholt? (neue/geleerte Messung während der async Abfragen) → Ergebnis verwerfen,
|
||||
// damit keine Höhen-Labels/Druckwerte der ALTEN Messung erscheinen.
|
||||
if (gen !== measureGenRef.current) return
|
||||
|
||||
let totalDist = 0
|
||||
for (let i = 1; i < coords.length; i++) {
|
||||
totalDist += haversineDistance(coords[i - 1], coords[i])
|
||||
@@ -1906,6 +1915,7 @@ export function MapView({
|
||||
// Reset measurement state when leaving measure mode (but keep info panel — user closes it)
|
||||
useEffect(() => {
|
||||
if (drawMode !== 'measure') {
|
||||
measureGenRef.current++ // pendende Höhen-Abfrage beim Verlassen entwerten
|
||||
measureMarkersRef.current.forEach(m => m.remove())
|
||||
measureMarkersRef.current = []
|
||||
measureCoordsRef.current = []
|
||||
@@ -2156,6 +2166,7 @@ export function MapView({
|
||||
|
||||
// Messung komplett entfernen (Linie, Marker, Höhen-Labels, Panel, Zustand)
|
||||
const clearMeasurement = useCallback(() => {
|
||||
measureGenRef.current++ // laufende Höhen-Abfragen der alten Messung entwerten
|
||||
measureMarkersRef.current.forEach(m => m.remove())
|
||||
measureMarkersRef.current = []
|
||||
measureCoordsRef.current = []
|
||||
|
||||
Reference in New Issue
Block a user