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
8071589e
Commit
8071589e
authored
May 25, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
skeletons for stats
parent
4f948605
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
181 additions
and
357 deletions
+181
-357
.env.goerli
configs/envs/.env.goerli
+1
-1
stats.ts
stubs/stats.ts
+36
-1
AddressBlocksValidatedListItem.tsx
...ddress/blocksValidated/AddressBlocksValidatedListItem.tsx
+2
-2
AddressCoinBalanceChart.tsx
ui/address/coinBalance/AddressCoinBalanceChart.tsx
+1
-1
AddressCoinBalanceListItem.tsx
ui/address/coinBalance/AddressCoinBalanceListItem.tsx
+1
-1
Stats.tsx
ui/pages/Stats.tsx
+4
-4
ChartWidget.tsx
ui/shared/chart/ChartWidget.tsx
+86
-95
ChartWidgetSkeleton.tsx
ui/shared/chart/ChartWidgetSkeleton.tsx
+0
-22
ChartWidgetContainer.tsx
ui/stats/ChartWidgetContainer.tsx
+7
-1
ChartsWidgetsList.tsx
ui/stats/ChartsWidgetsList.tsx
+18
-49
useStats.tsx
ui/stats/useStats.tsx
+20
-19
TokenDetailsVerifiedInfo.tsx
ui/token/TokenDetails/TokenDetailsVerifiedInfo.tsx
+0
-156
TokenTransferListItem.tsx
ui/token/TokenTransfer/TokenTransferListItem.tsx
+1
-1
TokensListItem.tsx
ui/tokens/TokensListItem.tsx
+2
-2
TxInternalsListItem.tsx
ui/tx/internals/TxInternalsListItem.tsx
+2
-2
No files found.
configs/envs/.env.goerli
View file @
8071589e
...
@@ -26,4 +26,4 @@ NEXT_PUBLIC_HAS_BEACON_CHAIN=false
...
@@ -26,4 +26,4 @@ NEXT_PUBLIC_HAS_BEACON_CHAIN=false
# api config
# api config
NEXT_PUBLIC_API_HOST=blockscout-main.test.aws-k8s.blockscout.com
NEXT_PUBLIC_API_HOST=blockscout-main.test.aws-k8s.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_STATS_API_HOST=https://stats-
test.aws-k8s
.blockscout.com
NEXT_PUBLIC_STATS_API_HOST=https://stats-
goerli.k8s-dev
.blockscout.com
stubs/stats.ts
View file @
8071589e
import
type
{
HomeStats
}
from
'
types/api/stats
'
;
import
type
{
HomeStats
,
StatsChartsSection
}
from
'
types/api/stats
'
;
export
const
HOMEPAGE_STATS
:
HomeStats
=
{
export
const
HOMEPAGE_STATS
:
HomeStats
=
{
average_block_time
:
14346
,
average_block_time
:
14346
,
...
@@ -18,3 +18,38 @@ export const HOMEPAGE_STATS: HomeStats = {
...
@@ -18,3 +18,38 @@ export const HOMEPAGE_STATS: HomeStats = {
total_transactions
:
'
193823272
'
,
total_transactions
:
'
193823272
'
,
transactions_today
:
'
0
'
,
transactions_today
:
'
0
'
,
};
};
export
const
STATS_CHARTS_SECTION
:
StatsChartsSection
=
{
id
:
'
placeholder
'
,
title
:
'
Placeholder
'
,
charts
:
[
{
id
:
'
chart_0
'
,
title
:
'
Average transaction fee
'
,
description
:
'
The average amount in ETH spent per transaction
'
,
units
:
'
ETH
'
,
},
{
id
:
'
chart_1
'
,
title
:
'
Transactions fees
'
,
description
:
'
Amount of tokens paid as fees
'
,
units
:
'
ETH
'
,
},
{
id
:
'
chart_2
'
,
title
:
'
New transactions
'
,
description
:
'
New transactions number
'
,
units
:
null
,
},
{
id
:
'
chart_3
'
,
title
:
'
Transactions growth
'
,
description
:
'
Cumulative transactions number
'
,
units
:
null
,
},
],
};
export
const
STATS_CHARTS
=
{
sections
:
[
STATS_CHARTS_SECTION
],
};
ui/address/blocksValidated/AddressBlocksValidatedListItem.tsx
View file @
8071589e
...
@@ -40,7 +40,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
...
@@ -40,7 +40,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
</
Flex
>
</
Flex
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Gas used
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Gas used
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
variant=
"
secondary"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
color=
"text_
secondary"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
<
Utilization
<
Utilization
colorScheme=
"gray"
colorScheme=
"gray"
value=
{
BigNumber
(
props
.
gas_used
||
0
).
dividedBy
(
BigNumber
(
props
.
gas_limit
)).
toNumber
()
}
value=
{
BigNumber
(
props
.
gas_used
||
0
).
dividedBy
(
BigNumber
(
props
.
gas_limit
)).
toNumber
()
}
...
@@ -49,7 +49,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
...
@@ -49,7 +49,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
</
Flex
>
</
Flex
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Reward
{
appConfig
.
network
.
currency
.
symbol
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Reward
{
appConfig
.
network
.
currency
.
symbol
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
variant=
"
secondary"
>
{
totalReward
.
toFixed
()
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
color=
"text_
secondary"
>
{
totalReward
.
toFixed
()
}
</
Skeleton
>
</
Flex
>
</
Flex
>
</
ListItemMobile
>
</
ListItemMobile
>
);
);
...
...
ui/address/coinBalance/AddressCoinBalanceChart.tsx
View file @
8071589e
...
@@ -25,7 +25,7 @@ const AddressCoinBalanceChart = ({ addressHash }: Props) => {
...
@@ -25,7 +25,7 @@ const AddressCoinBalanceChart = ({ addressHash }: Props) => {
title=
"Balances"
title=
"Balances"
items=
{
items
}
items=
{
items
}
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
h=
"
25
0px"
h=
"
30
0px"
/>
/>
);
);
};
};
...
...
ui/address/coinBalance/AddressCoinBalanceListItem.tsx
View file @
8071589e
...
@@ -57,7 +57,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
...
@@ -57,7 +57,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
)
}
)
}
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Age
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Age
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
variant=
"
secondary"
>
{
timeAgo
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
color=
"text_
secondary"
>
{
timeAgo
}
</
Skeleton
>
</
Flex
>
</
Flex
>
</
ListItemMobile
>
</
ListItemMobile
>
);
);
...
...
ui/pages/Stats.tsx
View file @
8071589e
...
@@ -12,14 +12,14 @@ import useStats from '../stats/useStats';
...
@@ -12,14 +12,14 @@ import useStats from '../stats/useStats';
const
Stats
=
()
=>
{
const
Stats
=
()
=>
{
const
{
const
{
is
Loading
,
is
PlaceholderData
,
isError
,
isError
,
sections
,
sections
,
currentSection
,
currentSection
,
handleSectionChange
,
handleSectionChange
,
interval
,
interval
,
handleIntervalChange
,
handleIntervalChange
,
debounceFilterCharts
,
handleFilterChange
,
displayedCharts
,
displayedCharts
,
filterQuery
,
filterQuery
,
}
=
useStats
();
}
=
useStats
();
...
@@ -39,14 +39,14 @@ const Stats = () => {
...
@@ -39,14 +39,14 @@ const Stats = () => {
onSectionChange=
{
handleSectionChange
}
onSectionChange=
{
handleSectionChange
}
interval=
{
interval
}
interval=
{
interval
}
onIntervalChange=
{
handleIntervalChange
}
onIntervalChange=
{
handleIntervalChange
}
onFilterInputChange=
{
debounceFilterCharts
}
onFilterInputChange=
{
handleFilterChange
}
/>
/>
</
Box
>
</
Box
>
<
ChartsWidgetsList
<
ChartsWidgetsList
filterQuery=
{
filterQuery
}
filterQuery=
{
filterQuery
}
isError=
{
isError
}
isError=
{
isError
}
is
Loading=
{
isLoading
}
is
PlaceholderData=
{
isPlaceholderData
}
charts=
{
displayedCharts
}
charts=
{
displayedCharts
}
interval=
{
interval
}
interval=
{
interval
}
/>
/>
...
...
ui/shared/chart/ChartWidget.tsx
View file @
8071589e
...
@@ -3,13 +3,13 @@ import {
...
@@ -3,13 +3,13 @@ import {
Center
,
Center
,
chakra
,
chakra
,
Flex
,
Flex
,
Grid
,
Icon
,
Icon
,
IconButton
,
Link
,
IconButton
,
Link
,
Menu
,
Menu
,
MenuButton
,
MenuButton
,
MenuItem
,
MenuItem
,
MenuList
,
MenuList
,
Skeleton
,
Text
,
Text
,
Tooltip
,
Tooltip
,
useColorModeValue
,
useColorModeValue
,
...
@@ -30,7 +30,6 @@ import { apos } from 'lib/html-entities';
...
@@ -30,7 +30,6 @@ import { apos } from 'lib/html-entities';
import
saveAsCSV
from
'
lib/saveAsCSV
'
;
import
saveAsCSV
from
'
lib/saveAsCSV
'
;
import
ChartWidgetGraph
from
'
./ChartWidgetGraph
'
;
import
ChartWidgetGraph
from
'
./ChartWidgetGraph
'
;
import
ChartWidgetSkeleton
from
'
./ChartWidgetSkeleton
'
;
import
FullscreenChartModal
from
'
./FullscreenChartModal
'
;
import
FullscreenChartModal
from
'
./FullscreenChartModal
'
;
export
type
Props
=
{
export
type
Props
=
{
...
@@ -110,10 +109,6 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
...
@@ -110,10 +109,6 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
}
}
},
[
items
,
title
]);
},
[
items
,
title
]);
if
(
isLoading
)
{
return
<
ChartWidgetSkeleton
hasDescription=
{
Boolean
(
description
)
}
/>;
}
const
hasItems
=
items
&&
items
.
length
>
2
;
const
hasItems
=
items
&&
items
.
length
>
2
;
const
content
=
(()
=>
{
const
content
=
(()
=>
{
...
@@ -137,6 +132,10 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
...
@@ -137,6 +132,10 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
);
);
}
}
if
(
isLoading
)
{
return
<
Skeleton
flexGrow=
{
1
}
w=
"100%"
/>;
}
if
(
!
hasItems
)
{
if
(
!
hasItems
)
{
return
(
return
(
<
Center
flexGrow=
{
1
}
>
<
Center
flexGrow=
{
1
}
>
...
@@ -146,7 +145,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
...
@@ -146,7 +145,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
}
}
return
(
return
(
<
Box
h=
"100%"
maxW=
"100%"
>
<
Box
flexGrow=
{
1
}
maxW=
"100%"
>
<
ChartWidgetGraph
<
ChartWidgetGraph
items=
{
items
}
items=
{
items
}
onZoom=
{
handleZoom
}
onZoom=
{
handleZoom
}
...
@@ -160,112 +159,104 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
...
@@ -160,112 +159,104 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError,
return
(
return
(
<>
<>
<
Bo
x
<
Fle
x
height=
"100%"
height=
"100%"
display=
"flex"
flexDirection=
"column"
ref=
{
ref
}
ref=
{
ref
}
flexDir=
"column"
padding=
{
{
base
:
3
,
lg
:
4
}
}
padding=
{
{
base
:
3
,
lg
:
4
}
}
borderRadius=
"md"
borderRadius=
"md"
border=
"1px"
border=
"1px"
borderColor=
{
borderColor
}
borderColor=
{
borderColor
}
className=
{
className
}
className=
{
className
}
>
>
<
Grid
<
Flex
columnGap=
{
6
}
mb=
{
1
}
alignItems=
"flex-start"
>
gridTemplateColumns=
"auto auto 36px"
<
Flex
flexGrow=
{
1
}
flexDir=
"column"
alignItems=
"flex-start"
>
gridColumnGap=
{
2
}
<
Skeleton
>
isLoaded=
{
!
isLoading
}
<
Text
fontWeight=
{
600
}
fontWeight=
{
600
}
size=
{
{
base
:
'
xs
'
,
lg
:
'
sm
'
}
}
fontSize=
"md"
lineHeight=
{
6
}
as=
"p"
size=
{
{
base
:
'
xs
'
,
lg
:
'
sm
'
}
}
>
{
title
}
</
Text
>
{
description
&&
(
<
Text
mb=
{
1
}
gridColumn=
{
1
}
as=
"p"
variant=
"secondary"
fontSize=
"xs"
>
>
{
description
}
{
title
}
</
Text
>
</
Skeleton
>
)
}
<
Tooltip
label=
"Reset zoom"
>
<
IconButton
hidden=
{
isZoomResetInitial
}
aria
-
label=
"Reset zoom"
colorScheme=
"blue"
w=
{
9
}
h=
{
8
}
gridColumn=
{
2
}
justifySelf=
"end"
alignSelf=
"top"
gridRow=
"1/3"
size=
"sm"
variant=
"outline"
onClick=
{
handleZoomResetClick
}
icon=
{
<
Icon
as=
{
repeatArrowIcon
}
w=
{
4
}
h=
{
4
}
/>
}
/>
</
Tooltip
>
{
hasItems
&&
(
{
description
&&
(
<
Menu
>
<
Skeleton
<
MenuButton
isLoaded=
{
!
isLoading
}
gridColumn=
{
3
}
color=
"text_secondary"
gridRow=
"1/3"
fontSize=
"xs"
justifySelf=
"end"
mt=
{
1
}
w=
"36px"
h=
"32px"
icon=
{
<
Icon
as=
{
dotsIcon
}
w=
{
4
}
h=
{
4
}
/>
}
colorScheme=
"gray"
variant=
"ghost"
as=
{
IconButton
}
>
>
<
VisuallyHidden
>
<
span
>
{
description
}
</
span
>
Open chart options menu
</
Skeleton
>
</
VisuallyHidden
>
)
}
</
MenuButton
>
</
Flex
>
<
MenuList
>
<
MenuItem
<
Flex
ml=
"auto"
columnGap=
{
2
}
>
display=
"flex"
<
Tooltip
label=
"Reset zoom"
>
alignItems=
"center"
<
IconButton
onClick=
{
showChartFullscreen
}
hidden=
{
isZoomResetInitial
}
>
aria
-
label=
"Reset zoom"
<
Icon
as=
{
scopeIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
colorScheme=
"blue"
w=
{
9
}
h=
{
8
}
size=
"sm"
variant=
"outline"
onClick=
{
handleZoomResetClick
}
icon=
{
<
Icon
as=
{
repeatArrowIcon
}
w=
{
4
}
h=
{
4
}
/>
}
/>
</
Tooltip
>
{
hasItems
&&
(
<
Menu
>
<
Skeleton
isLoaded=
{
!
isLoading
}
borderRadius=
"base"
>
<
MenuButton
w=
"36px"
h=
"32px"
icon=
{
<
Icon
as=
{
dotsIcon
}
w=
{
4
}
h=
{
4
}
/>
}
colorScheme=
"gray"
variant=
"ghost"
as=
{
IconButton
}
>
<
VisuallyHidden
>
Open chart options menu
</
VisuallyHidden
>
</
MenuButton
>
</
Skeleton
>
<
MenuList
>
<
MenuItem
display=
"flex"
alignItems=
"center"
onClick=
{
showChartFullscreen
}
>
<
Icon
as=
{
scopeIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
View fullscreen
View fullscreen
</
MenuItem
>
</
MenuItem
>
<
MenuItem
<
MenuItem
display=
"flex"
display=
"flex"
alignItems=
"center"
alignItems=
"center"
onClick=
{
handleFileSaveClick
}
onClick=
{
handleFileSaveClick
}
>
>
<
Icon
as=
{
imageIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
<
Icon
as=
{
imageIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
Save as PNG
Save as PNG
</
MenuItem
>
</
MenuItem
>
<
MenuItem
<
MenuItem
display=
"flex"
display=
"flex"
alignItems=
"center"
alignItems=
"center"
onClick=
{
handleSVGSavingClick
}
onClick=
{
handleSVGSavingClick
}
>
>
<
Icon
as=
{
svgFileIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
<
Icon
as=
{
svgFileIcon
}
boxSize=
{
5
}
mr=
{
3
}
/>
Save as CSV
Save as CSV
</
MenuItem
>
</
MenuItem
>
</
MenuList
>
</
MenuList
>
</
Menu
>
</
Menu
>
)
}
)
}
</
Grid
>
</
Flex
>
</
Flex
>
{
content
}
{
content
}
</
Bo
x
>
</
Fle
x
>
{
hasItems
&&
(
{
hasItems
&&
(
<
FullscreenChartModal
<
FullscreenChartModal
...
...
ui/shared/chart/ChartWidgetSkeleton.tsx
deleted
100644 → 0
View file @
4f948605
import
{
Box
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
interface
Props
{
hasDescription
:
boolean
;
}
const
ChartWidgetSkeleton
=
({
hasDescription
}:
Props
)
=>
{
return
(
<
Box
height=
"235px"
paddingY=
{
{
base
:
3
,
lg
:
4
}
}
>
<
Skeleton
w=
"75%"
h=
"24px"
/>
{
hasDescription
&&
<
Skeleton
w=
"50%"
h=
"18px"
mt=
{
1
}
/>
}
<
Skeleton
w=
"100%"
h=
"150px"
mt=
{
5
}
/>
</
Box
>
);
};
export
default
ChartWidgetSkeleton
;
ui/stats/ChartWidgetContainer.tsx
View file @
8071589e
...
@@ -14,13 +14,14 @@ type Props = {
...
@@ -14,13 +14,14 @@ type Props = {
units
?:
string
;
units
?:
string
;
interval
:
StatsIntervalIds
;
interval
:
StatsIntervalIds
;
onLoadingError
:
()
=>
void
;
onLoadingError
:
()
=>
void
;
isPlaceholderData
:
boolean
;
}
}
function
formatDate
(
date
:
Date
)
{
function
formatDate
(
date
:
Date
)
{
return
date
.
toISOString
().
substring
(
0
,
10
);
return
date
.
toISOString
().
substring
(
0
,
10
);
}
}
const
ChartWidgetContainer
=
({
id
,
title
,
description
,
interval
,
onLoadingError
,
units
}:
Props
)
=>
{
const
ChartWidgetContainer
=
({
id
,
title
,
description
,
interval
,
onLoadingError
,
units
,
isPlaceholderData
}:
Props
)
=>
{
const
selectedInterval
=
STATS_INTERVALS
[
interval
];
const
selectedInterval
=
STATS_INTERVALS
[
interval
];
const
endDate
=
selectedInterval
.
start
?
formatDate
(
new
Date
())
:
undefined
;
const
endDate
=
selectedInterval
.
start
?
formatDate
(
new
Date
())
:
undefined
;
...
@@ -32,6 +33,10 @@ const ChartWidgetContainer = ({ id, title, description, interval, onLoadingError
...
@@ -32,6 +33,10 @@ const ChartWidgetContainer = ({ id, title, description, interval, onLoadingError
from
:
startDate
,
from
:
startDate
,
to
:
endDate
,
to
:
endDate
,
},
},
queryOptions
:
{
enabled
:
!
isPlaceholderData
,
refetchOnMount
:
false
,
},
});
});
const
items
=
useMemo
(()
=>
data
?.
chart
?.
map
((
item
)
=>
{
const
items
=
useMemo
(()
=>
data
?.
chart
?.
map
((
item
)
=>
{
...
@@ -52,6 +57,7 @@ const ChartWidgetContainer = ({ id, title, description, interval, onLoadingError
...
@@ -52,6 +57,7 @@ const ChartWidgetContainer = ({ id, title, description, interval, onLoadingError
units=
{
units
}
units=
{
units
}
description=
{
description
}
description=
{
description
}
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
minH=
"230px"
/>
/>
);
);
};
};
...
...
ui/stats/ChartsWidgetsList.tsx
View file @
8071589e
import
{
Box
,
Grid
,
GridItem
,
Heading
,
List
,
ListItem
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Grid
,
Heading
,
List
,
ListItem
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
type
{
StatsChartsSection
}
from
'
types/api/stats
'
;
import
type
{
StatsChartsSection
}
from
'
types/api/stats
'
;
import
type
{
StatsIntervalIds
}
from
'
types/client/stats
'
;
import
type
{
StatsIntervalIds
}
from
'
types/client/stats
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
ChartWidgetSkeleton
from
'
ui/shared/chart/ChartWidgetSkeleton
'
;
import
EmptySearchResult
from
'
ui/shared/EmptySearchResult
'
;
import
EmptySearchResult
from
'
ui/shared/EmptySearchResult
'
;
import
ChartsLoadingErrorAlert
from
'
./ChartsLoadingErrorAlert
'
;
import
ChartsLoadingErrorAlert
from
'
./ChartsLoadingErrorAlert
'
;
...
@@ -14,14 +13,12 @@ import ChartWidgetContainer from './ChartWidgetContainer';
...
@@ -14,14 +13,12 @@ import ChartWidgetContainer from './ChartWidgetContainer';
type
Props
=
{
type
Props
=
{
filterQuery
:
string
;
filterQuery
:
string
;
isError
:
boolean
;
isError
:
boolean
;
is
Loading
:
boolean
;
is
PlaceholderData
:
boolean
;
charts
?:
Array
<
StatsChartsSection
>
;
charts
?:
Array
<
StatsChartsSection
>
;
interval
:
StatsIntervalIds
;
interval
:
StatsIntervalIds
;
}
}
const
skeletonsCount
=
4
;
const
ChartsWidgetsList
=
({
filterQuery
,
isError
,
isPlaceholderData
,
charts
,
interval
}:
Props
)
=>
{
const
ChartsWidgetsList
=
({
filterQuery
,
isError
,
isLoading
,
charts
,
interval
}:
Props
)
=>
{
const
[
isSomeChartLoadingError
,
setIsSomeChartLoadingError
]
=
useState
(
false
);
const
[
isSomeChartLoadingError
,
setIsSomeChartLoadingError
]
=
useState
(
false
);
const
isAnyChartDisplayed
=
charts
?.
some
((
section
)
=>
section
.
charts
.
length
>
0
);
const
isAnyChartDisplayed
=
charts
?.
some
((
section
)
=>
section
.
charts
.
length
>
0
);
const
isEmptyChartList
=
Boolean
(
filterQuery
)
&&
!
isAnyChartDisplayed
;
const
isEmptyChartList
=
Boolean
(
filterQuery
)
&&
!
isAnyChartDisplayed
;
...
@@ -30,29 +27,6 @@ const ChartsWidgetsList = ({ filterQuery, isError, isLoading, charts, interval }
...
@@ -30,29 +27,6 @@ const ChartsWidgetsList = ({ filterQuery, isError, isLoading, charts, interval }
()
=>
setIsSomeChartLoadingError
(
true
),
()
=>
setIsSomeChartLoadingError
(
true
),
[
setIsSomeChartLoadingError
]);
[
setIsSomeChartLoadingError
]);
const
skeletonElement
=
[
...
Array
(
skeletonsCount
)
]
.
map
((
e
,
i
)
=>
(
<
GridItem
key=
{
i
}
>
<
ChartWidgetSkeleton
hasDescription=
{
true
}
/>
</
GridItem
>
));
if
(
isLoading
)
{
return
(
<>
<
Skeleton
w=
"30%"
h=
"32px"
mb=
{
4
}
/>
<
Grid
templateColumns=
{
{
lg
:
'
repeat(2, minmax(0, 1fr))
'
,
}
}
gap=
{
4
}
>
{
skeletonElement
}
</
Grid
>
</>
);
}
if
(
isError
)
{
if
(
isError
)
{
return
<
ChartsLoadingErrorAlert
/>;
return
<
ChartsLoadingErrorAlert
/>;
}
}
...
@@ -77,32 +51,27 @@ const ChartsWidgetsList = ({ filterQuery, isError, isLoading, charts, interval }
...
@@ -77,32 +51,27 @@ const ChartsWidgetsList = ({ filterQuery, isError, isLoading, charts, interval }
marginBottom
:
0
,
marginBottom
:
0
,
}
}
}
}
>
>
<
Heading
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
mb=
{
4
}
display=
"inline-block"
>
size=
"md"
<
Heading
size=
"md"
>
mb=
{
4
}
{
section
.
title
}
>
</
Heading
>
{
section
.
title
}
</
Skeleton
>
</
Heading
>
<
Grid
<
Grid
templateColumns=
{
{
templateColumns=
{
{
lg
:
'
repeat(2, minmax(0, 1fr))
'
}
}
lg
:
'
repeat(2, minmax(0, 1fr))
'
,
}
}
gap=
{
4
}
gap=
{
4
}
>
>
{
section
.
charts
.
map
((
chart
)
=>
(
{
section
.
charts
.
map
((
chart
)
=>
(
<
GridItem
<
ChartWidgetContainer
key=
{
chart
.
id
}
key=
{
chart
.
id
}
>
id=
{
chart
.
id
}
<
ChartWidgetContainer
title=
{
chart
.
title
}
id=
{
chart
.
id
}
description=
{
chart
.
description
}
title=
{
chart
.
title
}
interval=
{
interval
}
description=
{
chart
.
description
}
units=
{
chart
.
units
||
undefined
}
interval=
{
interval
}
isPlaceholderData=
{
isPlaceholderData
}
units=
{
chart
.
units
||
undefined
}
onLoadingError=
{
handleChartLoadingError
}
onLoadingError=
{
handleChartLoadingError
}
/>
/>
</
GridItem
>
))
}
))
}
</
Grid
>
</
Grid
>
</
ListItem
>
</
ListItem
>
...
...
ui/stats/useStats.tsx
View file @
8071589e
import
debounce
from
'
lodash/debounce
'
;
import
React
,
{
useCallback
,
useMemo
,
useState
}
from
'
react
'
;
import
React
,
{
useCallback
,
useEffect
,
useMemo
,
useState
}
from
'
react
'
;
import
type
{
StatsChartInfo
,
StatsChartsSection
}
from
'
types/api/stats
'
;
import
type
{
StatsChartInfo
,
StatsChartsSection
}
from
'
types/api/stats
'
;
import
type
{
StatsIntervalIds
}
from
'
types/client/stats
'
;
import
type
{
StatsIntervalIds
}
from
'
types/client/stats
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
{
STATS_CHARTS
}
from
'
stubs/stats
'
;
function
isSectionMatches
(
section
:
StatsChartsSection
,
currentSection
:
string
):
boolean
{
function
isSectionMatches
(
section
:
StatsChartsSection
,
currentSection
:
string
):
boolean
{
return
currentSection
===
'
all
'
||
section
.
id
===
currentSection
;
return
currentSection
===
'
all
'
||
section
.
id
===
currentSection
;
...
@@ -15,30 +16,30 @@ function isChartNameMatches(q: string, chart: StatsChartInfo) {
...
@@ -15,30 +16,30 @@ function isChartNameMatches(q: string, chart: StatsChartInfo) {
}
}
export
default
function
useStats
()
{
export
default
function
useStats
()
{
const
{
data
,
isLoading
,
isError
}
=
useApiQuery
(
'
stats_lines
'
);
const
{
data
,
isPlaceholderData
,
isError
}
=
useApiQuery
(
'
stats_lines
'
,
{
queryOptions
:
{
placeholderData
:
STATS_CHARTS
,
},
});
const
[
currentSection
,
setCurrentSection
]
=
useState
(
'
all
'
);
const
[
currentSection
,
setCurrentSection
]
=
useState
(
'
all
'
);
const
[
filterQuery
,
setFilterQuery
]
=
useState
(
''
);
const
[
filterQuery
,
setFilterQuery
]
=
useState
(
''
);
const
[
displayedCharts
,
setDisplayedCharts
]
=
useState
(
data
?.
sections
);
const
[
interval
,
setInterval
]
=
useState
<
StatsIntervalIds
>
(
'
oneMonth
'
);
const
[
interval
,
setInterval
]
=
useState
<
StatsIntervalIds
>
(
'
oneMonth
'
);
const
sectionIds
=
useMemo
(()
=>
data
?.
sections
?.
map
(({
id
})
=>
id
),
[
data
]);
const
sectionIds
=
useMemo
(()
=>
data
?.
sections
?.
map
(({
id
})
=>
id
),
[
data
]);
// eslint-disable-next-line react-hooks/exhaustive-deps
const
debouncedFilterQuery
=
useDebounce
(
filterQuery
,
500
);
const
debounceFilterCharts
=
useCallback
(
debounce
(
q
=>
setFilterQuery
(
q
),
500
),
[]);
const
filterCharts
=
useCallback
((
q
:
string
,
currentSection
:
string
)
=>
{
const
displayedCharts
=
React
.
useMemo
((
)
=>
{
const
charts
=
data
?.
sections
return
data
?.
sections
?.
map
((
section
)
=>
{
?.
map
((
section
)
=>
{
const
charts
=
section
.
charts
.
filter
((
chart
)
=>
isSectionMatches
(
section
,
currentSection
)
&&
isChartNameMatches
(
q
,
chart
));
const
charts
=
section
.
charts
.
filter
((
chart
)
=>
isSectionMatches
(
section
,
currentSection
)
&&
isChartNameMatches
(
debouncedFilterQuery
,
chart
));
return
{
return
{
...
section
,
...
section
,
charts
,
charts
,
};
};
}).
filter
((
section
)
=>
section
.
charts
.
length
>
0
);
}).
filter
((
section
)
=>
section
.
charts
.
length
>
0
);
},
[
currentSection
,
data
?.
sections
,
debouncedFilterQuery
]);
setDisplayedCharts
(
charts
||
[]);
},
[
data
]);
const
handleSectionChange
=
useCallback
((
newSection
:
string
)
=>
{
const
handleSectionChange
=
useCallback
((
newSection
:
string
)
=>
{
setCurrentSection
(
newSection
);
setCurrentSection
(
newSection
);
...
@@ -48,33 +49,33 @@ export default function useStats() {
...
@@ -48,33 +49,33 @@ export default function useStats() {
setInterval
(
newInterval
);
setInterval
(
newInterval
);
},
[]);
},
[]);
useEffect
((
)
=>
{
const
handleFilterChange
=
useCallback
((
q
:
string
)
=>
{
filterCharts
(
filterQuery
,
currentSection
);
setFilterQuery
(
q
);
},
[
filterQuery
,
currentSection
,
filterCharts
]);
},
[]);
return
React
.
useMemo
(()
=>
({
return
React
.
useMemo
(()
=>
({
sections
:
data
?.
sections
,
sections
:
data
?.
sections
,
sectionIds
,
sectionIds
,
is
Loading
,
is
PlaceholderData
,
isError
,
isError
,
filterQuery
,
filterQuery
,
currentSection
,
currentSection
,
handleSectionChange
,
handleSectionChange
,
interval
,
interval
,
handleIntervalChange
,
handleIntervalChange
,
debounceFilterCharts
,
handleFilterChange
,
displayedCharts
,
displayedCharts
,
}),
[
}),
[
data
,
data
,
sectionIds
,
sectionIds
,
is
Loading
,
is
PlaceholderData
,
isError
,
isError
,
filterQuery
,
filterQuery
,
currentSection
,
currentSection
,
handleSectionChange
,
handleSectionChange
,
interval
,
interval
,
handleIntervalChange
,
handleIntervalChange
,
debounceFilterCharts
,
handleFilterChange
,
displayedCharts
,
displayedCharts
,
]);
]);
}
}
ui/token/TokenDetails/TokenDetailsVerifiedInfo.tsx
deleted
100644 → 0
View file @
4f948605
import
{
Flex
,
Link
,
Icon
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TokenVerifiedInfo
}
from
'
types/api/token
'
;
import
iconDocs
from
'
icons/docs.svg
'
;
import
iconEmail
from
'
icons/email.svg
'
;
import
iconLink
from
'
icons/link.svg
'
;
import
iconCoinGecko
from
'
icons/social/coingecko.svg
'
;
import
iconCoinMarketCap
from
'
icons/social/coinmarketcap.svg
'
;
import
iconDefiLlama
from
'
icons/social/defi_llama.svg
'
;
import
iconDiscord
from
'
icons/social/discord_filled.svg
'
;
import
iconFacebook
from
'
icons/social/facebook_filled.svg
'
;
import
iconGithub
from
'
icons/social/github_filled.svg
'
;
import
iconLinkedIn
from
'
icons/social/linkedin_filled.svg
'
;
import
iconMedium
from
'
icons/social/medium_filled.svg
'
;
import
iconOpenSea
from
'
icons/social/opensea_filled.svg
'
;
import
iconReddit
from
'
icons/social/reddit_filled.svg
'
;
import
iconSlack
from
'
icons/social/slack_filled.svg
'
;
import
iconTelegram
from
'
icons/social/telegram_filled.svg
'
;
import
iconTwitter
from
'
icons/social/twitter_filled.svg
'
;
import
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
import
TextSeparator
from
'
ui/shared/TextSeparator
'
;
interface
Props
{
data
:
TokenVerifiedInfo
;
}
interface
TServiceLink
{
field
:
keyof
TokenVerifiedInfo
;
icon
:
React
.
FunctionComponent
<
React
.
SVGAttributes
<
SVGElement
>>
;
hint
:
string
;
}
const
SOCIAL_LINKS
:
Array
<
TServiceLink
>
=
[
{
field
:
'
github
'
,
icon
:
iconGithub
,
hint
:
'
Github account
'
},
{
field
:
'
twitter
'
,
icon
:
iconTwitter
,
hint
:
'
Twitter account
'
},
{
field
:
'
telegram
'
,
icon
:
iconTelegram
,
hint
:
'
Telegram account
'
},
{
field
:
'
openSea
'
,
icon
:
iconOpenSea
,
hint
:
'
OpenSea page
'
},
{
field
:
'
linkedin
'
,
icon
:
iconLinkedIn
,
hint
:
'
LinkedIn page
'
},
{
field
:
'
facebook
'
,
icon
:
iconFacebook
,
hint
:
'
Facebook account
'
},
{
field
:
'
discord
'
,
icon
:
iconDiscord
,
hint
:
'
Discord account
'
},
{
field
:
'
medium
'
,
icon
:
iconMedium
,
hint
:
'
Medium account
'
},
{
field
:
'
slack
'
,
icon
:
iconSlack
,
hint
:
'
Slack account
'
},
{
field
:
'
reddit
'
,
icon
:
iconReddit
,
hint
:
'
Reddit account
'
},
];
const
PRICE_TICKERS
:
Array
<
TServiceLink
>
=
[
{
field
:
'
coinGeckoTicker
'
,
icon
:
iconCoinGecko
,
hint
:
'
Coin Gecko
'
},
{
field
:
'
coinMarketCapTicker
'
,
icon
:
iconCoinMarketCap
,
hint
:
'
Coin Market Cap
'
},
{
field
:
'
defiLlamaTicker
'
,
icon
:
iconDefiLlama
,
hint
:
'
Defi Llama
'
},
];
const
ServiceLink
=
({
href
,
hint
,
icon
}:
TServiceLink
&
{
href
:
string
|
undefined
})
=>
(
<
Link
href=
{
href
}
variant=
"secondary"
boxSize=
{
5
}
aria
-
label=
{
hint
}
title=
{
hint
}
target=
"_blank"
>
<
Icon
as=
{
icon
}
boxSize=
{
5
}
/>
</
Link
>
);
// todo_tom DELETE ME
const
TokenDetailsVerifiedInfo
=
({
data
}:
Props
)
=>
{
const
websiteLink
=
(()
=>
{
try
{
const
url
=
new
URL
(
data
.
projectWebsite
);
return
(
<
Flex
alignItems=
"center"
columnGap=
{
1
}
color=
"text_secondary"
_hover=
{
{
color
:
'
link_hovered
'
}
}
>
<
Icon
as=
{
iconLink
}
boxSize=
{
6
}
/>
<
LinkExternal
href=
{
data
.
projectWebsite
}
fontSize=
"md"
>
{
url
.
host
}
</
LinkExternal
>
</
Flex
>
);
}
catch
(
error
)
{
return
null
;
}
})();
const
docsLink
=
(()
=>
{
if
(
!
data
.
docs
)
{
return
null
;
}
return
(
<
Flex
alignItems=
"center"
columnGap=
{
1
}
color=
"text_secondary"
_hover=
{
{
color
:
'
link_hovered
'
}
}
>
<
Icon
as=
{
iconDocs
}
boxSize=
{
6
}
/>
<
LinkExternal
href=
{
data
.
docs
}
fontSize=
"md"
>
Documentation
</
LinkExternal
>
</
Flex
>
);
})();
const
supportLink
=
(()
=>
{
if
(
!
data
.
support
)
{
return
null
;
}
const
isEmail
=
data
.
support
.
includes
(
'
@
'
);
const
href
=
isEmail
?
`mailto:
${
data
.
support
}
`
:
data
.
support
;
return
(
<
Flex
alignItems=
"center"
columnGap=
{
1
}
color=
"text_secondary"
_hover=
{
{
color
:
'
link_hovered
'
}
}
>
<
Icon
as=
{
iconEmail
}
boxSize=
{
6
}
/>
<
Link
href=
{
href
}
target=
"_blank"
>
{
data
.
support
}
</
Link
>
</
Flex
>
);
})();
const
socialLinks
=
SOCIAL_LINKS
.
map
((
link
)
=>
({
...
link
,
href
:
data
[
link
.
field
]
}))
.
filter
(({
href
})
=>
href
);
const
priceTickersLinks
=
PRICE_TICKERS
.
map
((
link
)
=>
({
...
link
,
href
:
data
[
link
.
field
]
}))
.
filter
(({
href
})
=>
href
);
return
(
<
DetailsInfoItem
title=
"Links"
hint=
"Links to the project's official website and social media channels."
>
<
Flex
flexDir=
"column"
rowGap=
{
5
}
>
<
Flex
flexDir=
{
{
base
:
'
column
'
,
lg
:
'
row
'
}
}
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
columnGap=
{
6
}
rowGap=
{
2
}
>
{
websiteLink
}
{
docsLink
}
{
supportLink
}
</
Flex
>
{
(
socialLinks
.
length
>
0
||
priceTickersLinks
.
length
>
0
)
&&
(
<
Flex
columnGap=
{
2
}
rowGap=
{
2
}
flexWrap=
"wrap"
>
{
socialLinks
.
map
((
link
)
=>
<
ServiceLink
key=
{
link
.
field
}
{
...
link
}
/>)
}
{
priceTickersLinks
.
length
>
0
&&
(
<>
<
TextSeparator
color=
"divider"
/>
{
priceTickersLinks
.
map
((
link
)
=>
<
ServiceLink
key=
{
link
.
field
}
{
...
link
}
/>)
}
</>
)
}
</
Flex
>
)
}
</
Flex
>
</
DetailsInfoItem
>
);
};
export
default
React
.
memo
(
TokenDetailsVerifiedInfo
);
ui/token/TokenTransfer/TokenTransferListItem.tsx
View file @
8071589e
...
@@ -89,7 +89,7 @@ const TokenTransferListItem = ({
...
@@ -89,7 +89,7 @@ const TokenTransferListItem = ({
<
Skeleton
isLoaded=
{
!
isLoading
}
flexShrink=
{
0
}
fontWeight=
{
500
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
flexShrink=
{
0
}
fontWeight=
{
500
}
>
Value
Value
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
variant=
"
secondary"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_
secondary"
>
{
value
}
{
value
}
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
trimTokenSymbol
(
token
.
symbol
)
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
trimTokenSymbol
(
token
.
symbol
)
}
</
Skeleton
>
...
...
ui/tokens/TokensListItem.tsx
View file @
8071589e
...
@@ -77,12 +77,12 @@ const TokensTableItem = ({
...
@@ -77,12 +77,12 @@ const TokensTableItem = ({
{
totalValue
?.
usd
&&
(
{
totalValue
?.
usd
&&
(
<
HStack
spacing=
{
3
}
>
<
HStack
spacing=
{
3
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
On-chain market cap
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
On-chain market cap
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
variant=
"
secondary"
><
span
>
{
totalValue
.
usd
}
</
span
></
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
color=
"text_
secondary"
><
span
>
{
totalValue
.
usd
}
</
span
></
Skeleton
>
</
HStack
>
</
HStack
>
)
}
)
}
<
HStack
spacing=
{
3
}
>
<
HStack
spacing=
{
3
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Holders
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Holders
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
variant=
"
secondary"
><
span
>
{
Number
(
holders
).
toLocaleString
()
}
</
span
></
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
color=
"text_
secondary"
><
span
>
{
Number
(
holders
).
toLocaleString
()
}
</
span
></
Skeleton
>
</
HStack
>
</
HStack
>
</
ListItemMobile
>
</
ListItemMobile
>
);
);
...
...
ui/tx/internals/TxInternalsListItem.tsx
View file @
8071589e
...
@@ -45,13 +45,13 @@ const TxInternalsListItem = ({ type, from, to, value, success, error, gas_limit:
...
@@ -45,13 +45,13 @@ const TxInternalsListItem = ({ type, from, to, value, success, error, gas_limit:
</
Box
>
</
Box
>
<
HStack
spacing=
{
3
}
>
<
HStack
spacing=
{
3
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Value
{
appConfig
.
network
.
currency
.
symbol
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Value
{
appConfig
.
network
.
currency
.
symbol
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
variant=
"
secondary"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
color=
"text_
secondary"
>
{
BigNumber
(
value
).
div
(
BigNumber
(
10
**
appConfig
.
network
.
currency
.
decimals
)).
toFormat
()
}
{
BigNumber
(
value
).
div
(
BigNumber
(
10
**
appConfig
.
network
.
currency
.
decimals
)).
toFormat
()
}
</
Skeleton
>
</
Skeleton
>
</
HStack
>
</
HStack
>
<
HStack
spacing=
{
3
}
>
<
HStack
spacing=
{
3
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Gas limit
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
fontWeight=
{
500
}
>
Gas limit
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
variant=
"
secondary"
>
{
BigNumber
(
gasLimit
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontSize=
"sm"
color=
"text_
secondary"
>
{
BigNumber
(
gasLimit
).
toFormat
()
}
</
Skeleton
>
</
HStack
>
</
HStack
>
</
ListItemMobile
>
</
ListItemMobile
>
);
);
...
...
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