diff --git a/packages/mask/src/components/shared/WalletStatusBox/index.tsx b/packages/mask/src/components/shared/WalletStatusBox/index.tsx index a3c6c864fb4e..f0f8eb6f7a2d 100644 --- a/packages/mask/src/components/shared/WalletStatusBox/index.tsx +++ b/packages/mask/src/components/shared/WalletStatusBox/index.tsx @@ -21,7 +21,7 @@ import { WalletMessages } from '../../../plugins/Wallet/messages' import { useI18N } from '../../../utils' import { usePendingTransactions } from './usePendingTransactions' -const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ +const useStyles = makeStyles()((theme) => ({ content: { padding: theme.spacing(2, 3, 3), }, @@ -29,7 +29,7 @@ const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard } padding: theme.spacing(1.5), marginBottom: theme.spacing(2), display: 'flex', - backgroundColor: isDashboard ? getMaskColor(theme).primaryBackground2 : theme.palette.background.default, + backgroundColor: isDashboardPage() ? getMaskColor(theme).primaryBackground2 : theme.palette.background.default, borderRadius: 8, alignItems: 'center', }, @@ -92,15 +92,13 @@ const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard } }, })) interface WalletStatusBox { - isDashboard?: boolean disableChange?: boolean showPendingTransaction?: boolean } export function WalletStatusBox(props: WalletStatusBox) { const { t } = useI18N() - const isDashboard = isDashboardPage() - const { classes } = useStyles({ isDashboard }) + const { classes } = useStyles() const chainId = useChainId() const account = useAccount() const wallet = useWallet() @@ -140,7 +138,7 @@ export function WalletStatusBox(props: WalletStatusBox) { className={classNames( classes.statusBox, classes.currentAccount, - props.isDashboard ? classes.dashboardBackground : '', + isDashboardPage() ? classes.dashboardBackground : '', )}> void) | undefined +type Account = { account?: string; chainId: ChainId } +let deferredConnect: Promise | null = null +let resolveConnect: ((result: Account) => void) | undefined let rejectConnect: ((error: Error) => void) | undefined export async function connectWalletConnect() { - const [deferred, resolve, reject] = defer<{ account?: string; chainId: ChainId }>() + const [deferred, resolve, reject] = defer() + deferredConnect = deferred resolveConnect = resolve rejectConnect = reject createWalletConnect().then(resolve, reject) @@ -32,6 +35,7 @@ export async function connectWalletConnect() { export async function createWalletConnect() { const connector = await WalletConnect.createConnectorIfNeeded() + if (connector.connected) return { account: first(connector.accounts), @@ -45,8 +49,13 @@ export async function createWalletConnect() { } } +export async function untilWalletConnect() { + if (!deferredConnect) throw new Error('No connection.') + return deferredConnect +} + export async function cancelWalletConnect() { - rejectConnect?.(new Error('Failed to connect to WalletConnect.')) + rejectConnect?.(new Error('User rejected the request.')) } // #endregion diff --git a/packages/mask/src/extension/popups/components/LoadingPlaceholder/index.tsx b/packages/mask/src/extension/popups/components/LoadingPlaceholder/index.tsx index 1d8aae506255..ac0fdeaa9304 100644 --- a/packages/mask/src/extension/popups/components/LoadingPlaceholder/index.tsx +++ b/packages/mask/src/extension/popups/components/LoadingPlaceholder/index.tsx @@ -15,15 +15,21 @@ const useStyles = makeStyles()((theme) => ({ }, })) -export const LoadingPlaceholder = memo(() => { +export interface LoadingPlaceholderProps { + title?: string + titleColor?: string + iconColor?: string +} + +export const LoadingPlaceholder = memo((props: LoadingPlaceholderProps) => { const { t } = useI18N() const { classes } = useStyles() return (
- - - {t('loading')} + + + {props.title ?? t('loading')}
) diff --git a/packages/mask/src/plugins/Wallet/Dashboard/index.tsx b/packages/mask/src/plugins/Wallet/Dashboard/index.tsx index 780608eec12f..5e832820dbb1 100644 --- a/packages/mask/src/plugins/Wallet/Dashboard/index.tsx +++ b/packages/mask/src/plugins/Wallet/Dashboard/index.tsx @@ -23,7 +23,7 @@ const dashboard: Plugin.Dashboard.Definition = { - + diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx index 24cfe55458f3..e19bf8cf3d20 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx @@ -1,7 +1,7 @@ -import { useCallback, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { useAsyncRetry } from 'react-use' import { DialogContent } from '@mui/material' -import { makeStyles } from '@masknet/theme' +import { makeStyles, usePopupCustomSnackbar } from '@masknet/theme' import { safeUnreachable, delay } from '@dimensiondev/kit' import { ChainId, @@ -17,16 +17,30 @@ import { InjectedDialog } from '@masknet/shared' import { WalletMessages } from '../../messages' import { ConnectionProgress } from './ConnectionProgress' import Services from '../../../../extension/service' +import { isPopupPage } from '@masknet/shared-base' +import { LoadingPlaceholder } from '../../../../extension/popups/components/LoadingPlaceholder' +import { useI18N } from '../../../../utils' const useStyles = makeStyles()((theme) => ({ content: { padding: theme.spacing(2.5), }, + popupDialog: { + width: 200, + margin: 'auto', + }, + popupDialogPaper: { + backgroundColor: 'transparent', + }, + popupDialogContent: { + backgroundColor: 'rgba(0, 0, 0, 0.8)', + }, })) export interface ConnectWalletDialogProps {} export function ConnectWalletDialog(props: ConnectWalletDialogProps) { + const { t } = useI18N() const { classes } = useStyles() const [providerType, setProviderType] = useState() const [networkType, setNetworkType] = useState() @@ -150,8 +164,38 @@ export function ConnectWalletDialog(props: ConnectWalletDialogProps) { return true }, [open, connectTo, setConnectWalletDialog]) + const { showSnackbar } = usePopupCustomSnackbar() + useEffect(() => { + if (!isPopupPage() || !connection.error) return + setConnectWalletDialog({ + open: false, + }) + showSnackbar(connection.error.message, { + variant: 'error', + }) + }, [connection.error, showSnackbar]) + if (!providerType) return null + if (isPopupPage()) { + return ( + + + + + + ) + } + return ( diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/index.tsx index bec9a9ba05e9..29f60f158d17 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/index.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/index.tsx @@ -38,8 +38,13 @@ export const WalletConnectQRCodeDialog: React.FC = () => { useAsync(async () => { if (!open) return - await Services.Ethereum.connectWalletConnect() - closeDialog() + try { + await Services.Ethereum.untilWalletConnect() + } catch { + // do nothing + } finally { + closeDialog() + } }, [open]) let mode: QRCodeDialogProps['mode'] = 'qrcode' diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx index 6cdba83c2d33..4990f9dc09e4 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx @@ -39,9 +39,7 @@ const useStyles = makeStyles()((theme) => ({ color: theme.palette.text.primary, }, })) -export interface WalletStatusDialogProps { - isDashboard?: boolean -} +export interface WalletStatusDialogProps {} export function WalletStatusDialog(props: WalletStatusDialogProps) { const { t } = useI18N() @@ -65,7 +63,7 @@ export function WalletStatusDialog(props: WalletStatusDialogProps) { return ( - + {!chainIdValid ? ( diff --git a/packages/shared/src/contexts/components/InjectedDialog.tsx b/packages/shared/src/contexts/components/InjectedDialog.tsx index c540c56a4a25..0858e6d43491 100644 --- a/packages/shared/src/contexts/components/InjectedDialog.tsx +++ b/packages/shared/src/contexts/components/InjectedDialog.tsx @@ -27,6 +27,7 @@ interface StyleProps { const useStyles = makeStyles()((theme, { clean }) => ({ dialogTitle: { whiteSpace: 'nowrap', + display: 'flex', gridTemplateColumns: '50px auto 50px', }, dialogTitleEndingContent: {