1
- import React , { useEffect , useRef , useState } from 'react' ;
1
+ import React , { useCallback , useEffect , useRef , useState } from 'react' ;
2
2
3
3
import {
4
4
EverstakeRewardsEndpointType ,
@@ -7,13 +7,24 @@ import {
7
7
StakeAccountRewards ,
8
8
} from '@suite-common/wallet-core' ;
9
9
import { formatNetworkAmount } from '@suite-common/wallet-utils' ;
10
- import { Badge , Card , Column , Icon , Row , SkeletonStack , Text , Tooltip } from '@trezor/components' ;
10
+ import {
11
+ Badge ,
12
+ Card ,
13
+ Column ,
14
+ Icon ,
15
+ IconButton ,
16
+ Row ,
17
+ SkeletonStack ,
18
+ Text ,
19
+ Tooltip ,
20
+ } from '@trezor/components' ;
11
21
import { spacings } from '@trezor/theme' ;
12
22
import { SOLANA_EPOCH_DAYS } from '@suite-common/wallet-constants' ;
23
+ import { useDebounce } from '@trezor/react-utils' ;
13
24
14
25
import {
15
- CoinBalance ,
16
26
FiatValue ,
27
+ FormattedCryptoAmount ,
17
28
FormattedDate ,
18
29
HiddenPlaceholder ,
19
30
Translation ,
@@ -25,21 +36,25 @@ import { Pagination } from 'src/components/wallet';
25
36
import SkeletonTransactionItem from 'src/views/wallet/transactions/TransactionList/SkeletonTransactionItem' ;
26
37
import { ColDate } from 'src/views/wallet/transactions/TransactionList/TransactionsGroup/CommonComponents' ;
27
38
39
+ import { RewardsEmpty } from './RewardsEmpty' ;
40
+
28
41
const PAGE_SIZE_DEFAULT = 10 ;
29
42
30
43
interface RewardsListProps {
31
44
account : Account ;
32
45
}
33
46
34
47
export const RewardsList = ( { account } : RewardsListProps ) => {
35
- const anchor = useSelector ( state => state . router . anchor ) ;
36
48
const { data, isLoading } =
37
- useSelector ( state => selectStakingRewards ( state , account ? .symbol ) ) || { } ;
49
+ useSelector ( state => selectStakingRewards ( state , account . symbol ) ) || { } ;
38
50
39
51
const { rewards } = data ?? { } ;
52
+ const selectedAccountRewards = rewards ?. [ account . descriptor ] ;
53
+
40
54
const sectionRef = useRef < HTMLDivElement > ( null ) ;
41
55
42
56
const dispatch = useDispatch ( ) ;
57
+ const debounce = useDebounce ( ) ;
43
58
44
59
const perPage = PAGE_SIZE_DEFAULT ;
45
60
const startPage = 1 ;
@@ -50,32 +65,41 @@ export const RewardsList = ({ account }: RewardsListProps) => {
50
65
const startIndex = ( currentPage - 1 ) * perPage ;
51
66
const stopIndex = startIndex + perPage ;
52
67
68
+ const isSolanaMainnet = account . symbol === 'sol' ;
69
+
70
+ const fetchRewards = useCallback (
71
+ async ( { symbol, descriptor } : Account ) => {
72
+ await debounce ( ( ) => {
73
+ if ( symbol !== 'sol' ) return ;
74
+ dispatch (
75
+ fetchEverstakeRewards ( {
76
+ symbol,
77
+ endpointType : EverstakeRewardsEndpointType . GetRewards ,
78
+ address : descriptor ,
79
+ } ) ,
80
+ ) ;
81
+ } ) ;
82
+ } ,
83
+ [ dispatch , debounce ] ,
84
+ ) ;
85
+
53
86
useEffect ( ( ) => {
54
- // Fetch rewards only for the Solana mainnet
55
- if ( account . symbol === 'sol' ) {
56
- dispatch (
57
- fetchEverstakeRewards ( {
58
- symbol : account . symbol ,
59
- endpointType : EverstakeRewardsEndpointType . GetRewards ,
60
- address : account . descriptor ,
61
- } ) ,
62
- ) ;
63
- }
64
- } , [ anchor , account , dispatch ] ) ;
87
+ fetchRewards ( account ) ;
88
+ } , [ account , fetchRewards ] ) ;
65
89
66
90
useEffect ( ( ) => {
67
- if ( rewards ) {
68
- const slicedRewards = rewards ?. slice ( startIndex , stopIndex ) ;
91
+ if ( selectedAccountRewards ) {
92
+ const slicedRewards = selectedAccountRewards ?. slice ( startIndex , stopIndex ) ;
69
93
setSlicedRewards ( slicedRewards ) ;
70
94
}
71
- } , [ currentPage , rewards , startIndex , stopIndex ] ) ;
95
+ } , [ currentPage , selectedAccountRewards , startIndex , stopIndex ] ) ;
72
96
73
97
useEffect ( ( ) => {
74
98
// reset page on account change
75
99
setSelectedPage ( startPage ) ;
76
100
} , [ account . descriptor , account . symbol , startPage ] ) ;
77
101
78
- const totalItems = rewards ?. length ?? 0 ;
102
+ const totalItems = selectedAccountRewards ?. length ?? 0 ;
79
103
const showPagination = totalItems > perPage ;
80
104
const isLastPage = stopIndex >= totalItems ;
81
105
@@ -86,10 +110,29 @@ export const RewardsList = ({ account }: RewardsListProps) => {
86
110
}
87
111
} ;
88
112
113
+ if ( ! isSolanaMainnet || ! totalItems ) {
114
+ return < RewardsEmpty /> ;
115
+ }
116
+
89
117
return (
90
118
< DashboardSection
91
119
ref = { sectionRef }
92
120
heading = { < Translation id = "TR_REWARDS" /> }
121
+ actions = {
122
+ < Column >
123
+ < Tooltip
124
+ maxWidth = { 250 }
125
+ content = { < Translation id = "TR_STAKE_REFRESH_REWARDS_TOOLTIP" /> }
126
+ >
127
+ < IconButton
128
+ icon = "arrowClockwise"
129
+ variant = "tertiary"
130
+ size = "small"
131
+ onClick = { ( ) => fetchRewards ( account ) }
132
+ />
133
+ </ Tooltip >
134
+ </ Column >
135
+ }
93
136
data-testid = "@wallet/accounts/rewards-list"
94
137
>
95
138
{ isLoading ? (
@@ -147,7 +190,7 @@ export const RewardsList = ({ account }: RewardsListProps) => {
147
190
{ reward ?. amount && (
148
191
< Column alignItems = "end" >
149
192
< HiddenPlaceholder >
150
- < CoinBalance
193
+ < FormattedCryptoAmount
151
194
value = { formatNetworkAmount (
152
195
reward ?. amount ,
153
196
account . symbol ,
0 commit comments