Waseel: driver app, dispatch, POI suggestions, map fixes
This commit is contained in:
+26
-4
@@ -1,15 +1,17 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Platform, StyleSheet } from "react-native";
|
||||
import MapView, { Marker, PROVIDER_DEFAULT } from "react-native-maps";
|
||||
import MapViewDirections from "react-native-maps-directions";
|
||||
|
||||
import { icons } from "@/constants";
|
||||
import { useFetch } from "@/lib/fetch";
|
||||
import { tr } from "@/lib/i18n";
|
||||
import {
|
||||
calculateDriverTimes,
|
||||
calculateRegion,
|
||||
generateMarkersFromData,
|
||||
} from "@/lib/map";
|
||||
import { useTheme } from "@/lib/theme";
|
||||
import { useDriverStore, useLocationStore, useServiceStore } from "@/store";
|
||||
import type { Driver, MarkerData } from "@/types/type";
|
||||
|
||||
@@ -48,6 +50,7 @@ export const Map = () => {
|
||||
} = useLocationStore();
|
||||
const { service } = useServiceStore();
|
||||
const { selectedDriver, setDrivers } = useDriverStore();
|
||||
const { isDark } = useTheme();
|
||||
|
||||
// Online drivers of the selected service near the rider. Falls back to a
|
||||
// Beirut center when the rider's position isn't resolved yet so the map
|
||||
@@ -59,6 +62,7 @@ export const Map = () => {
|
||||
);
|
||||
|
||||
const [markers, setMarkers] = useState<MarkerData[]>([]);
|
||||
const mapRef = useRef<MapView>(null);
|
||||
|
||||
const region = calculateRegion({
|
||||
userLatitude,
|
||||
@@ -67,6 +71,23 @@ export const Map = () => {
|
||||
destinationLongitude,
|
||||
});
|
||||
|
||||
// `initialRegion` is read once, at mount. The map mounts before the location
|
||||
// fix arrives, so it would sit on the Beirut fallback forever and never zoom
|
||||
// out to fit a destination the rider picks later. Animate on every real
|
||||
// change instead. Keyed on the coordinates so the repeated setUserLocation
|
||||
// from reverse geocoding (same coords, new address) doesn't yank the camera
|
||||
// back while the rider is panning.
|
||||
const regionKey = `${region.latitude},${region.longitude},${region.latitudeDelta},${region.longitudeDelta}`;
|
||||
const lastRegionKey = useRef(regionKey);
|
||||
|
||||
useEffect(() => {
|
||||
if (lastRegionKey.current === regionKey) return;
|
||||
|
||||
lastRegionKey.current = regionKey;
|
||||
mapRef.current?.animateToRegion(region, 500);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [regionKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Array.isArray(drivers)) {
|
||||
if (!userLatitude || !userLongitude) return;
|
||||
@@ -113,15 +134,16 @@ export const Map = () => {
|
||||
|
||||
return (
|
||||
<MapView
|
||||
ref={mapRef}
|
||||
provider={PROVIDER_DEFAULT}
|
||||
style={styles.map}
|
||||
tintColor="black"
|
||||
tintColor={isDark ? "white" : "black"}
|
||||
mapType={MAP_TYPE}
|
||||
customMapStyle={MUTED_POI_STYLE}
|
||||
showsPointsOfInterest={false}
|
||||
initialRegion={region}
|
||||
showsUserLocation
|
||||
userInterfaceStyle="light"
|
||||
userInterfaceStyle={isDark ? "dark" : "light"}
|
||||
>
|
||||
{markers.map((marker) => (
|
||||
<Marker
|
||||
@@ -148,7 +170,7 @@ export const Map = () => {
|
||||
latitude: destinationLatitude,
|
||||
longitude: destinationLongitude,
|
||||
}}
|
||||
title="Destination"
|
||||
title={tr("components.map.destination")}
|
||||
image={icons.pin}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user