Commit f22a079f authored by tom's avatar tom Committed by isstuev

prototype

parent ba3b101e
import React from 'react';
export default function useIsMounted() {
const [ isMounted, setIsMounted ] = React.useState(false);
React.useEffect(() => {
setIsMounted(true);
}, [ ]);
return isMounted;
}
...@@ -11,7 +11,7 @@ import fetchApi from 'nextjs/utils/fetchApi'; ...@@ -11,7 +11,7 @@ import fetchApi from 'nextjs/utils/fetchApi';
import config from 'configs/app'; import config from 'configs/app';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
const Address = dynamic(() => import('ui/pages/Address'), { ssr: false }); import Address from 'ui/pages/Address';
const pathname: Route['pathname'] = '/address/[hash]'; const pathname: Route['pathname'] = '/address/[hash]';
......
...@@ -10,6 +10,7 @@ import type { Transaction, TransactionsSortingField, TransactionsSortingValue, T ...@@ -10,6 +10,7 @@ import type { Transaction, TransactionsSortingField, TransactionsSortingValue, T
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import getFilterValueFromQuery from 'lib/getFilterValueFromQuery'; import getFilterValueFromQuery from 'lib/getFilterValueFromQuery';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useIsMounted from 'lib/hooks/useIsMounted';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
...@@ -49,11 +50,13 @@ type Props = { ...@@ -49,11 +50,13 @@ type Props = {
scrollRef?: React.RefObject<HTMLDivElement>; scrollRef?: React.RefObject<HTMLDivElement>;
// for tests only // for tests only
overloadCount?: number; overloadCount?: number;
onLoad?: () => void;
} }
const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Props) => { const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props) => {
const router = useRouter(); const router = useRouter();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const isMounted = useIsMounted();
const [ socketAlert, setSocketAlert ] = React.useState(''); const [ socketAlert, setSocketAlert ] = React.useState('');
const [ newItemsCount, setNewItemsCount ] = React.useState(0); const [ newItemsCount, setNewItemsCount ] = React.useState(0);
...@@ -79,6 +82,12 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Props) => { ...@@ -79,6 +82,12 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Props) => {
}, },
}); });
React.useEffect(() => {
if (!addressTxsQuery.isPlaceholderData) {
onLoad?.();
}
}, [ addressTxsQuery.isPlaceholderData, onLoad ]);
const handleFilterChange = React.useCallback((val: string | Array<string>) => { const handleFilterChange = React.useCallback((val: string | Array<string>) => {
const newVal = getFilterValue(val); const newVal = getFilterValue(val);
...@@ -156,6 +165,10 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Props) => { ...@@ -156,6 +165,10 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Props) => {
handler: handleNewSocketMessage, handler: handleNewSocketMessage,
}); });
if (!isMounted) {
return null;
}
const filter = ( const filter = (
<AddressTxsFilter <AddressTxsFilter
defaultFilter={ filterValue } defaultFilter={ filterValue }
......
...@@ -39,7 +39,6 @@ import IconSvg from 'ui/shared/IconSvg'; ...@@ -39,7 +39,6 @@ import IconSvg from 'ui/shared/IconSvg';
import NetworkExplorers from 'ui/shared/NetworkExplorers'; import NetworkExplorers from 'ui/shared/NetworkExplorers';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs'; import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
const TOKEN_TABS = [ 'tokens_erc20', 'tokens_nfts', 'tokens_nfts_collection', 'tokens_nfts_list' ]; const TOKEN_TABS = [ 'tokens_erc20', 'tokens_nfts', 'tokens_nfts_collection', 'tokens_nfts_list' ];
...@@ -81,7 +80,7 @@ const AddressPageContent = () => { ...@@ -81,7 +80,7 @@ const AddressPageContent = () => {
id: 'txs', id: 'txs',
title: 'Transactions', title: 'Transactions',
count: addressTabsCountersQuery.data?.transactions_count, count: addressTabsCountersQuery.data?.transactions_count,
component: <AddressTxs scrollRef={ tabsScrollRef }/>, component: ({ onLoad }: { onLoad: () => void }) => <AddressTxs scrollRef={ tabsScrollRef } onLoad={ onLoad }/>,
}, },
txInterpretation.isEnabled && txInterpretation.provider === 'noves' ? txInterpretation.isEnabled && txInterpretation.provider === 'noves' ?
{ {
...@@ -250,10 +249,7 @@ const AddressPageContent = () => { ...@@ -250,10 +249,7 @@ const AddressPageContent = () => {
<AddressDetails addressQuery={ addressQuery } scrollRef={ tabsScrollRef }/> <AddressDetails addressQuery={ addressQuery } scrollRef={ tabsScrollRef }/>
{ /* should stay before tabs to scroll up with pagination */ } { /* should stay before tabs to scroll up with pagination */ }
<Box ref={ tabsScrollRef }></Box> <Box ref={ tabsScrollRef }></Box>
{ (isLoading || addressTabsCountersQuery.isPlaceholderData) ? { content }
<TabsSkeleton tabs={ tabs }/> :
content
}
</> </>
); );
}; };
......
import type { StyleProps, ThemingProps } from '@chakra-ui/react'; import type { StyleProps, ThemingProps } from '@chakra-ui/react';
import { Box, Tab, TabList, useColorModeValue } from '@chakra-ui/react'; import { Box, Skeleton, Tab, TabList, useColorModeValue } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useScrollDirection } from 'lib/contexts/scrollDirection'; import { useScrollDirection } from 'lib/contexts/scrollDirection';
...@@ -24,6 +24,7 @@ interface Props extends TabsProps { ...@@ -24,6 +24,7 @@ interface Props extends TabsProps {
activeTabIndex: number; activeTabIndex: number;
onItemClick: (index: number) => void; onItemClick: (index: number) => void;
themeProps: ThemingProps<'Tabs'>; themeProps: ThemingProps<'Tabs'>;
isLoading: boolean;
} }
const AdaptiveTabsList = (props: Props) => { const AdaptiveTabsList = (props: Props) => {
...@@ -113,8 +114,10 @@ const AdaptiveTabsList = (props: Props) => { ...@@ -113,8 +114,10 @@ const AdaptiveTabsList = (props: Props) => {
}, },
}} }}
> >
<Skeleton isLoaded={ !props.isLoading }>
{ typeof tab.title === 'function' ? tab.title() : tab.title } { typeof tab.title === 'function' ? tab.title() : tab.title }
<TabCounter count={ tab.count }/> <TabCounter count={ tab.count }/>
</Skeleton>
</Tab> </Tab>
); );
}) } }) }
......
...@@ -42,6 +42,7 @@ const TabsWithScroll = ({ ...@@ -42,6 +42,7 @@ const TabsWithScroll = ({
}: Props) => { }: Props) => {
const [ activeTabIndex, setActiveTabIndex ] = useState<number>(defaultTabIndex || 0); const [ activeTabIndex, setActiveTabIndex ] = useState<number>(defaultTabIndex || 0);
const [ screenWidth, setScreenWidth ] = React.useState(isBrowser() ? window.innerWidth : 0); const [ screenWidth, setScreenWidth ] = React.useState(isBrowser() ? window.innerWidth : 0);
const [ isLoading, setIsLoading ] = React.useState(true);
const tabsRef = useRef<HTMLDivElement>(null); const tabsRef = useRef<HTMLDivElement>(null);
...@@ -71,8 +72,20 @@ const TabsWithScroll = ({ ...@@ -71,8 +72,20 @@ const TabsWithScroll = ({
}; };
}, []); }, []);
const handleLoad = React.useCallback(() => {
setIsLoading(false);
}, []);
const renderContent = React.useCallback((component: TabItem['component']) => {
if (typeof component === 'function') {
return component({ onLoad: handleLoad });
}
return component;
}, [ handleLoad ]);
if (tabs.length === 1) { if (tabs.length === 1) {
return <div>{ tabs[0].component }</div>; return <div>{ renderContent(tabs[0].component) }</div>;
} }
return ( return (
...@@ -101,9 +114,10 @@ const TabsWithScroll = ({ ...@@ -101,9 +114,10 @@ const TabsWithScroll = ({
activeTabIndex={ activeTabIndex } activeTabIndex={ activeTabIndex }
onItemClick={ handleTabChange } onItemClick={ handleTabChange }
themeProps={ themeProps } themeProps={ themeProps }
isLoading={ isLoading }
/> />
<TabPanels> <TabPanels>
{ tabsList.map((tab) => <TabPanel padding={ 0 } key={ tab.id }>{ tab.component }</TabPanel>) } { tabsList.map((tab) => <TabPanel padding={ 0 } key={ tab.id }>{ renderContent(tab.component) }</TabPanel>) }
</TabPanels> </TabPanels>
</Tabs> </Tabs>
); );
......
...@@ -4,7 +4,7 @@ export interface TabItem { ...@@ -4,7 +4,7 @@ export interface TabItem {
id: string; id: string;
title: string | (() => React.ReactNode); title: string | (() => React.ReactNode);
count?: number | null; count?: number | null;
component: React.ReactNode; component: React.ReactNode | (({ onLoad }: { onLoad: () => void }) => React.ReactNode);
} }
export type RoutedTab = TabItem & { subTabs?: Array<string> } export type RoutedTab = TabItem & { subTabs?: Array<string> }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment