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: ConnectModal support Intl #416

Merged
merged 10 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/eight-lizards-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@ant-design/web3-common': patch
'@ant-design/web3': patch
---

feat: ConnectModal support Intl
12 changes: 8 additions & 4 deletions .dumi/theme/layouts/GlobalLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import React from 'react';
import { useOutlet, usePrefersColor, useLocation } from 'dumi';
import { useOutlet, usePrefersColor, useLocation, useIntl } from 'dumi';
import { Web3ConfigProvider, en_US, zh_CN } from '@ant-design/web3-common';

import SiteThemeProvider from '../SiteThemeProvider';

const GlobalLayout: React.FC = () => {
const outlet = useOutlet();
const { pathname } = useLocation();
const [color] = usePrefersColor();
const { locale } = useIntl();

return (
<SiteThemeProvider themeMode={color || 'auto'}>
<div className={pathname === '/' || pathname === '/zh-CN' ? 'home' : ''}>{outlet}</div>
</SiteThemeProvider>
<Web3ConfigProvider locale={locale === 'zh-CN' ? zh_CN : en_US}>
<SiteThemeProvider themeMode={color || 'auto'}>
<div className={pathname === '/' || pathname === '/zh-CN' ? 'home' : ''}>{outlet}</div>
</SiteThemeProvider>
</Web3ConfigProvider>
);
};

Expand Down
31 changes: 30 additions & 1 deletion packages/common/src/locale/en_US.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RequiredLocale } from '../types';
import type { RequiredLocale } from '../types';

const localeValues: RequiredLocale = {
ConnectButton: {
Expand All @@ -8,6 +8,35 @@ const localeValues: RequiredLocale = {
addressCopied: 'Address Copied!',
walletAddress: 'Wallet address',
},
ConnectModal: {
title: 'Connect Wallet',
guideTitle: 'What is a Wallet?',
guideInfos1Title: 'Manage your private key and assets',
guideInfos1Desc: 'Manage your private key and the assets of the corresponding chain address',
guideInfos2Title: 'Help you connect to DApp',
guideInfos2Desc: 'Authorize DApp to get your address, similar to login',
guideInfos3Title: 'Call smart contract',
guideInfos3Desc:
'Through authorization of private key signature, initiate interaction with smart contract on the chain',
guideInfosGetWalletBtnText: 'Get a Wallet',
guideInfosMoreLinkText: 'Learn More',
getWalletBtnText: 'Get',
getWalletPanelTitle: 'Get a Wallet',
getWalletPanelInfoTitle: "Not what you're looking for?",
getWalletPanelInfoDesc:
'Select a wallet on the left to get started with a different wallet provider.',
qrCodePanelTitleForDownload: 'Download {wallet.name}',
qrCodePanelTitleForScan: 'Scan with {wallet.name}',
qrCodePanelLinkForDownload: 'Click to go to the download page',
qrCodePanelLinkForConnect: 'Click to connect directly',
qrCodePanelDownloadTipForReady: 'Scan the QR code to download the wallet.',
qrCodePanelDownloadTipForNotReady: "Don't have",
walletCardPanelTitle: 'Get {selectedWallet.name}',
walletCardAppTitle: '{selectedWallet.name} for Mobile',
walletCardAppDesc: 'Use the mobile wallet to explore the world of Ethereum.',
walletCardExtensionTitle: '{selectedWallet.name} for {selectedExtension.browserName}',
footer: 'Powered by AntChain',
kiner-tang marked this conversation as resolved.
Show resolved Hide resolved
},
};

export default localeValues;
1 change: 1 addition & 0 deletions packages/common/src/locale/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as en_US } from './en_US';
export { default as zh_CN } from './zh_CN';
export { default as defaultLocale } from './default';
30 changes: 29 additions & 1 deletion packages/common/src/locale/zh_CN.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RequiredLocale } from '../types';
import type { RequiredLocale } from '../types';

const localeValues: RequiredLocale = {
ConnectButton: {
Expand All @@ -8,6 +8,34 @@ const localeValues: RequiredLocale = {
addressCopied: '地址复制成功!',
walletAddress: '钱包地址',
},
ConnectModal: {
title: '连接钱包',
guideTitle: '什么是钱包?',
guideInfos1Title: '管理私钥和资产',
guideInfos1Desc: '管理私钥和对应链地址的资产',
guideInfos2Title: '帮助你连接 DApp',
guideInfos2Desc: '授权 DApp 获取你的地址,类似登录',
guideInfos3Title: '调用智能合约',
guideInfos3Desc: '通过授权私钥签名,发起与链上智能合约的交互',
guideInfosGetWalletBtnText: '获取钱包',
guideInfosMoreLinkText: '了解更多',
getWalletBtnText: '获取',
getWalletPanelTitle: '获取钱包',
getWalletPanelInfoTitle: '没有找到你想要的?',
getWalletPanelInfoDesc: '在左侧选择钱包,以开始使用不同的钱包提供商。',
qrCodePanelTitleForDownload: '下载 {wallet.name}',
qrCodePanelTitleForScan: '使用 {wallet.name} 扫描',
qrCodePanelLinkForDownload: '点击前往下载页面',
qrCodePanelLinkForConnect: '点击直接连接',
qrCodePanelDownloadTipForReady: '扫描二维码下载钱包',
qrCodePanelDownloadTipForNotReady: '暂无',
walletCardPanelTitle: '获取 {selectedWallet.name}',
walletCardAppTitle: '在手机使用 {selectedWallet.name}',
walletCardAppDesc: '使用移动钱包探索以太坊世界。',
walletCardExtensionTitle:
'在 {selectedExtension.browserName} 浏览器中使用 {selectedWallet.name}',
footer: '蚂蚁链提供技术支持',
kiner-tang marked this conversation as resolved.
Show resolved Hide resolved
},
};

export default localeValues;
28 changes: 28 additions & 0 deletions packages/common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,36 @@ export interface RequiredLocale {
addressCopied: string;
walletAddress: string;
};
ConnectModal: {
title: string;
guideTitle: string;
guideInfos1Title: string;
guideInfos1Desc: string;
guideInfos2Title: string;
guideInfos2Desc: string;
guideInfos3Title: string;
guideInfos3Desc: string;
guideInfosGetWalletBtnText: string;
guideInfosMoreLinkText: string;
getWalletBtnText: string;
getWalletPanelTitle: string;
getWalletPanelInfoTitle: string;
getWalletPanelInfoDesc: string;
qrCodePanelTitleForDownload: string;
qrCodePanelTitleForScan: string;
qrCodePanelLinkForDownload: string;
qrCodePanelLinkForConnect: string;
qrCodePanelDownloadTipForReady: string;
qrCodePanelDownloadTipForNotReady: string;
walletCardPanelTitle: string;
walletCardAppTitle: string;
walletCardAppDesc: string;
walletCardExtensionTitle: string;
footer: string;
kiner-tang marked this conversation as resolved.
Show resolved Hide resolved
};
}

export interface Locale {
ConnectButton?: Partial<RequiredLocale['ConnectButton']>;
ConnectModal?: Partial<RequiredLocale['ConnectModal']>;
}
2 changes: 1 addition & 1 deletion packages/common/src/web3-config-provider/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { RequiredLocale, Locale, UniversalWeb3ProviderInterface } from '../types';
import defaultLocale from '../locale/en_US';
import defaultLocale from '../locale/default';

export interface Web3ConfigProviderProps extends UniversalWeb3ProviderInterface {
children?: React.ReactNode;
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/web3-config-provider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { ConfigContext, type Web3ConfigProviderProps, type ConfigConsumerProps } from './context';
import defaultLocale from '../locale/en_US';
import defaultLocale from '../locale/default';

const ProviderChildren: React.FC<ConfigConsumerProps & { children?: React.ReactNode }> = (
props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Get wallet', () => {
fireEvent.click(baseElement.querySelector('.ant-web3-connect-modal-wallet-item')!);
await waitFor(() => {
expect(baseElement.querySelector('.ant-web3-connect-modal-get-wallet-btn')?.textContent).toBe(
'GET',
'Get',
);
});

Expand Down
2 changes: 1 addition & 1 deletion packages/web3/src/connect-modal/__tests__/mock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const walletList = [
{
icon: 'https://xsgames.co/randomusers/avatar.php?g=pixel&key=3',
name: 'Test Wallet3',
remark: '备注3',
remark: 'remark 3',
group: 'Popular',
app: {
link: 'https://test.com/xxx',
Expand Down
49 changes: 24 additions & 25 deletions packages/web3/src/connect-modal/components/DefaultGuidePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@ import React, { useContext } from 'react';
import { connectModalContext } from '../context';
import type { ConnectModalProps } from '../interface';

const defaultGuide: ConnectModalProps['guide'] = {
title: 'What is a Wallet?',
infos: [
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*ApSUSaoUa_sAAAAAAAAAAAAADlrGAQ/original',
title: 'Manage your private key and assets',
description: 'Manage your private key and the assets of the corresponding chain address',
},
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*3lD7QpnbCPcAAAAAAAAAAAAADlrGAQ/original',
title: 'Help you connect to DApp',
description: 'Authorize DApp to get your address, similar to login',
},
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*gTROQqEY_TcAAAAAAAAAAAAADlrGAQ/original',
title: 'Call smart contract',
description:
'Through authorization of private key signature, initiate interaction with smart contract on the chain',
},
],
moreLink: 'https://ethereum.org/en/wallets/',
getWalletBtnText: 'Get a Wallet',
moreLinkText: 'Learn More',
};

const DefaultGuidePanel: React.FC<{
guide?: ConnectModalProps['guide'];
}> = (props) => {
const { localeMessage } = useContext(connectModalContext);
const defaultGuide: ConnectModalProps['guide'] = {
title: localeMessage.guideTitle,
infos: [
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*ApSUSaoUa_sAAAAAAAAAAAAADlrGAQ/original',
title: localeMessage.guideInfos1Title,
description: localeMessage.guideInfos1Desc,
},
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*3lD7QpnbCPcAAAAAAAAAAAAADlrGAQ/original',
title: localeMessage.guideInfos2Title,
description: localeMessage.guideInfos2Desc,
},
{
icon: 'https://mdn.alipayobjects.com/huamei_mutawc/afts/img/A*gTROQqEY_TcAAAAAAAAAAAAADlrGAQ/original',
title: localeMessage.guideInfos3Title,
description: localeMessage.guideInfos3Desc,
},
],
moreLink: 'https://ethereum.org/en/wallets/',
getWalletBtnText: localeMessage.guideInfosGetWalletBtnText,
moreLinkText: localeMessage.guideInfosMoreLinkText,
};
const { guide = defaultGuide } = props;

const { prefixCls, updatePanelRoute } = useContext(connectModalContext);
Expand Down
13 changes: 7 additions & 6 deletions packages/web3/src/connect-modal/components/GetWalletPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export type GetWalletPanelProps = Pick<ConnectModalProps, 'walletList'>;

const GetWalletPanel: React.FC<GetWalletPanelProps> = (props) => {
const { walletList = [] } = props;
const [messageApi, contextHolder] = message.useMessage();
const { prefixCls, updateSelectedWallet, updatePanelRoute } = useContext(connectModalContext);
const [, contextHolder] = message.useMessage();
const { prefixCls, updateSelectedWallet, updatePanelRoute, localeMessage } =
useContext(connectModalContext);

const list = (
<>
Expand All @@ -32,7 +33,7 @@ const GetWalletPanel: React.FC<GetWalletPanelProps> = (props) => {
updatePanelRoute('wallet');
}}
>
Get
{localeMessage.getWalletBtnText}
</Button>,
]}
>
Expand All @@ -50,15 +51,15 @@ const GetWalletPanel: React.FC<GetWalletPanelProps> = (props) => {
/>
</div>
<div className={`${prefixCls}-info`}>
<h3>Not what you&apos;re looking for?</h3>
<div>Select a wallet on the left to get started with a different wallet provider.</div>
<h3>{localeMessage.getWalletPanelInfoTitle}</h3>
<div>{localeMessage.getWalletPanelInfoDesc}</div>
</div>
</>
);

