import type { Dispatch, SetStateAction } from 'react'; import { useEffect, useRef, useState } from 'react'; import type { Route } from '@lifi/sdk'; import { ProgressToNextUpdate } from '../../components/ProgressToNextUpdate.js'; import { useRoutes } from '../../hooks/useRoutes.js'; import { useRouteExecutionStoreContext } from '../../stores/routes/RouteExecutionStore.js'; import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js'; export interface RouteTrackerProps { observableRouteId: string; onChange: Dispatch>; onFetching: Dispatch>; } export const RouteTracker = ({ observableRouteId, onChange, onFetching, }: RouteTrackerProps) => { const routeExecutionStore = useRouteExecutionStoreContext(); const setExecutableRoute = useSetExecutableRoute(); const [observableRoute, setObservableRoute] = useState( undefined, ); const observableRouteIdRef = useRef(undefined); useEffect(() => { const route = routeExecutionStore.getState().routes[observableRouteId]?.route; setObservableRoute(route); observableRouteIdRef.current = route?.id; }, [observableRouteId, routeExecutionStore]); const { routes, isFetching, dataUpdatedAt, refetchTime, refetch } = useRoutes( { observableRoute }, ); const currentRoute = routes?.[0]; /** * The reviewable route is the route that the user currently sees on the review page. * The observable route is the route for which we track bridges and exchanges. * This allows us to query the route using the same tool each time we refresh. * The observable and reviewable routes can be the same when we first enter the review page. */ useEffect(() => { if ( observableRouteIdRef.current && currentRoute && observableRouteIdRef.current !== currentRoute.id ) { // Only track the current route, don't maintain multiple observable routes observableRouteIdRef.current = currentRoute.id; setExecutableRoute(currentRoute, [currentRoute.id]); onChange(currentRoute.id); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentRoute?.id, observableRouteId, onChange, setExecutableRoute]); useEffect(() => { onFetching(isFetching); }, [isFetching, onFetching]); const handleRefetch = () => { refetch(); }; return ( ); };