Skip to content

Commit db929de

Browse files
chore: identity key text colors
1 parent f3ef2de commit db929de

File tree

4 files changed

+134
-87
lines changed

4 files changed

+134
-87
lines changed

src/colors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const primaryTextColor = "#B2BCC9";
88
export const secondaryTextColor = "#67696A";
99
export const regularTextColor = "#8E909D";
1010
export const iconButtonColor = "#B4B4B4";
11+
export const headerLabelTextColor = "#949494";
1112

1213
export const containerBorderColor = "rgba(250, 250, 250, 0.12)";
1314
export const containerBackgroundColor = "rgba(250, 250, 250, 0.05)";
@@ -17,7 +18,7 @@ export const popoverBackgroundColor = "#1C2129";
1718
export const rowSeparatorBackgroundColor = "#333333";
1819

1920
export const navButtonTextColor = "#F7F7F7";
20-
export const navButtonInactiveTextColor = "#949494";
21+
export const navButtonInactiveTextColor = headerLabelTextColor;
2122

2223
// slot navigation
2324
export const slotNavFilterBackgroundColor = "#00205F";

src/features/Header/IdentityKey.tsx

Lines changed: 79 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { myStakePctAtom, myStakeAmountAtom } from "../../atoms";
1111
import type { PropsWithChildren } from "react";
1212
import { useEffect } from "react";
1313
import { DateTime } from "luxon";
14-
import { getFmtStake, getDurationText, slowDateTimeNow } from "../../utils";
14+
import { slowDateTimeNow, getSolString, getDurationValues } from "../../utils";
1515
import { formatNumber } from "../../numUtils";
1616
import { useInterval, useMedia, useUpdate } from "react-use";
1717
import clsx from "clsx";
@@ -48,11 +48,10 @@ export default function IdentityKey() {
4848
{isXXNarrowScreen && (
4949
<Label
5050
label="Validator Name"
51-
value={
52-
truncateKey ? `${identityKey?.substring(0, 8)}...` : identityKey
53-
}
5451
tooltip="The validators identity public key"
55-
/>
52+
>
53+
{truncateKey ? `${identityKey?.substring(0, 8)}...` : identityKey}
54+
</Label>
5655
)}
5756
{isXNarrowScreen && (
5857
<>
@@ -104,9 +103,10 @@ function DropdownMenu() {
104103
<PeerIcon url={peer?.info?.icon_url} size={24} isYou />
105104
<Label
106105
label="Validator Name"
107-
value={identityKey}
108106
tooltip="The validators identity public key"
109-
/>
107+
>
108+
{identityKey}
109+
</Label>
110110
</Flex>
111111
<StakeValue />
112112
<StakePct />
@@ -125,68 +125,75 @@ function VotePubkey() {
125125
return (
126126
<Label
127127
label="Vote Pubkey"
128-
value={peer?.vote[0]?.vote_account}
129128
tooltip="The public key of vote account, encoded in base58"
130-
/>
129+
>
130+
{peer?.vote[0]?.vote_account}
131+
</Label>
131132
);
132133
}
133134

134135
function VoteBalance() {
135136
const voteBalance = useAtomValue(voteBalanceAtom);
137+
const solString = getSolString(voteBalance);
136138

137139
return (
138140
<>
139141
<Label
140142
label="Vote Balance"
141-
value={getFmtStake(voteBalance) ?? "-"}
142143
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>
144147
</>
145148
);
146149
}
147150

148151
function IdentityBalance() {
149152
const identityBalance = useAtomValue(identityBalanceAtom);
153+
const solString = getSolString(identityBalance);
150154

151155
return (
152156
<Label
153157
label="Identity Balance"
154-
value={getFmtStake(identityBalance) ?? "-"}
155158
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>
157162
);
158163
}
159164

160165
function StakePct() {
161166
const stakePct = useAtomValue(myStakePctAtom);
162-
let value = "-";
163167

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+
});
171175

172176
return (
173177
<Label
174178
label="Stake %"
175-
value={value}
176179
tooltip="What percentage of total stake is delegated to this validator"
177-
/>
180+
>
181+
<ValueWithSuffix value={value} suffix="%" />
182+
</Label>
178183
);
179184
}
180185

181186
function StakeValue() {
182187
const stake = useAtomValue(myStakeAmountAtom);
188+
const solString = getSolString(stake);
183189

184190
return (
185191
<Label
186192
label="Stake Amount"
187-
value={getFmtStake(stake) ?? "-"}
188193
tooltip="Amount of total stake that is delegated to this validator"
189-
/>
194+
>
195+
<ValueWithSuffix value={solString} suffix="SOL" />
196+
</Label>
190197
);
191198
}
192199

@@ -207,58 +214,82 @@ function Commission() {
207214
);
208215

209216
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>
218223
);
219224
}
220225

