import { useEffect, useRef } from 'react'; import { StyleSheet } from 'react-native'; import MapView, { Marker, Polyline } from 'react-native-maps'; import type { Coord, Place, Route } from '@/lib/types'; export type RideMapProps = { pickup: Coord; userLocation: Coord | null; showsUserLocation: boolean; destination: Place | null; route: Route | null; topInset: number; }; const ZOOMED_IN = { latitudeDelta: 0.02, longitudeDelta: 0.02 }; export function RideMap({ pickup, userLocation, showsUserLocation, destination, route, topInset }: RideMapProps) { const mapRef = useRef(null); // Centre on the user the first time we learn where they are. const hasCentred = useRef(false); useEffect(() => { if (!userLocation || hasCentred.current || destination) return; hasCentred.current = true; mapRef.current?.animateToRegion({ ...userLocation, ...ZOOMED_IN }, 600); }, [userLocation, destination]); // Frame the whole route once it arrives. useEffect(() => { if (!route) return; mapRef.current?.fitToCoordinates(route.coordinates, { edgePadding: { top: topInset + 80, right: 48, bottom: 460, left: 48 }, animated: true, }); }, [route, topInset]); // Zoom back in on the pickup when the destination is cleared. const hadDestination = useRef(false); useEffect(() => { if (hadDestination.current && !destination) mapRef.current?.animateToRegion({ ...pickup, ...ZOOMED_IN }, 500); hadDestination.current = destination !== null; // Only react to the destination changing, not to the pickup drifting. // eslint-disable-next-line react-hooks/exhaustive-deps }, [destination]); return ( {!showsUserLocation && } {destination && } {route && ( )} ); }