From 46d49a9f0d269f613bf77e715c92d3cad34ebe0d Mon Sep 17 00:00:00 2001 From: Nicholas Barnett Date: Fri, 2 Aug 2024 14:39:41 -0500 Subject: [PATCH] chore: added last block + load more --- src/app/_components/BlockList/BlockCount.tsx | 77 +++++++++---------- .../BlocksPage/BlocksPageBlockListGrouped.tsx | 2 +- .../BlocksPageBlockListUngrouped.tsx | 2 +- .../BlocksPage/BlocksPageHeaders.tsx | 7 +- .../BlockList/Grouped/BlockListGrouped.tsx | 72 ++++++++++------- .../BlockList/Grouped/skeleton.tsx | 4 +- .../HomePage/HomePageBlockListUngrouped.tsx | 2 +- .../Ungrouped/BlockListUngrouped.tsx | 68 ++++++++-------- .../BlockList/data/useBlockListBtcBlocks.ts | 45 ----------- .../data/useBlocksPageBlockListGrouped.tsx | 13 ++-- .../data/useBlocksPageBlockListUngrouped.ts | 13 ++-- .../BlockList/data/useHomePageBlockList.ts | 13 ++-- .../data/useHomePageInitialBlockList.ts | 6 +- src/common/queries/useBurnBlock.ts | 38 +++++++++ 14 files changed, 190 insertions(+), 172 deletions(-) delete mode 100644 src/app/_components/BlockList/data/useBlockListBtcBlocks.ts diff --git a/src/app/_components/BlockList/BlockCount.tsx b/src/app/_components/BlockList/BlockCount.tsx index 5e7290a79..1c3cc17eb 100644 --- a/src/app/_components/BlockList/BlockCount.tsx +++ b/src/app/_components/BlockList/BlockCount.tsx @@ -1,70 +1,65 @@ import { useColorModeValue } from '@chakra-ui/react'; -import { ArrowUpRight } from '@phosphor-icons/react'; +import { CaretDown } from '@phosphor-icons/react'; import pluralize from 'pluralize'; -import { memo, useMemo } from 'react'; +import { memo } from 'react'; -import { Circle } from '../../../common/components/Circle'; -import { ExplorerLink } from '../../../common/components/ExplorerLinks'; -import { Flex } from '../../../ui/Flex'; +import { Button } from '../../../ui/Button'; import { Icon } from '../../../ui/Icon'; import { Text } from '../../../ui/Text'; export const BlockCount = memo(function ({ count, - btcBlockHash, isFirst, + loadMoreStxBlocksHandler, + minimized = false, }: { count: number; - btcBlockHash?: string; isFirst?: boolean; + loadMoreStxBlocksHandler?: () => void; + minimized?: boolean; }) { - // TODO: remove. use theme const bgColor = useColorModeValue('purple.100', 'slate.900'); const bgColorHover = useColorModeValue('purple.200', 'slate.850'); const textColor = useColorModeValue('purple.600', 'purple.400'); const iconColor = useColorModeValue('purple.600', 'purple.200'); - const content = useMemo(() => { - return ( + + return ( + ); }); diff --git a/src/app/_components/BlockList/BlocksPage/BlocksPageBlockListGrouped.tsx b/src/app/_components/BlockList/BlocksPage/BlocksPageBlockListGrouped.tsx index 34b2cf8f4..1bc58cd70 100644 --- a/src/app/_components/BlockList/BlocksPage/BlocksPageBlockListGrouped.tsx +++ b/src/app/_components/BlockList/BlocksPage/BlocksPageBlockListGrouped.tsx @@ -23,7 +23,7 @@ function BlocksPageBlockListGroupedBase() { <> {!liveUpdates && } - + {!liveUpdates && } - + (response); + const btcBlock = burnBlocks[0]; return ( @@ -84,7 +87,7 @@ function LastConfirmedBitcoinBlockCard() { - 214 + {btcBlock.stacks_blocks.length} Stacks blocks @@ -92,7 +95,7 @@ function LastConfirmedBitcoinBlockCard() { - 4354 + {btcBlock.total_tx_count} Stacks transactions diff --git a/src/app/_components/BlockList/Grouped/BlockListGrouped.tsx b/src/app/_components/BlockList/Grouped/BlockListGrouped.tsx index 37e51fb58..b72a47dab 100644 --- a/src/app/_components/BlockList/Grouped/BlockListGrouped.tsx +++ b/src/app/_components/BlockList/Grouped/BlockListGrouped.tsx @@ -7,7 +7,6 @@ import { useInfiniteQueryResult } from '../../../../common/hooks/useInfiniteQuer import { useBlocksByBurnBlock } from '../../../../common/queries/useBlocksByBurnBlock'; import { truncateMiddle } from '../../../../common/utils/utils'; import { Box } from '../../../../ui/Box'; -import { Button } from '../../../../ui/Button'; import { Flex } from '../../../../ui/Flex'; import { Grid } from '../../../../ui/Grid'; import { HStack } from '../../../../ui/HStack'; @@ -169,52 +168,56 @@ export function BurnBlockGroupGridLayout({ } export function BurnBlockGroupGrid({ - btcBlock, blocksCount, stxBlocks, + stxBlocksLimit, lastStxBlock, minimized, isFirst, loadMoreStxBlocksHandler, }: { - btcBlock: BlockListBtcBlock; stxBlocks: BlockListStxBlock[]; lastStxBlock: BlockListStxBlock | null; - minimized: boolean; + stxBlocksLimit?: number; blocksCount: number; isFirst: boolean; + minimized?: boolean; loadMoreStxBlocksHandler?: () => void; }) { - const numStxBlocksNotDisplayed = blocksCount - stxBlocks.length; + const stxBlocksToDisplay = useMemo( + () => (stxBlocksLimit ? stxBlocks.slice(0, stxBlocksLimit) : stxBlocks), + [stxBlocks, stxBlocksLimit] + ); + const numStxBlocksNotDisplayed = blocksCount - stxBlocksToDisplay.length; const showLastStxBlock = lastStxBlock && numStxBlocksNotDisplayed > 1; return ( - {minimized || stxBlocks.length === 0 ? null : } - {stxBlocks.map((stxBlock, i) => ( + {minimized || stxBlocksToDisplay.length === 0 ? null : } + {stxBlocksToDisplay.map((stxBlock, i) => ( - {i < stxBlocks.length - 1 && ( + {i < stxBlocksToDisplay.length - 1 && ( )} ))} - {stxBlocks.length < blocksCount ? ( - - ) : null} {numStxBlocksNotDisplayed > 0 ? ( - + + + ) : null} {showLastStxBlock ? ( @@ -329,7 +332,7 @@ export function BurnBlockGroup({ btcBlock: BlockListBtcBlock; stxBlocks: BlockListStxBlock[]; isFirst: boolean; - stxBlocksLimit: number; + stxBlocksLimit?: number; minimized?: boolean; }) { const [enabled, setEnabled] = useState(false); @@ -341,24 +344,27 @@ export function BurnBlockGroup({ offset: stxBlocks.length, enabled, }, - 'additional-stx-blocks' + 'additional-stx-blocks-loaded' ); const { fetchNextPage, hasNextPage } = response; - const additionalStxBlocks = useInfiniteQueryResult(response); + const additionalStxBlocksLoaded = useInfiniteQueryResult(response); const handleLoadMoreStxBlocks = useCallback(() => { setEnabled(true); if (hasNextPage) { - console.log('fetching next page'); fetchNextPage(); } }, [fetchNextPage, hasNextPage]); const allStxBlocks = useMemo(() => { - return stxBlocks.concat(additionalStxBlocks.map(createBlockListStxBlock)); - }, [stxBlocks, additionalStxBlocks]); + return stxBlocks.concat(additionalStxBlocksLoaded.map(createBlockListStxBlock)); + }, [stxBlocks, additionalStxBlocksLoaded]); - const unaccountedStxBlocks = btcBlock.blockCount ? allStxBlocks.length - btcBlock.blockCount : 0; + // Live updates cause unaccounted blocks and txs + const unaccountedStxBlocks = useMemo( + () => allStxBlocks.length - btcBlock.blockCount, + [allStxBlocks, btcBlock.blockCount] + ); const unaccountedTxs = useMemo( () => unaccountedStxBlocks > 0 @@ -368,14 +374,22 @@ export function BurnBlockGroup({ : 0, [allStxBlocks, unaccountedStxBlocks] ); + const txsCount = isFirst ? btcBlock.txsCount + unaccountedTxs // For the first btc block, if live is on, then the btc block tx count can be stale and we need to account for the unaccounted txs : btcBlock.txsCount; - const blocksCount = isFirst ? btcBlock.blockCount + unaccountedStxBlocks : btcBlock.blockCount; - const queryForLastStxBlockRequireed = allStxBlocks.length < blocksCount; + const blocksCount = useMemo( + () => (isFirst ? btcBlock.blockCount + unaccountedStxBlocks : btcBlock.blockCount), + [btcBlock, unaccountedStxBlocks, isFirst] + ); + + const queryForLastStxBlockRequired = useMemo( + () => allStxBlocks.length < blocksCount, + [allStxBlocks, blocksCount] + ); const lastStxBlockResponse = useBlocksByBurnBlock(btcBlock.height, 1, { offset: blocksCount - 1, - enabled: queryForLastStxBlockRequireed, + enabled: queryForLastStxBlockRequired, }); const lastStxBlock = useInfiniteQueryResult(lastStxBlockResponse)[0]; const lastStxBlockFormatted = useMemo( @@ -388,9 +402,9 @@ export function BurnBlockGroup({ diff --git a/src/app/_components/BlockList/Grouped/skeleton.tsx b/src/app/_components/BlockList/Grouped/skeleton.tsx index f20e955c8..69f2b56e4 100644 --- a/src/app/_components/BlockList/Grouped/skeleton.tsx +++ b/src/app/_components/BlockList/Grouped/skeleton.tsx @@ -165,9 +165,9 @@ export function HomePageBlockListGroupedSkeleton() { export function BlocksPageBlockListGroupedSkeleton() { return ( ); } diff --git a/src/app/_components/BlockList/HomePage/HomePageBlockListUngrouped.tsx b/src/app/_components/BlockList/HomePage/HomePageBlockListUngrouped.tsx index 0530623cd..66584f95f 100644 --- a/src/app/_components/BlockList/HomePage/HomePageBlockListUngrouped.tsx +++ b/src/app/_components/BlockList/HomePage/HomePageBlockListUngrouped.tsx @@ -18,7 +18,7 @@ function HomePageBlockListUngroupedBase() { <> {!liveUpdates && } - + diff --git a/src/app/_components/BlockList/Ungrouped/BlockListUngrouped.tsx b/src/app/_components/BlockList/Ungrouped/BlockListUngrouped.tsx index cc09dd5ec..271dc3cdd 100644 --- a/src/app/_components/BlockList/Ungrouped/BlockListUngrouped.tsx +++ b/src/app/_components/BlockList/Ungrouped/BlockListUngrouped.tsx @@ -8,7 +8,6 @@ import { useInfiniteQueryResult } from '../../../../common/hooks/useInfiniteQuer import { useBlocksByBurnBlock } from '../../../../common/queries/useBlocksByBurnBlock'; import { truncateMiddle } from '../../../../common/utils/utils'; import { Box } from '../../../../ui/Box'; -import { Button } from '../../../../ui/Button'; import { Flex, FlexProps } from '../../../../ui/Flex'; import { Grid } from '../../../../ui/Grid'; import { HStack } from '../../../../ui/HStack'; @@ -23,7 +22,7 @@ import { useBlockListContext } from '../BlockListContext'; import { LineAndNode } from '../LineAndNode'; import { ScrollableBox } from '../ScrollableDiv'; import { getFadeAnimationStyle, mobileBorderCss } from '../consts'; -import { BlockListBtcBlock, BlockListStxBlock } from '../types'; +import { BlockListStxBlock } from '../types'; import { BlockListData, createBlockListStxBlock } from '../utils'; interface BtcBlockRowProps { @@ -260,30 +259,34 @@ export function StxBlocksGridLayout({ } function StxBlocksGrid({ - btcBlock, blocksCount, stxBlocks, lastStxBlock, + stxBlocksLimit, minimized = false, isFirst, loadMoreStxBlocksHandler, }: { - btcBlock: BlockListBtcBlock; stxBlocks: BlockListStxBlock[]; lastStxBlock: BlockListStxBlock | null; + stxBlocksLimit?: number; blocksCount: number; minimized?: boolean; isFirst: boolean; loadMoreStxBlocksHandler?: () => void; }) { - const numStxBlocksNotDisplayed = blocksCount - stxBlocks.length; + const stxBlocksToDisplay = useMemo( + () => (stxBlocksLimit ? stxBlocks.slice(0, stxBlocksLimit) : stxBlocks), + [stxBlocks, stxBlocksLimit] + ); + const numStxBlocksNotDisplayed = blocksCount - stxBlocksToDisplay.length; const showLastStxBlock = lastStxBlock && numStxBlocksNotDisplayed > 1; return ( {minimized ? null : } - {stxBlocks.map((stxBlock, i) => ( + {stxBlocksToDisplay.map((stxBlock, i) => ( - {i < stxBlocks.length - 1 && ( + {i < stxBlocksToDisplay.length - 1 && ( )} ))} - {stxBlocks.length < blocksCount ? ( - - ) : null} {numStxBlocksNotDisplayed > 0 ? ( - + + + ) : null} {showLastStxBlock ? ( @@ -349,7 +352,7 @@ function StxBlocksGroupedByBtcBlock({ offset: stxBlocks.length, enabled, }, - 'additional-stx-blocks' + 'additional-stx-blocks-loaded' ); const { fetchNextPage, hasNextPage } = response; const additionalStxBlocks = useInfiniteQueryResult(response); @@ -357,7 +360,6 @@ function StxBlocksGroupedByBtcBlock({ const handleLoadMoreStxBlocks = useCallback(() => { setEnabled(true); if (hasNextPage) { - console.log('fetching next page'); fetchNextPage(); } }, [fetchNextPage, hasNextPage]); @@ -366,21 +368,23 @@ function StxBlocksGroupedByBtcBlock({ return stxBlocks.concat(additionalStxBlocks.map(createBlockListStxBlock)); }, [stxBlocks, additionalStxBlocks]); - const unaccountedStxBlocks = btcBlock.blockCount ? allStxBlocks.length - btcBlock.blockCount : 0; - const blocksCount = isFirst ? btcBlock.blockCount + unaccountedStxBlocks : btcBlock.blockCount; - // const numStxBlocksNotDisplayed = - // blocksCount - (stxBlocksLimit || 0) > 1 - // ? blocksCount - (stxBlocksLimit || 0) - 1 - // : blocksCount - (stxBlocksLimit || 0); - // const displayedStxBlocks = useMemo( - // () => (stxBlocksLimit ? blockList.stxBlocks.slice(0, stxBlocksLimit) : blockList.stxBlocks), - // [blockList.stxBlocks, stxBlocksLimit] - // ); - // const isThereALastStxBlock = stxBlocks.length - displayedStxBlocks.length >= 2; - const queryForLastStxBlockRequireed = allStxBlocks.length < blocksCount; + // Live updates cause unaccounted blocks and txs + const unaccountedStxBlocks = useMemo( + () => allStxBlocks.length - btcBlock.blockCount, + [allStxBlocks, btcBlock.blockCount] + ); + const blocksCount = useMemo( + () => (isFirst ? btcBlock.blockCount + unaccountedStxBlocks : btcBlock.blockCount), + [btcBlock, unaccountedStxBlocks, isFirst] + ); + + const queryForLastStxBlockRequired = useMemo( + () => allStxBlocks.length < blocksCount, + [allStxBlocks, blocksCount] + ); const lastStxBlockResponse = useBlocksByBurnBlock(btcBlock.height, 1, { offset: blocksCount - 1, - enabled: queryForLastStxBlockRequireed, + enabled: queryForLastStxBlockRequired, }); const lastStxBlock = useInfiniteQueryResult(lastStxBlockResponse)[0]; const lastStxBlockFormatted = useMemo( @@ -392,12 +396,12 @@ function StxBlocksGroupedByBtcBlock({ diff --git a/src/app/_components/BlockList/data/useBlockListBtcBlocks.ts b/src/app/_components/BlockList/data/useBlockListBtcBlocks.ts deleted file mode 100644 index 0bbe627ef..000000000 --- a/src/app/_components/BlockList/data/useBlockListBtcBlocks.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { UseQueryResult, useQueries, useQueryClient } from '@tanstack/react-query'; -import { useEffect, useMemo, useRef } from 'react'; - -import { Block, BurnBlock, NakamotoBlock } from '@stacks/blockchain-api-client'; - -import { useGetBurnBlockQuery } from '../../../../common/queries/useBurnBlock'; - -// fetch the btc blocks for the stx blocks -export const useBlockListBtcBlocks = (latestStxBlocks: (Block | NakamotoBlock)[]) => { - const accumulatedStxBlocksRef = useRef>(new Set()); - const btcBlocksHashesRef = useRef>(new Set()); - const btcBlocksRef = useRef([] as BurnBlock[]); - - useEffect(() => { - if (latestStxBlocks.length > 0) { - latestStxBlocks.forEach(block => { - if (!accumulatedStxBlocksRef.current.has(block.burn_block_hash)) { - accumulatedStxBlocksRef.current.add(block.burn_block_hash); - } - }); - } - }, [latestStxBlocks]); - - const queryClient = useQueryClient(); - const getQuery = useGetBurnBlockQuery(); - const btcBlockQueries = useMemo(() => { - const hashes = Array.from(accumulatedStxBlocksRef.current).filter( - hash => !btcBlocksHashesRef.current.has(hash) - ); - return { - queries: hashes.map(hash => { - return getQuery(hash); - }), - combine: (response: UseQueryResult[]) => response.map(r => r.data), - }; - }, [accumulatedStxBlocksRef, getQuery]); - const btcBlocks = useQueries(btcBlockQueries, queryClient); - const filteredBtcBlocks = btcBlocks.filter(block => !!block) as BurnBlock[]; - filteredBtcBlocks.forEach(block => { - btcBlocksHashesRef.current.add(block.burn_block_hash); - }); - btcBlocksRef.current = [...filteredBtcBlocks, ...btcBlocksRef.current]; - - return { btcBlocks: btcBlocksRef.current }; -}; diff --git a/src/app/_components/BlockList/data/useBlocksPageBlockListGrouped.tsx b/src/app/_components/BlockList/data/useBlocksPageBlockListGrouped.tsx index 4c9c72369..7b9eb4043 100644 --- a/src/app/_components/BlockList/data/useBlocksPageBlockListGrouped.tsx +++ b/src/app/_components/BlockList/data/useBlocksPageBlockListGrouped.tsx @@ -1,9 +1,9 @@ import { useCallback, useEffect, useRef, useState } from 'react'; +import { useFetchMultipleBurnBlocks } from '../../../../common/queries/useBurnBlock'; import { useBlockListContext } from '../BlockListContext'; import { useBlockListWebSocket } from '../Sockets/useBlockListWebSocket'; import { BlockListData, generateBlockList, mergeBlockLists, waitForFadeAnimation } from '../utils'; -import { useBlockListBtcBlocks } from './useBlockListBtcBlocks'; import { useBlocksGroupedInitialBlockList } from './useBlocksPageGroupedInitialBlockList'; import { generateBtcBlocksMap } from './utils'; @@ -41,14 +41,17 @@ export function useBlocksPageBlockListGrouped(btcBlockLimit: number = 3) { [blockList] ); - const { btcBlocks: latestBtcBlocks } = useBlockListBtcBlocks(latestStxBlocksFromWebSocket); + const fetchBurnBlocks = useFetchMultipleBurnBlocks(); const showLatestStxBlocksFromWebSocket = useCallback(() => { setBlockListLoading(true); - waitForFadeAnimation(() => { + waitForFadeAnimation(async () => { + const btcBlocks = await fetchBurnBlocks( + latestStxBlocksFromWebSocket.map(block => block.burn_block_hash) + ); const websocketBlockList = generateBlockList( latestStxBlocksFromWebSocket, - generateBtcBlocksMap(latestBtcBlocks) + generateBtcBlocksMap(btcBlocks) ); updateBlockListManually(websocketBlockList); clearLatestStxBlocksFromWebSocket(); @@ -59,7 +62,7 @@ export function useBlocksPageBlockListGrouped(btcBlockLimit: number = 3) { updateBlockListManually, setBlockListLoading, clearLatestStxBlocksFromWebSocket, - latestBtcBlocks, + fetchBurnBlocks, ]); const updateBlockListWithQuery = useCallback( diff --git a/src/app/_components/BlockList/data/useBlocksPageBlockListUngrouped.ts b/src/app/_components/BlockList/data/useBlocksPageBlockListUngrouped.ts index a9b038ebf..5c902a70f 100644 --- a/src/app/_components/BlockList/data/useBlocksPageBlockListUngrouped.ts +++ b/src/app/_components/BlockList/data/useBlocksPageBlockListUngrouped.ts @@ -2,10 +2,10 @@ import { useCallback, useEffect, useRef, useState } from 'react'; +import { useFetchMultipleBurnBlocks } from '../../../../common/queries/useBurnBlock'; import { useBlockListContext } from '../BlockListContext'; import { useBlockListWebSocket } from '../Sockets/useBlockListWebSocket'; import { BlockListData, generateBlockList, mergeBlockLists, waitForFadeAnimation } from '../utils'; -import { useBlockListBtcBlocks } from './useBlockListBtcBlocks'; import { useBlocksPageUngroupedInitialBlockList } from './useBlocksPageUngroupedInitialBlockList'; import { generateBtcBlocksMap } from './utils'; @@ -34,7 +34,7 @@ export function useBlocksPageBlockListUngrouped(btcBlockLimit: number = 3) { clearLatestStxBlocks: clearLatestStxBlocksFromWebSocket, } = useBlockListWebSocket(liveUpdates, initialStxBlocksHashes); - const { btcBlocks: latestBtcBlocks } = useBlockListBtcBlocks(latestStxBlocksFromWebSocket); + const fetchBurnBlocks = useFetchMultipleBurnBlocks(); // manually update the block list with block list updates from the websocket const updateBlockListManually = useCallback( @@ -47,10 +47,13 @@ export function useBlocksPageBlockListUngrouped(btcBlockLimit: number = 3) { const showLatestStxBlocksFromWebSocket = useCallback(() => { setBlockListLoading(true); - waitForFadeAnimation(() => { + waitForFadeAnimation(async () => { + const btcBlocks = await fetchBurnBlocks( + latestStxBlocksFromWebSocket.map(block => block.burn_block_hash) + ); const websocketBlockList = generateBlockList( latestStxBlocksFromWebSocket, - generateBtcBlocksMap(latestBtcBlocks) + generateBtcBlocksMap(btcBlocks) ); updateBlockListManually(websocketBlockList); clearLatestStxBlocksFromWebSocket(); @@ -61,7 +64,7 @@ export function useBlocksPageBlockListUngrouped(btcBlockLimit: number = 3) { updateBlockListManually, setBlockListLoading, clearLatestStxBlocksFromWebSocket, - latestBtcBlocks, + fetchBurnBlocks, ]); const updateBlockListWithQuery = useCallback( diff --git a/src/app/_components/BlockList/data/useHomePageBlockList.ts b/src/app/_components/BlockList/data/useHomePageBlockList.ts index cc9a7c754..1939b8486 100644 --- a/src/app/_components/BlockList/data/useHomePageBlockList.ts +++ b/src/app/_components/BlockList/data/useHomePageBlockList.ts @@ -1,9 +1,9 @@ import { useCallback, useEffect, useRef, useState } from 'react'; +import { useFetchMultipleBurnBlocks } from '../../../../common/queries/useBurnBlock'; import { useBlockListContext } from '../BlockListContext'; import { useBlockListWebSocket } from '../Sockets/useBlockListWebSocket'; import { BlockListData, generateBlockList, mergeBlockLists, waitForFadeAnimation } from '../utils'; -import { useBlockListBtcBlocks } from './useBlockListBtcBlocks'; import { useHomePageInitialBlockList } from './useHomePageInitialBlockList'; import { generateBtcBlocksMap } from './utils'; @@ -35,14 +35,17 @@ export function useHomePageBlockList(btcBlockLimit: number = 3) { clearLatestStxBlocks: clearLatestStxBlocksFromWebSocket, } = useBlockListWebSocket(liveUpdates, initialStxBlocksHashes); - const { btcBlocks: latestBtcBlocks } = useBlockListBtcBlocks(latestStxBlocksFromWebSocket); + const fetchBurnBlocks = useFetchMultipleBurnBlocks(); const showLatestStxBlocksFromWebSocket = useCallback(() => { setBlockListLoading(true); - waitForFadeAnimation(() => { + waitForFadeAnimation(async () => { + const btcBlocks = await fetchBurnBlocks( + latestStxBlocksFromWebSocket.map(block => block.burn_block_hash) + ); const websocketBlockList = generateBlockList( latestStxBlocksFromWebSocket, - generateBtcBlocksMap(latestBtcBlocks) + generateBtcBlocksMap(btcBlocks) ); updateBlockListManually(websocketBlockList); clearLatestStxBlocksFromWebSocket(); @@ -53,7 +56,7 @@ export function useHomePageBlockList(btcBlockLimit: number = 3) { updateBlockListManually, setBlockListLoading, clearLatestStxBlocksFromWebSocket, - latestBtcBlocks, + fetchBurnBlocks, ]); const updateBlockListWithQuery = useCallback( diff --git a/src/app/_components/BlockList/data/useHomePageInitialBlockList.ts b/src/app/_components/BlockList/data/useHomePageInitialBlockList.ts index 6bd9d2cb9..4dc8edce2 100644 --- a/src/app/_components/BlockList/data/useHomePageInitialBlockList.ts +++ b/src/app/_components/BlockList/data/useHomePageInitialBlockList.ts @@ -27,13 +27,13 @@ export function useHomePageInitialBlockList(blockListLimit: number = 3) { const btcBlocksMap = useBtcBlocksMap(btcBlocks); const latestBurnBlockStxBlocks = useSuspenseInfiniteQueryResult( - useSuspenseBlocksByBurnBlock(latestBurnBlock.burn_block_height) + useSuspenseBlocksByBurnBlock(latestBurnBlock.burn_block_height, 3) ); const secondLatestBurnBlockStxBlocks = useSuspenseInfiniteQueryResult( - useSuspenseBlocksByBurnBlock(secondLatestBurnBlock.burn_block_height) + useSuspenseBlocksByBurnBlock(secondLatestBurnBlock.burn_block_height, 3) ); const thirdLatestBurnBlockStxBlocks = useSuspenseInfiniteQueryResult( - useSuspenseBlocksByBurnBlock(thirdLatestBurnBlock.burn_block_height) + useSuspenseBlocksByBurnBlock(thirdLatestBurnBlock.burn_block_height, 3) ); const refetchInitialBlockList = useRefetchInitialBlockList([ diff --git a/src/common/queries/useBurnBlock.ts b/src/common/queries/useBurnBlock.ts index f49bf19df..a15a1e0cb 100644 --- a/src/common/queries/useBurnBlock.ts +++ b/src/common/queries/useBurnBlock.ts @@ -2,6 +2,7 @@ import { UseQueryResult, UseSuspenseQueryResult, useQuery, + useQueryClient, useSuspenseQuery, } from '@tanstack/react-query'; @@ -11,6 +12,43 @@ import { useApi } from '../api/useApi'; export const BURN_BLOCKS_QUERY_KEY = 'burnBlocks'; +export function useFetchBurnBlock(): (heightOrHash: string | number) => Promise { + const api = useApi(); + const queryClient = useQueryClient(); + + return async (heightOrHash: string | number) => { + const queryKey = [BURN_BLOCKS_QUERY_KEY, heightOrHash]; + + const cachedData = queryClient.getQueryData(queryKey); + if (cachedData) { + return cachedData; + } + + // Fetch the data and update the cache + const fetchBurnBlock = async (): Promise => { + return api.burnBlocksApi.getBurnBlock({ heightOrHash }); + }; + + return queryClient.fetchQuery({ + queryKey, + queryFn: fetchBurnBlock, + staleTime: Infinity, + }); + }; +} + +export function useFetchMultipleBurnBlocks(): ( + heightOrHashes: (string | number)[] +) => Promise { + const fetchBurnBlock = useFetchBurnBlock(); + + return async (heightOrHashes: (string | number)[]) => { + const burnBlockPromises = heightOrHashes.map(heightOrHash => fetchBurnBlock(heightOrHash)); + + return await Promise.all(burnBlockPromises); + }; +} + export function useGetBurnBlockQuery() { const api = useApi(); return (heightOrHash: string | number) => ({