mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
data refetching
This commit is contained in:
@@ -7,6 +7,8 @@ SocketMessage.BlocksIndexStatus |
|
||||
SocketMessage.TxStatusUpdate |
|
||||
SocketMessage.NewTx |
|
||||
SocketMessage.NewPendingTx |
|
||||
SocketMessage.AddressTokenBalance |
|
||||
SocketMessage.AddressCoinBalance |
|
||||
SocketMessage.Unknown;
|
||||
|
||||
interface SocketMessageParamsGeneric<Event extends string | undefined, Payload extends object | unknown> {
|
||||
@@ -15,6 +17,16 @@ interface SocketMessageParamsGeneric<Event extends string | undefined, Payload e
|
||||
handler: (payload: Payload) => void;
|
||||
}
|
||||
|
||||
interface AddressCoinBalancePayload {
|
||||
coin_balance: {
|
||||
block_number: number;
|
||||
block_timestamp: string;
|
||||
delta: string;
|
||||
transaction_hash: string | null;
|
||||
value: string;
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace SocketMessage {
|
||||
export type NewBlock = SocketMessageParamsGeneric<'new_block', NewBlockSocketResponse>;
|
||||
@@ -22,5 +34,7 @@ export namespace SocketMessage {
|
||||
export type TxStatusUpdate = SocketMessageParamsGeneric<'collated', NewBlockSocketResponse>;
|
||||
export type NewTx = SocketMessageParamsGeneric<'transaction', { transaction: number }>;
|
||||
export type NewPendingTx = SocketMessageParamsGeneric<'pending_transaction', { pending_transaction: number }>;
|
||||
export type AddressTokenBalance = SocketMessageParamsGeneric<'token_balance', { block_number: number }>;
|
||||
export type AddressCoinBalance = SocketMessageParamsGeneric<'coin_balance', AddressCoinBalancePayload>;
|
||||
export type Unknown = SocketMessageParamsGeneric<undefined, unknown>;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import appConfig from 'configs/app/config';
|
||||
import metamaskIcon from 'icons/metamask.svg';
|
||||
import qrCodeIcon from 'icons/qr_code.svg';
|
||||
import starOutlineIcon from 'icons/star_outline.svg';
|
||||
import walletIcon from 'icons/wallet.svg';
|
||||
import useFetch from 'lib/hooks/useFetch';
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import AddressIcon from 'ui/shared/address/AddressIcon';
|
||||
@@ -23,8 +22,7 @@ import ExternalLink from 'ui/shared/ExternalLink';
|
||||
import HashStringShorten from 'ui/shared/HashStringShorten';
|
||||
|
||||
import AddressDetailsSkeleton from './details/AddressDetailsSkeleton';
|
||||
import TokenSelectDesktop from './tokenSelect/TokenSelectDesktop';
|
||||
import TokenSelectMobile from './tokenSelect/TokenSelectMobile';
|
||||
import TokenSelect from './tokenSelect/TokenSelect';
|
||||
|
||||
interface Props {
|
||||
addressQuery: UseQueryResult<TAddress>;
|
||||
@@ -99,16 +97,7 @@ const AddressDetails = ({ addressQuery }: Props) => {
|
||||
alignSelf="center"
|
||||
py="2px"
|
||||
>
|
||||
{ tokenBalancesQuery.data.length > 0 ? (
|
||||
<>
|
||||
{ isMobile ? <TokenSelectMobile data={ tokenBalancesQuery.data }/> : <TokenSelectDesktop data={ tokenBalancesQuery.data }/> }
|
||||
<Button variant="outline" size="sm" ml={ 3 }>
|
||||
<Icon as={ walletIcon } boxSize={ 5 }/>
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
'-'
|
||||
) }
|
||||
<TokenSelect/>
|
||||
</DetailsInfoItem>
|
||||
<DetailsInfoItem
|
||||
title="Transactions"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Box, Button, Icon, Skeleton } from '@chakra-ui/react';
|
||||
import { useQuery, useQueryClient, useIsFetching } from '@tanstack/react-query';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import type { SocketMessage } from 'lib/socket/types';
|
||||
import type { Address, AddressTokenBalance } from 'types/api/address';
|
||||
import { QueryKeys } from 'types/client/queries';
|
||||
|
||||
import walletIcon from 'icons/wallet.svg';
|
||||
import useFetch from 'lib/hooks/useFetch';
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import useSocketChannel from 'lib/socket/useSocketChannel';
|
||||
import useSocketMessage from 'lib/socket/useSocketMessage';
|
||||
|
||||
import TokenSelectDesktop from './TokenSelectDesktop';
|
||||
import TokenSelectMobile from './TokenSelectMobile';
|
||||
|
||||
const TokenSelect = () => {
|
||||
const router = useRouter();
|
||||
const fetch = useFetch();
|
||||
const isMobile = useIsMobile();
|
||||
const queryClient = useQueryClient();
|
||||
const [ blockNumber, setBlockNumber ] = React.useState<number>();
|
||||
|
||||
const addressQueryData = queryClient.getQueryData<Address>([ QueryKeys.address, router.query.id ]);
|
||||
|
||||
const { data, isError, isLoading, refetch } = useQuery<unknown, unknown, Array<AddressTokenBalance>>(
|
||||
[ QueryKeys.addressTokenBalances, addressQueryData?.hash ],
|
||||
async() => await fetch(`/node-api/addresses/${ addressQueryData?.hash }/token-balances`),
|
||||
{
|
||||
enabled: Boolean(addressQueryData),
|
||||
},
|
||||
);
|
||||
const balancesIsFetching = useIsFetching({ queryKey: [ QueryKeys.addressTokenBalances, addressQueryData?.hash ] });
|
||||
|
||||
const handleTokenBalanceMessage: SocketMessage.AddressTokenBalance['handler'] = React.useCallback((payload) => {
|
||||
if (payload.block_number !== blockNumber) {
|
||||
refetch();
|
||||
setBlockNumber(payload.block_number);
|
||||
}
|
||||
}, [ blockNumber, refetch ]);
|
||||
const handleCoinBalanceMessage: SocketMessage.AddressCoinBalance['handler'] = React.useCallback((payload) => {
|
||||
if (payload.coin_balance.block_number !== blockNumber) {
|
||||
refetch();
|
||||
setBlockNumber(payload.coin_balance.block_number);
|
||||
}
|
||||
}, [ blockNumber, refetch ]);
|
||||
|
||||
const channel = useSocketChannel({
|
||||
topic: `addresses:${ addressQueryData?.hash.toLowerCase() }`,
|
||||
isDisabled: !addressQueryData,
|
||||
});
|
||||
useSocketMessage({
|
||||
channel,
|
||||
event: 'coin_balance',
|
||||
handler: handleCoinBalanceMessage,
|
||||
});
|
||||
useSocketMessage({
|
||||
channel,
|
||||
event: 'token_balance',
|
||||
handler: handleTokenBalanceMessage,
|
||||
});
|
||||
|
||||
const button = (
|
||||
<Button variant="outline" size="sm" ml={ 3 }>
|
||||
<Icon as={ walletIcon } boxSize={ 5 }/>
|
||||
</Button>
|
||||
);
|
||||
|
||||
if (isLoading || balancesIsFetching === 1) {
|
||||
return (
|
||||
<>
|
||||
<Skeleton h={ 8 } w="160px"/>
|
||||
{ data && data.length > 0 && button }
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (isError || data.length === 0) {
|
||||
return <Box py="6px">0</Box>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ isMobile ? <TokenSelectMobile data={ data }/> : <TokenSelectDesktop data={ data }/> }
|
||||
{ button }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TokenSelect);
|
||||
Reference in New Issue
Block a user