chain switcher for developers (#1055)

* chain switcher for developers

* suspense

* remove log
This commit is contained in:
Léo Galley
2024-10-10 13:22:12 -04:00
committed by GitHub
parent f8118bc22b
commit b89e81e1c5
6 changed files with 77 additions and 12 deletions

View File

@@ -0,0 +1,49 @@
import { useErrors } from 'apps/web/contexts/Errors';
import Dropdown from 'apps/web/src/components/Dropdown';
import DropdownItem from 'apps/web/src/components/DropdownItem';
import DropdownMenu from 'apps/web/src/components/DropdownMenu';
import DropdownToggle from 'apps/web/src/components/DropdownToggle';
import { useCallback } from 'react';
import { Chain } from 'viem';
import { useAccount, useSwitchChain } from 'wagmi';
export function DropdownChainSwitcher({
chain,
currentChain,
}: {
chain: Chain;
currentChain: Chain;
}) {
const { switchChainAsync } = useSwitchChain();
const { logError } = useErrors();
const handleSwitchChain = useCallback(() => {
if (chain !== currentChain) {
switchChainAsync({ chainId: chain.id }).catch((error) =>
logError(error, 'Failed to switch chain'),
);
}
}, [chain, currentChain, logError, switchChainAsync]);
return <DropdownItem onClick={handleSwitchChain}>{chain.name}</DropdownItem>;
}
export default function ChainDropdown() {
const { chain: currentChain, isConnected } = useAccount();
const { chains } = useSwitchChain();
if (!isConnected || !currentChain) return null;
return (
<Dropdown>
<DropdownToggle>
<span className="inline-block rounded bg-blue-5 px-3 py-1 text-blue-50">
{currentChain.name}
</span>
</DropdownToggle>
<DropdownMenu>
{chains.map((chain) => (
<DropdownChainSwitcher key={chain.id} chain={chain} currentChain={currentChain} />
))}
</DropdownMenu>
</Dropdown>
);
}

View File

@@ -25,6 +25,8 @@ import classNames from 'classnames';
import { useCallback, useEffect, useState } from 'react';
import { useCopyToClipboard } from 'usehooks-ts';
import { useAccount, useSwitchChain } from 'wagmi';
import ChainDropdown from 'apps/web/src/components/ChainDropdown';
import { useSearchParams } from 'next/navigation';
export enum ConnectWalletButtonVariants {
Default,
@@ -54,6 +56,9 @@ export function ConnectWalletButton({
() => switchChain({ chainId: base.id }),
[switchChain],
);
const searchParams = useSearchParams();
const showChainSwitcher = searchParams?.get('showChainSwitcher');
const [isMounted, setIsMounted] = useState<boolean>(false);
useEffect(() => {
@@ -142,11 +147,15 @@ export function ConnectWalletButton({
<Wallet>
<ConnectWallet
withWalletAggregator
className="rounded-none bg-transparent p-2 hover:bg-gray-40/20"
className="flex items-center justify-center rounded-none bg-transparent p-2 hover:bg-gray-40/20"
>
<UserAvatar />
<Name chain={basenameChain} className={userAddressClasses} />
<div className="flex items-center gap-2">
<UserAvatar />
<Name chain={basenameChain} className={userAddressClasses} />
{showChainSwitcher && <ChainDropdown />}
</div>
</ConnectWallet>
<WalletDropdown className="rounded bg-white font-sans shadow-md">
<Identity className={classNames('px-4 pb-2 pt-3 font-display', className)}>
<UserAvatar />

View File

@@ -1,5 +1,5 @@
'use client';
import React, { useState, useCallback } from 'react';
import React, { useState, useCallback, Suspense } from 'react';
import { AnimatePresence, motion, cubicBezier } from 'framer-motion';
import Link from 'next/link';
import { ActionType, ComponentType } from 'libs/base-ui/utils/logEvent';
@@ -258,7 +258,9 @@ function DesktopNav({ color }: DesktopNavProps) {
eventName="github"
/>
</Dropdown>
<ConnectWalletButton color={color} className="relative inline-block" />
<Suspense>
<ConnectWalletButton color={color} className="relative inline-block" />
</Suspense>
</div>
);
}

View File

@@ -1,5 +1,5 @@
'use client';
import React, { useCallback, useEffect, useState } from 'react';
import React, { Suspense, useCallback, useEffect, useState } from 'react';
import { AnimatePresence, motion, cubicBezier } from 'framer-motion';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
@@ -281,7 +281,9 @@ function MobileMenu({ color }: MobileMenuProps) {
</div>
<div className="mb-8">
<ConnectWalletButton color={REVERSE_COLOR[color]} className="" />
<Suspense>
<ConnectWalletButton color={REVERSE_COLOR[color]} className="" />
</Suspense>
</div>
<div className="flex flex-row justify-between gap-4 justify-self-end pb-8">

View File

@@ -12,7 +12,7 @@ import classNames from 'classnames';
import useBasenameChain from 'apps/web/src/hooks/useBasenameChain';
import { base, baseSepolia } from 'viem/chains';
import { Icon } from 'apps/web/src/components/Icon/Icon';
import { useCallback } from 'react';
import { Suspense, useCallback } from 'react';
import { isDevelopment } from 'apps/web/src/constants';
import ImageAdaptive from 'apps/web/src/components/ImageAdaptive';
@@ -111,10 +111,12 @@ export default function UsernameNav() {
<ImageAdaptive src={usernameBaseLogo as StaticImageData} alt="Base" />
</Link>
<span className={walletStateClasses}>
<ConnectWalletButton
color="black"
connectWalletButtonVariant={ConnectWalletButtonVariants.Default}
/>
<Suspense>
<ConnectWalletButton
color="black"
connectWalletButtonVariant={ConnectWalletButtonVariants.Default}
/>
</Suspense>
</span>
</nav>
</div>

View File

@@ -67,6 +67,7 @@ type CCAEventData = {
userId?: string;
error?: string;
wallet_type?: string;
wallet_connector_id?: string;
flag_key?: string;
variant?: string | undefined;
experiment_key?: string | undefined;