Skip to content

Commit 4aebca2

Browse files
committed
feat: miscellaneous chain icon changes
1 parent ce0da51 commit 4aebca2

File tree

8 files changed

+437
-191
lines changed

8 files changed

+437
-191
lines changed

.changeset/metal-mails-ring.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
- Small fix for ChainIcon: Always resolve IPFS URI
5+
6+
- Improve test coverage

packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx

Lines changed: 151 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ import {
99
TextAlignJustifyIcon,
1010
} from "@radix-ui/react-icons";
1111
import { useQuery } from "@tanstack/react-query";
12-
import { type JSX, useCallback, useContext, useEffect, useState } from "react";
12+
import {
13+
type Dispatch,
14+
type JSX,
15+
type SetStateAction,
16+
useCallback,
17+
useContext,
18+
useEffect,
19+
useState,
20+
} from "react";
1321
import { trackPayEvent } from "../../../../analytics/track/pay.js";
1422
import type { Chain } from "../../../../chains/types.js";
1523
import type { ThirdwebClient } from "../../../../client/client.js";
@@ -51,11 +59,7 @@ import type {
5159
ConnectButton_detailsModalOptions,
5260
PayUIOptions,
5361
} from "../../../core/hooks/connection/ConnectButtonProps.js";
54-
import {
55-
useChainFaucets,
56-
useChainIconUrl,
57-
useChainName,
58-
} from "../../../core/hooks/others/useChainQuery.js";
62+
import { useChainFaucets } from "../../../core/hooks/others/useChainQuery.js";
5963
import { useActiveAccount } from "../../../core/hooks/wallets/useActiveAccount.js";
6064
import { useActiveWallet } from "../../../core/hooks/wallets/useActiveWallet.js";
6165
import { useActiveWalletChain } from "../../../core/hooks/wallets/useActiveWalletChain.js";
@@ -70,7 +74,7 @@ import type {
7074
import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js";
7175
import { useWalletInfo } from "../../../core/utils/wallet.js";
7276
import { WalletUIStatesProvider } from "../../providers/wallet-ui-states-provider.js";
73-
import { ChainIcon } from "../components/ChainIcon.js";
77+
import { ChainActiveDot } from "../components/ChainActiveDot.js";
7478
import { CopyIcon } from "../components/CopyIcon.js";
7579
import { IconContainer } from "../components/IconContainer.js";
7680
import { Modal } from "../components/Modal.js";
@@ -81,6 +85,7 @@ import { ToolTip } from "../components/Tooltip.js";
8185
import { WalletImage } from "../components/WalletImage.js";
8286
import { Container, Line } from "../components/basic.js";
8387
import { Button, IconButton } from "../components/buttons.js";
88+
import { fallbackChainIcon } from "../components/fallbackChainIcon.js";
8489
import { Link, Text } from "../components/text.js";
8590
import { fadeInAnimation } from "../design-system/animations.js";
8691
import { StyledButton } from "../design-system/elements.js";
@@ -95,6 +100,9 @@ import {
95100
import { AccountBlobbie } from "../prebuilt/Account/blobbie.js";
96101
import { AccountName } from "../prebuilt/Account/name.js";
97102
import { AccountProvider } from "../prebuilt/Account/provider.js";
103+
import { ChainIcon } from "../prebuilt/Chain/icon.js";
104+
import { ChainName } from "../prebuilt/Chain/name.js";
105+
import { ChainProvider } from "../prebuilt/Chain/provider.js";
98106
import type { LocaleId } from "../types.js";
99107
import { MenuButton, MenuLink } from "./MenuButton.js";
100108
import { ScreenSetupContext, useSetupScreen } from "./Modal/screen.js";
@@ -386,8 +394,6 @@ export function DetailsModal(props: {
386394
const theme = parseTheme(props.theme);
387395

388396
const activeWallet = useActiveWallet();
389-
const chainIconQuery = useChainIconUrl(walletChain);
390-
const chainNameQuery = useChainName(walletChain);
391397
const chainFaucetsQuery = useChainFaucets(walletChain);
392398

393399
const disableSwitchChain = !activeWallet?.switchChain;
@@ -417,93 +423,6 @@ export function DetailsModal(props: {
417423
}
418424
}, [activeAccount, closeModal]);
419425

420-
const networkSwitcherButton = (
421-
<MenuButton
422-
type="button"
423-
disabled={disableSwitchChain}
424-
onClick={() => {
425-
setScreen("network-switcher");
426-
}}
427-
data-variant="primary"
428-
>
429-
<div
430-
style={{
431-
display: "flex",
432-
alignItems: "center",
433-
position: "relative",
434-
}}
435-
>
436-
{!chainIconQuery.isLoading ? (
437-
<ChainIcon
438-
chainIconUrl={chainIconQuery.url}
439-
size={iconSize.md}
440-
active
441-
client={client}
442-
/>
443-
) : (
444-
<Skeleton height={`${iconSize.md}px`} width={`${iconSize.md}px`} />
445-
)}
446-
</div>
447-
448-
{chainNameQuery.isLoading ? (
449-
<Skeleton height="16px" width="150px" />
450-
) : (
451-
<Text color="primaryText" size="md" multiline>
452-
{chainNameQuery.name || `Unknown chain #${walletChain?.id}`}
453-
<Text color="secondaryText" size="xs">
454-
{props.showBalanceInFiat ? (
455-
<>
456-
<AccountBalance
457-
fallbackComponent={<Skeleton height="1em" width="70px" />}
458-
loadingComponent={<Skeleton height="1em" width="70px" />}
459-
chain={walletChain}
460-
tokenAddress={
461-
props.displayBalanceToken?.[Number(walletChain?.id)]
462-
}
463-
formatFn={(props: AccountBalanceInfo) =>
464-
formatAccountTokenBalance({ ...props, decimals: 7 })
465-
}
466-
/>{" "}
467-
<AccountBalance
468-
loadingComponent={<Skeleton height="1em" width="30px" />}
469-
chain={walletChain}
470-
tokenAddress={
471-
props.displayBalanceToken?.[Number(walletChain?.id)]
472-
}
473-
formatFn={(props: AccountBalanceInfo) =>
474-
` (${formatAccountFiatBalance({ ...props, decimals: 3 })})`
475-
}
476-
showBalanceInFiat="USD"
477-
/>
478-
</>
479-
) : (
480-
<AccountBalance
481-
fallbackComponent={<Skeleton height="1em" width="100px" />}
482-
loadingComponent={<Skeleton height="1em" width="100px" />}
483-
formatFn={(props: AccountBalanceInfo) =>
484-
formatAccountTokenBalance({ ...props, decimals: 7 })
485-
}
486-
chain={walletChain}
487-
tokenAddress={
488-
props.displayBalanceToken?.[Number(walletChain?.id)]
489-
}
490-
/>
491-
)}
492-
</Text>
493-
</Text>
494-
)}
495-
496-
<StyledChevronRightIcon
497-
width={iconSize.sm}
498-
height={iconSize.sm}
499-
style={{
500-
flexShrink: 0,
501-
marginLeft: "auto",
502-
}}
503-
/>
504-
</MenuButton>
505-
);
506-
507426
const { hideSendFunds, hideReceiveFunds, hideBuyFunds } =
508427
props.detailsModal || {};
509428

@@ -749,7 +668,13 @@ export function DetailsModal(props: {
749668
}}
750669
>
751670
{/* Network Switcher */}
752-
{networkSwitcherButton}
671+
<NetworkSwitcherButton
672+
client={props.client}
673+
setScreen={() => setScreen("network-switcher")}
674+
disableSwitchChain={disableSwitchChain}
675+
showBalanceInFiat={props.detailsModal?.showBalanceInFiat}
676+
displayBalanceToken={props.displayBalanceToken}
677+
/>
753678

754679
{/* Transactions */}
755680
<MenuButton
@@ -1099,6 +1024,135 @@ export function DetailsModal(props: {
10991024
);
11001025
}
11011026

1027+
/**
1028+
* When this button is clicked, it will switch to the screen where users
1029+
* can select a chain to switch to.
1030+
* @internal
1031+
*/
1032+
function NetworkSwitcherButton(props: {
1033+
setScreen: Dispatch<SetStateAction<"network-switcher">>;
1034+
disableSwitchChain: boolean;
1035+
displayBalanceToken: Record<number, string> | undefined;
1036+
client: ThirdwebClient;
1037+
showBalanceInFiat?: SupportedFiatCurrency;
1038+
}) {
1039+
const { disableSwitchChain, setScreen, showBalanceInFiat, client } = props;
1040+
const walletChain = useActiveWalletChain();
1041+
if (!walletChain) {
1042+
return null;
1043+
}
1044+
return (
1045+
<MenuButton
1046+
type="button"
1047+
disabled={disableSwitchChain}
1048+
onClick={() => {
1049+
setScreen("network-switcher");
1050+
}}
1051+
data-variant="primary"
1052+
>
1053+
<ChainProvider chain={walletChain}>
1054+
<div
1055+
style={{
1056+
display: "flex",
1057+
alignItems: "center",
1058+
position: "relative",
1059+
}}
1060+
>
1061+
<Container
1062+
style={{
1063+
position: "relative",
1064+
display: "flex",
1065+
flexShrink: 0,
1066+
alignItems: "center",
1067+
}}
1068+
>
1069+
<ChainIcon
1070+
client={client}
1071+
loadingComponent={
1072+
<Skeleton
1073+
height={`${iconSize.md}px`}
1074+
width={`${iconSize.md}px`}
1075+
/>
1076+
}
1077+
fallbackComponent={
1078+
<img
1079+
src={fallbackChainIcon}
1080+
alt=""
1081+
style={{
1082+
width: `${iconSize.md}px`,
1083+
height: `${iconSize.md}px`,
1084+
}}
1085+
/>
1086+
}
1087+
style={{
1088+
width: `${iconSize.md}px`,
1089+
height: `${iconSize.md}px`,
1090+
}}
1091+
/>
1092+
<ChainActiveDot />
1093+
</Container>
1094+
</div>
1095+
1096+
<Text color="primaryText" size="md" multiline>
1097+
<ChainName
1098+
loadingComponent={<Skeleton height="16px" width="150px" />}
1099+
fallbackComponent={<span>Unknown chain #{walletChain?.id}</span>}
1100+
/>
1101+
<Text color="secondaryText" size="xs">
1102+
{showBalanceInFiat ? (
1103+
<>
1104+
<AccountBalance
1105+
fallbackComponent={<Skeleton height="1em" width="70px" />}
1106+
loadingComponent={<Skeleton height="1em" width="70px" />}
1107+
chain={walletChain}
1108+
tokenAddress={
1109+
props.displayBalanceToken?.[Number(walletChain?.id)]
1110+
}
1111+
formatFn={(props: AccountBalanceInfo) =>
1112+
formatAccountTokenBalance({ ...props, decimals: 7 })
1113+
}
1114+
/>{" "}
1115+
<AccountBalance
1116+
loadingComponent={<Skeleton height="1em" width="30px" />}
1117+
chain={walletChain}
1118+
tokenAddress={
1119+
props.displayBalanceToken?.[Number(walletChain?.id)]
1120+
}
1121+
formatFn={(props: AccountBalanceInfo) =>
1122+
` (${formatAccountFiatBalance({ ...props, decimals: 3 })})`
1123+
}
1124+
showBalanceInFiat="USD"
1125+
/>
1126+
</>
1127+
) : (
1128+
<AccountBalance
1129+
fallbackComponent={<Skeleton height="1em" width="100px" />}
1130+
loadingComponent={<Skeleton height="1em" width="100px" />}
1131+
formatFn={(props: AccountBalanceInfo) =>
1132+
formatAccountTokenBalance({ ...props, decimals: 7 })
1133+
}
1134+
chain={walletChain}
1135+
tokenAddress={
1136+
props.displayBalanceToken?.[Number(walletChain?.id)]
1137+
}
1138+
/>
1139+
)}
1140+
</Text>
1141+
</Text>
1142+
</ChainProvider>
1143+
1144+
<StyledChevronRightIcon
1145+
width={iconSize.sm}
1146+
height={iconSize.sm}
1147+
style={{
1148+
flexShrink: 0,
1149+
marginLeft: "auto",
1150+
}}
1151+
/>
1152+
</MenuButton>
1153+
);
1154+
}
1155+
11021156
const WalletInfoButton = /* @__PURE__ */ StyledButton((_) => {
11031157
const theme = useCustomTheme();
11041158
return {

0 commit comments

Comments
 (0)