/* eslint-disable react/no-array-index-key */ import type { Route } from '@lifi/sdk'; import { Collapse, Grow, Stack, Typography } from '@mui/material'; import { useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import type { RouteObject } from 'react-router-dom'; import { useRoutes as useDOMRoutes, useNavigate } from 'react-router-dom'; import { useAccount } from '../../hooks/useAccount.js'; import { useRoutes } from '../../hooks/useRoutes.js'; import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'; import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'; import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'; import { useFieldValues } from '../../stores/form/useFieldValues.js'; import { WidgetEvent } from '../../types/events.js'; import { navigationRoutes } from '../../utils/navigationRoutes.js'; import { PageContainer } from '../PageContainer.js'; import { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'; import { RouteCard } from '../RouteCard/RouteCard.js'; import { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js'; import { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'; import { CollapseContainer, Container, Header, RouteTopLevelGrow, RoutesExpandedCollapse, ScrollableContainer, } from './RoutesExpanded.style.js'; const timeout = { enter: 225, exit: 225, appear: 0 }; const routes: RouteObject[] = [ { path: '/', element: true, }, { path: '*', element: null, }, ]; export const RoutesExpanded = () => { const element = useDOMRoutes(routes); const match = Boolean(element?.props?.children); return (
); }; export const RoutesExpandedElement = () => { const { t } = useTranslation(); const navigate = useNavigate(); const { subvariant } = useWidgetConfig(); const routesRef = useRef(); const emitter = useWidgetEvents(); const routesActiveRef = useRef(false); const { routes, isLoading, isFetching, isFetched, dataUpdatedAt, refetchTime, fromChain, refetch, setReviewableRoute, } = useRoutes(); const { account } = useAccount({ chainType: fromChain?.chainType }); const [toAddress] = useFieldValues('toAddress'); const { requiredToAddress } = useToAddressRequirements(); const handleRouteClick = ( e: React.MouseEvent, route: Route, ) => { e.preventDefault(); e.stopPropagation(); setReviewableRoute(route); navigate(navigationRoutes.transactionExecution, { state: { routeId: route.id }, }); }; const onExit = () => { // Clean routes cache on exit routesRef.current = undefined; }; // We cache routes results in ref for a better exit animation if (routesRef.current && !routes) { routesActiveRef.current = false; } else { routesRef.current = routes; routesActiveRef.current = Boolean(routes); } const currentRoute = routesRef.current?.[0]; const expanded = Boolean( routesActiveRef.current || isLoading || isFetching || isFetched, ); const routeNotFound = !currentRoute && !isLoading && !isFetching && expanded; const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress; const allowInteraction = account.isConnected && !toAddressUnsatisfied; useEffect(() => { emitter.emit(WidgetEvent.WidgetExpanded, expanded); }, [emitter, expanded]); return (
{subvariant === 'custom' ? t('header.youPay') : t('header.receive')} refetch()} sx={{ marginRight: -1 }} />
{routeNotFound ? ( ) : isLoading || (isFetching && !routesRef.current?.length) ? ( Array.from({ length: 3 }).map((_, index) => ( )) ) : ( routesRef.current?.map((route: Route, index: number) => ( handleRouteClick(e, route) : undefined } active={index === 0} expanded={routesRef.current?.length === 1} /> )) )}
); };