mirror of
https://github.com/placeholder-soft/web.git
synced 2026-04-28 19:05:28 +08:00
chain switcher for developers (#1055)
* chain switcher for developers * suspense * remove log
This commit is contained in:
49
apps/web/src/components/ChainDropdown/index.tsx
Normal file
49
apps/web/src/components/ChainDropdown/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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 />
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user