Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimized connect-button code #481

Merged
merged 10 commits into from
Jan 12, 2024
5 changes: 5 additions & 0 deletions .changeset/thick-singers-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ant-design/web3': patch
---

refactor: Optimization ConnectButton code
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ describe('more-wallets-connect', () => {
});
fireEvent.click(walletItems[1]!);
await vi.waitFor(() => {
expect(baseElement.querySelector('.ant-web3-connect-modal-qr-code-box')).toBeTruthy();
const qrCodeBox = baseElement.querySelector('.ant-web3-connect-modal-qr-code-box');
if (qrCodeBox !== null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边原来的写法没问题吧? 为什么要改成这样。 !== null 才except toBeTruthy 不是多余了。 然后现在落后主分支很多代码了,可以同步一下主分支的代码。

expect(qrCodeBox).toBeTruthy();
return true;
}
return false;
});
fireEvent.click(walletItems[0]!);
await vi.waitFor(() => {
Expand Down
113 changes: 53 additions & 60 deletions packages/web3/src/connect-button/connect-button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useContext, useMemo, useState } from 'react';
import { CopyOutlined, LoginOutlined, UserOutlined } from '@ant-design/icons';
import type { Chain } from '@ant-design/web3-common';
import type { ButtonProps } from 'antd';
import { Avatar, Button, ConfigProvider, Divider, Dropdown, message, Space } from 'antd';
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
Expand All @@ -8,9 +9,12 @@ import classNames from 'classnames';
import { Address } from '../address';
import { CryptoPrice } from '../crypto-price';
import useIntl from '../hooks/useIntl';
import type { IntlType } from '../hooks/useIntl';
import { fillWith0x, writeCopyText } from '../utils';
import { ChainSelect } from './chain-select';
import type { ChainSelectProps } from './chain-select';
import type { ConnectButtonProps, ConnectButtonTooltipProps } from './interface';
import type { ProfileModalProps } from './profile-modal';
import { ProfileModal } from './profile-modal';
import { useStyle } from './style';
import { ConnectButtonTooltip } from './tooltip';
Expand Down Expand Up @@ -73,21 +77,39 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
...restProps,
};

