Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
24 changes: 24 additions & 0 deletions packages/icons/general/AddUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { createIcon } from '../utils'
import type { SvgIcon } from '@mui/material'

export const AddUserIcon: typeof SvgIcon = createIcon(
'AddUserIcon',
<g>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M15.5 12.159a.6.6 0 0 1 .6.6v4.062a.6.6 0 0 1-1.2 0v-4.062a.6.6 0 0 1 .6-.6Z"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M18.132 14.79a.6.6 0 0 1-.6.6h-4.065a.6.6 0 0 1 0-1.2h4.065a.6.6 0 0 1 .6.6ZM9.298 2.41a2.992 2.992 0 1 0 0 5.984 2.992 2.992 0 0 0 0-5.983ZM5.106 5.403a4.192 4.192 0 1 1 8.384 0 4.192 4.192 0 0 1-8.384 0Z"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.519 8.988a7.797 7.797 0 0 1 8.497 1.69.6.6 0 0 1-.848.848 6.597 6.597 0 0 0-11.263 4.666.6.6 0 0 1-1.2 0A7.798 7.798 0 0 1 6.52 8.988Z"
/>
</g>,
'0 0 18 18',
)
20 changes: 20 additions & 0 deletions packages/icons/general/PopupRestore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createIcon } from '../utils'
import type { SvgIcon } from '@mui/material'

export const PopupRestoreIcon: typeof SvgIcon = createIcon(
'PopupRestoreIcon',
<g>
<path d="m13.777 8.974-3.636 1.02a.323.323 0 0 0-.213.458.38.38 0 0 0 .023.042l1.942 3.17a.46.46 0 0 0 .554.18.33.33 0 0 0 .177-.173l.501-.743c.863.446 1.46.842 1.802 1.673l.527 1.28a.457.457 0 0 0 .516.27.33.33 0 0 0 .27-.29l.115-1c.208-1.655-.805-3.351-2.512-4.207l.474-1.174c.074-.182-.037-.4-.249-.485a.452.452 0 0 0-.29-.021Zm-2.892 1.6 2.37-.667-.303.752c-.074.183.037.4.248.485 1.376.556 2.287 1.74 2.372 3.016-.514-1.052-1.464-1.911-2.629-2.38-.21-.085-.442-.006-.516.177l-.277.686-1.265-2.07Z" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.998 3.895c-.907.417-1.19.873-1.19 1.165 0 .292.283.747 1.19 1.165.856.394 2.08.654 3.465.654 1.384 0 2.609-.26 3.464-.654.908-.418 1.19-.873 1.19-1.165 0-.292-.283-.748-1.19-1.165-.855-.394-2.08-.654-3.464-.654-1.385 0-2.61.26-3.465.654Zm-.502-1.09c1.046-.482 2.45-.764 3.967-.764s2.92.282 3.966.764c.995.457 1.888 1.211 1.888 2.255 0 1.044-.893 1.797-1.888 2.255-1.046.482-2.449.764-3.966.764-1.518 0-2.92-.282-3.967-.764-.994-.458-1.888-1.211-1.888-2.255 0-1.044.894-1.798 1.888-2.255ZM5.775 9.292c.708.375 1.738.655 2.942.738l-.082 1.197c-1.325-.091-2.529-.401-3.422-.875-.859-.455-1.605-1.165-1.605-2.115h1.2c0 .262.224.661.967 1.055ZM5.775 12.24c.708.374 1.738.654 2.942.737l-.082 1.197c-1.325-.091-2.529-.401-3.422-.875-.859-.455-1.605-1.165-1.605-2.115h1.2c0 .263.224.661.967 1.055ZM5.678 14.94c.755.4 2.1.713 4.374.713v1.2c-2.347 0-3.924-.318-4.935-.852-1.053-.557-1.509-1.365-1.509-2.223h1.2c0 .355.156.784.87 1.162Z"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M14.717 4.358a.6.6 0 0 1 .6.6v2.548a.6.6 0 1 1-1.2 0V4.958a.6.6 0 0 1 .6-.6ZM4.208 4.358a.6.6 0 0 1 .6.6v8.82a.6.6 0 0 1-1.2 0v-8.82a.6.6 0 0 1 .6-.6Z"
/>
</g>,
'0 0 18 18',
)
2 changes: 2 additions & 0 deletions packages/icons/general/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,5 @@ export * from './FacebookRound'
export * from './InstagramRound'
export * from './MindsRound'
export * from './CircleLoading'
export * from './AddUser'
export * from './PopupRestore'
2 changes: 2 additions & 0 deletions packages/mask/shared-ui/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,8 @@
"popups_add_wallet": "Add Wallet",
"popups_profile_photo": "Profile Photo",
"popups_public_key": "Public Key",
"popups_create_persona": "Create Persona",
"popups_restore_and_login": "Restore or Login",
"popups_name": "Name",
"popups_social_account": "Social Accounts",
"popups_connected_wallets": "Connected Wallets",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { memo } from 'react'
import { useMatch } from 'react-router-dom'
import { Box, GlobalStyles, Paper } from '@mui/material'
import { makeStyles } from '@masknet/theme'
import { PopupRoutes } from '@masknet/shared-base'
import { useMyPersonas } from '../../../../components/DataSource/useMyPersonas'
import { InitialPlaceholder } from '../InitialPlaceholder'

