import { useRef } from "react"; import { Image, StyleSheet, View } from "react-native"; import MapView, { PROVIDER_DEFAULT, type Region } from "react-native-maps"; import { icons } from "@/constants"; import { useTheme } from "@/lib/theme"; // Fine-tuning a pickup or drop-off point. // // The pin does NOT move — the map moves under it. Dragging a marker means // fighting for a few pixels with the same thumb that pans the map, and on a // phone the marker spends most of the gesture hidden under the finger holding // it. Anchoring the pin to the centre of the screen and sliding the map // underneath makes the target the one thing always visible, which is why every // ride-hailing app converged on it. // // The component is deliberately dumb: it reports the centre when the map // settles and nothing else. Reverse geocoding, debouncing and confirmation all // live on the screen, so this stays reusable for the origin and the // destination alike. export type PinAdjusterProps = { initial: { latitude: number; longitude: number }; /** Fired when the map stops moving, with the coordinate under the pin. */ onSettled: (coords: { latitude: number; longitude: number }) => void; /** Fired as soon as a drag starts, to clear a now-stale address label. */ onMoveStart?: () => void; }; // Tight enough that the rider is choosing a doorway, not a district. const ZOOM_DELTA = 0.004; const styles = StyleSheet.create({ map: StyleSheet.absoluteFillObject, // Sits above the map and ignores touches, so panning still reaches the map. pinLayer: { ...StyleSheet.absoluteFillObject, alignItems: "center", justifyContent: "center", }, pin: { width: 36, height: 36, // The pin's point is at its bottom edge, but the coordinate we report is // the centre of the screen — so lift it by its own height to put the tip, // not the middle of the graphic, on the spot being chosen. marginBottom: 36, }, // A small ground marker under the tip: without it, on a busy map, it is // genuinely hard to tell which pixel the pin is pointing at. dot: { position: "absolute", width: 8, height: 8, borderRadius: 4, backgroundColor: "rgba(2,134,255,0.9)", borderWidth: 1, borderColor: "#ffffff", }, }); export const PinAdjuster = ({ initial, onSettled, onMoveStart, }: PinAdjusterProps) => { const { isDark } = useTheme(); const mapRef = useRef(null); const region: Region = { latitude: initial.latitude, longitude: initial.longitude, latitudeDelta: ZOOM_DELTA, longitudeDelta: ZOOM_DELTA, }; return ( onSettled({ latitude: next.latitude, longitude: next.longitude }) } /> ); };