const renderChainSelect = () => {
if (availableChains && availableChains.length > 1) {
return (
<ChainSelect
hashId={hashId}
onSwitchChain={onSwitchChain}
currentChain={chain}
chains={availableChains}
/>
);
}
return null;
const chainProps: ChainSelectProps = {
hashId,
onSwitchChain,
currentChain: chain,
chains: availableChains as Chain[],
};

const chainSelect = renderChainSelect();
const profileModalProps: ProfileModalProps = {
intl,
open: profileOpen,
__hashId__: hashId,
onDisconnect: () => {
setProfileOpen(false);
onDisconnectClick?.();
},
onClose: () => {
setProfileOpen(false);
},
address: account?.address,
name: account?.name,
avatar: avatar ?? {
icon: chain?.icon ? (
<div className={`${prefixCls}-chain-icon`}>{chain?.icon}</div>
) : (
<UserOutlined className={`${prefixCls}-default-icon`} />
),
},
balance,
modalProps: typeof profileModal === 'object' ? profileModal : undefined,
};

const chainSelect =
(availableChains && availableChains.length > 1 && <ChainSelect {...chainProps} />) || null;
shanchuan1 marked this conversation as resolved.
Show resolved Hide resolved

const buttonInnerText = (
<div className={`${prefixCls}-content`}>
Expand All @@ -114,36 +136,6 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
<Button {...buttonProps}>{buttonInnerText}</Button>
);

const profileModalContent = (
<ProfileModal
intl={intl}
open={profileOpen}
__hashId__={hashId}
onDisconnect={() => {
setProfileOpen(false);
onDisconnectClick?.();
}}
onClose={() => {
setProfileOpen(false);
}}
address={account?.address}
name={account?.name}
avatar={
avatar ?? {
icon: chain?.icon ? (
<div className={`${prefixCls}-chain-icon`}>{chain?.icon}</div>
) : (
<UserOutlined className={`${prefixCls}-default-icon`} />
),
}
}
balance={balance}
modalProps={typeof profileModal === 'object' ? profileModal : undefined}
/>
);

let content = buttonContent;

const defaultMenuItems: MenuItemType[] = useMemo(
() => [
{
Expand Down Expand Up @@ -194,8 +186,8 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
return combinedItems;
}, [actionsMenu, defaultMenuItems, account]);

if (mergedMenuItems.length > 0) {
content = (
const content =
mergedMenuItems.length > 0 ? (
<Dropdown
open={showMenu}
onOpenChange={setShowMenu}
Expand All @@ -206,35 +198,36 @@ export const ConnectButton: React.FC<ConnectButtonProps> = (props) => {
>
{buttonContent}
</Dropdown>
) : (
buttonContent
);
}

const mergedTooltipCopyable: ConnectButtonTooltipProps['copyable'] =
typeof tooltip === 'object' ? tooltip.copyable !== false : !!tooltip;

let tooltipTitle: string = tooltip && account?.address ? fillWith0x(account?.address) : '';
if (typeof tooltip === 'object' && typeof tooltip.title === 'string') {
tooltipTitle = tooltip.title;
}
const ConnectButtonTooltipProps: () => ConnectButtonTooltipProps & { intl: IntlType } = () => {
shanchuan1 marked this conversation as resolved.
Show resolved Hide resolved
const mergedTooltipCopyable: ConnectButtonTooltipProps['copyable'] =
typeof tooltip === 'object' ? tooltip.copyable !== false : !!tooltip;
return {
intl,
copyable: mergedTooltipCopyable,
title: tooltipTitle,
prefixCls,
__hashId__: hashId,
...(typeof tooltip === 'object' ? tooltip : {}),
};
};

const main = (
<>
{contextHolder}
{tooltipTitle ? (
<ConnectButtonTooltip
intl={intl}
copyable={mergedTooltipCopyable}
title={tooltipTitle}
prefixCls={prefixCls}
__hashId__={hashId}
{...(typeof tooltip === 'object' ? tooltip : {})}
>
{content}
</ConnectButtonTooltip>
<ConnectButtonTooltip {...ConnectButtonTooltipProps()}>{content}</ConnectButtonTooltip>
) : (
content
)}
{profileModalContent}
<ProfileModal {...profileModalProps} />
</>
);

Expand Down
1 change: 0 additions & 1 deletion packages/web3/src/connect-button/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { AvatarProps, ButtonProps, MenuProps, TooltipProps } from 'antd';
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';

import type { AddressProps } from '../address';
import type { ProfileModalProps } from './profile-modal';
shanchuan1 marked this conversation as resolved.
Show resolved Hide resolved

export type ConnectButtonTooltipProps = TooltipProps & {
__hashId__?: string;
Expand Down
38 changes: 20 additions & 18 deletions packages/web3/src/connect-button/profile-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useContext } from 'react';
import { Address } from '@ant-design/web3';
import type { Balance } from '@ant-design/web3-common';
import { Avatar, Button, ConfigProvider, message, Modal, Space, type AvatarProps } from 'antd';
import type { ModalProps } from 'antd';
import { Avatar, Button, ConfigProvider, message, Modal, Space } from 'antd';
import type { AvatarProps, ModalProps } from 'antd';
import classNames from 'classnames';

import { CryptoPrice } from '../crypto-price';
Expand Down Expand Up @@ -41,26 +41,28 @@ export const ProfileModal: React.FC<ProfileModalProps> = ({
const prefixCls = getPrefixCls('web3-connect-button-profile-modal');
const [messageApi, contextHolder] = message.useMessage();

const footer = (
<div className={classNames(`${prefixCls}-footer`, __hashId__)}>
{address ? (
<Button
onClick={() => {
writeCopyText(address).then(() => {
messageApi.success(intl.getMessage(intl.messages.addressCopied));
});
}}
>
{intl.getMessage(intl.messages.copyAddress)}
</Button>
) : null}
<Button onClick={onDisconnect}>{intl.getMessage(intl.messages.disconnect)}</Button>
</div>
);

return (
<>
{contextHolder}
<Modal
footer={
<div className={classNames(`${prefixCls}-footer`, __hashId__)}>
{address ? (
<Button
onClick={() => {
writeCopyText(address).then(() => {
messageApi.success(intl.getMessage(intl.messages.addressCopied));
});
}}
>
{intl.getMessage(intl.messages.copyAddress)}
</Button>
) : null}
<Button onClick={onDisconnect}>{intl.getMessage(intl.messages.disconnect)}</Button>
</div>
}
footer={footer}
width={280}
{...modalProps}
onCancel={onClose}
Expand Down
Loading