From bc98aebce45bce4594961ea2e2227b0926e3382d Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Mon, 25 Oct 2021 13:00:19 +0800 Subject: [PATCH 1/5] chore: wallet status box --- .../src/components/shared/WalletStatusBox.tsx | 192 ++++++++++++++ .../SNSAdaptor/WalletStatusDialog/index.tsx | 235 +----------------- 2 files changed, 198 insertions(+), 229 deletions(-) create mode 100644 packages/maskbook/src/components/shared/WalletStatusBox.tsx diff --git a/packages/maskbook/src/components/shared/WalletStatusBox.tsx b/packages/maskbook/src/components/shared/WalletStatusBox.tsx new file mode 100644 index 000000000000..aa4787d20ddf --- /dev/null +++ b/packages/maskbook/src/components/shared/WalletStatusBox.tsx @@ -0,0 +1,192 @@ +import { FormattedAddress, useRemoteControlledDialog, useValueRef, useSnackbarCallback } from '@masknet/shared' +import { WalletMessages } from '../../plugins/Wallet/messages' +import classNames from 'classnames' +import { currentProviderSettings } from '../../plugins/Wallet/settings' +import { useCopyToClipboard } from 'react-use' +import { Copy, ExternalLink } from 'react-feather' +import { useI18N } from '../../utils' +import Services from '../../extension/service' +import { ProviderType, resolveAddressLinkOnExplorer, useWallet, useChainId } from '@masknet/web3-shared-evm' +import { Button, Link, Typography } from '@mui/material' +import { makeStyles, getMaskColor } from '@masknet/theme' +import { WalletIcon } from './WalletIcon' +import { useCallback } from 'react' + +const useStyles = makeStyles()((theme) => ({ + content: { + padding: theme.spacing(2, 3, 3), + }, + currentAccount: { + padding: theme.spacing(2, 3), + marginBottom: theme.spacing(2), + display: 'flex', + backgroundColor: getMaskColor(theme).twitterBackground, + borderRadius: 8, + alignItems: 'center', + }, + accountInfo: { + fontSize: 16, + flexGrow: 1, + marginLeft: theme.spacing(1), + }, + accountName: { + fontSize: 16, + marginRight: 6, + }, + infoRow: { + display: 'flex', + alignItems: 'center', + }, + actionButton: { + fontSize: 12, + marginLeft: theme.spacing(1), + backgroundColor: theme.palette.mode === 'light' ? '#111418' : 'rgb(29, 155, 240)', + ...(theme.palette.mode === 'light' + ? { + '&:hover': { + backgroundColor: '#2f3640', + }, + } + : {}), + padding: theme.spacing(1, 2), + }, + address: { + fontSize: 16, + marginRight: theme.spacing(1), + display: 'inline-block', + }, + link: { + color: theme.palette.text.secondary, + fontSize: 14, + display: 'flex', + alignItems: 'center', + }, + linkIcon: { + marginRight: theme.spacing(1), + color: '#1C68F3', + }, + networkIcon: { + backgroundColor: '#fff !important', + }, + providerIcon: { + backgroundColor: '#F7F9FA !important', + }, +})) + +export function WalletStatusBox() { + const { t } = useI18N() + const chainId = useChainId() + const selectedWallet = useWallet() + const { classes } = useStyles() + const { setDialog: setRenameDialog } = useRemoteControlledDialog(WalletMessages.events.walletRenameDialogUpdated) + const selectedProviderType = useValueRef(currentProviderSettings) + + //#region copy addr to clipboard + const [, copyToClipboard] = useCopyToClipboard() + const onCopy = useSnackbarCallback( + async (ev: React.MouseEvent) => { + ev.stopPropagation() + copyToClipboard(selectedWallet?.address ?? '') + }, + [], + undefined, + undefined, + undefined, + t('copy_success_of_wallet_addr'), + ) + //#endregion + + //#region change provider + const { openDialog: openSelectProviderDialog } = useRemoteControlledDialog( + WalletMessages.events.selectProviderDialogUpdated, + ) + //#endregion + + //#region walletconnect + const { setDialog: setWalletConnectDialog } = useRemoteControlledDialog( + WalletMessages.events.walletConnectQRCodeDialogUpdated, + ) + //#endregion + + const onDisconnect = useCallback(async () => { + if (selectedProviderType !== ProviderType.WalletConnect) return + setWalletConnectDialog({ + open: true, + uri: await Services.Ethereum.createConnectionURI(), + }) + }, [selectedProviderType, setWalletConnectDialog]) + + const onChange = useCallback(() => { + openSelectProviderDialog() + }, [openSelectProviderDialog]) + + return selectedWallet ? ( +
+ +
+
+ {selectedWallet.name} + { + setRenameDialog({ + open: true, + wallet: selectedWallet, + }) + }}> + {/* */} + +
+
+ + + + + + + + + +
+
+
+ {selectedProviderType === ProviderType.WalletConnect ? ( + + ) : null} + +
+
+ ) : null +} diff --git a/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx b/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx index f5bc390cb206..55313c33f95e 100644 --- a/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx +++ b/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletStatusDialog/index.tsx @@ -1,53 +1,20 @@ -import { FormattedAddress, useRemoteControlledDialog, useValueRef, useSnackbarCallback } from '@masknet/shared' -import { - ProviderType, - resolveAddressLinkOnExplorer, - useChainId, - useChainIdValid, - useWallet, -} from '@masknet/web3-shared-evm' -import { Button, DialogActions, DialogContent, Link, Typography } from '@mui/material' +import { useRemoteControlledDialog } from '@masknet/shared' +import { useChainIdValid } from '@masknet/web3-shared-evm' +import { DialogActions, DialogContent, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import ErrorIcon from '@mui/icons-material/Error' -import classNames from 'classnames' import { useCallback } from 'react' -import { Copy, ExternalLink } from 'react-feather' -import { useCopyToClipboard } from 'react-use' import { InjectedDialog } from '../../../../components/shared/InjectedDialog' import { MaskApplicationBox } from '../../../../components/shared/MaskApplicationBox' -import { WalletIcon } from '../../../../components/shared/WalletIcon' -import Services from '../../../../extension/service' +import { WalletStatusBox } from '../../../../components/shared/WalletStatusBox' import { useI18N } from '../../../../utils' import { WalletMessages } from '../../messages' -import { currentProviderSettings } from '../../settings' import { MaskMessages } from '../../../../utils/messages' -import { getMaskColor } from '@masknet/theme' const useStyles = makeStyles()((theme) => ({ content: { padding: theme.spacing(2, 3, 3), }, - currentAccount: { - padding: theme.spacing(2, 3), - marginBottom: theme.spacing(2), - display: 'flex', - backgroundColor: getMaskColor(theme).twitterBackground, - borderRadius: 8, - alignItems: 'center', - }, - accountInfo: { - fontSize: 16, - flexGrow: 1, - marginLeft: theme.spacing(1), - }, - accountName: { - fontSize: 16, - marginRight: 6, - }, - infoRow: { - display: 'flex', - alignItems: 'center', - }, footer: { fontSize: 12, textAlign: 'left', @@ -55,51 +22,11 @@ const useStyles = makeStyles()((theme) => ({ borderTop: `1px solid ${theme.palette.divider}`, justifyContent: 'flex-start', }, - transactionList: { - alignItems: 'center', - }, - actions: {}, - actionButton: { - fontSize: 12, - marginLeft: theme.spacing(1), - backgroundColor: theme.palette.mode === 'light' ? '#111418' : 'rgb(29, 155, 240)', - ...(theme.palette.mode === 'light' - ? { - '&:hover': { - backgroundColor: '#2f3640', - }, - } - : {}), - padding: theme.spacing(1, 2), - }, - changeButton: { - borderRadius: 20, - }, - iconWrapper: { - position: 'relative', - height: 48, - width: 48, - marginRight: theme.spacing(1.5), - }, - tip: { - flex: 1, - fontSize: 14, - }, address: { fontSize: 16, marginRight: theme.spacing(1), display: 'inline-block', }, - link: { - color: theme.palette.text.secondary, - fontSize: 14, - display: 'flex', - alignItems: 'center', - }, - linkIcon: { - marginRight: theme.spacing(1), - color: '#1C68F3', - }, subTitle: { fontSize: 18, lineHeight: '24px', @@ -107,68 +34,13 @@ const useStyles = makeStyles()((theme) => ({ marginBottom: 11.5, color: theme.palette.text.primary, }, - networkIcon: { - backgroundColor: '#fff !important', - }, - providerIcon: { - backgroundColor: '#F7F9FA !important', - }, - applicationBox: { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - backgroundColor: getMaskColor(theme).twitterBackground, - borderRadius: '8px', - cursor: 'pointer', - height: 100, - '&:hover': { - transform: 'translateX(2.5px) translateY(-2px)', - boxShadow: `0px 12px 28px ${ - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.1)' : 'rgba(255, 255, 255, 0.02)' - }`, - }, - }, - applicationWrapper: { - display: 'grid', - gridTemplateColumns: '123px 123px 123px 123px', - gridTemplateRows: '100px', - rowGap: 12, - justifyContent: 'space-between', - height: 324, - }, - applicationImg: { - width: 36, - height: 36, - marginBottom: 10, - }, })) -export interface WalletStatusDialogProps {} - -export function WalletStatusDialog(props: WalletStatusDialogProps) { +export function WalletStatusDialog() { const { t } = useI18N() const { classes } = useStyles() - const chainId = useChainId() const chainIdValid = useChainIdValid() - const selectedWallet = useWallet() - const selectedProviderType = useValueRef(currentProviderSettings) - - //#region copy addr to clipboard - const [, copyToClipboard] = useCopyToClipboard() - const onCopy = useSnackbarCallback( - async (ev: React.MouseEvent) => { - ev.stopPropagation() - copyToClipboard(selectedWallet?.address ?? '') - }, - [], - undefined, - undefined, - undefined, - t('copy_success_of_wallet_addr'), - ) - //#endregion //#region remote controlled dialog logic const { open, closeDialog: _closeDialog } = useRemoteControlledDialog( @@ -184,106 +56,11 @@ export function WalletStatusDialog(props: WalletStatusDialogProps) { }, []) //#endregion - //#region change provider - const { openDialog: openSelectProviderDialog } = useRemoteControlledDialog( - WalletMessages.events.selectProviderDialogUpdated, - ) - //#endregion - - //#region walletconnect - const { setDialog: setWalletConnectDialog } = useRemoteControlledDialog( - WalletMessages.events.walletConnectQRCodeDialogUpdated, - ) - //#endregion - - const { setDialog: setRenameDialog } = useRemoteControlledDialog(WalletMessages.events.walletRenameDialogUpdated) - - const onDisconnect = useCallback(async () => { - if (selectedProviderType !== ProviderType.WalletConnect) return - closeDialog() - setWalletConnectDialog({ - open: true, - uri: await Services.Ethereum.createConnectionURI(), - }) - }, [selectedProviderType, closeDialog, setWalletConnectDialog]) - const onChange = useCallback(() => { - closeDialog() - openSelectProviderDialog() - }, [closeDialog, openSelectProviderDialog]) - - if (!selectedWallet) return null - return ( {t('wallets')} -
- -
-
- {selectedWallet.name} - { - setRenameDialog({ - open: true, - wallet: selectedWallet, - }) - }}> - {/* */} - -
-
- - - - - - - - - -
-
-
- {selectedProviderType === ProviderType.WalletConnect ? ( - - ) : null} - -
-
+ {t('applications')}
From bc9152baaca81822815b8e4764032b498b740940 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Mon, 25 Oct 2021 15:25:34 +0800 Subject: [PATCH 2/5] chore: chain tab style --- .../src/components/shared/AbstractTab.tsx | 1 + .../src/components/shared/NetworkTab.tsx | 38 +++++++++++++------ .../plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx | 24 +++++++++++- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/packages/maskbook/src/components/shared/AbstractTab.tsx b/packages/maskbook/src/components/shared/AbstractTab.tsx index 584d283f8f7c..8050f8e0de15 100644 --- a/packages/maskbook/src/components/shared/AbstractTab.tsx +++ b/packages/maskbook/src/components/shared/AbstractTab.tsx @@ -6,6 +6,7 @@ import { useStylesExtends } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ tab: { minWidth: 'unset', + background: theme.palette.mode === 'light' ? '#F6F8F8' : '#17191D', }, tabPanel: { marginTop: theme.spacing(1), diff --git a/packages/maskbook/src/components/shared/NetworkTab.tsx b/packages/maskbook/src/components/shared/NetworkTab.tsx index cfb696cb37e3..dfd6dcad8fdb 100644 --- a/packages/maskbook/src/components/shared/NetworkTab.tsx +++ b/packages/maskbook/src/components/shared/NetworkTab.tsx @@ -1,16 +1,36 @@ import { makeStyles } from '@masknet/theme' import { useStylesExtends } from '@masknet/shared' import AbstractTab, { AbstractTabProps } from './AbstractTab' -import { ChainId } from '@masknet/web3-shared-evm' +import type { ChainId } from '@masknet/web3-shared-evm' -const useStyles = makeStyles()(() => ({})) +interface StyleProps { + chainLength: number + parentWidth: number +} +const useStyles = makeStyles()((theme, props) => ({ + tabs: { + '& .MuiTabs-flexContainer': { + display: 'grid', + gridTemplateColumns: Array(props.chainLength) + .fill(props.parentWidth / props.chainLength + 'px') + .join(' '), + columnGap: 1, + backgroundColor: theme.palette.background.paper, + }, + }, +})) interface NetworkTabProps extends withClasses<'tab' | 'tabs' | 'tabPanel' | 'indicator' | 'focusTab' | 'tabPaper'> { + chains: { chainName: string; chainId: ChainId }[] setChainId: (chainId: ChainId) => void chainId: ChainId + parentWidth: number } export function NetworkTab(props: NetworkTabProps) { - const classes = useStylesExtends(useStyles(), props) - const { chainId, setChainId } = props + const classes = useStylesExtends( + useStyles({ chainLength: props.chains.length, parentWidth: props.parentWidth }), + props, + ) + const { chainId, setChainId, chains } = props const createTabItem = (name: string, chainId: ChainId) => ({ label: {name}, sx: { p: 0 }, @@ -18,14 +38,8 @@ export function NetworkTab(props: NetworkTabProps) { }) const tabProps: AbstractTabProps = { - tabs: [ - createTabItem('ETH', ChainId.Mainnet), - createTabItem('BSC', ChainId.BSC), - createTabItem('Polygon/Matic', ChainId.Matic), - createTabItem('Arbitrum', ChainId.Arbitrum), - createTabItem('xDai', ChainId.xDai), - ], - index: [ChainId.Mainnet, ChainId.BSC, ChainId.Matic, ChainId.Arbitrum, ChainId.xDai].indexOf(chainId), + tabs: chains.map((chain) => createTabItem(chain.chainName, chain.chainId)), + index: chains.map((chain) => chain.chainId).indexOf(chainId), classes, hasOnlyOneChild: true, } diff --git a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx index f32f89b369be..3ce7e4bf3940 100644 --- a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx +++ b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx @@ -16,6 +16,7 @@ import { } from '@masknet/web3-shared-evm' import classNames from 'classnames' import { NetworkTab } from '../../../components/shared/NetworkTab' +import { WalletStatusBox } from '../../../components/shared/WalletStatusBox' import { useI18N } from '../../../utils' import { useSpaceStationCampaignInfo } from './hooks/useSpaceStationCampaignInfo' import { NftAirdropCard } from './NftAirdropCard' @@ -200,10 +201,14 @@ const useStyles = makeStyles()((theme, props) => ({ top: 0, width: '100%', zIndex: 2, - paddingTop: theme.spacing(4), + paddingTop: theme.spacing(1), paddingBottom: theme.spacing(2), backgroundColor: theme.palette.background.paper, }, + walletStatusBox: { + width: 535, + margin: '24px auto', + }, })) interface ClaimAllDialogProps { @@ -345,8 +350,23 @@ export function ClaimAllDialog(props: ClaimAllDialogProps) { }}> +
+ +
- +
{(showNftAirdrop || loadingAirdrop) && chainId === ChainId.Matic ? ( From dd5aff2a15657dd01717ea8e0d6baed3c0fad78f Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Tue, 26 Oct 2021 12:53:23 +0800 Subject: [PATCH 3/5] chore: second dir entry --- .../src/components/shared/AbstractTab.tsx | 1 - .../shared/EntrySecondLevelDialog.tsx | 53 ++++ .../components/shared/MaskApplicationBox.tsx | 230 +++++++++++++----- .../src/components/shared/NetworkTab.tsx | 16 +- .../src/components/shared/assets/dHEDGE.png | Bin 0 -> 1176 bytes .../shared/assets/pool_together.png | Bin 0 -> 4273 bytes .../components/shared/assets/valuables.png | Bin 0 -> 1096 bytes .../src/components/shared/assets/zerion.png | Bin 0 -> 18039 bytes .../plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx | 8 +- 9 files changed, 235 insertions(+), 73 deletions(-) create mode 100644 packages/maskbook/src/components/shared/EntrySecondLevelDialog.tsx create mode 100644 packages/maskbook/src/components/shared/assets/dHEDGE.png create mode 100644 packages/maskbook/src/components/shared/assets/pool_together.png create mode 100644 packages/maskbook/src/components/shared/assets/valuables.png create mode 100644 packages/maskbook/src/components/shared/assets/zerion.png diff --git a/packages/maskbook/src/components/shared/AbstractTab.tsx b/packages/maskbook/src/components/shared/AbstractTab.tsx index 8050f8e0de15..584d283f8f7c 100644 --- a/packages/maskbook/src/components/shared/AbstractTab.tsx +++ b/packages/maskbook/src/components/shared/AbstractTab.tsx @@ -6,7 +6,6 @@ import { useStylesExtends } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ tab: { minWidth: 'unset', - background: theme.palette.mode === 'light' ? '#F6F8F8' : '#17191D', }, tabPanel: { marginTop: theme.spacing(1), diff --git a/packages/maskbook/src/components/shared/EntrySecondLevelDialog.tsx b/packages/maskbook/src/components/shared/EntrySecondLevelDialog.tsx new file mode 100644 index 000000000000..35b46b2665c9 --- /dev/null +++ b/packages/maskbook/src/components/shared/EntrySecondLevelDialog.tsx @@ -0,0 +1,53 @@ +import { DialogContent } from '@mui/material' +import { makeStyles } from '@masknet/theme' +import { InjectedDialog } from './InjectedDialog' +import { WalletStatusBox } from './WalletStatusBox' +import { MaskApplicationBox, MaskAppEntry } from './MaskApplicationBox' +import type { ChainId } from '@masknet/web3-shared-evm' + +const useStyles = makeStyles()((theme) => ({ + content: { + padding: theme.spacing(2, 3, 3), + minHeight: 491, + }, + footer: { + fontSize: 12, + textAlign: 'left', + padding: theme.spacing(2), + borderTop: `1px solid ${theme.palette.divider}`, + justifyContent: 'flex-start', + }, + address: { + fontSize: 16, + marginRight: theme.spacing(1), + display: 'inline-block', + }, + subTitle: { + fontSize: 18, + lineHeight: '24px', + fontWeight: 600, + marginBottom: 11.5, + color: theme.palette.text.primary, + }, +})) + +interface EntrySecondLevelDialogProps { + title: string + entries?: MaskAppEntry[] + chains?: ChainId[] + open: boolean + closeDialog: () => void +} + +export function EntrySecondLevelDialog(props: EntrySecondLevelDialogProps) { + const { classes } = useStyles() + + return ( + + + + + + + ) +} diff --git a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx index 4feba0232b69..d7a3721ee609 100644 --- a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx +++ b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx @@ -1,5 +1,5 @@ import { Typography } from '@mui/material' -import { useCallback } from 'react' +import { useCallback, useState } from 'react' import { makeStyles } from '@masknet/theme' import { getMaskColor } from '@masknet/theme' import { MaskMessages } from '../../utils/messages' @@ -8,8 +8,43 @@ import { RedPacketPluginID } from '../../plugins/RedPacket/constants' import { FileServicePluginID } from '../../plugins/FileService/constants' import { ITO_PluginID } from '../../plugins/ITO/constants' import { ClaimAllDialog } from '../../plugins/ITO/SNSAdaptor/ClaimAllDialog' +import { EntrySecondLevelDialog } from './EntrySecondLevelDialog' +import { NetworkTab } from './NetworkTab' +import { ChainId, useChainId } from '@masknet/web3-shared-evm' const useStyles = makeStyles()((theme) => ({ + abstractTabWrapper: { + position: 'sticky', + top: 0, + width: '100%', + zIndex: 2, + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(2), + backgroundColor: theme.palette.background.paper, + }, + tab: { + height: 36, + minHeight: 36, + fontWeight: 300, + }, + tabs: { + width: 552, + height: 36, + minHeight: 36, + margin: '0 auto', + borderRadius: 4, + backgroundColor: theme.palette.background.default, + '& .Mui-selected': { + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.primary.main, + }, + }, + tabPanel: { + marginTop: theme.spacing(3), + }, + indicator: { + display: 'none', + }, applicationBox: { display: 'flex', flexDirection: 'column', @@ -25,6 +60,7 @@ const useStyles = makeStyles()((theme) => ({ }, }, applicationWrapper: { + marginTop: 4, display: 'grid', gridTemplateColumns: '123px 123px 123px 123px', gridTemplateRows: '100px', @@ -39,10 +75,21 @@ const useStyles = makeStyles()((theme) => ({ }, })) -interface MaskApplicationBoxProps {} +export interface MaskAppEntry { + title: string + img: string + onClick: any + supportedChains?: ChainId[] +} + +interface MaskApplicationBoxProps { + secondEntries?: MaskAppEntry[] + secondEntryChainTabs?: ChainId[] +} -export function MaskApplicationBox({}: MaskApplicationBoxProps) { +export function MaskApplicationBox({ secondEntries, secondEntryChainTabs }: MaskApplicationBoxProps) { const { classes } = useStyles() + const currentChainId = useChainId() //#region Encrypted message const openEncryptedMessage = useCallback( (id?: string) => @@ -65,78 +112,141 @@ export function MaskApplicationBox({}: MaskApplicationBoxProps) { } = useControlledDialog() //#endregion - return ( - <> -
- {[ - { - title: 'Lucky Drop', - img: new URL('./assets/lucky_drop.png', import.meta.url).toString(), - onClick: useCallback(() => { - openEncryptedMessage(RedPacketPluginID) - }, []), - }, - { - title: 'File service', - img: new URL('./assets/files.png', import.meta.url).toString(), - onClick: useCallback(() => { - openEncryptedMessage(FileServicePluginID) - }, []), - }, - { - title: 'ITO', - img: new URL('./assets/token.png', import.meta.url).toString(), - onClick: useCallback(() => { - openEncryptedMessage(ITO_PluginID) - }, []), - }, - { - title: 'Claim', - img: new URL('./assets/gift.png', import.meta.url).toString(), - onClick: onClaimAllDialogOpen, - }, - { - title: 'Mask Bridge', - img: new URL('./assets/bridge.png', import.meta.url).toString(), - }, + //#region second level entry dialog + const { + open: isSecondLevelEntryDialogOpen, + onOpen: onSecondLevelEntryDialogOpen, + onClose: onSecondLevelEntryDialogClose, + } = useControlledDialog() + + const [secondLevelEntryDialogTitle, setSecondLevelEntryDialogTitle] = useState('') + const [secondLevelEntryChains, setSecondLevelEntryChains] = useState([]) + const [secondLevelEntries, setSecondLevelEntries] = useState([]) + + const [chainId, setChainId] = useState( + secondEntryChainTabs?.includes(currentChainId) ? currentChainId : ChainId.Mainnet, + ) + + const openSecondEntryDir = useCallback((title: string, maskAppEntries: MaskAppEntry[], chains: ChainId[]) => { + setSecondLevelEntryDialogTitle(title) + setSecondLevelEntries(maskAppEntries) + setSecondLevelEntryChains(chains) + onSecondLevelEntryDialogOpen() + }, []) + //#endregion + + function createEntry(title: string, img: string, onClick: any, supportedChains?: ChainId[]) { + return { + title, + img, + onClick, + supportedChains, + } + } + + const firstLevelEntries: MaskAppEntry[] = [ + createEntry('Lucky Drop', new URL('./assets/lucky_drop.png', import.meta.url).toString(), () => { + openEncryptedMessage(RedPacketPluginID) + }), + createEntry('File service', new URL('./assets/files.png', import.meta.url).toString(), () => { + openEncryptedMessage(FileServicePluginID) + }), + createEntry('ITO', new URL('./assets/token.png', import.meta.url).toString(), () => { + openEncryptedMessage(ITO_PluginID) + }), + createEntry('Claim', new URL('./assets/gift.png', import.meta.url).toString(), onClaimAllDialogOpen), + createEntry('Mask Bridge', new URL('./assets/bridge.png', import.meta.url).toString(), undefined), + createEntry('Mask Box', new URL('./assets/mask_box.png', import.meta.url).toString(), undefined), + createEntry('Swap', new URL('./assets/swap.png', import.meta.url).toString(), undefined), + createEntry('Fiat on/off ramp', new URL('./assets/fiat_ramp.png', import.meta.url).toString(), undefined), + createEntry('NFTs', new URL('./assets/nft.png', import.meta.url).toString(), () => + openSecondEntryDir( + 'NFTs', + [ { - title: 'Mask Box', + title: 'MaskBox', img: new URL('./assets/mask_box.png', import.meta.url).toString(), + onClick: () => {}, }, { - title: 'Swap', - img: new URL('./assets/swap.png', import.meta.url).toString(), + title: 'Valuables', + img: new URL('./assets/valuables.png', import.meta.url).toString(), + onClick: () => {}, }, + ], + [ChainId.Mainnet, ChainId.BSC], + ), + ), + createEntry('Investment', new URL('./assets/investment.png', import.meta.url).toString(), () => + openSecondEntryDir( + 'Investment', + [ { - title: 'Fiat on/off ramp', - img: new URL('./assets/fiat_ramp.png', import.meta.url).toString(), + title: 'Zerion', + img: new URL('./assets/zerion.png', import.meta.url).toString(), + onClick: () => {}, + supportedChains: [ChainId.Mainnet], }, { - title: 'NFTs', - img: new URL('./assets/nft.png', import.meta.url).toString(), + title: 'dHEDGE', + img: new URL('./assets/dHEDGE.png', import.meta.url).toString(), + onClick: () => {}, }, + ], + [ChainId.Mainnet, ChainId.BSC, ChainId.Matic, ChainId.Arbitrum, ChainId.xDai], + ), + ), + createEntry('Saving', new URL('./assets/saving.png', import.meta.url).toString(), undefined), + createEntry('Alternative', new URL('./assets/more.png', import.meta.url).toString(), () => + openSecondEntryDir( + 'Alternative', + [ { - title: 'Investment', - img: new URL('./assets/investment.png', import.meta.url).toString(), + title: 'PoolTogether', + img: new URL('./assets/pool_together.png', import.meta.url).toString(), + onClick: () => {}, }, - { - title: 'Saving', - img: new URL('./assets/saving.png', import.meta.url).toString(), - }, - { - title: 'Alternative', - img: new URL('./assets/more.png', import.meta.url).toString(), - }, - ].map(({ title, img, onClick }, i) => ( -
- - {title} -
- ))} + ], + [ChainId.Mainnet, ChainId.BSC, ChainId.Matic, ChainId.Arbitrum, ChainId.xDai], + ), + ), + ] + + return ( + <> + {secondEntryChainTabs?.length ? ( +
+ +
+ ) : null} +
+ {(secondEntries ?? firstLevelEntries).map(({ title, img, onClick, supportedChains }, i) => + !supportedChains || supportedChains?.includes(chainId) ? ( +
+ + {title} +
+ ) : null, + )}
{isClaimAllDialogOpen ? ( ) : null} + {isSecondLevelEntryDialogOpen ? ( + + ) : null} ) } diff --git a/packages/maskbook/src/components/shared/NetworkTab.tsx b/packages/maskbook/src/components/shared/NetworkTab.tsx index dfd6dcad8fdb..cead29f4739f 100644 --- a/packages/maskbook/src/components/shared/NetworkTab.tsx +++ b/packages/maskbook/src/components/shared/NetworkTab.tsx @@ -1,26 +1,30 @@ import { makeStyles } from '@masknet/theme' import { useStylesExtends } from '@masknet/shared' import AbstractTab, { AbstractTabProps } from './AbstractTab' -import type { ChainId } from '@masknet/web3-shared-evm' +import { ChainId, getChainDetailed } from '@masknet/web3-shared-evm' interface StyleProps { chainLength: number parentWidth: number } const useStyles = makeStyles()((theme, props) => ({ + tab: { + background: theme.palette.mode === 'light' ? '#F6F8F8' : '#17191D', + }, tabs: { '& .MuiTabs-flexContainer': { display: 'grid', gridTemplateColumns: Array(props.chainLength) - .fill(props.parentWidth / props.chainLength + 'px') + .fill(Math.floor(props.parentWidth / props.chainLength) - 1 + 'px') .join(' '), columnGap: 1, backgroundColor: theme.palette.background.paper, }, }, })) + interface NetworkTabProps extends withClasses<'tab' | 'tabs' | 'tabPanel' | 'indicator' | 'focusTab' | 'tabPaper'> { - chains: { chainName: string; chainId: ChainId }[] + chains: ChainId[] setChainId: (chainId: ChainId) => void chainId: ChainId parentWidth: number @@ -38,8 +42,10 @@ export function NetworkTab(props: NetworkTabProps) { }) const tabProps: AbstractTabProps = { - tabs: chains.map((chain) => createTabItem(chain.chainName, chain.chainId)), - index: chains.map((chain) => chain.chainId).indexOf(chainId), + tabs: chains.map((chainId) => + createTabItem(getChainDetailed(chainId)?.chain?.replace('Matic', 'Polygon') ?? 'Unknown', chainId), + ), + index: chains.indexOf(chainId), classes, hasOnlyOneChild: true, } diff --git a/packages/maskbook/src/components/shared/assets/dHEDGE.png b/packages/maskbook/src/components/shared/assets/dHEDGE.png new file mode 100644 index 0000000000000000000000000000000000000000..bdff40cfed1aaab73677f5af22409ef059af7e24 GIT binary patch literal 1176 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>caTa()7BevDc!MzGQrl@Ofr5<1 zLGDfr>(0r%1aer?9eo`c7&i8E|4C#8a&8g4!*do*C$-(zzA!CSSBPC`HFc77i*gF@*FF2vxi|xb6zY4Q z@16PHebd=VN5en=%a^NA0on!z0=t{1+x9Nszp{0o(7rR9!&gV``*HFAmepr$Kh00i zQe@h-Uf|r}`tr~?o~fCky6z6;U+XN+wNK_$T5!Adr<(TfQ~KL#ER^QV=6Dh8WU=%1 z=g+?VS$4e*b|uO(ciI}7PRm}Mw*LZ;YB)#vwRa6S0%vYDUXZ@Lb(;0REMxhen}L#B zj2E!~Jh4BYGi@gWGgA{M#jY*+d=fkT7Wb&aB6KvdTaC#3}@q8nRW95S_E@pU%L zTDXJn<^fR8>xsRcAaeLeTJD`%?Em%arCm`PYuEqm?YzvL z`qM>wuKm`%|H5=#9lk&7Gu8gS^>VGEz=gRjsa|>U+Nbw#`I+_EkmZY|PVjc61^ufM zXKKa%(3)0Ty2YJDuQDzoR0fE+-U+ z{0=gGk@Zh!Le94v|BKwaV!GEm2)EgDfjsXnVSDMdf9>VxW-?yl)MzpOY<`_h`rlV)-RZAYc>c(~J^k~=M*f%O zp=*BqXR(;`>-1~!d%GWq*i;qX^H7x|b{U z7i{oJ{a17R=j7)H*_;a(iOCCm_Fb%FwBY*Z)n`v#5`1Xl{*`g+JN=zSvwwn$7cjVU YzkX9tn2W#Up1UBvr>mdKI;Vst0IKHdy8r+H literal 0 HcmV?d00001 diff --git a/packages/maskbook/src/components/shared/assets/pool_together.png b/packages/maskbook/src/components/shared/assets/pool_together.png new file mode 100644 index 0000000000000000000000000000000000000000..9344b060e8db9f3040fbfa4cd0759b15b76e5107 GIT binary patch literal 4273 zcmV;i5KixjP)@~0drDELIAGL9O(c600d`2O+f$vv5yP~wlDb4%=YBu}Q7UIJgzY0|`W^J0-AvE63@$dtHCVu@XF3G8o%77bDm3HP#?B{`s_hk;L%q6B0Ud4es<<2#C;2=@LI2zeGih45ta0G}^) z$;De;r~m{O6ngMh05u5MHwf4XWIw%EfKU`k5dUP`<_%$DqJ#;FvIhxcAu{0sc?@LO zCBOR1AuKr73y52h+R-X|_9_sc{e)F!Jy19;C<7F_?7JMY@AR1c=L-}U`Str9SP-lf z5VtN3?>alEZFYcHOCuIFI|1qvJbHRm(B0@1Csj$-Rp3kmc zKly*M9k=CmlPHGtq~lL~pfHeB5a|O&GWz~mIEH6n0p$!X@Py$b57R`IcmH{5Iv4hW zqoXb~8(P8U;sY$km5doI8su(IY)Ij)lP{0Xec`O|zOk0;04M z9ehgESzOp$61`&0v9c!%BlaAWxqw;U@^bv#XV06g!XbM7bO+Xu&BGd9IQRusnOMqN_I7z#=WX*0hCXthA}?rMt-Sk2ge8l8tKKFec9myhui*<*F2JD>qQ z0=mD31A75DX6NN!j&JL;v9#{DU<69{$hAi|ASbzFAl^;r#FGyqISnR0Y>#DkE{4jzCs z72Rbg>54^VfDroR=E?tve}h@s0{}x)tVJ#it-4e^?DO^f^-0I~WH(rwYc?=TKJ(dW z2Q;832BPp-uvPJ3dmn%;P`ERCa>yI(IfeJY6rv*H@nFI)(ETjpLCEIe=!H763-2*# zKvxhgFr_2_6?(lru!E3Xd$>Ecwco!5rbfX<0-BV<_k2|`k6+CGP)l5=M?e@zkJF-e zF9(p3_)5`ZR&%l|+Q>g2rSE_d1fhsD1EYsotq*@UjuMCj z6)5=x<_Vo#;%AlHJtHEo*T=WXGB8TiT>UX$Q|T;S^7}_x$`cyvK!SS7&|e1?qNoG& zWHfM=F{IPqqXJPZBB~xEUnC%XwJm)D5(UyEQnNsVf%&4H3<@{1xCZivzjxS=eb7Zs zk_Zn5lm32o2)#14O;Z4k=&VGG0_jyyAjud)C?1x!uiVP~ZsK7qq$i*j6%hxr3~Uzn zDJYF-3ZM~v0+I#Nf4ih4BE~%8pxvY{l?knBeN7bqNCc#4Ii!Q7ngVFPE6{{AkREt# zP=XZg#=@C;W8$pkU`!w>T^-aN2G<}KtQnehu-xhAyTq@BlAc^%5 z`{GFy5J;2v@>rjfy~JttZ2iScf=Pot*{UCkV}&(uL%3aYsYI)Qw?Q?nNB1R~$|D=X7!DPW2@!-2I1F;Abv(~RN20)bkap~oGlGk1n`8i5 z$F$;rS~0C}2*iWcXK@Xvt5QIu_ju_f7=OXjeqkCAki>c{*D?pw(vpAlm)Qcv?Hj_*&d|hn zH#IAxBiN>t&O`s$KpezkvHNRxSv(eiX6U`uRo**IGK~L;+!w|^!V!42{vU|yZQ*uG zI$!`p0+JM~Jg*H|_h7EUYy*3Q>BnnYn)op};QJztgG@c$%I-_C|A&Cs(i1bydS(Pf zCB-U2)zW#B4Q3P@`PaTkGM3qP@zLcr6XOByEAubO+*j{NyuD5{TjB}sOUVtYU_?Ny z#E)@+Ad4caDs8R>G?)d<iNg znW0R!w2#ETNajl+rfE?eDT7VQ;^;v9zLZ$XqsrzC)9~g@zjR|OC7S(KSL000y zKYeZtMbND8@VQ^ay9l!W<|N2w@5MVQZ;Ric+xOr@wuss3RN-@BcK5b0zQ^vVpXWbVHM`nGLtHwlP{mc&CAm$gCqLQl` zmsrbKdr9Ic1F2~2%1&)TYs7;Pau4azz3$?7gEp~i4*#H1r|VrIXA}HpdYSnWPW!XI|X2Z zKA9enLk0_|+(R@Q#Rw=~`$uLyFqqBuWpyuXFiH(FjfcfChoml)n`~oNv3Mq0z);sh z;?pQZK+}7MSz6DA5MUa*i;AadF(FU<4E)4RiaByK-TH8A9X0TR3nsj67Yd@dWqzlv z@P%2~lxDAFHmJcX3meW}ms=NF-vyJ4s!s`exqurD$&ktkg;^h@Fac$pxv(*HR9yGi z*cfz2IG7r{F15B?r9V4)mMrf*qEp3#>_UMMD3D~uP+aXa$nf?M@L=@%pD^)-r}lI2 z(m|%y(V1ZdI9B&L`Coi9nFGnNh8`qKB6H#R!<|gsj)#>yXge%@k+8VMUZhHAubeAMCv|D;Q~T`LNL?MnEY}NHQ?iA@AX8vMLLLn#MW-r6if!7JG`bI0C37$t|4*OgO`pj!nWzu~tB% z@L=0#LW;1M#_K=s3T;$T%Ud1L1PM(QqFIKRL8fG@~qpfTpn^b)`|lcy-vN zZhX_drLOHlkx>c(A@Lw6&EDZSU$%-I@H9zj1cVsBHKh*lo*bh4ku50Yx@$AunsPq( z+QM_a|ZGxAOq#Di2qKnS1fZalE&<8qs}v|1EFC0y7jNh|H-)x>7nF&i~! zb)K?jTQVwRfl|nu|Jc{t1<8AoZ$f{ily#nIRL%m8lJsQbOw<_yY!r@n2Ny%AqHt0w zEufU73v&A0{1=2}tt_ijITt2Ge9!v{(9nq|#tCRP%Fz9&1t%b6FbF`2Qnb%%!3hYV zR8GNz3th;` zR-Ax1Gpu$-T_BBAUO-7OtZsok8i2zIh-F~2Eg(g~#X#T$gm=-Ibp^7(rSeWdjA-^H z?9SB#s5nkQd0f%JYeU7Uw1AS^CCzSuTpUz!3p8s0of5C(TxqH;AWwFy$jq=n`f>mj zrrH7`B=g;)r8H??5iT^96%g--*3y;{meR+EuOxRZ>9w?mIxPfG!#h zO=4U;s%e2}6XTWubV19nx-ji=OA8wHN(R%Vo)^YlRn*)85(TGUF|rV62$XbA z{~5e-T{%``l~FnY#kZ#P;`oL{8y3u<*k{7(vQPE|`u)ALcVAp|YEUBhg5!LKDNVLm zaeZtsOB6qA)_=?X{T-Bua>YRTE6au{U&`-B;|r%;vpE(n2BP;bUk4a&B{y6-`)bRA zm}d&KBi>9tS;SS%7EnNIPobQ1(^;TI{=8_bn=PUXD{H}y%r?PszPK33kqajvM=qRz z9Jz1;a^%7Z$dL;tAV)5ofE>AS0&?WS3CNKPCm=^Itn3HkQ*I(bS)Y0(?>nX~@kGU= zF4;Wnf`wQ&n9BQQnvJL67zI1hZrIo!Yo7~Sa;u*TU<0ihry*&?#Xyc+H~~3w;RNK! zg%gk?7fwKn!!xiD>*_${jZZ`R(QE7Aks!mnGrVU};FAH)OI~~ieNy0U%d_);lORJ) Tx{O}Y00000NkvXXu0mjfP|)3C literal 0 HcmV?d00001 diff --git a/packages/maskbook/src/components/shared/assets/valuables.png b/packages/maskbook/src/components/shared/assets/valuables.png new file mode 100644 index 0000000000000000000000000000000000000000..3b3ff2a3b26888532f1ed8915790b8473b520267 GIT binary patch literal 1096 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>caTa()7BevDc!MzGQrl@Ofr5<1 zLGDfr>(0r%1aer?9eo`c7&i8E|4C$JU|_!M>Eakt!T9#>UEkXQGHoBX%YV;Re{plc zmv!Y|*<524ZZ_mKm^bjAVABiXN_qTS&)$YxDzG&|0tKUEL9C7Hom3eDt zZhGRmJ##mgX(g@?jdI)kqAKrTu-G3Ak+U*F%^ za}-$@Rur=D477ZBXTHQ2^Mw(Pr^Bl{Ki-+2ywKv~-`SJQBK^>m05es8ZhV4AV>=9|Zb_Fc@I ztphdRueN{ZeD&79gp8W?nXCT1H#a@xcV=pOP^x zPPLP&8vZx7&zvv*j`NdvP>jRWUxMO)R{rV8S|}d;bM~4A|E_+Tr=GoV-Vp|`{`9l4 z!i5)1H#=8yFX^}6JO7f#-=AhqVa7}Kd!i0^%vOAE;4QGpGghFOH(Sdrxq0=JeFADy zamqmED${dY&qu{fUSd=KPwKSFSJ9YLY6otLOC>$8f4}74r{+_J!MDyE-2L?LYfy#9 zsjNRysj@fs1tnYRuS@^bnYgre&40VI zGe6C}JMq(x-l{US)Ss?~{QfnCa;L&$9MmU?ojG^R_GJFN4>QhgE5BE&UZv%?@BY^J zpT6nVui9PwRb^?~vH4LiSG64HeswV9Qj=s#-qV+#PNr_Hn)J9?X66^pPdS_aWPM#R zaZ3W*Z2eEZw|{PZxKCQOt}Ca{Txg^8`zN#4rq$m4_51n~e<~wYxY&?AVNF z+vlBpdR1H3`BsUn-?H0BzE{pF>w6NbE{B}+7#I>#{xSBPyYYE(t0}0QVDNPHb6Mw< G&;$U5apVF3 literal 0 HcmV?d00001 diff --git a/packages/maskbook/src/components/shared/assets/zerion.png b/packages/maskbook/src/components/shared/assets/zerion.png new file mode 100644 index 0000000000000000000000000000000000000000..25156e8c48fa2d16f4230d530b8ed569f5052411 GIT binary patch literal 18039 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 KMNUMnLSTZ%^9XYQ literal 0 HcmV?d00001 diff --git a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx index 3ce7e4bf3940..f7323967d866 100644 --- a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx +++ b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx @@ -359,13 +359,7 @@ export function ClaimAllDialog(props: ClaimAllDialogProps) { chainId={chainId} setChainId={setChainId} classes={classes} - chains={[ - { chainName: 'ETH', chainId: ChainId.Mainnet }, - { chainName: 'BSC', chainId: ChainId.BSC }, - { chainName: 'Polygon/Matic', chainId: ChainId.Matic }, - { chainName: 'Arbitrum', chainId: ChainId.Arbitrum }, - { chainName: 'xDai', chainId: ChainId.xDai }, - ]} + chains={[ChainId.Mainnet, ChainId.BSC, ChainId.Matic, ChainId.Arbitrum, ChainId.xDai]} />
From c207865611e592cd8479e6bcb950ebc3fb25234f Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Tue, 26 Oct 2021 13:07:07 +0800 Subject: [PATCH 4/5] chore: fix style --- .../src/components/shared/MaskApplicationBox.tsx | 1 - packages/maskbook/src/components/shared/NetworkTab.tsx | 9 ++------- .../src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx index d7a3721ee609..05e6e4325ee2 100644 --- a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx +++ b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx @@ -217,7 +217,6 @@ export function MaskApplicationBox({ secondEntries, secondEntryChainTabs }: Mask {secondEntryChainTabs?.length ? (
()((theme, props) => ({ tab: { @@ -15,7 +14,7 @@ const useStyles = makeStyles()((theme, props) => ({ '& .MuiTabs-flexContainer': { display: 'grid', gridTemplateColumns: Array(props.chainLength) - .fill(Math.floor(props.parentWidth / props.chainLength) - 1 + 'px') + .fill(100 / props.chainLength + '%') .join(' '), columnGap: 1, backgroundColor: theme.palette.background.paper, @@ -27,13 +26,9 @@ interface NetworkTabProps extends withClasses<'tab' | 'tabs' | 'tabPanel' | 'ind chains: ChainId[] setChainId: (chainId: ChainId) => void chainId: ChainId - parentWidth: number } export function NetworkTab(props: NetworkTabProps) { - const classes = useStylesExtends( - useStyles({ chainLength: props.chains.length, parentWidth: props.parentWidth }), - props, - ) + const classes = useStylesExtends(useStyles({ chainLength: props.chains.length }), props) const { chainId, setChainId, chains } = props const createTabItem = (name: string, chainId: ChainId) => ({ label: {name}, diff --git a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx index f7323967d866..8753bd7606da 100644 --- a/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx +++ b/packages/maskbook/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx @@ -355,7 +355,6 @@ export function ClaimAllDialog(props: ClaimAllDialogProps) {
Date: Wed, 27 Oct 2021 12:35:24 +0800 Subject: [PATCH 5/5] chore: reply review --- .../components/shared/MaskApplicationBox.tsx | 46 +++++++++++++------ .../src/components/shared/NetworkTab.tsx | 9 ++-- .../src/components/shared/WalletStatusBox.tsx | 5 +- packages/web3-shared/evm/assets/chains.json | 2 +- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx index 05e6e4325ee2..031a74cdc840 100644 --- a/packages/maskbook/src/components/shared/MaskApplicationBox.tsx +++ b/packages/maskbook/src/components/shared/MaskApplicationBox.tsx @@ -7,10 +7,13 @@ import { useControlledDialog } from '../../utils/hooks/useControlledDialog' import { RedPacketPluginID } from '../../plugins/RedPacket/constants' import { FileServicePluginID } from '../../plugins/FileService/constants' import { ITO_PluginID } from '../../plugins/ITO/constants' +import { PluginTransakMessages } from '../../plugins/Transak/messages' +import { PluginTraderMessages } from '../../plugins/Trader/messages' import { ClaimAllDialog } from '../../plugins/ITO/SNSAdaptor/ClaimAllDialog' import { EntrySecondLevelDialog } from './EntrySecondLevelDialog' import { NetworkTab } from './NetworkTab' -import { ChainId, useChainId } from '@masknet/web3-shared-evm' +import { ChainId, useChainId, useAccount } from '@masknet/web3-shared-evm' +import { useRemoteControlledDialog } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ abstractTabWrapper: { @@ -55,8 +58,8 @@ const useStyles = makeStyles()((theme) => ({ cursor: 'pointer', height: 100, '&:hover': { - transform: 'translateX(2.5px) translateY(-2px)', - boxShadow: theme.palette.mode === 'light' ? '0px 12px 28px rgba(0, 0, 0, 0.1)' : 'none', + transform: 'scale(1.05) translateY(-4px)', + boxShadow: theme.palette.mode === 'light' ? '0px 10px 16px rgba(0, 0, 0, 0.1)' : 'none', }, }, applicationWrapper: { @@ -90,6 +93,7 @@ interface MaskApplicationBoxProps { export function MaskApplicationBox({ secondEntries, secondEntryChainTabs }: MaskApplicationBoxProps) { const { classes } = useStyles() const currentChainId = useChainId() + const account = useAccount() //#region Encrypted message const openEncryptedMessage = useCallback( (id?: string) => @@ -112,6 +116,14 @@ export function MaskApplicationBox({ secondEntries, secondEntryChainTabs }: Mask } = useControlledDialog() //#endregion + //#region Swap + const { openDialog: openSwapDialog } = useRemoteControlledDialog(PluginTraderMessages.swapDialogUpdated) + //#endregion + + //#region Fiat on/off ramp + const { setDialog: setBuyDialog } = useRemoteControlledDialog(PluginTransakMessages.buyTokenDialogUpdated) + //#endregion + //#region second level entry dialog const { open: isSecondLevelEntryDialogOpen, @@ -145,20 +157,24 @@ export function MaskApplicationBox({ secondEntries, secondEntryChainTabs }: Mask } const firstLevelEntries: MaskAppEntry[] = [ - createEntry('Lucky Drop', new URL('./assets/lucky_drop.png', import.meta.url).toString(), () => { - openEncryptedMessage(RedPacketPluginID) - }), - createEntry('File service', new URL('./assets/files.png', import.meta.url).toString(), () => { - openEncryptedMessage(FileServicePluginID) - }), - createEntry('ITO', new URL('./assets/token.png', import.meta.url).toString(), () => { - openEncryptedMessage(ITO_PluginID) - }), + createEntry('Lucky Drop', new URL('./assets/lucky_drop.png', import.meta.url).toString(), () => + openEncryptedMessage(RedPacketPluginID), + ), + createEntry('File service', new URL('./assets/files.png', import.meta.url).toString(), () => + openEncryptedMessage(FileServicePluginID), + ), + createEntry('ITO', new URL('./assets/token.png', import.meta.url).toString(), () => + openEncryptedMessage(ITO_PluginID), + ), createEntry('Claim', new URL('./assets/gift.png', import.meta.url).toString(), onClaimAllDialogOpen), - createEntry('Mask Bridge', new URL('./assets/bridge.png', import.meta.url).toString(), undefined), + createEntry('Mask Bridge', new URL('./assets/bridge.png', import.meta.url).toString(), () => + window.open('https://bridge.mask.io/#/', '_blank', 'noopener noreferrer'), + ), createEntry('Mask Box', new URL('./assets/mask_box.png', import.meta.url).toString(), undefined), - createEntry('Swap', new URL('./assets/swap.png', import.meta.url).toString(), undefined), - createEntry('Fiat on/off ramp', new URL('./assets/fiat_ramp.png', import.meta.url).toString(), undefined), + createEntry('Swap', new URL('./assets/swap.png', import.meta.url).toString(), openSwapDialog), + createEntry('Fiat on/off ramp', new URL('./assets/fiat_ramp.png', import.meta.url).toString(), () => + setBuyDialog({ open: true, address: account }), + ), createEntry('NFTs', new URL('./assets/nft.png', import.meta.url).toString(), () => openSecondEntryDir( 'NFTs', diff --git a/packages/maskbook/src/components/shared/NetworkTab.tsx b/packages/maskbook/src/components/shared/NetworkTab.tsx index 131c1a27f591..1d7fb22b7f71 100644 --- a/packages/maskbook/src/components/shared/NetworkTab.tsx +++ b/packages/maskbook/src/components/shared/NetworkTab.tsx @@ -9,6 +9,10 @@ interface StyleProps { const useStyles = makeStyles()((theme, props) => ({ tab: { background: theme.palette.mode === 'light' ? '#F6F8F8' : '#17191D', + marginRight: 1, + '&:last-child': { + marginRight: 0, + }, }, tabs: { '& .MuiTabs-flexContainer': { @@ -16,7 +20,6 @@ const useStyles = makeStyles()((theme, props) => ({ gridTemplateColumns: Array(props.chainLength) .fill(100 / props.chainLength + '%') .join(' '), - columnGap: 1, backgroundColor: theme.palette.background.paper, }, }, @@ -37,9 +40,7 @@ export function NetworkTab(props: NetworkTabProps) { }) const tabProps: AbstractTabProps = { - tabs: chains.map((chainId) => - createTabItem(getChainDetailed(chainId)?.chain?.replace('Matic', 'Polygon') ?? 'Unknown', chainId), - ), + tabs: chains.map((chainId) => createTabItem(getChainDetailed(chainId)?.chain ?? 'Unknown', chainId)), index: chains.indexOf(chainId), classes, hasOnlyOneChild: true, diff --git a/packages/maskbook/src/components/shared/WalletStatusBox.tsx b/packages/maskbook/src/components/shared/WalletStatusBox.tsx index aa4787d20ddf..d1c4ba9a09a4 100644 --- a/packages/maskbook/src/components/shared/WalletStatusBox.tsx +++ b/packages/maskbook/src/components/shared/WalletStatusBox.tsx @@ -141,9 +141,8 @@ export function WalletStatusBox() { open: true, wallet: selectedWallet, }) - }}> - {/* */} - + }} + />
diff --git a/packages/web3-shared/evm/assets/chains.json b/packages/web3-shared/evm/assets/chains.json index 6cf783d64c85..acab2845dbe0 100644 --- a/packages/web3-shared/evm/assets/chains.json +++ b/packages/web3-shared/evm/assets/chains.json @@ -174,7 +174,7 @@ "chainId": 137, "fullName": "Polygon", "shortName": "matic", - "chain": "Matic", + "chain": "Polygon", "network": "mainnet", "networkId": 137, "nativeCurrency": {