From 3e0772ffb800a4432688fc80d70170baae8999ee Mon Sep 17 00:00:00 2001 From: dharaneesh-r Date: Thu, 18 Jun 2026 15:05:29 +0530 Subject: [PATCH] updates on the activeSection and dispatch --- src/pages/nearle/dispatch/ActiveSection.js | 22 ++++-- src/pages/nearle/dispatch/Dispatch.js | 89 +++++++++++++++++++--- 2 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/pages/nearle/dispatch/ActiveSection.js b/src/pages/nearle/dispatch/ActiveSection.js index 6976465..aab6c32 100644 --- a/src/pages/nearle/dispatch/ActiveSection.js +++ b/src/pages/nearle/dispatch/ActiveSection.js @@ -7,6 +7,7 @@ import { MdMyLocation, MdInventory2 } from 'react-icons/md'; +import dayjs from 'dayjs'; import { getStatusStyle, getActiveOrder } from './dispatchShared'; const ActiveSection = ({ @@ -83,13 +84,20 @@ const ActiveSection = ({ {riderName} - - {statusStyle.label} - +
+ + {statusStyle.label} + + {o.deliverytime && ( + + {dayjs(o.deliverytime).isValid() ? dayjs(o.deliverytime).format('HH:mm:ss') : String(o.deliverytime)} + + )} +
{dropArea && ( diff --git a/src/pages/nearle/dispatch/Dispatch.js b/src/pages/nearle/dispatch/Dispatch.js index 9bff09b..35e9bad 100644 --- a/src/pages/nearle/dispatch/Dispatch.js +++ b/src/pages/nearle/dispatch/Dispatch.js @@ -800,8 +800,46 @@ const MapController = ({ focusedItem, viewMode, orders, kitchens, locationKey }) // automatically. Either way motion is smooth and never freezes mid-trip. // `duration` is only the seed used for the very first segment (no prior fix to // measure against yet). -const MIN_GLIDE_MS = 800; // floor: don't animate faster than this even on rapid fixes -const MAX_GLIDE_MS = 32_000; // ceiling: cover the ~30s backend cadence + small buffer +const MIN_GLIDE_MS = 200; // floor: don't animate faster than this even on rapid fixes +const MAX_GLIDE_MS = 2500; // ceiling: tighter ceiling for 1s update cadence +const interpolatePath = (path, t) => { + if (!path || path.length === 0) return null; + if (path.length === 1) return path[0]; + if (t <= 0) return path[0]; + if (t >= 1) return path[path.length - 1]; + + const segmentDistances = []; + let totalDistance = 0; + for (let i = 0; i < path.length - 1; i++) { + const p1 = path[i]; + const p2 = path[i + 1]; + const dLat = p2[0] - p1[0]; + const dLng = p2[1] - p1[1]; + const dist = Math.sqrt(dLat * dLat + dLng * dLng); + segmentDistances.push(dist); + totalDistance += dist; + } + + if (totalDistance === 0) return path[0]; + + const targetDistance = t * totalDistance; + let accumulatedDistance = 0; + for (let i = 0; i < segmentDistances.length; i++) { + const nextDistance = accumulatedDistance + segmentDistances[i]; + if (nextDistance >= targetDistance) { + const segT = (targetDistance - accumulatedDistance) / segmentDistances[i]; + const p1 = path[i]; + const p2 = path[i + 1]; + return [ + p1[0] + (p2[0] - p1[0]) * segT, + p1[1] + (p2[1] - p1[1]) * segT + ]; + } + accumulatedDistance = nextDistance; + } + return path[path.length - 1]; +}; + const AnimatedRiderMarker = ({ target, icon, duration = 950, zIndexOffset, eventHandlers, children, markerRef: externalRef }) => { const markerRef = useRef(null); const rafRef = useRef(null); @@ -861,17 +899,46 @@ const AnimatedRiderMarker = ({ target, icon, duration = 950, zIndexOffset, event prevFixTsRef.current = startTs; const startLat = from.lat; const startLng = from.lng; + + let active = true; + let osrmPath = null; + + // Fetch OSRM route for this step so the bike follows the roads + const fetchOsrmPath = async () => { + const url = `https://router.project-osrm.org/route/v1/driving/${from.lng},${from.lat};${to.lng},${to.lat}?overview=full&geometries=geojson`; + try { + const res = await fetch(url); + const json = await res.json(); + if (active && json.routes && json.routes[0]) { + osrmPath = json.routes[0].geometry.coordinates.map(c => [c[1], c[0]]); + } + } catch (e) { + console.error('OSRM animated rider marker fetch error:', e); + } + }; + fetchOsrmPath(); + const step = (now) => { + if (!active) return; const t = Math.min(1, (now - startTs) / segMs); - // Linear interpolation → constant speed. Spanning the glide across the - // full inter-fix interval chains consecutive segments into one continuous - // motion (a vehicle moving down the road) rather than the accelerate/brake - // feel an easing curve gives, or the dart-then-freeze of a fixed duration. - marker.setLatLng([startLat + dLat * t, startLng + dLng * t]); + + if (osrmPath && osrmPath.length >= 2) { + const pos = interpolatePath(osrmPath, t); + if (pos) { + marker.setLatLng(pos); + } else { + marker.setLatLng([startLat + dLat * t, startLng + dLng * t]); + } + } else { + // Fallback to linear interpolation if OSRM route isn't available + marker.setLatLng([startLat + dLat * t, startLng + dLng * t]); + } + if (t < 1) rafRef.current = requestAnimationFrame(step); }; rafRef.current = requestAnimationFrame(step); return () => { + active = false; if (rafRef.current) cancelAnimationFrame(rafRef.current); }; }, [lat, lon, duration]); @@ -1455,13 +1522,13 @@ const Dispatch = ({ // hub (latitude/longitude/logdate/status). We render those positions as // markers on the main dispatch map so the operator sees where each rider // actually is — matching the Reports → Riders Logs page. - const RIDER_LOG_POLL_MS = 15000; + const RIDER_LOG_POLL_MS = 1000; const { data: ridersLocationLogs } = useQuery({ queryKey: [selectedAppLocationId, selectedDate, ''], queryFn: fetchRidersLogs, refetchInterval: RIDER_LOG_POLL_MS, refetchIntervalInBackground: false, - staleTime: 5 * 1000, + staleTime: 0, refetchOnWindowFocus: false }); @@ -4143,7 +4210,7 @@ const Dispatch = ({ */} - {(focusedRider || focusedKitchen) ? ( + {((focusedRider && !isAllActiveView) || focusedKitchen) ? (
{focusedRider ? ( @@ -5028,7 +5095,7 @@ const Dispatch = ({ // existing views behave exactly as they did before. const LiveMarker = isAllActiveView ? AnimatedRiderMarker : Marker; const positionProps = isAllActiveView - ? { target: [r.lat, r.lon], duration: 15000 } + ? { target: [r.lat, r.lon], duration: 1000 } : { position: [r.lat, r.lon] }; return (