import { useAccount } from '@lifi/wallet-management' import { Box, List } from '@mui/material' import { useVirtualizer } from '@tanstack/react-virtual' import { type JSX, useCallback, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' import { PageContainer } from '../../components/PageContainer.js' import { TransactionCardSkeleton } from '../../components/TransactionCard/TransactionCardSkeleton.js' import { useHeader } from '../../hooks/useHeader.js' import { useListHeight } from '../../hooks/useListHeight.js' import { useTransactionList } from '../../hooks/useTransactionList.js' import { useRouteExecutionStore } from '../../stores/routes/RouteExecutionStore.js' import { RouteExecutionStatus } from '../../stores/routes/types.js' import { ActiveTransactionItem } from './ActiveTransactionItem.js' import { ActivitiesPageMenuButton } from './ActivitiesPageMenuButton.js' import { TransactionHistoryEmpty } from './TransactionHistoryEmpty.js' import { TransactionHistoryItem } from './TransactionHistoryItem.js' const SKELETON_COUNT = 2 export const ActivitiesPage = (): JSX.Element => { // Parent ref and useVirtualizer should be in one file to avoid blank page (0 virtual items) issue const parentRef = useRef(null) const { items, isLoading } = useTransactionList() const { t } = useTranslation() const { accounts } = useAccount() const accountAddresses = useMemo( () => accounts.map((account) => account.address), [accounts] ) const hasFailedItems = useRouteExecutionStore( useCallback( (state) => Object.values(state.routes).some( (r) => r?.status === RouteExecutionStatus.Failed && accountAddresses.includes(r.route.fromAddress) ), [accountAddresses] ) ) useHeader( t('header.activities'), hasFailedItems ? : null ) const { listHeight } = useListHeight({ listParentRef: parentRef, }) const hasStoreItems = items.length > 0 const skeletonCount = isLoading && hasStoreItems ? SKELETON_COUNT : 0 const totalCount = items.length + skeletonCount const getItemKey = useCallback( (index: number) => { if (index >= items.length) { return `skeleton-${index}` } const item = items[index] if (item.type === 'active') { return `active-${item.routeId}` } return `${item.type}-${item.txHash || item.routeExecution.route.id}` }, [items] ) const { getVirtualItems, getTotalSize, measureElement } = useVirtualizer({ count: hasStoreItems ? totalCount : 0, overscan: 3, paddingEnd: 12, getScrollElement: () => parentRef.current, estimateSize: (index) => (items[index]?.type === 'active' ? 218 : 196), getItemKey, }) const isEmpty = !items.length && !isLoading return ( {isEmpty ? ( ) : isLoading && !hasStoreItems ? ( {Array.from({ length: SKELETON_COUNT }).map((_, index) => ( ))} ) : ( {getVirtualItems().map((item) => { const listItem = item.index < items.length ? items[item.index] : null return (
  • {!listItem ? ( ) : listItem.type === 'active' ? ( ) : ( )}
  • ) })}
    )}
    ) }