function GlobalCss() {
return (
Expand Down Expand Up @@ -39,17 +35,12 @@ export interface PopupFrameProps extends React.PropsWithChildren<{}> {}

export const PopupFrame = memo<PopupFrameProps>((props) => {
const { classes } = useStyles()
const personas = useMyPersonas()

const matchRecovery = [useMatch(PopupRoutes.WalletRecovered), useMatch(PopupRoutes.Unlock)].some(Boolean)

return (
<>
<GlobalCss />
<Paper elevation={0} style={{ height: '100vh', overflowY: 'auto', minHeight: 560, borderRadius: 0 }}>
<Box className={classes.container}>
{personas.length === 0 && !matchRecovery ? <InitialPlaceholder /> : props.children}
</Box>
<Box className={classes.container}>{props.children}</Box>
</Paper>
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useChainId, useWallets, useWeb3State } from '@masknet/plugin-infra/web3
import { isSameAddress } from '@masknet/web3-shared-evm'
import { NextIDAction, NextIDPlatform, PopupRoutes } from '@masknet/shared-base'
import { useAsync, useAsyncFn } from 'react-use'
import { compact } from 'lodash-unified'
import { compact, sortBy } from 'lodash-unified'
import type { ConnectedWalletInfo } from '../type'
import { NextIDProof } from '@masknet/web3-providers'
import Service from '../../../../service'
Expand Down Expand Up @@ -46,14 +46,24 @@ const ConnectedWallets = memo(() => {

return {
...x,
name: `${x.platform} wallet ${index + 1}`,
name: '',
}
}
return null
}),
)

return compact(results)
return sortBy(compact(results), (x) => Number(x.created_at))
.map((x, index) => {
if (!x.name)
return {
...x,
name: `${x.platform} wallet ${index + 1}`,
}

return x
})
.reverse()
}, [wallets, NameService, proofs])

const [confirmState, onConfirmRelease] = useAsyncFn(
Expand Down
153 changes: 109 additions & 44 deletions packages/mask/src/extension/popups/pages/Personas/Home/UI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import { memo } from 'react'
import { makeStyles } from '@masknet/theme'
import { Navigator } from '../../../components/Navigator'
import { Avatar, Typography } from '@mui/material'
import { ArrowRightIosIcon, MenuPersonasActiveIcon } from '@masknet/icons'
import { Avatar, Button, Typography } from '@mui/material'
import { AddUserIcon, ArrowRightIosIcon, EmptyIcon, MenuPersonasActiveIcon, PopupRestoreIcon } from '@masknet/icons'
import { formatPersonaFingerprint, PopupRoutes, formatPersonaName } from '@masknet/shared-base'
import { CopyIconButton } from '../../../components/CopyIconButton'
import { useI18N } from '../../../../../utils'
Expand Down Expand Up @@ -56,6 +56,31 @@ const useStyles = makeStyles()({
color: '#7B8192',
fontSize: 24,
},
placeholder: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: 318,
},
controller: {
display: 'flex',
flexDirection: 'column',
rowGap: 12,
padding: '0 16px 16px 16px',
},
button: {
padding: '11px 0',
borderRadius: 8,
fontWeight: 700,
fontSize: 14,
width: '100%',

'& > svg': {
marginLeft: 4,
fontSize: 18,
},
},
})