221226
function StartupTime() {
222227
const startupTime = useAtomValue(startupTimeAtom);
223228

224-
const getValue = () => {
225-
if (!startupTime) return "-";
229+
const getValues = () => {
230+
if (!startupTime) return;
226231
const uptimeDuration = slowDateTimeNow.diff(
227232
DateTime.fromMillis(
228233
Math.floor(Number(startupTime.startupTimeNanos) / 1_000_000),
229234
),
230235
);
231236

232-
const text = getDurationText(uptimeDuration.rescale(), {
237+
return getDurationValues(uptimeDuration.rescale(), {
233238
omitSeconds: true,
234239
});
235-
return text;
236240
};
237241

242+
const values = getValues();
243+
238244
const update = useUpdate();
239245
useInterval(update, 60_000);
240246

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+
);
242257
}
243258

244259
interface LabelProps {
245260
label: string;
246-
value?: string | null;
247-
color?: string;
248261
tooltip?: string;
249262
}
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>;
257266

258267
return (
259268
<Flex direction="column">
260269
<Text className={styles.label}>{label}</Text>
261-
{tooltip ? <Tooltip content={tooltip}>{textValue}</Tooltip> : textValue}
270+
{tooltip ? <Tooltip content={tooltip}>{content}</Tooltip> : content}
262271
</Flex>
263272
);
264273
}
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+
}

src/features/Header/identityKey.module.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616
}
1717

1818
.label {
19-
color: var(--skip-rate-label-color);
19+
color: var(--header-label-text-color);
2020
font-size: 10px;
2121
}
2222

2323
.value {
2424
color: var(--dropdown-button-text-color);
2525
font-size: 12px;
2626
font-style: normal;
27+
line-height: normal;
28+
.value-suffix {
29+
color: var(--header-label-text-color);
30+
}
2731
}
2832
}
2933

src/utils.ts

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -39,46 +39,51 @@ export interface DurationOptions {
3939
omitSeconds?: boolean;
4040
}
4141

42-
function getUnitText(value: number, suffix: string, showZeros: boolean) {
43-
if (value === 0 && !showZeros) return;
44-
return `${value}${suffix}`;
45-
}
46-
47-
function getUnitTexts(duration: Duration, options?: DurationOptions) {
42+
function getUnitValues(
43+
duration: Duration,
44+
options?: DurationOptions,
45+
): [number, string][] {
4846
if (options?.showOnlyTwoSignificantUnits) {
49-
const firstUnitIndex = descendingUnits.findIndex(({ unit }) => {
50-
return !!duration[unit];
51-
});
47+
const firstUnitIndex = descendingUnits.findIndex(
48+
({ unit }) => !!duration[unit],
49+
);
5250
return descendingUnits
5351
.slice(firstUnitIndex, firstUnitIndex + 2)
54-
.map(({ unit, suffix }) => {
55-
const value = duration[unit];
56-
return getUnitText(value, suffix, true);
57-
});
52+
.map(({ unit, suffix }) => [duration[unit], suffix]);
5853
}
5954

6055
return descendingUnits
61-
.map(({ unit, suffix }) => {
62-
if (options?.omitSeconds && unit === "seconds") return;
63-
64-
const value = duration[unit];
65-
if (!value) return;
56+
.filter(({ unit }) => {
57+
if (options?.omitSeconds && unit === "seconds") return false;
6658

67-
return getUnitText(value, suffix, false);
59+
// drop zero values
60+
return !!duration[unit];
6861
})
69-
.filter((v) => !!v);
62+
.map(({ unit, suffix }) => [duration[unit], suffix]);
63+
}
64+
65+
export function getDurationValues(
66+
duration?: Duration,
67+
options?: DurationOptions,
68+
): [number, string][] | undefined {
69+
if (!duration) return;
70+
71+
if (duration.toMillis() < 1000) return [[0, "s"]];
72+
73+
const units = getUnitValues(duration, options);
74+
return units.length ? units : [[0, "s"]];
7075
}
7176

7277
export function getDurationText(
7378
duration?: Duration,
7479
options?: DurationOptions,
7580
) {
76-
if (!duration) return "Never";
77-
78-
if (duration.toMillis() < 1000) return "0s";
81+
const values = getDurationValues(duration, options);
82+
if (!values) return "Never";
7983

80-
const texts = getUnitTexts(duration, options);
81-
return texts.join(" ") || "0s";
84+
return values.reduce((acc, valSuffix) => {
85+
return `${acc} ${valSuffix.join("")}`;
86+
}, "");
8287
}
8388

8489
export let slowDateTimeNow = DateTime.now();
@@ -100,24 +105,30 @@ export function getStake(peer: Peer) {
100105
);
101106
}
102107

103-
export function getFmtStake(stake?: bigint) {
104-
if (stake === undefined) return;
108+
export function getSolString(lamportAmount?: bigint) {
109+
if (lamportAmount === undefined) return;
105110

106-
let value = "";
107-
const solAmount = Number(stake) / lamportsPerSol;
111+
const solAmount = Number(lamportAmount) / lamportsPerSol;
108112
if (solAmount < 1) {
109-
value = solAmount.toLocaleString();
110-
} else if (solAmount < 100) {
111-
value = solAmount.toLocaleString(undefined, {
113+
return solAmount.toLocaleString();
114+
}
115+
116+
if (solAmount < 100) {
117+
return solAmount.toLocaleString(undefined, {
112118
maximumFractionDigits: 2,
113119
});
114-
} else {
115-
value = solAmount.toLocaleString(undefined, {
116-
maximumFractionDigits: 0,
117-
});
118120
}
119121

120-
return `${value}\xa0SOL`;
122+
return solAmount.toLocaleString(undefined, {
123+
maximumFractionDigits: 0,
124+
});
125+
}
126+
127+
export function getFmtStake(stake?: bigint) {
128+
const solString = getSolString(stake);
129+
if (solString === undefined) return;
130+
131+
return `${solString}\xa0SOL`;
121132
}
122133

123134
/** Dumb workaround for Array.isArray type checking with eslint for readonly arrays */

0 commit comments

Comments
 (0)