return (
<div className={`${prefixCls}-get-wallet-panel`}>
<MainPanelHeader title="Get a Wallet" />
<MainPanelHeader title={localeMessage.getWalletPanelTitle} />
{list}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/web3/src/connect-modal/components/MainPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import GetWalletPanel from './GetWalletPanel';
import QrCode from './QrCode';
import WalletCard from './WalletCard';

export type MainPanelProps = Pick<ConnectModalProps, 'guide' | 'walletList'> & {
export type MainPanelProps = Pick<ConnectModalProps, 'guide' | 'walletList' | 'locale'> & {
simple: boolean;
};

Expand Down
16 changes: 13 additions & 3 deletions packages/web3/src/connect-modal/components/ModalPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import { ConnectModalContextProvider } from '../context';
import { useStyle } from '../style';
import useMode from '../hooks/useMode';
import type { PanelRoute, Wallet } from '../interface';
import useIntl from '../../hooks/useIntl';

export type ModalPanelProps = ConnectModalProps;

const ModalPanel: React.FC<ModalPanelProps> = (props) => {
const { title, footer, walletList, groupOrder, guide, mode, onWalletSelected } = props;
const { title, footer, walletList, groupOrder, guide, mode, onWalletSelected, locale } = props;
const intl = useIntl('ConnectModal', locale);

const [panelRoute, setPanelRoute] = React.useState<PanelRoute>('init');
const routeStack = React.useRef<PanelRoute[]>(['init']);
Expand All @@ -24,10 +26,16 @@ const ModalPanel: React.FC<ModalPanelProps> = (props) => {

const mergedTitle = mergeReactNodeProps(
title,
<h2 className={`${prefixCls}-title`}>Connect Modal</h2>,
<h2 className={`${prefixCls}-title`}>{intl.messages.title}</h2>,
(node) => <h2 className={`${prefixCls}-title`}>{node}</h2>,
);

const mergedFooter = mergeReactNodeProps(
footer,
<div className={`${prefixCls}-footer`}>{intl.messages.footer}</div>,
(node) => <div className={`${prefixCls}-footer`}>{node}</div>,
);

const updatePanelRoute = React.useCallback((route: PanelRoute, clear: boolean = false) => {
if (clear) {
routeStack.current = ['init'];
Expand Down Expand Up @@ -72,6 +80,8 @@ const ModalPanel: React.FC<ModalPanelProps> = (props) => {
updatePanelRoute,
panelRouteBack,
canBack: routeStack.current.length > 1,
localeMessage: intl.messages,
getMessage: intl.getMessage,
}}
>
<div
Expand All @@ -89,7 +99,7 @@ const ModalPanel: React.FC<ModalPanelProps> = (props) => {
<div className={`${prefixCls}-list-container`}>
<WalletList walletList={walletList} groupOrder={groupOrder} />
</div>
{footer && <div className={`${prefixCls}-footer`}>{footer}</div>}
{mergedFooter}
</div>
)}
{!(panelRoute === 'init' && isSimple) && (
Expand Down
Loading