export interface PersonaHomeUIProps {
Expand All @@ -65,58 +90,98 @@ export interface PersonaHomeUIProps {
accountsCount: number
walletsCount: number
onEdit: () => void
onCreatePersona: () => void
onRestore: () => void
fetchProofsLoading: boolean
isEmpty?: boolean
}

export const PersonaHomeUI = memo<PersonaHomeUIProps>(
({ avatar, fingerprint, nickname, accountsCount, walletsCount, onEdit, fetchProofsLoading }) => {
({
avatar,
fingerprint,
nickname,
accountsCount,
walletsCount,
onEdit,
fetchProofsLoading,
isEmpty,
onCreatePersona,
onRestore,
}) => {
const { t } = useI18N()
const { classes } = useStyles()

return (
<>
<div className={classes.container}>
<div className={classes.item}>
<Typography>{t('popups_profile_photo')}</Typography>
{avatar ? (
<Avatar src={avatar} className={classes.avatar} />
) : (
<MenuPersonasActiveIcon
className={classes.avatar}
style={{ fill: '#f9fafa', backgroundColor: '#F9FAFA', borderRadius: 99 }}
/>
)}
</div>
<div className={classes.item}>
<Typography>{t('popups_public_key')}</Typography>
{fingerprint ? (
<Typography className={classes.content}>
{formatPersonaFingerprint(fingerprint, 4)}
<CopyIconButton text={fingerprint} className={classes.copy} />
</Typography>
) : null}
</div>
<Link className={classes.item} to={PopupRoutes.PersonaRename} onClick={onEdit}>
<Typography>{t('popups_name')}</Typography>
<Typography className={classes.content} onClick={onEdit}>
{formatPersonaName(nickname)}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
<Link className={classes.item} to={PopupRoutes.SocialAccounts}>
<Typography>{t('popups_social_account')}</Typography>
<Typography className={classes.content}>
{accountsCount}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
<Link className={classes.item} to={PopupRoutes.ConnectedWallets}>
<Typography>{t('popups_connected_wallets')}</Typography>
<Typography className={classes.content}>
{!fetchProofsLoading ? walletsCount : '...'}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
{!isEmpty ? (
<>
<div className={classes.item}>
<Typography>{t('popups_profile_photo')}</Typography>
{avatar ? (
<Avatar src={avatar} className={classes.avatar} />
) : (
<MenuPersonasActiveIcon
className={classes.avatar}
style={{ fill: '#f9fafa', backgroundColor: '#F9FAFA', borderRadius: 99 }}
/>
)}
</div>
<div className={classes.item}>
<Typography>{t('popups_public_key')}</Typography>
{fingerprint ? (
<Typography className={classes.content}>
{formatPersonaFingerprint(fingerprint, 4)}
<CopyIconButton text={fingerprint} className={classes.copy} />
</Typography>
) : null}
</div>
<Link className={classes.item} to={PopupRoutes.PersonaRename} onClick={onEdit}>
<Typography>{t('popups_name')}</Typography>
<Typography className={classes.content} onClick={onEdit}>
{formatPersonaName(nickname)}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
<Link className={classes.item} to={PopupRoutes.SocialAccounts}>
<Typography>{t('popups_social_account')}</Typography>
<Typography className={classes.content}>
{accountsCount}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
<Link className={classes.item} to={PopupRoutes.ConnectedWallets}>
<Typography>{t('popups_connected_wallets')}</Typography>
<Typography className={classes.content}>
{!fetchProofsLoading ? walletsCount : '...'}
<ArrowRightIosIcon className={classes.arrow} />
</Typography>
</Link>
</>
) : (
<>
<div className={classes.placeholder}>
<EmptyIcon style={{ fontSize: 60 }} />
</div>
<div className={classes.controller}>
<Button
className={classes.button}
style={{ backgroundColor: '#07101B', color: '#F2F5F6' }}
onClick={onCreatePersona}>
{t('popups_create_persona')}
<AddUserIcon style={{ fill: '#F2F5F6' }} />
</Button>
<Button
className={classes.button}
style={{ backgroundColor: '#FFFFFF', color: '#07101B' }}
onClick={onRestore}>
{t('popups_restore_and_login')}
<PopupRestoreIcon style={{ fill: '#07101B' }} />
</Button>
</div>
</>
)}
</div>
<Navigator />
</>
Expand Down
25 changes: 23 additions & 2 deletions packages/mask/src/extension/popups/pages/Personas/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { memo, useCallback, useMemo } from 'react'
import { PersonaHomeUI } from './UI'
import { PersonaContext } from '../hooks/usePersonaContext'
import { NextIDPlatform } from '@masknet/shared-base'
import { DashboardRoutes, NextIDPlatform } from '@masknet/shared-base'
import { useTitle } from '../../../hook/useTitle'

const PersonaHome = memo(() => {
const { avatar, currentPersona, proofs, setSelectedPersona, fetchProofsLoading } = PersonaContext.useContainer()
const { avatar, currentPersona, proofs, setSelectedPersona, fetchProofsLoading, personas } =
PersonaContext.useContainer()

const wallets = useMemo(() => {
if (!proofs) return []
Expand All @@ -15,15 +17,34 @@ const PersonaHome = memo(() => {
setSelectedPersona(currentPersona)
}, [currentPersona])

const onCreatePersona = useCallback(() => {
browser.tabs.create({
active: true,
url: browser.runtime.getURL(`/dashboard.html#${DashboardRoutes.SignUp}`),
})
}, [])

const onRestore = useCallback(() => {
browser.tabs.create({
active: true,
url: browser.runtime.getURL(`/dashboard.html#${DashboardRoutes.SignIn}`),
})
}, [])

useTitle('')

return (
<PersonaHomeUI
isEmpty={!personas?.length}
avatar={avatar}
fingerprint={currentPersona?.identifier.compressedPoint}
nickname={currentPersona?.nickname}
accountsCount={currentPersona?.linkedProfiles.length ?? 0}
walletsCount={wallets.length}
onEdit={onEdit}
fetchProofsLoading={fetchProofsLoading}
onCreatePersona={onCreatePersona}
onRestore={onRestore}
/>
)
})
Expand Down