Skip to content

Commit 6b51a85

Browse files
committed
Merge branch 'main' of github.com:fleetbase/storefront-app into app/oli-max
2 parents d46c995 + d682b88 commit 6b51a85

20 files changed

+527
-336
lines changed
27 KB
Loading

src/components/DeliveryRoutePreview.tsx

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import { faStore, faPerson } from '@fortawesome/free-solid-svg-icons';
66
import MapView, { Marker, PROVIDER_GOOGLE, PROVIDER_DEFAULT } from 'react-native-maps';
77
import MapViewDirections from 'react-native-maps-directions';
88
import { Vehicle } from '@fleetbase/sdk';
9+
import { FoodTruck } from '@fleetbase/storefront';
910
import { restoreFleetbasePlace, getCoordinatesObject, createFauxPlace, formattedAddressFromPlace, makeCoordinatesFloat } from '../utils/location';
10-
import { config, storefrontConfig, getFoodTruckById, isArray } from '../utils';
11+
import { config, storefrontConfig, getFoodTruckById, isArray, isObject } from '../utils';
1112
import LocationMarker from './LocationMarker';
1213
import VehicleMarker from './VehicleMarker';
1314
import LoadingOverlay from './LoadingOverlay';
@@ -17,7 +18,6 @@ import useStorefront from '../hooks/use-storefront';
1718
import { adapter as fleetbaseAdapter } from '../hooks/use-fleetbase';
1819

