Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
1fae6db7
Commit
1fae6db7
authored
Apr 15, 2024
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
performance improvement on address page
parent
41a982c6
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
134 additions
and
63 deletions
+134
-63
AddressAccountHistory.tsx
ui/address/AddressAccountHistory.tsx
+8
-1
AddressBlocksValidated.tsx
ui/address/AddressBlocksValidated.tsx
+8
-1
AddressCoinBalance.tsx
ui/address/AddressCoinBalance.tsx
+12
-1
AddressDetails.tsx
ui/address/AddressDetails.tsx
+4
-1
AddressInternalTxs.tsx
ui/address/AddressInternalTxs.tsx
+12
-1
AddressLogs.tsx
ui/address/AddressLogs.tsx
+12
-1
AddressTokenTransfers.tsx
ui/address/AddressTokenTransfers.tsx
+16
-9
AddressTokens.tsx
ui/address/AddressTokens.tsx
+11
-1
AddressTxs.tsx
ui/address/AddressTxs.tsx
+3
-9
AddressUserOps.tsx
ui/address/AddressUserOps.tsx
+8
-1
AddressWithdrawals.tsx
ui/address/AddressWithdrawals.tsx
+12
-1
Address.tsx
ui/pages/Address.tsx
+19
-18
AdaptiveTabsList.tsx
ui/shared/Tabs/AdaptiveTabsList.tsx
+1
-1
RoutedTabs.tsx
ui/shared/Tabs/RoutedTabs.tsx
+3
-1
TabsWithScroll.tsx
ui/shared/Tabs/TabsWithScroll.tsx
+4
-15
types.ts
ui/shared/Tabs/types.ts
+1
-1
No files found.
ui/address/AddressAccountHistory.tsx
View file @
1fae6db7
...
...
@@ -7,6 +7,7 @@ import type { NovesHistoryFilterValue } from 'types/api/noves';
import
{
NovesHistoryFilterValues
}
from
'
types/api/noves
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
NOVES_TRANSLATE
}
from
'
stubs/noves/NovesTranslate
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
...
@@ -25,10 +26,12 @@ const getFilterValue = (getFilterValueFromQuery<NovesHistoryFilterValue>).bind(n
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressAccountHistory
=
({
scrollRef
}:
Props
)
=>
{
const
AddressAccountHistory
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
).
toLowerCase
();
...
...
@@ -49,6 +52,10 @@ const AddressAccountHistory = ({ scrollRef }: Props) => {
setFilterValue
(
newVal
);
},
[
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
actionBar
=
(
<
ActionBar
mt=
{
-
6
}
pb=
{
{
base
:
6
,
md
:
5
}
}
>
<
AccountHistoryFilter
...
...
ui/address/AddressBlocksValidated.tsx
View file @
1fae6db7
...
...
@@ -8,6 +8,7 @@ import type { AddressBlocksValidatedResponse } from 'types/api/address';
import
config
from
'
configs/app
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
...
...
@@ -25,12 +26,14 @@ import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksVali
interface
Props
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressBlocksValidated
=
({
scrollRef
}:
Props
)
=>
{
const
AddressBlocksValidated
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
addressHash
=
String
(
router
.
query
.
hash
);
const
query
=
useQueryWithPages
({
...
...
@@ -84,6 +87,10 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
handler
:
handleNewSocketMessage
,
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
query
.
data
?.
items
?
(
<>
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
...
...
ui/address/AddressCoinBalance.tsx
View file @
1fae6db7
...
...
@@ -6,6 +6,7 @@ import type { SocketMessage } from 'lib/socket/types';
import
type
{
AddressCoinBalanceHistoryResponse
}
from
'
types/api/address
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
...
...
@@ -17,10 +18,16 @@ import SocketAlert from 'ui/shared/SocketAlert';
import
AddressCoinBalanceChart
from
'
./coinBalance/AddressCoinBalanceChart
'
;
import
AddressCoinBalanceHistory
from
'
./coinBalance/AddressCoinBalanceHistory
'
;
const
AddressCoinBalance
=
()
=>
{
type
Props
=
{
isTabsLoading
?:
boolean
;
}
const
AddressCoinBalance
=
({
isTabsLoading
}:
Props
)
=>
{
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
addressHash
=
getQueryParamString
(
router
.
query
.
hash
);
...
...
@@ -78,6 +85,10 @@ const AddressCoinBalance = () => {
handler
:
handleNewSocketMessage
,
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
return
(
<>
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
...
...
ui/address/AddressDetails.tsx
View file @
1fae6db7
...
...
@@ -3,6 +3,7 @@ import { useRouter } from 'next/router';
import
React
from
'
react
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
AddressCounterItem
from
'
ui/address/details/AddressCounterItem
'
;
import
ServiceDegradationWarning
from
'
ui/shared/alerts/ServiceDegradationWarning
'
;
...
...
@@ -60,6 +61,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
has_validated_blocks
:
false
,
}),
[
addressHash
]);
const
isMounted
=
useIsMounted
();
// error handling (except 404 codes)
if
(
addressQuery
.
isError
)
{
if
(
isCustomAppError
(
addressQuery
.
error
))
{
...
...
@@ -74,7 +77,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
const
data
=
addressQuery
.
isError
?
error404Data
:
addressQuery
.
data
;
if
(
!
data
)
{
if
(
!
data
||
!
isMounted
)
{
return
null
;
}
...
...
ui/address/AddressInternalTxs.tsx
View file @
1fae6db7
...
...
@@ -6,6 +6,7 @@ import type { AddressFromToFilter } from 'types/api/address';
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
INTERNAL_TX
}
from
'
stubs/internalTx
'
;
...
...
@@ -22,8 +23,14 @@ import AddressIntTxsList from './internals/AddressIntTxsList';
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
AddressInternalTxs
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressInternalTxs
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
[
filterValue
,
setFilterValue
]
=
React
.
useState
<
AddressFromToFilter
>
(
getFilterValue
(
router
.
query
.
filter
));
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
...
@@ -55,6 +62,10 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
onFilterChange
({
filter
:
newVal
});
},
[
onFilterChange
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
...
...
ui/address/AddressLogs.tsx
View file @
1fae6db7
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
LOG
}
from
'
stubs/log
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
...
@@ -12,8 +13,14 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
const
AddressLogs
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressLogs
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
{
data
,
isPlaceholderData
,
isError
,
pagination
}
=
useQueryWithPages
({
...
...
@@ -41,6 +48,10 @@ const AddressLogs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>
</
ActionBar
>
);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
data
.
items
.
map
((
item
,
index
)
=>
<
LogItem
key=
{
index
}
{
...
item
}
type=
"address"
isLoading=
{
isPlaceholderData
}
/>)
:
null
;
return
(
...
...
ui/address/AddressTokenTransfers.tsx
View file @
1fae6db7
...
...
@@ -13,6 +13,7 @@ import { getResourceKey } from 'lib/api/useApiQuery';
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
...
...
@@ -63,14 +64,16 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
// for tests only
overloadCount
?:
number
;
}
const
AddressTokenTransfers
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
}:
Props
)
=>
{
const
AddressTokenTransfers
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
isMobile
=
useIsMobile
();
const
isMounted
=
useIsMounted
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
);
...
...
@@ -179,6 +182,18 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
handler
:
handleNewSocketMessage
,
});
const
tokenData
=
React
.
useMemo
(()
=>
({
address
:
tokenFilter
||
''
,
name
:
''
,
icon_url
:
''
,
symbol
:
''
,
type
:
'
ERC-20
'
as
const
,
}),
[
tokenFilter
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
numActiveFilters
=
(
filters
.
type
?.
length
||
0
)
+
(
filters
.
filter
?
1
:
0
);
const
isActionBarHidden
=
!
tokenFilter
&&
!
numActiveFilters
&&
!
data
?.
items
.
length
&&
!
currentAddress
;
...
...
@@ -218,14 +233,6 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
</>
)
:
null
;
const
tokenData
=
React
.
useMemo
(()
=>
({
address
:
tokenFilter
||
''
,
name
:
''
,
icon_url
:
''
,
symbol
:
''
,
type
:
'
ERC-20
'
as
const
,
}),
[
tokenFilter
]);
const
tokenFilterComponent
=
tokenFilter
&&
(
<
Flex
alignItems=
"center"
flexWrap=
"wrap"
mb=
{
{
base
:
isActionBarHidden
?
3
:
6
,
lg
:
0
}
}
mr=
{
4
}
>
<
Text
whiteSpace=
"nowrap"
mr=
{
2
}
py=
{
1
}
>
Filtered by token
</
Text
>
...
...
ui/address/AddressTokens.tsx
View file @
1fae6db7
...
...
@@ -9,6 +9,7 @@ import { useAppContext } from 'lib/contexts/app';
import
*
as
cookies
from
'
lib/cookies
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
NFT_TOKEN_TYPE_IDS
}
from
'
lib/token/tokenTypes
'
;
import
{
ADDRESS_TOKEN_BALANCE_ERC_20
,
ADDRESS_NFT_1155
,
ADDRESS_COLLECTION
}
from
'
stubs/address
'
;
...
...
@@ -41,9 +42,14 @@ const TAB_LIST_PROPS_MOBILE = {
const
getTokenFilterValue
=
(
getFilterValuesFromQuery
<
NFTTokenType
>
).
bind
(
null
,
NFT_TOKEN_TYPE_IDS
);
const
AddressTokens
=
()
=>
{
type
Props
=
{
isTabsLoading
?:
boolean
;
}
const
AddressTokens
=
({
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMobile
=
useIsMobile
();
const
isMounted
=
useIsMounted
();
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
...
...
@@ -99,6 +105,10 @@ const AddressTokens = () => {
setTokenTypes
(
value
);
},
[
nftsQuery
,
collectionsQuery
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
nftTypeFilter
=
(
<
PopoverFilter
isActive=
{
tokenTypes
&&
tokenTypes
.
length
>
0
}
contentProps=
{
{
w
:
'
200px
'
}
}
appliedFiltersNum=
{
tokenTypes
?.
length
}
>
<
TokenTypeFilter
<
NFTTokenType
>
nftOnly onChange=
{
handleTokenTypesChange
}
defaultValue=
{
tokenTypes
}
/
>
...
...
ui/address/AddressTxs.tsx
View file @
1fae6db7
...
...
@@ -48,12 +48,12 @@ const matchFilter = (filterValue: AddressFromToFilter, transaction: Transaction,
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
// for tests only
overloadCount
?:
number
;
onLoad
?:
()
=>
void
;
}
const
AddressTxs
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
onLoad
}:
Props
)
=>
{
const
AddressTxs
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
isMounted
=
useIsMounted
();
...
...
@@ -82,12 +82,6 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
},
});
React
.
useEffect
(()
=>
{
if
(
!
addressTxsQuery
.
isPlaceholderData
)
{
onLoad
?.();
}
},
[
addressTxsQuery
.
isPlaceholderData
,
onLoad
]);
const
handleFilterChange
=
React
.
useCallback
((
val
:
string
|
Array
<
string
>
)
=>
{
const
newVal
=
getFilterValue
(
val
);
...
...
@@ -165,7 +159,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
handler: handleNewSocketMessage,
});
if (!isMounted) {
if (!isMounted
|| isTabsLoading
) {
return null;
}
...
...
ui/address/AddressUserOps.tsx
View file @
1fae6db7
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
USER_OPS_ITEM
}
from
'
stubs/userOps
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
...
@@ -9,10 +10,12 @@ import UserOpsContent from 'ui/userOps/UserOpsContent';
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressUserOps
=
({
scrollRef
}:
Props
)
=>
{
const
AddressUserOps
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
...
@@ -29,6 +32,10 @@ const AddressUserOps = ({ scrollRef }: Props) => {
filters
:
{
sender
:
hash
},
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
return
<
UserOpsContent
query=
{
userOpsQuery
}
showSender=
{
false
}
/>;
};
...
...
ui/address/AddressWithdrawals.tsx
View file @
1fae6db7
...
...
@@ -2,6 +2,7 @@ import { Show, Hide } from '@chakra-ui/react';
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
WITHDRAWAL
}
from
'
stubs/withdrawals
'
;
...
...
@@ -12,8 +13,13 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import
BeaconChainWithdrawalsListItem
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsListItem
'
;
import
BeaconChainWithdrawalsTable
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable
'
;
const
AddressWithdrawals
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressWithdrawals
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
...
@@ -28,6 +34,11 @@ const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
}
}),
},
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
...
...
ui/pages/Address.tsx
View file @
1fae6db7
import
{
Box
,
Flex
,
HStack
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
dynamic
from
'
next/dynamic
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
...
...
@@ -17,7 +16,7 @@ import AddressAccountHistory from 'ui/address/AddressAccountHistory';
import
AddressBlocksValidated
from
'
ui/address/AddressBlocksValidated
'
;
import
AddressCoinBalance
from
'
ui/address/AddressCoinBalance
'
;
import
AddressContract
from
'
ui/address/AddressContract
'
;
//
import AddressDetails from 'ui/address/AddressDetails';
import
AddressDetails
from
'
ui/address/AddressDetails
'
;
import
AddressInternalTxs
from
'
ui/address/AddressInternalTxs
'
;
import
AddressLogs
from
'
ui/address/AddressLogs
'
;
import
AddressTokens
from
'
ui/address/AddressTokens
'
;
...
...
@@ -41,8 +40,6 @@ import NetworkExplorers from 'ui/shared/NetworkExplorers';
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
const
AddressDetails
=
dynamic
(()
=>
import
(
'
ui/address/AddressDetails
'
),
{
ssr
:
false
});
const
TOKEN_TABS
=
[
'
tokens_erc20
'
,
'
tokens_nfts
'
,
'
tokens_nfts_collection
'
,
'
tokens_nfts_list
'
];
const
txInterpretation
=
config
.
features
.
txInterpretation
;
...
...
@@ -77,19 +74,22 @@ const AddressPageContent = () => {
const
contractTabs
=
useContractTabs
(
addressQuery
.
data
);
const
isLoading
=
addressQuery
.
isPlaceholderData
||
(
config
.
features
.
userOps
.
isEnabled
&&
userOpsAccountQuery
.
isPlaceholderData
);
const
isTabsLoading
=
isLoading
||
addressTabsCountersQuery
.
isPlaceholderData
;
const
tabs
:
Array
<
RoutedTab
>
=
React
.
useMemo
(()
=>
{
return
[
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
count
:
addressTabsCountersQuery
.
data
?.
transactions_count
,
component
:
({
onLoad
}:
{
onLoad
:
()
=>
void
})
=>
<
AddressTxs
scrollRef=
{
tabsScrollRef
}
onLoad=
{
onLoad
}
/>,
component
:
<
AddressTxs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
txInterpretation
.
isEnabled
&&
txInterpretation
.
provider
===
'
noves
'
?
{
id
:
'
account_history
'
,
title
:
'
Account history
'
,
component
:
<
AddressAccountHistory
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressAccountHistory
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
undefined
,
config
.
features
.
userOps
.
isEnabled
&&
Boolean
(
userOpsAccountQuery
.
data
?.
total_ops
)
?
...
...
@@ -97,7 +97,7 @@ const AddressPageContent = () => {
id
:
'
user_ops
'
,
title
:
'
User operations
'
,
count
:
userOpsAccountQuery
.
data
?.
total_ops
,
component
:
<
AddressUserOps
/>,
component
:
<
AddressUserOps
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
undefined
,
config
.
features
.
beaconChain
.
isEnabled
&&
addressTabsCountersQuery
.
data
?.
withdrawals_count
?
...
...
@@ -105,39 +105,39 @@ const AddressPageContent = () => {
id
:
'
withdrawals
'
,
title
:
'
Withdrawals
'
,
count
:
addressTabsCountersQuery
.
data
?.
withdrawals_count
,
component
:
<
AddressWithdrawals
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressWithdrawals
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
undefined
,
{
id
:
'
token_transfers
'
,
title
:
'
Token transfers
'
,
count
:
addressTabsCountersQuery
.
data
?.
token_transfers_count
,
component
:
<
AddressTokenTransfers
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressTokenTransfers
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
{
id
:
'
tokens
'
,
title
:
'
Tokens
'
,
count
:
addressTabsCountersQuery
.
data
?.
token_balances_count
,
component
:
<
AddressTokens
/>,
component
:
<
AddressTokens
isTabsLoading=
{
isTabsLoading
}
/>,
subTabs
:
TOKEN_TABS
,
},
{
id
:
'
internal_txns
'
,
title
:
'
Internal txns
'
,
count
:
addressTabsCountersQuery
.
data
?.
internal_txs_count
,
component
:
<
AddressInternalTxs
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressInternalTxs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
{
id
:
'
coin_balance_history
'
,
title
:
'
Coin balance history
'
,
component
:
<
AddressCoinBalance
/>,
component
:
<
AddressCoinBalance
isTabsLoading=
{
isTabsLoading
}
/>,
},
config
.
chain
.
verificationType
===
'
validation
'
&&
addressTabsCountersQuery
.
data
?.
validations_count
?
{
id
:
'
blocks_validated
'
,
title
:
'
Blocks validated
'
,
count
:
addressTabsCountersQuery
.
data
?.
validations_count
,
component
:
<
AddressBlocksValidated
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressBlocksValidated
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
undefined
,
addressTabsCountersQuery
.
data
?.
logs_count
?
...
...
@@ -145,9 +145,10 @@ const AddressPageContent = () => {
id
:
'
logs
'
,
title
:
'
Logs
'
,
count
:
addressTabsCountersQuery
.
data
?.
logs_count
,
component
:
<
AddressLogs
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressLogs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
undefined
,
addressQuery
.
data
?.
is_contract
?
{
id
:
'
contract
'
,
title
:
()
=>
{
...
...
@@ -166,9 +167,7 @@ const AddressPageContent = () => {
subTabs
:
contractTabs
.
map
(
tab
=>
tab
.
id
),
}
:
undefined
,
].
filter
(
Boolean
);
},
[
addressQuery
.
data
,
contractTabs
,
addressTabsCountersQuery
.
data
,
userOpsAccountQuery
.
data
]);
const
isLoading
=
addressQuery
.
isPlaceholderData
||
(
config
.
features
.
userOps
.
isEnabled
&&
userOpsAccountQuery
.
isPlaceholderData
);
},
[
addressQuery
.
data
,
contractTabs
,
addressTabsCountersQuery
.
data
,
userOpsAccountQuery
.
data
,
isTabsLoading
]);
const
tags
=
(
<
EntityTags
...
...
@@ -185,7 +184,9 @@ const AddressPageContent = () => {
/>
);
const
content
=
(
addressQuery
.
isError
||
addressQuery
.
isDegradedData
)
?
null
:
<
RoutedTabs
tabs=
{
tabs
}
tabListProps=
{
{
mt
:
8
}
}
/>;
const
content
=
(
addressQuery
.
isError
||
addressQuery
.
isDegradedData
)
?
null
:
<
RoutedTabs
tabs=
{
tabs
}
tabListProps=
{
{
mt
:
8
}
}
isLoading=
{
isLoading
||
addressTabsCountersQuery
.
isPlaceholderData
}
/>;
const
backLink
=
React
.
useMemo
(()
=>
{
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/accounts
'
);
...
...
ui/shared/Tabs/AdaptiveTabsList.tsx
View file @
1fae6db7
...
...
@@ -24,7 +24,7 @@ interface Props extends TabsProps {
activeTabIndex
:
number
;
onItemClick
:
(
index
:
number
)
=>
void
;
themeProps
:
ThemingProps
<
'
Tabs
'
>
;
isLoading
:
boolean
;
isLoading
?
:
boolean
;
}
const
AdaptiveTabsList
=
(
props
:
Props
)
=>
{
...
...
ui/shared/Tabs/RoutedTabs.tsx
View file @
1fae6db7
...
...
@@ -17,9 +17,10 @@ interface Props extends ThemingProps<'Tabs'> {
stickyEnabled
?:
boolean
;
className
?:
string
;
onTabChange
?:
(
index
:
number
)
=>
void
;
isLoading
?:
boolean
;
}
const
RoutedTabs
=
({
tabs
,
tabListProps
,
rightSlot
,
rightSlotProps
,
stickyEnabled
,
className
,
onTabChange
,
...
themeProps
}:
Props
)
=>
{
const
RoutedTabs
=
({
tabs
,
tabListProps
,
rightSlot
,
rightSlotProps
,
stickyEnabled
,
className
,
onTabChange
,
isLoading
,
...
themeProps
}:
Props
)
=>
{
const
router
=
useRouter
();
const
tabIndex
=
useTabIndexFromQuery
(
tabs
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
...
@@ -63,6 +64,7 @@ const RoutedTabs = ({ tabs, tabListProps, rightSlot, rightSlotProps, stickyEnabl
stickyEnabled=
{
stickyEnabled
}
onTabChange=
{
handleTabChange
}
defaultTabIndex=
{
tabIndex
}
isLoading=
{
isLoading
}
{
...
themeProps
}
/>
);
...
...
ui/shared/Tabs/TabsWithScroll.tsx
View file @
1fae6db7
...
...
@@ -25,6 +25,7 @@ export interface Props extends ThemingProps<'Tabs'> {
stickyEnabled
?:
boolean
;
onTabChange
?:
(
index
:
number
)
=>
void
;
defaultTabIndex
?:
number
;
isLoading
?:
boolean
;
className
?:
string
;
}
...
...
@@ -37,12 +38,12 @@ const TabsWithScroll = ({
stickyEnabled
,
onTabChange
,
defaultTabIndex
,
isLoading
,
className
,
...
themeProps
}:
Props
)
=>
{
const
[
activeTabIndex
,
setActiveTabIndex
]
=
useState
<
number
>
(
defaultTabIndex
||
0
);
const
[
screenWidth
,
setScreenWidth
]
=
React
.
useState
(
isBrowser
()
?
window
.
innerWidth
:
0
);
const
[
isLoading
,
setIsLoading
]
=
React
.
useState
(
true
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
...
@@ -72,20 +73,8 @@ 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
)
{
return
<
div
>
{
renderContent
(
tabs
[
0
].
component
)
}
</
div
>;
return
<
div
>
{
tabs
[
0
].
component
}
</
div
>;
}
return
(
...
...
@@ -117,7 +106,7 @@ const TabsWithScroll = ({
isLoading=
{
isLoading
}
/>
<
TabPanels
>
{
tabsList
.
map
((
tab
)
=>
<
TabPanel
padding=
{
0
}
key=
{
tab
.
id
}
>
{
renderContent
(
tab
.
component
)
}
</
TabPanel
>)
}
{
tabsList
.
map
((
tab
)
=>
<
TabPanel
padding=
{
0
}
key=
{
tab
.
id
}
>
{
tab
.
component
}
</
TabPanel
>)
}
</
TabPanels
>
</
Tabs
>
);
...
...
ui/shared/Tabs/types.ts
View file @
1fae6db7
...
...
@@ -4,7 +4,7 @@ export interface TabItem {
id
:
string
;
title
:
string
|
(()
=>
React
.
ReactNode
);
count
?:
number
|
null
;
component
:
React
.
ReactNode
|
(({
onLoad
}:
{
onLoad
:
()
=>
void
})
=>
React
.
ReactNode
)
;
component
:
React
.
ReactNode
;
}
export
type
RoutedTab
=
TabItem
&
{
subTabs
?:
Array
<
string
>
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment