diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index 01c040ad091b..5d0dceda7fd0 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -66,7 +66,7 @@ "unknown": "Unknown", "message": "Message", "dashboard_tab_collectibles": "Collectibles", - "dashboard_no_collectible_found": "No collectible found", + "dashboard_no_collectible_found": "No collectible found.", "days": "Every {{days}} days", "decrypted_postbox_add_recipients": "Append recipients", "decrypted_postbox_decrypting": "Mask decrypting…", @@ -1004,11 +1004,11 @@ "nft_button_add_collectible": "Add Collectible", "nft_avatar": "NFT Avatar", "plugin_profile_no_wallets": "Connect your wallet here.
This section will be shown to your encrypted friends.
The display content includes digital art, donations, badges
and other public information on chain.", - "plugin_profile_binding_rules_title": "The NFT gallary will show NFTs as below rules:", - "plugin_profile_binding_rule1": "Twitter nickname is ENS.", - "plugin_profile_binding_rule2": "Twitter bio contains ENS(e.g. vitalik.eth) or valid address.", - "plugin_profile_binding_rule3": "Twitter ID + {{suffix}} is ENS.", - "plugin_profile_binding_rule4": "Address used to sign the avatar.", + "plugin_profile_binding_rules_title": "The wallet address discovery rules:", + "plugin_profile_binding_rule1": "The nickname is ENS or RNS.", + "plugin_profile_binding_rule2": "The bio contains ENS, RNS or a valid address.", + "plugin_profile_binding_rule3": "The ID + suffix is ENS or RNS.", + "plugin_profile_binding_rule4": "The address used to sign the PFP NFTs.", "plugin_profile_current_display_of": "Current display of {{type}}: ", "plugin_profile_loading": "Loading...", "plugin_profile_error_no_address": "Failed to find any valid address.", diff --git a/packages/mask/shared-ui/locales/qya-AA.json b/packages/mask/shared-ui/locales/qya-AA.json index 513d60779375..ab9103f0495c 100644 --- a/packages/mask/shared-ui/locales/qya-AA.json +++ b/packages/mask/shared-ui/locales/qya-AA.json @@ -1006,7 +1006,7 @@ "plugin_profile_binding_rules_title": "crwdns10417:0crwdne10417:0", "plugin_profile_binding_rule1": "crwdns10419:0crwdne10419:0", "plugin_profile_binding_rule2": "crwdns10421:0crwdne10421:0", - "plugin_profile_binding_rule3": "crwdns10423:0{{suffix}}crwdne10423:0", + "plugin_profile_binding_rule3": "crwdns10423:0crwdne10423:0", "plugin_profile_binding_rule4": "crwdns10425:0crwdne10425:0", "plugin_profile_current_display_of": "crwdns10427:0{{type}}crwdne10427:0", "plugin_profile_loading": "crwdns10669:0crwdne10669:0", diff --git a/packages/mask/shared-ui/locales/zh-CN.json b/packages/mask/shared-ui/locales/zh-CN.json index 5966413499b0..8fabcca5564a 100644 --- a/packages/mask/shared-ui/locales/zh-CN.json +++ b/packages/mask/shared-ui/locales/zh-CN.json @@ -886,11 +886,11 @@ "nft_button_add_collectible": "添加收藏品", "nft_avatar": "NFT 头像", "plugin_profile_no_wallets": "在此连接您的钱包。
此部分将显示给您的加密朋友。
显示内容包括数字艺术、捐赠、徽章
和其他链上的公开信息。", - "plugin_profile_binding_rules_title": "Web3 按如下规则展示NFTs:", - "plugin_profile_binding_rule1": "您的Twitter 昵称为ENS。", - "plugin_profile_binding_rule2": "您的Twitter bio 包含 ENS(例如,vitalik.eth) 或有效地址。", - "plugin_profile_binding_rule3": "您的Twitter ID + {{suffix}} 是ENS。", - "plugin_profile_binding_rule4": "用于签署NFT 头像的地址。", + "plugin_profile_binding_rules_title": "Web3 按如下规则发现钱包地址:", + "plugin_profile_binding_rule1": "您的昵称为 ENS 或者 RNS。", + "plugin_profile_binding_rule2": "您的个人介绍中包含 ENS、RNS 或有效地址。", + "plugin_profile_binding_rule3": "您的 ID + 词缀是 ENS 或者 RNS。", + "plugin_profile_binding_rule4": "用于签署 NFT 头像的地址。", "plugin_profile_current_display_of": "当前显示 {{type}}: ", "plugin_vcent_last_offer_at": "最新的OFFER为" } diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index 51ada8636acc..27ca10376005 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -117,10 +117,11 @@ interface CollectibleListUIProps extends withClasses<'empty' | 'button' | 'text' } function CollectibleListUI(props: CollectibleListUIProps) { const { provider, wallet, collectibles, loading, collectiblesRetry, error, readonly, hasRetry = true } = props - const classes = useStylesExtends(useStyles(), props) const { t } = useI18N() + const classes = useStylesExtends(useStyles(), props) + + useEffect(() => WalletMessages.events.erc721TokensUpdated.on(collectiblesRetry)) - WalletMessages.events.erc721TokensUpdated.on(collectiblesRetry) if (loading) return ( @@ -171,13 +172,13 @@ function CollectibleListUI(props: CollectibleListUIProps) { ) } -export interface CollectibleListAddressProps extends withClasses<'empty' | 'button'> { +export interface CollectibleListProps extends withClasses<'empty' | 'button'> { address: string collection?: string setCount: (count: number) => void } -export function CollectibleListAddress(props: CollectibleListAddressProps) { +export function CollectibleList(props: CollectibleListProps) { const { address, collection, setCount } = props const provider = useValueRef(currentNonFungibleAssetDataProviderSettings) const chainId = ChainId.Mainnet @@ -198,20 +199,15 @@ export function CollectibleListAddress(props: CollectibleListAddressProps) { }, [provider, address]) useEffect(() => { - if (collectibles.length) { - setRendCollectibles([...rendCollectibles, ...collectibles]) - if (hasNextPage) { - const timer = setTimeout(() => { - setPage(page + 1) - }, 1000) - - return () => { - clearTimeout(timer) - } - } + if (!collectibles.length) return + setRendCollectibles([...rendCollectibles, ...collectibles]) + if (!hasNextPage) return + const timer = setTimeout(() => { + setPage(page + 1) + }, 1000) + return () => { + clearTimeout(timer) } - - return () => {} }, [collectibles]) useEffect(() => { @@ -233,8 +229,9 @@ export function CollectibleListAddress(props: CollectibleListAddressProps) { } export function CollectionList({ address }: { address: string }) { - const provider = useValueRef(currentNonFungibleAssetDataProviderSettings) const chainId = ChainId.Mainnet + const provider = useValueRef(currentNonFungibleAssetDataProviderSettings) + const { t } = useI18N() const [page, setPage] = useState(0) const { classes } = useStyles() const [counts, setCounts] = useState([]) @@ -248,22 +245,26 @@ export function CollectionList({ address }: { address: string }) { }, [provider, address]) useEffect(() => { - if (collections.length) { - setRendCollections([...rendCollections, ...collections]) - if (hasNextPage) { - const timer = setTimeout(() => { - setPage(page + 1) - }, 3000) - - return () => { - clearTimeout(timer) - } - } + if (!collections.length) return + setRendCollections([...rendCollections, ...collections]) + if (!hasNextPage) return + const timer = setTimeout(() => { + setPage(page + 1) + }, 3000) + return () => { + clearTimeout(timer) } - - return () => {} }, [collections]) + if (!rendCollections.length) + return ( + + + {t('dashboard_no_collectible_found')} + + + ) + return ( {rendCollections.map((x, i) => ( @@ -281,7 +282,7 @@ export function CollectionList({ address }: { address: string }) { {counts[i] ? `(${counts[i]})` : null} - { diff --git a/packages/mask/src/plugins/Profile/SNSAdaptor/DonationsPage.tsx b/packages/mask/src/plugins/Profile/SNSAdaptor/DonationsPage.tsx index 2393ada10c2e..04bd28ed30ae 100644 --- a/packages/mask/src/plugins/Profile/SNSAdaptor/DonationsPage.tsx +++ b/packages/mask/src/plugins/Profile/SNSAdaptor/DonationsPage.tsx @@ -1,20 +1,19 @@ -import { makeStyles } from '@masknet/theme' -import { CircularProgress, Link } from '@mui/material' import urlcat from 'urlcat' -import type { GeneralAssetWithTags } from '../types' +import { makeStyles } from '@masknet/theme' +import { Link } from '@mui/material' +import type { AddressName } from '@masknet/web3-shared-evm' +import type { GeneralAsset, GeneralAssetWithTags } from '../types' import { RSS3_DEFAULT_IMAGE } from '../constants' import { DonationCard } from './components' -import { useDonations } from './hooks' import { useI18N } from '../../../utils' -const getDonationLink = (address: string, donation: GeneralAssetWithTags) => { +const getDonationLink = (label: string, donation: GeneralAssetWithTags) => { const { platform, identity, id, type } = donation - return urlcat('https://rss3.bio/:address/singlegitcoin/:platform/:identity/:id/:type', { - address, + return urlcat(`https://${label}.bio/singlegitcoin/:platform/:identity/:id/:type`, { platform, identity, id, - type, + type: type.replaceAll('-', '.'), }) } @@ -30,28 +29,23 @@ const useStyles = makeStyles()((theme) => ({ })) export interface DonationPageProps { - address: string + addressName?: AddressName + donations?: GeneralAsset[] } export function DonationPage(props: DonationPageProps) { - const { address } = props - const { classes } = useStyles() - const { donations, loading } = useDonations(address) + const { addressName, donations = [] } = props const { t } = useI18N() + const { classes } = useStyles() + + if (!addressName) return null - if (loading) { - return ( -
- -
- ) - } return (
{donations.map((donation) => ( diff --git a/packages/mask/src/plugins/Profile/SNSAdaptor/EnhancedProfile.tsx b/packages/mask/src/plugins/Profile/SNSAdaptor/EnhancedProfile.tsx index 8af942239e14..f3d530424382 100644 --- a/packages/mask/src/plugins/Profile/SNSAdaptor/EnhancedProfile.tsx +++ b/packages/mask/src/plugins/Profile/SNSAdaptor/EnhancedProfile.tsx @@ -3,7 +3,7 @@ import { useUpdateEffect } from 'react-use' import { Box, Typography } from '@mui/material' import { unreachable } from '@dimensiondev/kit' import { makeStyles, useStylesExtends } from '@masknet/theme' -import { AddressNameType, useAddressNames } from '@masknet/web3-shared-evm' +import { AddressName, AddressNameType, useAddressNames } from '@masknet/web3-shared-evm' import { MaskMessages, useI18N } from '../../../utils' import { useLocationChange } from '../../../utils/hooks/useLocationChange' import { WalletsPage } from './WalletsPage' @@ -15,7 +15,33 @@ import { PageTags } from '../types' import { PageTag } from './PageTag' import { AddressViewer } from './components/AddressViewer' import { useCurrentVisitingIdentity } from '../../../components/DataSource/useActivatedUI' -import { useDao } from './hooks' +import { useDao, useDonations, useFootprints } from './hooks' + +function getAddressName(currentTag: PageTags, addressNames: AddressName[]) { + const getAddressByType = (type: AddressNameType) => addressNames?.find((x) => x.type === type) + + const addressLiteral = getAddressByType(AddressNameType.ADDRESS) + const addressENS = getAddressByType(AddressNameType.ENS) + const addressUNS = getAddressByType(AddressNameType.UNS) + const addressGUN = getAddressByType(AddressNameType.GUN) + const addressRSS3 = getAddressByType(AddressNameType.RSS3) + const addressTheGraph = getAddressByType(AddressNameType.THE_GRAPH) + + switch (currentTag) { + case PageTags.WalletTag: + return + case PageTags.NFTTag: + return addressENS || addressUNS || addressRSS3 || addressLiteral || addressGUN || addressTheGraph + case PageTags.DonationTag: + return addressRSS3 || addressENS || addressUNS || addressLiteral || addressGUN || addressTheGraph + case PageTags.FootprintTag: + return addressRSS3 || addressENS || addressUNS || addressLiteral || addressGUN || addressTheGraph + case PageTags.DAOTag: + return + default: + unreachable(currentTag) + } +} const useStyles = makeStyles()((theme) => ({ root: { @@ -41,17 +67,14 @@ export function EnhancedProfilePage(props: EnhancedProfilePageProps) { const { t } = useI18N() const classes = useStylesExtends(useStyles(), props) - //#region identity const identity = useCurrentVisitingIdentity() - const { value: addressNames, loading: loadingAddressNames } = useAddressNames(identity) - //#endregion + const { value: addressNames = [], loading: loadingAddressNames } = useAddressNames(identity) const [hidden, setHidden] = useState(true) - const { value: daoPayload } = useDao(identity.identifier) - const [currentTag, setCurrentTag] = useState(PageTags.NFTTag) + const [currentTag, setCurrentTag] = useState() useLocationChange(() => { - setCurrentTag(PageTags.NFTTag) + setCurrentTag(undefined) MaskMessages.events.profileNFTsTabUpdated.sendToLocal('reset') }) @@ -62,57 +85,57 @@ export function EnhancedProfilePage(props: EnhancedProfilePageProps) { }, [identity]) useUpdateEffect(() => { - setCurrentTag(PageTags.NFTTag) + setCurrentTag(undefined) }, [identity.identifier]) - const addressName = useMemo(() => { - const getAddressByType = (type: AddressNameType) => addressNames?.find((x) => x.type === type) + const addressNFTs = getAddressName(PageTags.NFTTag, addressNames) + const addressRSS3 = getAddressName(PageTags.DonationTag, addressNames) + + const { value: daoPayload, loading: loadingDAO } = useDao(identity.identifier) + const { value: donations, loading: loadingDonations } = useDonations(addressRSS3?.resolvedAddress ?? '') + const { value: footprints, loading: loadingFootprints } = useFootprints(addressRSS3?.resolvedAddress ?? '') - const addressLiteral = getAddressByType(AddressNameType.ADDRESS) - const addressENS = getAddressByType(AddressNameType.ENS) - const addressUNS = getAddressByType(AddressNameType.UNS) - const addressGUN = getAddressByType(AddressNameType.GUN) - const addressRSS3 = getAddressByType(AddressNameType.RSS3) - const addressTheGraph = getAddressByType(AddressNameType.THE_GRAPH) + const currentTagComputed = currentTag ?? (addressNFTs ? PageTags.NFTTag : daoPayload ? PageTags.DAOTag : undefined) - switch (currentTag) { + const addressName = useMemo(() => { + if (!currentTagComputed) return + switch (currentTagComputed) { case PageTags.WalletTag: return case PageTags.NFTTag: - return addressENS || addressUNS || addressRSS3 || addressLiteral || addressGUN || addressTheGraph + return addressNFTs case PageTags.DonationTag: - return addressRSS3 || addressENS || addressUNS || addressLiteral || addressGUN || addressTheGraph + return addressRSS3 case PageTags.FootprintTag: - return addressRSS3 || addressENS || addressUNS || addressLiteral || addressGUN || addressTheGraph + return addressRSS3 case PageTags.DAOTag: return default: - unreachable(currentTag) + unreachable(currentTagComputed) } - }, [currentTag, addressNames]) - - const address = addressName?.resolvedAddress ?? '' + }, [currentTagComputed, addressNFTs, addressRSS3]) const content = useMemo(() => { - switch (currentTag) { + if (!currentTagComputed) return null + switch (currentTagComputed) { case PageTags.WalletTag: return case PageTags.NFTTag: - return + return case PageTags.DonationTag: - return + return case PageTags.FootprintTag: - return + return case PageTags.DAOTag: return default: - unreachable(currentTag) + unreachable(currentTagComputed) } - }, [address, currentTag, daoPayload, identity.identifier]) + }, [addressNFTs, addressRSS3, currentTagComputed, daoPayload, donations, footprints, identity.identifier]) if (hidden) return null - if (loadingAddressNames) + if (loadingAddressNames || loadingDAO) return (
) - if (!addressName) + if (!addressNFTs && !addressRSS3 && !daoPayload) return (
- -
-
- +
+ {addressName ? ( +
+ +
+ ) : null}
{content}
) diff --git a/packages/mask/src/plugins/Profile/SNSAdaptor/FootprintPage.tsx b/packages/mask/src/plugins/Profile/SNSAdaptor/FootprintPage.tsx index 21cf9d77e585..d3c0ab8dd04b 100644 --- a/packages/mask/src/plugins/Profile/SNSAdaptor/FootprintPage.tsx +++ b/packages/mask/src/plugins/Profile/SNSAdaptor/FootprintPage.tsx @@ -1,10 +1,11 @@ import urlcat from 'urlcat' import { makeStyles } from '@masknet/theme' -import { CircularProgress, Link } from '@mui/material' -import type { GeneralAssetWithTags } from '../types' +import { Link } from '@mui/material' +import type { AddressName } from '@masknet/web3-shared-evm' +import type { GeneralAsset, GeneralAssetWithTags } from '../types' import { RSS3_DEFAULT_IMAGE } from '../constants' import { FootprintCard } from './components' -import { useFootprints, useRss3Profile } from './hooks' +import { useRss3Profile } from './hooks' const useStyles = makeStyles()((theme) => ({ address: { @@ -17,43 +18,35 @@ const useStyles = makeStyles()((theme) => ({ }, })) -const getFootprintLink = (address: string, footprint: GeneralAssetWithTags) => { +const getFootprintLink = (label: string, footprint: GeneralAssetWithTags) => { const { platform, identity, id, type } = footprint - return urlcat('https://rss3.bio/:address/singlefootprint/:platform/:identity/:id/:type', { - address, + return urlcat(`https://${label}.bio/singlefootprint/:platform/:identity/:id/:type`, { platform, identity, id, - type, + type: type.replaceAll('-', '.'), }) } export interface FootprintPageProps { - address: string + addressName?: AddressName + footprints?: GeneralAsset[] } export function FootprintPage(props: FootprintPageProps) { - const { address } = props + const { addressName, footprints = [] } = props const { classes } = useStyles() - const { value: profile } = useRss3Profile(address) + const { value: profile } = useRss3Profile(addressName?.resolvedAddress ?? '') const username = profile?.name - const { footprints, loading } = useFootprints(address) - - if (loading) { - return ( -
- -
- ) - } + if (!addressName) return null return (
{footprints.map((footprint) => ( diff --git a/packages/mask/src/plugins/Profile/SNSAdaptor/NFTPage.tsx b/packages/mask/src/plugins/Profile/SNSAdaptor/NFTPage.tsx index 03bf9848f2ae..8f5f64b7d9d1 100644 --- a/packages/mask/src/plugins/Profile/SNSAdaptor/NFTPage.tsx +++ b/packages/mask/src/plugins/Profile/SNSAdaptor/NFTPage.tsx @@ -1,7 +1,5 @@ import { getMaskColor, makeStyles, useStylesExtends } from '@masknet/theme' -import { Box, Typography } from '@mui/material' import { CollectionList } from '../../../extension/options-page/DashboardComponents/CollectibleList' -import { useI18N } from '../../../utils' const useStyles = makeStyles()((theme) => ({ root: { @@ -22,18 +20,8 @@ export interface NFTPageProps extends withClasses<'text' | 'button'> { export function NFTPage(props: NFTPageProps) { const { address } = props - const { t } = useI18N() const classes = useStylesExtends(useStyles(), props) - if (!address) - return ( -
- - {t('dashboard_no_collectible_found')} - -
- ) - return (
diff --git a/packages/mask/src/plugins/Profile/SNSAdaptor/PageTag.tsx b/packages/mask/src/plugins/Profile/SNSAdaptor/PageTag.tsx index dcf77987e852..2cdfa68795c2 100644 --- a/packages/mask/src/plugins/Profile/SNSAdaptor/PageTag.tsx +++ b/packages/mask/src/plugins/Profile/SNSAdaptor/PageTag.tsx @@ -2,8 +2,9 @@ import classNames from 'classnames' import { makeStyles } from '@masknet/theme' import { Button } from '@mui/material' import { useI18N } from '../../../utils' -import { PageTags } from '../types' -import { useDonations, useFootprints, Dao_Payload } from './hooks' +import { GeneralAsset, PageTags } from '../types' +import type { AddressName } from '@masknet/web3-shared-evm' +import type { Dao_Payload } from './hooks' const useStyles = makeStyles()((theme) => ({ root: { @@ -43,21 +44,21 @@ const useStyles = makeStyles()((theme) => ({ })) export interface PageTagProps { - tag: PageTags - address: string - daoPayload: Dao_Payload | undefined + tag?: PageTags + daoPayload?: Dao_Payload + donations?: GeneralAsset[] + footprints?: GeneralAsset[] + addressNFTs?: AddressName + addressRSS3?: AddressName onChange: (tag: PageTags) => void } export function PageTag(props: PageTagProps) { - const { classes } = useStyles() - const { onChange, tag, address, daoPayload } = props + const { tag, daoPayload, donations, footprints, addressNFTs, addressRSS3, onChange } = props const { t } = useI18N() + const { classes } = useStyles() - const { donations } = useDonations(address) - const { footprints } = useFootprints(address) - const hasDonations = donations.length > 0 - const hasFootprints = footprints.length > 0 + if (!tag) return null return (
@@ -68,14 +69,16 @@ export function PageTag(props: PageTagProps) { size="medium"> {t('wallets')} - - {hasDonations ? ( + {addressNFTs ? ( + + ) : null} + {donations?.length ? (