From 02b296a3fa52631513abcd70c59ba478525029b1 Mon Sep 17 00:00:00 2001 From: George Kartalis Date: Thu, 30 Jul 2026 15:27:12 +0200 Subject: [PATCH] fix: early exit when userLocation is undefined --- src/app/Scenes/Map/GlobalMap.tsx | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/app/Scenes/Map/GlobalMap.tsx b/src/app/Scenes/Map/GlobalMap.tsx index 83e717fe1e7..834cbed99fd 100644 --- a/src/app/Scenes/Map/GlobalMap.tsx +++ b/src/app/Scenes/Map/GlobalMap.tsx @@ -116,10 +116,12 @@ export const GlobalMap: React.FC = (props) => { } const onPressUserPositionButton = () => { - // @ts-expect-error STRICTNESS_MIGRATION --- 🚨 Unsafe legacy code 🚨 Please delete this and fix any type errors if you have time 🙏 - const { lat, lng } = userLocation + if (!isValidLatLng(userLocation)) { + return + } + cameraRef.current?.setCamera({ - centerCoordinate: [lng, lat], + centerCoordinate: [userLocation.lng, userLocation.lat], zoomLevel: DefaultZoomLevel, animationDuration: 500, }) @@ -146,7 +148,7 @@ export const GlobalMap: React.FC = (props) => { isLoading={!viewer.city} onPress={onPressCitySwitcherButton} /> - {!!userLocation && ( + {!!isValidLatLng(userLocation) && ( = (props) => { } const onUserLocationUpdate = (location: MapboxGL.Location) => { - if (!location || !location.coords) { + const coords = location?.coords + + // The native side sends updates with an empty `coords` object before the first location fix + // lands (and for heading-only updates), which would otherwise leave us with a location made of + // `undefined`s and crash the camera. + if (typeof coords?.latitude !== "number" || typeof coords?.longitude !== "number") { return } - setUserLocation(longCoordsToLocation(location.coords)) + setUserLocation(longCoordsToLocation(coords)) } const onRegionIsChanging = async () => { @@ -590,6 +597,14 @@ const longCoordsToLocation = (coords: { longitude: number; latitude: number }) = return { lat: coords.latitude, lng: coords.longitude } } +/** + * `city.coordinates` is nullable in the schema and location updates can arrive without coordinates, + * so make sure we actually have numbers before handing them over to the map. + */ +const isValidLatLng = (location: any): location is { lat: number; lng: number } => { + return typeof location?.lat === "number" && typeof location?.lng === "number" +} + const tracks = { trackPinTap: (_: any, __: any, args: any) => { const actionName = args[0]