@@ -11,7 +11,7 @@ import { myStakePctAtom, myStakeAmountAtom } from "../../atoms";
11
11
import type { PropsWithChildren } from "react" ;
12
12
import { useEffect } from "react" ;
13
13
import { DateTime } from "luxon" ;
14
- import { getFmtStake , getDurationText , slowDateTimeNow } from "../../utils" ;
14
+ import { slowDateTimeNow , getSolString , getDurationValues } from "../../utils" ;
15
15
import { formatNumber } from "../../numUtils" ;
16
16
import { useInterval , useMedia , useUpdate } from "react-use" ;
17
17
import clsx from "clsx" ;
@@ -48,11 +48,10 @@ export default function IdentityKey() {
48
48
{ isXXNarrowScreen && (
49
49
< Label
50
50
label = "Validator Name"
51
- value = {
52
- truncateKey ? `${ identityKey ?. substring ( 0 , 8 ) } ...` : identityKey
53
- }
54
51
tooltip = "The validators identity public key"
55
- />
52
+ >
53
+ { truncateKey ? `${ identityKey ?. substring ( 0 , 8 ) } ...` : identityKey }
54
+ </ Label >
56
55
) }
57
56
{ isXNarrowScreen && (
58
57
< >
@@ -104,9 +103,10 @@ function DropdownMenu() {
104
103
< PeerIcon url = { peer ?. info ?. icon_url } size = { 24 } isYou />
105
104
< Label
106
105
label = "Validator Name"
107
- value = { identityKey }
108
106
tooltip = "The validators identity public key"
109
- />
107
+ >
108
+ { identityKey }
109
+ </ Label >
110
110
</ Flex >
111
111
< StakeValue />
112
112
< StakePct />
@@ -125,68 +125,75 @@ function VotePubkey() {
125
125
return (
126
126
< Label
127
127
label = "Vote Pubkey"
128
- value = { peer ?. vote [ 0 ] ?. vote_account }
129
128
tooltip = "The public key of vote account, encoded in base58"
130
- />
129
+ >
130
+ { peer ?. vote [ 0 ] ?. vote_account }
131
+ </ Label >
131
132
) ;
132
133
}
133
134
134
135
function VoteBalance ( ) {
135
136
const voteBalance = useAtomValue ( voteBalanceAtom ) ;
137
+ const solString = getSolString ( voteBalance ) ;
136
138
137
139
return (
138
140
< >
139
141
< Label
140
142
label = "Vote Balance"
141
- value = { getFmtStake ( voteBalance ) ?? "-" }
142
143
tooltip = "Account balance of this validators vote account. The balance is on the highest slot of the currently active fork of the validator."
143
- />
144
+ >
145
+ < ValueWithSuffix value = { solString } suffix = "SOL" />
146
+ </ Label >
144
147
</ >
145
148
) ;
146
149
}
147
150
148
151
function IdentityBalance ( ) {
149
152
const identityBalance = useAtomValue ( identityBalanceAtom ) ;
153
+ const solString = getSolString ( identityBalance ) ;
150
154
151
155
return (
152
156
< Label
153
157
label = "Identity Balance"
154
- value = { getFmtStake ( identityBalance ) ?? "-" }
155
158
tooltip = "Account balance of this validators identity account. The balance is on the highest slot of the currently active fork of the validator."
156
- />
159
+ >
160
+ < ValueWithSuffix value = { solString } suffix = "SOL" />
161
+ </ Label >
157
162
) ;
158
163
}
159
164
160
165
function StakePct ( ) {
161
166
const stakePct = useAtomValue ( myStakePctAtom ) ;
162
- let value = "-" ;
163
167
164
- if ( stakePct !== undefined ) {
165
- value = formatNumber ( stakePct , {
166
- significantDigits : 4 ,
167
- trailingZeroes : false ,
168
- } ) ;
169
- value += "%" ;
170
- }
168
+ const value =
169
+ stakePct === undefined
170
+ ? undefined
171
+ : formatNumber ( stakePct , {
172
+ significantDigits : 4 ,
173
+ trailingZeroes : false ,
174
+ } ) ;
171
175
172
176
return (
173
177
< Label
174
178
label = "Stake %"
175
- value = { value }
176
179
tooltip = "What percentage of total stake is delegated to this validator"
177
- />
180
+ >
181
+ < ValueWithSuffix value = { value } suffix = "%" />
182
+ </ Label >
178
183
) ;
179
184
}
180
185
181
186
function StakeValue ( ) {
182
187
const stake = useAtomValue ( myStakeAmountAtom ) ;
188
+ const solString = getSolString ( stake ) ;
183
189
184
190
return (
185
191
< Label
186
192
label = "Stake Amount"
187
- value = { getFmtStake ( stake ) ?? "-" }
188
193
tooltip = "Amount of total stake that is delegated to this validator"
189
- />
194
+ >
195
+ < ValueWithSuffix value = { solString } suffix = "SOL" />
196
+ </ Label >
190
197
) ;
191
198
}
192
199
@@ -207,58 +214,82 @@ function Commission() {
207
214
) ;
208
215
209
216
return (
210
- < Label
211
- label = "Commission"
212
- value = {
213
- maxCommission ?. commission !== undefined
214
- ? maxCommission . commission . toLocaleString ( ) + "%"
215
- : "-"
216
- }
217
- />
217
+ < Label label = "Commission" >
218
+ < ValueWithSuffix
219
+ value = { maxCommission ?. commission ?. toLocaleString ( ) }
220
+ suffix = "%"
221
+ />
222
+ </ Label >
218
223
) ;
219
224
}
220
225
221
226
function StartupTime ( ) {
222
227
const startupTime = useAtomValue ( startupTimeAtom ) ;
223
228
224
- const getValue = ( ) => {
225
- if ( ! startupTime ) return "-" ;
229
+ const getValues = ( ) => {
230
+ if ( ! startupTime ) return ;
226
231
const uptimeDuration = slowDateTimeNow . diff (
227
232
DateTime . fromMillis (
228
233
Math . floor ( Number ( startupTime . startupTimeNanos ) / 1_000_000 ) ,
229
234
) ,
230
235
) ;
231
236
232
- const text = getDurationText ( uptimeDuration . rescale ( ) , {
237
+ return getDurationValues ( uptimeDuration . rescale ( ) , {
233
238
omitSeconds : true ,
234
239
} ) ;
235
- return text ;
236
240
} ;
237
241
242
+ const values = getValues ( ) ;
243
+
238
244
const update = useUpdate ( ) ;
239
245
useInterval ( update , 60_000 ) ;
240
246
241
- return < Label label = "Uptime" value = { getValue ( ) } /> ;
247
+ return (
248
+ < Label label = "Uptime" >
249
+ { values ?. map ( ( [ value , suffix ] , i ) => (
250
+ < >
251
+ { i !== 0 && "\xa0" }
252
+ < ValueWithSuffix key = { i } value = { value } suffix = { suffix } excludeSpace />
253
+ </ >
254
+ ) ) }
255
+ </ Label >
256
+ ) ;
242
257
}
243
258
244
259
interface LabelProps {
245
260
label : string ;
246
- value ?: string | null ;
247
- color ?: string ;
248
261
tooltip ?: string ;
249
262
}
250
- function Label ( { label, value, color, tooltip } : LabelProps ) {
251
- if ( ! value ) return null ;
252
- const textValue = (
253
- < Text className = { styles . value } style = { { color : color } } >
254
- { value }
255
- </ Text >
256
- ) ;
263
+ function Label ( { label, tooltip, children } : PropsWithChildren < LabelProps > ) {
264
+ if ( ! children ) return null ;
265
+ const content = < div className = { styles . value } > { children } </ div > ;
257
266
258
267
return (
259
268
< Flex direction = "column" >
260
269
< Text className = { styles . label } > { label } </ Text >
261
- { tooltip ? < Tooltip content = { tooltip } > { textValue } </ Tooltip > : textValue }
270
+ { tooltip ? < Tooltip content = { tooltip } > { content } </ Tooltip > : content }
262
271
</ Flex >
263
272
) ;
264
273
}
274
+
275
+ function ValueWithSuffix ( {
276
+ value,
277
+ suffix,
278
+ valueColor,
279
+ excludeSpace,
280
+ } : {
281
+ value ?: string | number ;
282
+ suffix : string ;
283
+ valueColor ?: string ;
284
+ excludeSpace ?: boolean ;
285
+ } ) {
286
+ return (
287
+ < >
288
+ < span style = { { color : valueColor } } >
289
+ { value }
290
+ { ! excludeSpace && "\xa0" }
291
+ </ span >
292
+ < span className = { styles . valueSuffix } > { suffix } </ span >
293
+ </ >
294
+ ) ;
295
+ }
0 commit comments