1920
/* ---------- Helpers ---------- */
20-
2121
const DEFAULT_REGION = {
2222
latitude: 37.7749,
2323
longitude: -122.4194,
@@ -74,11 +74,10 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
7474

7575
const [bearing, setBearing] = useState(0);
7676
const [findingOrigin, setFindingOrigin] = useState(false);
77-
const [dontFindOrigin, setDontFindOrigin] = useState(false);
7877
const [ready, setReady] = useState(false);
7978

8079
// -------- Origin & destination --------
81-
const initialOrigin = useMemo(
80+
const initialStart = useMemo(
8281
() =>
8382
currentStoreLocation === undefined
8483
? createFauxPlace()
@@ -89,7 +88,17 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
8988
[currentStoreLocation]
9089
);
9190

92-
const [start, setStart] = useState(initialOrigin);
91+
// REFACTORED: Handle object customOrigin immediately without async
92+
const resolvedStart = useMemo(() => {
93+
// If customOrigin is an object with id, use it directly
94+
if (isObject(customOrigin) && customOrigin.id) {
95+
return customOrigin;
96+
}
97+
// Otherwise use initial start (will be fetched async if it's a string ID)
98+
return initialStart;
99+
}, [customOrigin, initialStart]);
100+
101+
const [start, setStart] = useState(resolvedStart);
93102
const end = useMemo(() => restoreFleetbasePlace(currentLocation), [currentLocation]);
94103
const origin = useMemo(() => getCoordinatesObject(start), [start]);
95104
const destination = useMemo(() => getCoordinatesObject(end), [end]);
@@ -99,7 +108,7 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
99108
const [mapRegion, setMapRegion] = useState(() => getSafeInitialRegion(origin, initialDeltas));
100109
const [zoomLevel, setZoomLevel] = useState(() => calculateZoomLevel(mapRegion.latitudeDelta));
101110
const markerOffset = useMemo(() => calculateOffset(zoomLevel), [zoomLevel]);
102-
const isOriginFoodTruck = useMemo(() => start?.resource === 'food-truck' || start?.getAttribute?.('resource') === 'food-truck', [start]);
111+
const isOriginFoodTruck = useMemo(() => start instanceof FoodTruck || start?.resource === 'food-truck', [start]);
103112
const providerIsGoogle = Platform.OS === 'android' || PROVIDER_DEFAULT === PROVIDER_GOOGLE;
104113

105114
/* ---------- Bearing polling ---------- */
@@ -232,25 +241,31 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
232241
[destination, mapRegion, initialDeltas]
233242
);
234243

235-
/* ---------- customOrigin resolution ---------- */
236-
const updateOriginFromCustomOrigin = useCallback(async () => {
237-
if (dontFindOrigin || findingOrigin) return;
244+
const handleMovement = useCallback(
245+
({ coordinates }) => {
246+
if (coordinates) focusMoving(coordinates);
247+
},
248+
[focusMoving]
249+
);
238250

239-
// No custom origin: we’re done (we already seeded start)
240-
if (!customOrigin) {
241-
setFindingOrigin(false);
251+
/* ---------- REFACTORED: Async fetch for string IDs only ---------- */
252+
const fetchOriginFromStringId = useCallback(async () => {
253+
// Only fetch if customOrigin is a string ID (not an object)
254+
if (!customOrigin || typeof customOrigin !== 'string') {
255+
setReady(true);
256+
return;
257+
}
258+
259+
// Already fetched
260+
if (start?.id === customOrigin || start?.store_location_id === customOrigin) {
242261
setReady(true);
243262
return;
244263
}
245264

246265
setFindingOrigin(true);
247266

248267
try {
249-
if (typeof customOrigin !== 'string') {
250-
if (customOrigin.id && customOrigin.id !== start?.id) {
251-
setStart(customOrigin);
252-
}
253-
} else if (customOrigin.startsWith('food_truck')) {
268+
if (customOrigin.startsWith('food_truck')) {
254269
const cachedFoodTruck = getFoodTruckById(customOrigin);
255270
if (cachedFoodTruck) {
256271
setStart(cachedFoodTruck);
@@ -259,10 +274,11 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
259274
public_id: customOrigin,
260275
with_deleted: true,
261276
});
262-
setStart(isArray(foodTruck) && foodTruck.length ? foodTruck[0] : foodTruck);
277+
const resolvedFoodTruck = isArray(foodTruck) && foodTruck.length ? foodTruck[0] : foodTruck;
278+
setStart(resolvedFoodTruck);
263279
}
264280
} else if (customOrigin.startsWith('store_location')) {
265-
if (store && customOrigin !== start?.store_location_id) {
281+
if (store) {
266282
const storeLocation = await store.getLocation(customOrigin);
267283
setStart(
268284
restoreFleetbasePlace({
@@ -279,17 +295,16 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
279295
setFindingOrigin(false);
280296
setReady(true);
281297
}
282-
}, [customOrigin, dontFindOrigin, start?.id, start?.store_location_id, storefront, store]);
298+
}, [customOrigin, start?.id, start?.store_location_id, storefront, store]);
283299

284300
useEffect(() => {
285301
if (!storefront || !store) {
286-
setFindingOrigin(false);
287302
setReady(true);
288303
return;
289304
}
290305

291-
updateOriginFromCustomOrigin(customOrigin);
292-
}, [storefront, store, customOrigin, updateOriginFromCustomOrigin]);
306+
fetchOriginFromStringId();
307+
}, [storefront, store, customOrigin, fetchOriginFromStringId]);
293308

294309
// Keep initial region sane if origin becomes available later
295310
useEffect(() => {
@@ -306,6 +321,15 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
306321
}
307322
}, [origin, initialDeltas]);
308323

324+
// Cleanup on unmount
325+
useEffect(() => {
326+
return () => {
327+
stopBearingPoll();
328+
isPollingBearing.current = false;
329+
lastFollowTsRef.current = 0;
330+
};
331+
}, [stopBearingPoll]);
332+
309333
// -------- Render --------
310334
const initialRegion = useMemo(() => getSafeInitialRegion(origin, initialDeltas), [origin, initialDeltas]);
311335

@@ -324,7 +348,7 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
324348
onRegionChangeComplete={handleRegionChangeComplete}
325349
mapType={storefrontConfig('defaultMapType', 'standard')}
326350
showsCompass={false}
327-
onRegionChange={startBearingPoll}
351+
onRegionChange={() => startBearingPoll()}
328352
onRegionChangeComplete={(region) => {
329353
stopBearingPoll();
330354
handleRegionChangeComplete(region);
@@ -338,13 +362,7 @@ const DeliveryRoutePreview = ({ children, zoom = 1, width = '100%', height = '10
338362
vehicle={new Vehicle(start.getAttribute('vehicle'), fleetbaseAdapter)}
339363
mapBearing={bearing}
340364
providerIsGoogle={providerIsGoogle}
341-
onMovement={({ coordinates }) => {
342-
// VehicleMarker internally animates marker;
343-
// here we make the map follow its movement.
344-
if (coordinates) {
345-
focusMoving(coordinates);
346-
}
347-
}}
365+
onMovement={handleMovement}
348366
>
349367
<YStack opacity={0.9} mt='$2' bg='$background' borderRadius='$6' px='$2' py='$1' alignItems='center' justifyContent='center'>
350368
<Text fontSize={14} color='$textPrimary' numberOfLines={1}>

src/components/DriverMarker.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const DriverMarker = ({ driver, onPositionChange, onHeadingChange, onMovement, .
99
const markerRef = useRef();
1010
const listenerRef = useRef();
1111
const lastCoordinatesRef = useRef(null);
12+
const addEventRef = useRef(addEvent);
13+
const clearEventsRef = useRef(clearEvents);
1214

1315
const handleEvent = useCallback(
1416
(data) => {
@@ -80,8 +82,7 @@ const DriverMarker = ({ driver, onPositionChange, onHeadingChange, onMovement, .
8082
useCallback(() => {
8183
const trackDriverMovement = async () => {
8284
const listener = await listen(`driver.${driver.id}`, (event) => {
83-
console.log(`[Socket Channel: driver.${driver.id}]`, event);
84-
addEvent(event);
85+
addEventRef.current(event);
8586
});
8687
if (listener) {
8788
listenerRef.current = listener;
@@ -97,11 +98,14 @@ const DriverMarker = ({ driver, onPositionChange, onHeadingChange, onMovement, .
9798
clearEvents();
9899
lastCoordinatesRef.current = null; // Reset on unmount
99100
};
100-
}, [listen, driver.id, addEvent, clearEvents])
101+
}, [listen, driver.id])
101102
);
102103

103104
const { latitude, longitude } = driver;
105+
const heading = driver.getAttribute('heading') ?? 0;
104106
const coord = makeCoordinatesFloat({ latitude, longitude });
107+
const avatarUrl = driver.getAttribute('avatar_url');
108+
const avatarSource = avatarUrl ? { uri: avatarUrl } : require('../../assets/images/vehicles/light_commercial_van.png');
105109

106110
// Initialize last coordinates with the vehicle's initial position
107111
useEffect(() => {
@@ -110,7 +114,13 @@ const DriverMarker = ({ driver, onPositionChange, onHeadingChange, onMovement, .
110114
}
111115
}, [latitude, longitude]);
112116

113-
return <TrackingMarker ref={markerRef} coordinate={coord} imageSource={{ uri: driver.getAttribute('avatar_url') }} size={{ width: 50, height: 50 }} {...props} />;
117+
// Event buffer method refs
118+
useEffect(() => {
119+
addEventRef.current = addEvent;
120+
clearEventsRef.current = clearEvents;
121+
}, [addEvent, clearEvents]);
122+
123+
return <TrackingMarker ref={markerRef} coordinate={coord} initialRotation={heading} imageSource={avatarSource} size={{ width: 50, height: 50 }} {...props} />;
114124
};
115125

116126
export default DriverMarker;

0 commit comments

Comments
 (0)