From 221fbfcf1088f415f77d7a4428d418a72b31a7e1 Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 8 Feb 2022 14:36:43 +0800 Subject: [PATCH 01/18] feat: add fetch nfts v2 --- .../nonFungibleCollectibleAssetV2.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts diff --git a/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts b/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts new file mode 100644 index 000000000000..26d8e12b8673 --- /dev/null +++ b/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts @@ -0,0 +1,53 @@ +import { getOpenSeaNFTList, getRaribleNFTList, getNFTScanNFTs } from '@masknet/web3-providers' +import type { ERC721TokenDetailed } from '@masknet/web3-shared-evm' +import type { ProducerArgBase, ProducerKeyFunction, ProducerPushFunction, RPCMethodRegistrationValue } from '../types' +import { collectAllPageDate } from '../helper/request' + +export interface NonFungibleTokenAssetArgs extends ProducerArgBase { + address: string +} + +const nonFungibleCollectibleAsset = async ( + push: ProducerPushFunction, + getKeys: ProducerKeyFunction, + args: NonFungibleTokenAssetArgs, +): Promise => { + const { address } = args + const size = 50 + const openSeaApiKey = await getKeys('opensea') + + const fromOpenSea = collectAllPageDate( + (page) => getOpenSeaNFTList(openSeaApiKey, address, page, size), + size, + push, + ) + + const fromRarible = collectAllPageDate( + (page, pageInfo) => getRaribleNFTList(openSeaApiKey, address, page, size, pageInfo), + size, + push, + ) + + const formNFTScanERC721 = collectAllPageDate( + (page) => getNFTScanNFTs(address, 'erc721', page, size), + size, + push, + ) + + const fromNFTScanERC1155 = collectAllPageDate( + (page) => getNFTScanNFTs(address, 'erc1155', page, size), + size, + push, + ) + + await Promise.allSettled([fromOpenSea, fromRarible, formNFTScanERC721, fromNFTScanERC1155]) +} + +const producer: RPCMethodRegistrationValue = { + method: 'mask.fetchNonFungibleCollectibleAssetV2', + producer: nonFungibleCollectibleAsset, + distinctBy: (item) => + `${item.tokenId.toLowerCase()}_${item.contractDetailed.address.toLowerCase()}_${item.contractDetailed.chainId}`, +} + +export default producer From f352eb0f7087b769b200ab4929eaf8e15dc36866 Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 8 Feb 2022 16:20:14 +0800 Subject: [PATCH 02/18] feat: show nft by collection --- .../CollectibleList/LoadingCollectible.tsx | 34 ++++ .../CollectibleList/index.tsx | 145 +++++++++--------- 2 files changed, 108 insertions(+), 71 deletions(-) create mode 100644 packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/LoadingCollectible.tsx diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/LoadingCollectible.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/LoadingCollectible.tsx new file mode 100644 index 000000000000..1431851834aa --- /dev/null +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/LoadingCollectible.tsx @@ -0,0 +1,34 @@ +import { makeStyles } from '@masknet/theme' +import { Box, Skeleton } from '@mui/material' + +const useStyles = makeStyles()((theme) => ({ + root: { + display: 'grid', + flexWrap: 'wrap', + gridTemplateColumns: 'repeat(auto-fill, minmax(172px, 1fr))', + gridGap: theme.spacing(1), + }, + card: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + position: 'relative', + padding: theme.spacing(1), + }, +})) + +export const LoadingCollectible = () => { + const { classes } = useStyles() + return ( + + {Array.from({ length: 3 }) + .fill(0) + .map((_, i) => ( + + + + + ))} + + ) +} 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 f3c0cc005631..643612773f83 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -1,7 +1,8 @@ -import { createContext, useEffect, useMemo } from 'react' -import { useValueRef } from '@masknet/shared' +import { createContext, useEffect, useMemo, useState } from 'react' +import { TokenIcon, useValueRef } from '@masknet/shared' import { ChainId, + ERC721TokenCollectionInfo, ERC721TokenDetailed, isSameAddress, NonFungibleAssetProvider, @@ -10,13 +11,14 @@ import { useCollections, Wallet, } from '@masknet/web3-shared-evm' -import { Box, Button, Skeleton, Typography } from '@mui/material' +import { Box, Button, Skeleton, Stack, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import { currentNonFungibleAssetDataProviderSettings } from '../../../../plugins/Wallet/settings' import { useI18N } from '../../../../utils' import { CollectibleCard } from './CollectibleCard' import { Image } from '../../../../components/shared/Image' import { WalletMessages } from '@masknet/plugin-wallet' +import { LoadingCollectible } from './LoadingCollectible' export const CollectibleContext = createContext<{ collectiblesRetry: () => void @@ -180,7 +182,6 @@ function CollectibleListUI(props: CollectibleListUIProps) { export interface CollectibleListProps extends withClasses<'empty' | 'button'> { address: string - collection?: string collectibles: ERC721TokenDetailed[] error?: string loading: boolean @@ -210,6 +211,7 @@ export function CollectionList({ address }: { address: string }) { const chainId = ChainId.Mainnet const { t } = useI18N() const { classes } = useStyles() + const [selectedCollection, setSelectedCollection] = useState() const { data: collections, @@ -229,25 +231,18 @@ export function CollectionList({ address }: { address: string }) { return collectibles.filter((item) => !item.collection) }, [collections?.length, collectibles?.length]) + const renderCollectibles = useMemo(() => { + return (collectibles ?? []).filter((x) => { + if (!selectedCollection) return true + return ( + isSameAddress(selectedCollection.address, x.contractDetailed.address) || + selectedCollection.addresses?.find((r) => isSameAddress(r, x.contractDetailed.address)) + ) + }) + }, [selectedCollection?.address, collectibles.length]) + if (loadingCollectionDone !== SocketState.done) { - return ( - - {Array.from({ length: 3 }) - .fill(0) - .map((_, i) => ( - - - - - ))} - - ) + return } if (!isLoading && !collections.length) @@ -261,34 +256,39 @@ export function CollectionList({ address }: { address: string }) { return ( - {(collections ?? []).map((x, i) => { - const renderCollectibles = collectibles.filter( - (c) => - isSameAddress(c.contractDetailed.address, x.address) || - x.addresses?.find((r) => isSameAddress(r, c.contractDetailed.address)), - ) - return ( - - - - {x.iconURL ? ( - - ) : null} + {!selectedCollection && loadingCollectibleDone && ( + + All({collectibles.length}) + + )} + + + + {selectedCollection && ( + + + {selectedCollection.iconURL ? ( + + ) : null} + + + {selectedCollection.name} + {loadingCollectibleDone && renderCollectibles.length + ? `(${renderCollectibles.length})` + : null} + - - {x.name} - {loadingCollectibleDone && renderCollectibles.length - ? `(${renderCollectibles.length})` - : null} - - + )} { retryFetchCollectible() retryFetchCollection() @@ -297,31 +297,34 @@ export function CollectionList({ address }: { address: string }) { loading={loadingCollectibleDone !== SocketState.done && renderCollectibles.length === 0} /> - ) - })} - {!!renderWithRarible.length && ( - - - - Rarible ({renderWithRarible.length}) - - - { - retryFetchCollectible() - retryFetchCollection() - }} - collectibles={renderWithRarible} - loading={false} - /> - )} + + {(collections ?? []).map((x, i) => { + return ( + + setSelectedCollection(x)}> + {x.iconURL ? ( + + ) : ( + + )} + + + ) + })} + {!!renderWithRarible.length && ( + + + Other + + + )} + + ) } From df77d28efcf02fb80d86aa6bc293f6088218d79a Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 8 Feb 2022 17:57:17 +0800 Subject: [PATCH 03/18] feat: handle other collection --- .../CollectibleList/index.tsx | 28 +++++++++++++++---- .../web3-shared/evm/hooks/useCollectibles.ts | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) 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 643612773f83..9526cdc9a6d5 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -211,7 +211,7 @@ export function CollectionList({ address }: { address: string }) { const chainId = ChainId.Mainnet const { t } = useI18N() const { classes } = useStyles() - const [selectedCollection, setSelectedCollection] = useState() + const [selectedCollection, setSelectedCollection] = useState('all') const { data: collections, @@ -232,14 +232,16 @@ export function CollectionList({ address }: { address: string }) { }, [collections?.length, collectibles?.length]) const renderCollectibles = useMemo(() => { + if (selectedCollection === 'all') return collectibles + if (!selectedCollection) return collectibles.filter((x) => !x.collection) + return (collectibles ?? []).filter((x) => { - if (!selectedCollection) return true return ( isSameAddress(selectedCollection.address, x.contractDetailed.address) || selectedCollection.addresses?.find((r) => isSameAddress(r, x.contractDetailed.address)) ) }) - }, [selectedCollection?.address, collectibles.length]) + }, [selectedCollection, collectibles.length]) if (loadingCollectionDone !== SocketState.done) { return @@ -256,15 +258,29 @@ export function CollectionList({ address }: { address: string }) { return ( - {!selectedCollection && loadingCollectibleDone && ( + {selectedCollection === 'all' && loadingCollectibleDone && ( - All({collectibles.length}) + All {collectibles.length ? `(${collectibles.length})` : null} )} - {selectedCollection && ( + {!selectedCollection && selectedCollection !== 'all' && ( + + + Other + {loadingCollectibleDone && renderCollectibles.length + ? `(${renderCollectibles.length})` + : null} + + + )} + {selectedCollection && selectedCollection !== 'all' && ( {selectedCollection.iconURL ? ( diff --git a/packages/web3-shared/evm/hooks/useCollectibles.ts b/packages/web3-shared/evm/hooks/useCollectibles.ts index a7f302e9dc19..d2da17606b45 100644 --- a/packages/web3-shared/evm/hooks/useCollectibles.ts +++ b/packages/web3-shared/evm/hooks/useCollectibles.ts @@ -22,7 +22,7 @@ export function useCollectibles(address: string, chainId: ChainId | null, depend const id = `mask.fetchNonFungibleCollectibleAsset_${address}_${chainId}` const message = { id: dependReady === undefined ? id : dependReady ? id : '', - method: 'mask.fetchNonFungibleCollectibleAsset', + method: 'mask.fetchNonFungibleCollectibleAssetV2', params: { address: address, pageSize: 30, From 8e2b8a5fb74352787b5c2390f2c5b95d7dd4fd55 Mon Sep 17 00:00:00 2001 From: Lantt Date: Fri, 11 Feb 2022 13:43:19 +0800 Subject: [PATCH 04/18] refactor: create collection icon component --- .../CollectibleList/CollectionIcon.tsx | 67 +++++++++++++ .../CollectibleList/index.tsx | 94 +++++++++++++------ 2 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx new file mode 100644 index 000000000000..3536289070d5 --- /dev/null +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx @@ -0,0 +1,67 @@ +import type { ERC721TokenCollectionInfo } from '@masknet/web3-shared-evm' +import { memo } from 'react' +import { Box, Tooltip } from '@mui/material' +import { Image } from '../../../../components/shared/Image' +import { makeStyles } from '@masknet/theme' +import { TokenIcon } from '@masknet/shared' +import classNames from 'classnames' + +const useStyles = makeStyles()((theme) => ({ + collectionWrap: { + width: '24px', + height: '24px', + borderRadius: '50%', + background: 'rgba(229,232,235,1)', + cursor: 'pointer', + }, + collectionImg: { + objectFit: 'cover', + width: '100%', + height: '100%', + borderRadius: '50%', + }, + tip: { + padding: theme.spacing(1), + color: '#ffffff', + }, + selected: { + border: '2px solid #1D9BF0', + borderRadius: '50%', + }, +})) + +interface CollectionIconProps { + selectedCollection?: string + collection: ERC721TokenCollectionInfo + onClick?(): void +} + +export const CollectionIcon = memo(({ collection, onClick, selectedCollection }) => { + const { classes } = useStyles() + return ( + + + {collection.iconURL ? ( + + ) : ( + + )} + + + ) +}) 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 9526cdc9a6d5..02f8a814fc4b 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -1,5 +1,5 @@ import { createContext, useEffect, useMemo, useState } from 'react' -import { TokenIcon, useValueRef } from '@masknet/shared' +import { useValueRef } from '@masknet/shared' import { ChainId, ERC721TokenCollectionInfo, @@ -11,19 +11,30 @@ import { useCollections, Wallet, } from '@masknet/web3-shared-evm' -import { Box, Button, Skeleton, Stack, Typography } from '@mui/material' +import { Box, Button, Skeleton, Stack, styled, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import { currentNonFungibleAssetDataProviderSettings } from '../../../../plugins/Wallet/settings' import { useI18N } from '../../../../utils' import { CollectibleCard } from './CollectibleCard' -import { Image } from '../../../../components/shared/Image' import { WalletMessages } from '@masknet/plugin-wallet' import { LoadingCollectible } from './LoadingCollectible' +import { CollectionIcon } from './CollectionIcon' export const CollectibleContext = createContext<{ collectiblesRetry: () => void }>(null!) +const AllNetworkButton = styled(Button)(({ theme }) => ({ + display: 'inline-block', + padding: 0, + borderRadius: '50%', + fontSize: 12, + '&:hover': { + boxShadow: 'none', + }, + opacity: 0.5, +})) + const useStyles = makeStyles()((theme) => ({ root: { display: 'grid', @@ -83,6 +94,21 @@ const useStyles = makeStyles()((theme) => ({ height: '100%', borderRadius: '50%', }, + networkSelected: { + background: theme.palette.primary.main, + color: '#ffffff', + opacity: 1, + '&:after': { + content: '""', + position: 'absolute', + bottom: -8, + right: (30 - 4) / 2, + display: 'inline-block', + width: 4, + height: 4, + borderRadius: '50%', + }, + }, })) interface CollectibleItemProps { @@ -258,12 +284,24 @@ export function CollectionList({ address }: { address: string }) { return ( - {selectedCollection === 'all' && loadingCollectibleDone && ( - - All {collectibles.length ? `(${collectibles.length})` : null} - - )} - + + {}}> + ALL + + theme.palette.primary.main} fontSize="12px"> + All {collectibles.length ? `(${collectibles.length})` : null} + + + {!selectedCollection && selectedCollection !== 'all' && ( @@ -282,15 +320,7 @@ export function CollectionList({ address }: { address: string }) { )} {selectedCollection && selectedCollection !== 'all' && ( - - {selectedCollection.iconURL ? ( - - ) : null} - + {(collections ?? []).map((x, i) => { return ( - - setSelectedCollection(x)}> - {x.iconURL ? ( - - ) : ( - - )} - + + setSelectedCollection(x)} + /> ) })} {!!renderWithRarible.length && ( - + Date: Mon, 14 Feb 2022 13:57:39 +0800 Subject: [PATCH 05/18] feat: user can select display address --- .../Collectible/SNSAdaptor/NFTPage.tsx | 65 ++++++++++++++----- .../plugins/Collectible/SNSAdaptor/index.tsx | 6 +- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx index b3f43ad5b3f2..36f569af4a41 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx @@ -1,8 +1,12 @@ import { getMaskColor, makeStyles } from '@masknet/theme' -import { Box, Typography, Link } from '@mui/material' -import { useI18N } from '../../../utils' -import { AddressName, resolveAddressLinkOnExplorer, formatEthereumAddress, ChainId } from '@masknet/web3-shared-evm' +import { Box, MenuItem, Button } from '@mui/material' +import { ShadowRootMenu, useI18N } from '../../../utils' +import type { AddressName } from '@masknet/web3-shared-evm' import { CollectionList } from '../../../extension/options-page/DashboardComponents/CollectibleList' +import { useState } from 'react' +import { first } from 'lodash-unified' +import { formatEthereumAddress } from '@masknet/web3-shared-evm' +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' const useStyles = makeStyles()((theme) => ({ root: { @@ -29,34 +33,59 @@ const useStyles = makeStyles()((theme) => ({ listStyleType: 'decimal', paddingLeft: 16, }, + button: { + border: `1px solid ${theme.palette.text.primary} !important`, + color: `${theme.palette.text.primary} !important`, + borderRadius: 9999, + background: 'transparent', + '&:hover': { + background: 'rgba(15, 20, 25, 0.1)', + }, + }, })) export interface NFTPageProps { - addressName?: AddressName + addressNames?: AddressName[] } export function NFTPage(props: NFTPageProps) { - const { addressName } = props + const { addressNames } = props const { classes } = useStyles() const { t } = useI18N() - if (!addressName) return null + const [anchorEl, setAnchorEl] = useState(null) + + const [selectedAddress, setSelectedAddress] = useState(first(addressNames)) + const onOpen = (event: React.MouseEvent) => setAnchorEl(event.currentTarget) + const onClose = () => setAnchorEl(null) + const onSelect = (option: AddressName) => { + setSelectedAddress(option) + onClose() + } + + if (!selectedAddress) return null return (
+ + {(addressNames ?? []).map((x) => { + return ( + onSelect(x)}> + {formatEthereumAddress(x.label, 5)} + + ) + })} + - - - {t('plugin_wallet_nft_wall_current_display')} - - {formatEthereumAddress(addressName.resolvedAddress ?? '', 4)} - - - + - +
) } diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx index 171a280e2fa5..5fc6612f35c9 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx @@ -1,4 +1,4 @@ -import { uniq, first } from 'lodash-unified' +import { uniq } from 'lodash-unified' import { Plugin, usePostInfoDetails, usePluginWrapper } from '@masknet/plugin-infra' import { PostInspector } from './PostInspector' import { base } from '../base' @@ -30,9 +30,7 @@ const sns: Plugin.SNSAdaptor.Definition = { label: 'NFTs', priority: 1, UI: { - TabContent: ({ addressNames = [] }) => ( - - ), + TabContent: ({ addressNames = [] }) => , }, Utils: { addressNameSorter: (a, z) => { From 5740326b6d5f49ef1f2a812a9b46b92dec9bafa6 Mon Sep 17 00:00:00 2001 From: Lantt Date: Mon, 14 Feb 2022 13:59:03 +0800 Subject: [PATCH 06/18] fix: i18n key --- packages/mask/shared-ui/locales/en-US.json | 1 - packages/mask/shared-ui/locales/qya-AA.json | 1 - packages/mask/shared-ui/locales/zh-CN.json | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index d9e3f301a1fb..ea2f8604f060 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -326,7 +326,6 @@ "plugin_wallet_name_placeholder": "Enter 1-12 characters", "plugin_wallet_fail_to_sign": "Failed to sign password.", "plugin_wallet_cancel_sign": "Signature canceled.", - "plugin_wallet_nft_wall_current_display": "Current display: ", "plugin_red_packet_display_name": "Plugin: Lucky Drop", "plugin_red_packet_claimed": "Claimed", "plugin_red_packet_erc20_tab_title": "Token", diff --git a/packages/mask/shared-ui/locales/qya-AA.json b/packages/mask/shared-ui/locales/qya-AA.json index 81c7caae1388..b89c5996d88a 100644 --- a/packages/mask/shared-ui/locales/qya-AA.json +++ b/packages/mask/shared-ui/locales/qya-AA.json @@ -326,7 +326,6 @@ "plugin_wallet_name_placeholder": "crwdns4705:0crwdne4705:0", "plugin_wallet_fail_to_sign": "crwdns4707:0crwdne4707:0", "plugin_wallet_cancel_sign": "crwdns4709:0crwdne4709:0", - "plugin_wallet_nft_wall_current_display": "crwdns13185:0crwdne13185:0", "plugin_red_packet_display_name": "crwdns4711:0crwdne4711:0", "plugin_red_packet_claimed": "crwdns10205:0crwdne10205:0", "plugin_red_packet_erc20_tab_title": "crwdns8143:0crwdne8143:0", diff --git a/packages/mask/shared-ui/locales/zh-CN.json b/packages/mask/shared-ui/locales/zh-CN.json index 9ed9571c3d11..861de61be2aa 100644 --- a/packages/mask/shared-ui/locales/zh-CN.json +++ b/packages/mask/shared-ui/locales/zh-CN.json @@ -324,7 +324,6 @@ "plugin_wallet_name_placeholder": "输入1-12 个字符", "plugin_wallet_fail_to_sign": "无法签名密码。", "plugin_wallet_cancel_sign": "签名已取消。", - "plugin_wallet_nft_wall_current_display": "当前显示: ", "plugin_red_packet_display_name": "插件:红包", "plugin_red_packet_claimed": "已认领", "plugin_red_packet_erc20_tab_title": "代币", From 08b16815f1d975efdc5094e2927a6562e9862b88 Mon Sep 17 00:00:00 2001 From: Lantt Date: Mon, 14 Feb 2022 16:13:21 +0800 Subject: [PATCH 07/18] feat: shoudl filter duplate address --- .../mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx index 36f569af4a41..ee94624242f3 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx @@ -4,7 +4,7 @@ import { ShadowRootMenu, useI18N } from '../../../utils' import type { AddressName } from '@masknet/web3-shared-evm' import { CollectionList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { useState } from 'react' -import { first } from 'lodash-unified' +import { first, uniqBy } from 'lodash-unified' import { formatEthereumAddress } from '@masknet/web3-shared-evm' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' @@ -71,10 +71,10 @@ export function NFTPage(props: NFTPageProps) { onClose={onClose} anchorEl={anchorEl} PaperProps={{ style: { maxHeight: 192 } }}> - {(addressNames ?? []).map((x) => { + {uniqBy(addressNames ?? [], (x) => x.resolvedAddress.toLowerCase()).map((x) => { return ( onSelect(x)}> - {formatEthereumAddress(x.label, 5)} + {x.type}: {formatEthereumAddress(x.label, 5)} ) })} From 7edd69142eac2a3076b5393a40d5f45d4d082ec9 Mon Sep 17 00:00:00 2001 From: Lantt Date: Mon, 14 Feb 2022 16:35:52 +0800 Subject: [PATCH 08/18] feat: remove dep collection api --- .../CollectibleList/CollectionIcon.tsx | 4 +- .../CollectibleList/index.tsx | 52 +++++++------------ .../Collectible/SNSAdaptor/NFTPage.tsx | 3 +- 3 files changed, 22 insertions(+), 37 deletions(-) diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx index 3536289070d5..b985aeffe01e 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx @@ -1,10 +1,10 @@ -import type { ERC721TokenCollectionInfo } from '@masknet/web3-shared-evm' import { memo } from 'react' import { Box, Tooltip } from '@mui/material' import { Image } from '../../../../components/shared/Image' import { makeStyles } from '@masknet/theme' import { TokenIcon } from '@masknet/shared' import classNames from 'classnames' +import type { ERC721ContractDetailed } from '@masknet/web3-shared-evm' const useStyles = makeStyles()((theme) => ({ collectionWrap: { @@ -32,7 +32,7 @@ const useStyles = makeStyles()((theme) => ({ interface CollectionIconProps { selectedCollection?: string - collection: ERC721TokenCollectionInfo + collection: ERC721ContractDetailed onClick?(): void } 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 02f8a814fc4b..de83179777ef 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -2,13 +2,12 @@ import { createContext, useEffect, useMemo, useState } from 'react' import { useValueRef } from '@masknet/shared' import { ChainId, - ERC721TokenCollectionInfo, + ERC721ContractDetailed, ERC721TokenDetailed, isSameAddress, NonFungibleAssetProvider, SocketState, useCollectibles, - useCollections, Wallet, } from '@masknet/web3-shared-evm' import { Box, Button, Skeleton, Stack, styled, Typography } from '@mui/material' @@ -17,8 +16,8 @@ import { currentNonFungibleAssetDataProviderSettings } from '../../../../plugins import { useI18N } from '../../../../utils' import { CollectibleCard } from './CollectibleCard' import { WalletMessages } from '@masknet/plugin-wallet' -import { LoadingCollectible } from './LoadingCollectible' import { CollectionIcon } from './CollectionIcon' +import { uniqBy } from 'lodash-unified' export const CollectibleContext = createContext<{ collectiblesRetry: () => void @@ -98,15 +97,8 @@ const useStyles = makeStyles()((theme) => ({ background: theme.palette.primary.main, color: '#ffffff', opacity: 1, - '&:after': { - content: '""', - position: 'absolute', - bottom: -8, - right: (30 - 4) / 2, - display: 'inline-block', - width: 4, - height: 4, - borderRadius: '50%', + '&:hover': { + background: theme.palette.primary.main, }, }, })) @@ -237,43 +229,38 @@ export function CollectionList({ address }: { address: string }) { const chainId = ChainId.Mainnet const { t } = useI18N() const { classes } = useStyles() - const [selectedCollection, setSelectedCollection] = useState('all') + const [selectedCollection, setSelectedCollection] = useState('all') - const { - data: collections, - retry: retryFetchCollection, - state: loadingCollectionDone, - } = useCollections(address, chainId) const { data: collectibles, state: loadingCollectibleDone, retry: retryFetchCollectible, - } = useCollectibles(address, chainId, !!collections.length) + } = useCollectibles(address, chainId) - const isLoading = loadingCollectibleDone !== SocketState.done || loadingCollectionDone !== SocketState.done + const isLoading = loadingCollectibleDone !== SocketState.done const renderWithRarible = useMemo(() => { if (isLoading) return [] return collectibles.filter((item) => !item.collection) - }, [collections?.length, collectibles?.length]) + }, [collectibles?.length]) const renderCollectibles = useMemo(() => { if (selectedCollection === 'all') return collectibles if (!selectedCollection) return collectibles.filter((x) => !x.collection) return (collectibles ?? []).filter((x) => { - return ( - isSameAddress(selectedCollection.address, x.contractDetailed.address) || - selectedCollection.addresses?.find((r) => isSameAddress(r, x.contractDetailed.address)) - ) + return isSameAddress(selectedCollection.address, x.contractDetailed.address) }) }, [selectedCollection, collectibles.length]) - if (loadingCollectionDone !== SocketState.done) { - return - } + const collections = useMemo(() => { + return uniqBy( + collectibles.map((x) => x.contractDetailed), + (x) => x.address.toLowerCase(), + ) + }, [collectibles.length]) - if (!isLoading && !collections.length) + if (!isLoading && !collectibles.length) return ( @@ -305,7 +292,7 @@ export function CollectionList({ address }: { address: string }) { {!selectedCollection && selectedCollection !== 'all' && ( - + )} {selectedCollection && selectedCollection !== 'all' && ( - + { retryFetchCollectible() - retryFetchCollection() }} collectibles={renderCollectibles} loading={loadingCollectibleDone !== SocketState.done && renderCollectibles.length === 0} @@ -345,7 +331,7 @@ export function CollectionList({ address }: { address: string }) { - {(collections ?? []).map((x, i) => { + {collections.map((x, i) => { return ( (null) const [selectedAddress, setSelectedAddress] = useState(first(addressNames)) From d0e75c59351be81a6d4a910ec7091626aa9f91f1 Mon Sep 17 00:00:00 2001 From: Lantt Date: Mon, 14 Feb 2022 16:45:00 +0800 Subject: [PATCH 09/18] feat: should use preview image link in nft api --- .../DashboardComponents/CollectibleList/CollectibleCard.tsx | 6 +++--- packages/provider-proxy/src/index.ts | 2 ++ packages/web3-providers/src/opensea/index.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx index b867d8b91a0f..7d7ca7f8f172 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx @@ -79,7 +79,7 @@ export function CollectibleCard(props: CollectibleCardProps) { (entries) => { entries.forEach((item) => { if (!item.isIntersecting) return - setImageLinkWithLazy(token.info.mediaUrl!) + setImageLinkWithLazy(token.info.imageURL || token.info.mediaUrl!) observer.unobserve(item.target) }) }, @@ -101,7 +101,7 @@ export function CollectibleCard(props: CollectibleCardProps) { theme.palette.mode === 'dark' ? new URL('./nft_token_fallback_dark.png', import.meta.url) : new URL('./nft_token_fallback.png', import.meta.url) - const { value: isImageToken, loading } = useImageChecker(token.info.mediaUrl) + const { value: isImageToken, loading } = useImageChecker(token.info.imageURL || token.info.mediaUrl) return ( )} - {token.info.mediaUrl ? ( + {token.info.imageURL || token.info.mediaUrl ? ( loading ? ( ) : isImageToken && imageLinkWithLazy ? ( diff --git a/packages/provider-proxy/src/index.ts b/packages/provider-proxy/src/index.ts index b02c896bc350..ad76efa9d6a6 100644 --- a/packages/provider-proxy/src/index.ts +++ b/packages/provider-proxy/src/index.ts @@ -2,9 +2,11 @@ import type { RPCMethodRegistrationValue } from './types' import fungibleTokenProducer from './producers/fungibleTokenAsset' import nonFungibleCollectionAsset from './producers/nonFungibleCollectionAsset' import nonFungibleCollectibleAsset from './producers/nonFungibleCollectibleAsset' +import nonFungibleCollectibleAssetV2 from './producers/nonFungibleCollectibleAssetV2' export const producers: RPCMethodRegistrationValue[] = [ fungibleTokenProducer, nonFungibleCollectibleAsset, + nonFungibleCollectibleAssetV2, nonFungibleCollectionAsset, ] diff --git a/packages/web3-providers/src/opensea/index.ts b/packages/web3-providers/src/opensea/index.ts index 86cbd320f630..c7693ef98b03 100644 --- a/packages/web3-providers/src/opensea/index.ts +++ b/packages/web3-providers/src/opensea/index.ts @@ -63,7 +63,7 @@ function createERC721TokenFromAsset( chainId: ChainId, asset: OpenSeaResponse, ): ERC721TokenDetailed { - const imageURL = asset?.image_url ?? asset?.image_preview_url ?? '' + const imageURL = asset?.image_preview_url ?? asset?.image_url ?? '' return createERC721Token( createERC721ContractFromAssetContract(asset?.asset_contract?.address, chainId, asset?.asset_contract), { From afb879be1cccc937edb4711964c78e4801891433 Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 15 Feb 2022 12:23:30 +0800 Subject: [PATCH 10/18] feat: select address style --- .../CollectibleList/CollectionIcon.tsx | 5 +- .../CollectibleList/index.tsx | 79 +++++++++++-------- .../Collectible/SNSAdaptor/NFTPage.tsx | 13 +-- 3 files changed, 54 insertions(+), 43 deletions(-) diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx index b985aeffe01e..5de4329a01c1 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx @@ -32,12 +32,15 @@ const useStyles = makeStyles()((theme) => ({ interface CollectionIconProps { selectedCollection?: string - collection: ERC721ContractDetailed + collection?: ERC721ContractDetailed onClick?(): void } export const CollectionIcon = memo(({ collection, onClick, selectedCollection }) => { const { classes } = useStyles() + if (!collection) { + return + } return ( void @@ -48,9 +51,7 @@ const useStyles = makeStyles()((theme) => ({ justifyContent: 'center', height: '100%', }, - button: { - marginTop: theme.spacing(1), - }, + button: {}, container: { height: 'calc(100% - 52px)', overflow: 'auto', @@ -225,11 +226,18 @@ export function CollectibleList(props: CollectibleListProps) { ) } -export function CollectionList({ address }: { address: string }) { +export function CollectionList({ + addressName, + onSelectAddress, +}: { + addressName: AddressName + onSelectAddress: (event: React.MouseEvent) => void +}) { const chainId = ChainId.Mainnet const { t } = useI18N() const { classes } = useStyles() - const [selectedCollection, setSelectedCollection] = useState('all') + const [selectedCollection, setSelectedCollection] = useState('all') + const { resolvedAddress: address } = addressName const { data: collectibles, @@ -260,6 +268,8 @@ export function CollectionList({ address }: { address: string }) { ) }, [collectibles.length]) + console.log(collections) + if (!isLoading && !collectibles.length) return ( @@ -271,24 +281,32 @@ export function CollectionList({ address }: { address: string }) { return ( - - {}}> - ALL - - theme.palette.primary.main} fontSize="12px"> - All {collectibles.length ? `(${collectibles.length})` : null} - + + + setSelectedCollection('all')}> + ALL + + theme.palette.primary.main} fontSize="12px"> + All {collectibles.length ? `(${collectibles.length})` : null} + + + + + - + {!selectedCollection && selectedCollection !== 'all' && ( @@ -322,9 +340,7 @@ export function CollectionList({ address }: { address: string }) { )} { - retryFetchCollectible() - }} + retry={retryFetchCollectible} collectibles={renderCollectibles} loading={loadingCollectibleDone !== SocketState.done && renderCollectibles.length === 0} /> @@ -356,13 +372,12 @@ export function CollectionList({ address }: { address: string }) { alignItems="center" justifyContent="center" sx={{ marginTop: '8px', marginBottom: '12px', minWidth: 30, maxHeight: 24 }}> - - Other - + setSelectedCollection(undefined)} + /> )} diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx index 30f241d18ec0..d7772572fd63 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/NFTPage.tsx @@ -1,12 +1,11 @@ import { getMaskColor, makeStyles } from '@masknet/theme' -import { Box, MenuItem, Button } from '@mui/material' +import { MenuItem } from '@mui/material' import { ShadowRootMenu } from '../../../utils' import type { AddressName } from '@masknet/web3-shared-evm' import { CollectionList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { useState } from 'react' import { first, uniqBy } from 'lodash-unified' import { formatEthereumAddress } from '@masknet/web3-shared-evm' -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' const useStyles = makeStyles()((theme) => ({ root: { @@ -73,18 +72,12 @@ export function NFTPage(props: NFTPageProps) { {uniqBy(addressNames ?? [], (x) => x.resolvedAddress.toLowerCase()).map((x) => { return ( onSelect(x)}> - {x.type}: {formatEthereumAddress(x.label, 5)} + {formatEthereumAddress(x.label, 5)} ) })} - - - - + ) } From f6584bf5468ed0c13a35ff0409ddc49933947ead Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 15 Feb 2022 12:29:27 +0800 Subject: [PATCH 11/18] feat: add provide by for fetch nft api --- packages/web3-providers/src/NFTScan/index.ts | 3 ++- packages/web3-providers/src/opensea/index.ts | 3 ++- packages/web3-providers/src/rarible/index.ts | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/web3-providers/src/NFTScan/index.ts b/packages/web3-providers/src/NFTScan/index.ts index a5710a6138b7..ec3724bea5e8 100644 --- a/packages/web3-providers/src/NFTScan/index.ts +++ b/packages/web3-providers/src/NFTScan/index.ts @@ -117,7 +117,8 @@ export class NFTScanAPI implements NonFungibleTokenAPI.Provider { data: [], hasNextPage: false, } - const data = response.data.content.map(createERC721TokenAsset) + const data = + response.data.content.map(createERC721TokenAsset).map((x) => ({ ...x, provideBy: 'NFTScan' })) ?? [] const total = response.data.total return { data, diff --git a/packages/web3-providers/src/opensea/index.ts b/packages/web3-providers/src/opensea/index.ts index c7693ef98b03..0b708c25c2a2 100644 --- a/packages/web3-providers/src/opensea/index.ts +++ b/packages/web3-providers/src/opensea/index.ts @@ -284,7 +284,8 @@ export class OpenSeaAPI implements NonFungibleTokenAPI.Provider { ['non-fungible', 'semi-fungible'].includes(x.asset_contract.asset_contract_type) || ['ERC721', 'ERC1155'].includes(x.asset_contract.schema_name), ) - .map((asset: OpenSeaResponse) => createERC721TokenFromAsset(from, asset.token_id, chainId, asset)) ?? [] + .map((asset: OpenSeaResponse) => createERC721TokenFromAsset(from, asset.token_id, chainId, asset)) + .map((x) => ({ ...x, provideBy: 'OpenSea' })) ?? [] return { data: assets, hasNextPage: assets.length === size, diff --git a/packages/web3-providers/src/rarible/index.ts b/packages/web3-providers/src/rarible/index.ts index 2b7119c04d38..37b80dbbf416 100644 --- a/packages/web3-providers/src/rarible/index.ts +++ b/packages/web3-providers/src/rarible/index.ts @@ -171,9 +171,11 @@ export class RaribleAPI implements NonFungibleTokenAPI.Provider { hasNextPage: false, } - const data = asset.items - .map((asset) => createERC721TokenFromAsset(asset.contract, asset.tokenId, asset)) - .filter((x) => x.info?.owner?.toLowerCase() === from.toLowerCase()) + const data = + asset.items + .map((asset) => createERC721TokenFromAsset(asset.contract, asset.tokenId, asset)) + .filter((x) => x.info?.owner?.toLowerCase() === from.toLowerCase()) + .map((x) => ({ ...x, provideBy: 'Rarible' })) ?? [] return { data, hasNextPage: !!asset.continuation, From 4e7ebe207f02e2cdfe830facd7f0780a68d08907 Mon Sep 17 00:00:00 2001 From: Lantt Date: Tue, 15 Feb 2022 15:29:59 +0800 Subject: [PATCH 12/18] fix: nftscan response convert --- .../CollectibleList/CollectionIcon.tsx | 1 + .../CollectibleList/index.tsx | 38 ++++++++++++------- packages/web3-providers/src/NFTScan/index.ts | 3 +- packages/web3-providers/src/NFTScan/utils.ts | 8 ++++ 4 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 packages/web3-providers/src/NFTScan/utils.ts diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx index 5de4329a01c1..8d6ce4752bd8 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx @@ -19,6 +19,7 @@ const useStyles = makeStyles()((theme) => ({ width: '100%', height: '100%', borderRadius: '50%', + color: theme.palette.primary.main, }, tip: { padding: theme.spacing(1), 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 fc52fb9e5067..e8e411b87e60 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -10,6 +10,7 @@ import { NonFungibleAssetProvider, SocketState, useCollectibles, + useCollections, Wallet, } from '@masknet/web3-shared-evm' import { Box, Button, Skeleton, Stack, styled, Typography } from '@mui/material' @@ -95,8 +96,14 @@ const useStyles = makeStyles()((theme) => ({ borderRadius: '50%', }, networkSelected: { + width: 24, + height: 24, + minHeight: 24, + minWidth: 24, + lineHeight: '24px', background: theme.palette.primary.main, color: '#ffffff', + fontSize: 10, opacity: 1, '&:hover': { background: theme.palette.primary.main, @@ -239,6 +246,8 @@ export function CollectionList({ const [selectedCollection, setSelectedCollection] = useState('all') const { resolvedAddress: address } = addressName + const { data: collectionsFormRemote } = useCollections(address, chainId) + const { data: collectibles, state: loadingCollectibleDone, @@ -265,8 +274,20 @@ export function CollectionList({ return uniqBy( collectibles.map((x) => x.contractDetailed), (x) => x.address.toLowerCase(), - ) - }, [collectibles.length]) + ).map((x) => { + const item = collectionsFormRemote.find((c) => c.address === x.address) + if (item) { + return { + name: item.name, + symbol: item.name, + baseURI: item.iconURL, + iconURL: item.iconURL, + address: item.address, + } as ERC721ContractDetailed + } + return x + }) + }, [collectibles.length, collectionsFormRemote]) console.log(collections) @@ -281,18 +302,9 @@ export function CollectionList({ return ( - + - setSelectedCollection('all')}> + setSelectedCollection('all')}> ALL theme.palette.primary.main} fontSize="12px"> diff --git a/packages/web3-providers/src/NFTScan/index.ts b/packages/web3-providers/src/NFTScan/index.ts index ec3724bea5e8..514e5191137c 100644 --- a/packages/web3-providers/src/NFTScan/index.ts +++ b/packages/web3-providers/src/NFTScan/index.ts @@ -6,6 +6,7 @@ import type { NonFungibleTokenAPI } from '..' import { NFTSCAN_ACCESS_TOKEN_URL, NFTSCAN_BASE_API } from './constants' import type { NFTScanAsset, NFT_Assets } from './types' import { isProxyENV } from '../helpers' +import { toNonIPFSImage } from './utils' const tokenCache = new Map<'token', { token: string; expiration: Date }>() @@ -58,7 +59,7 @@ function createERC721TokenAsset(asset: NFTScanAsset) { { name: payload?.name ?? asset.nft_name ?? asset.nft_platform_name ?? '', description: payload?.description ?? '', - mediaUrl: payload?.image ?? '', + mediaUrl: toNonIPFSImage(asset.nft_cover ?? asset.nft_content_uri ?? payload.image ?? ''), owner: asset.nft_holder ?? '', }, asset.token_id, diff --git a/packages/web3-providers/src/NFTScan/utils.ts b/packages/web3-providers/src/NFTScan/utils.ts new file mode 100644 index 000000000000..151c9f50e212 --- /dev/null +++ b/packages/web3-providers/src/NFTScan/utils.ts @@ -0,0 +1,8 @@ +import { resolveIPFSLink } from '@masknet/web3-shared-evm' + +export function toNonIPFSImage(url?: string) { + if (!url) return '' + if (url.startsWith('http') || url.startsWith('data')) return url + if (url.startsWith('ipfs://')) return resolveIPFSLink(decodeURIComponent(url).replace('ipfs://', '')) + return resolveIPFSLink(url) +} From 214455abca0095c01170febc00a0dbcdd35dff17 Mon Sep 17 00:00:00 2001 From: Lantt Date: Thu, 17 Feb 2022 11:19:12 +0800 Subject: [PATCH 13/18] feat: improve loading nft --- .../CollectibleList/index.tsx | 4 +- .../nonFungibleCollectibleAssetV2.ts | 52 ++++++++++--------- 2 files changed, 28 insertions(+), 28 deletions(-) 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 e8e411b87e60..dc72b3dc4cac 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -287,9 +287,7 @@ export function CollectionList({ } return x }) - }, [collectibles.length, collectionsFormRemote]) - - console.log(collections) + }, [collectibles.length, collectionsFormRemote.length]) if (!isLoading && !collectibles.length) return ( diff --git a/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts b/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts index 26d8e12b8673..a47fb30b34a5 100644 --- a/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts +++ b/packages/provider-proxy/src/producers/nonFungibleCollectibleAssetV2.ts @@ -16,31 +16,33 @@ const nonFungibleCollectibleAsset = async ( const size = 50 const openSeaApiKey = await getKeys('opensea') - const fromOpenSea = collectAllPageDate( - (page) => getOpenSeaNFTList(openSeaApiKey, address, page, size), - size, - push, - ) - - const fromRarible = collectAllPageDate( - (page, pageInfo) => getRaribleNFTList(openSeaApiKey, address, page, size, pageInfo), - size, - push, - ) - - const formNFTScanERC721 = collectAllPageDate( - (page) => getNFTScanNFTs(address, 'erc721', page, size), - size, - push, - ) - - const fromNFTScanERC1155 = collectAllPageDate( - (page) => getNFTScanNFTs(address, 'erc1155', page, size), - size, - push, - ) - - await Promise.allSettled([fromOpenSea, fromRarible, formNFTScanERC721, fromNFTScanERC1155]) + try { + await collectAllPageDate( + (page) => getOpenSeaNFTList(openSeaApiKey, address, page, size), + size, + push, + ) + } finally { + const fromRarible = collectAllPageDate( + (page, pageInfo) => getRaribleNFTList(openSeaApiKey, address, page, size, pageInfo), + size, + push, + ) + + const formNFTScanERC721 = collectAllPageDate( + (page) => getNFTScanNFTs(address, 'erc721', page, size), + size, + push, + ) + + const fromNFTScanERC1155 = collectAllPageDate( + (page) => getNFTScanNFTs(address, 'erc1155', page, size), + size, + push, + ) + + await Promise.allSettled([fromRarible, formNFTScanERC721, fromNFTScanERC1155]) + } } const producer: RPCMethodRegistrationValue = { From 845dedd2ca8ab302cad5836941e4c08f8fa54e7e Mon Sep 17 00:00:00 2001 From: Lantt Date: Thu, 17 Feb 2022 14:56:46 +0800 Subject: [PATCH 14/18] refactor: pr feedback --- packages/mask/shared-ui/locales/en-US.json | 1 + .../CollectibleList/CollectionIcon.tsx | 3 ++- .../DashboardComponents/CollectibleList/index.tsx | 6 ++++-- packages/web3-providers/src/NFTScan/index.ts | 5 ++--- packages/web3-providers/src/NFTScan/utils.ts | 8 -------- packages/web3-providers/src/rarible/index.ts | 12 ++++++------ packages/web3-providers/src/rarible/utils.ts | 6 ------ packages/web3-shared/evm/pipes/index.ts | 8 ++++++++ 8 files changed, 23 insertions(+), 26 deletions(-) delete mode 100644 packages/web3-providers/src/NFTScan/utils.ts delete mode 100644 packages/web3-providers/src/rarible/utils.ts diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index ea2f8604f060..bbd21169522f 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -64,6 +64,7 @@ "message": "Message", "dashboard_tab_collectibles": "Collectibles", "dashboard_no_collectible_found": "No collectible found.", + "dashboard_collectible_menu_all": "All ({{count}})", "days": "Every {{days}} days", "decrypted_postbox_add_recipients": "Append recipients", "decrypted_postbox_decrypting": "Mask decrypting…", diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx index 8d6ce4752bd8..0d31b3b041f5 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectionIcon.tsx @@ -5,6 +5,7 @@ import { makeStyles } from '@masknet/theme' import { TokenIcon } from '@masknet/shared' import classNames from 'classnames' import type { ERC721ContractDetailed } from '@masknet/web3-shared-evm' +import { isSameAddress } from '@masknet/web3-shared-evm' const useStyles = makeStyles()((theme) => ({ collectionWrap: { @@ -53,7 +54,7 @@ export const CollectionIcon = memo(({ collection, onClick, {collection.iconURL ? ( 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 dc72b3dc4cac..46208ff456a3 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -275,7 +275,7 @@ export function CollectionList({ collectibles.map((x) => x.contractDetailed), (x) => x.address.toLowerCase(), ).map((x) => { - const item = collectionsFormRemote.find((c) => c.address === x.address) + const item = collectionsFormRemote.find((c) => isSameAddress(c.address, x.address)) if (item) { return { name: item.name, @@ -306,7 +306,9 @@ export function CollectionList({ ALL theme.palette.primary.main} fontSize="12px"> - All {collectibles.length ? `(${collectibles.length})` : null} + {t('dashboard_collectible_menu_all', { + count: collectibles.length, + })} diff --git a/packages/web3-providers/src/NFTScan/index.ts b/packages/web3-providers/src/NFTScan/index.ts index 514e5191137c..ca59e1b4b571 100644 --- a/packages/web3-providers/src/NFTScan/index.ts +++ b/packages/web3-providers/src/NFTScan/index.ts @@ -1,4 +1,4 @@ -import { ChainId, createERC721ContractDetailed, createERC721Token } from '@masknet/web3-shared-evm' +import { ChainId, createERC721ContractDetailed, createERC721Token, resolveResourceLink } from '@masknet/web3-shared-evm' import addSeconds from 'date-fns/addSeconds' import isBefore from 'date-fns/isBefore' import urlcat from 'urlcat' @@ -6,7 +6,6 @@ import type { NonFungibleTokenAPI } from '..' import { NFTSCAN_ACCESS_TOKEN_URL, NFTSCAN_BASE_API } from './constants' import type { NFTScanAsset, NFT_Assets } from './types' import { isProxyENV } from '../helpers' -import { toNonIPFSImage } from './utils' const tokenCache = new Map<'token', { token: string; expiration: Date }>() @@ -59,7 +58,7 @@ function createERC721TokenAsset(asset: NFTScanAsset) { { name: payload?.name ?? asset.nft_name ?? asset.nft_platform_name ?? '', description: payload?.description ?? '', - mediaUrl: toNonIPFSImage(asset.nft_cover ?? asset.nft_content_uri ?? payload.image ?? ''), + mediaUrl: resolveResourceLink(asset.nft_cover ?? asset.nft_content_uri ?? payload.image ?? ''), owner: asset.nft_holder ?? '', }, asset.token_id, diff --git a/packages/web3-providers/src/NFTScan/utils.ts b/packages/web3-providers/src/NFTScan/utils.ts deleted file mode 100644 index 151c9f50e212..000000000000 --- a/packages/web3-providers/src/NFTScan/utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { resolveIPFSLink } from '@masknet/web3-shared-evm' - -export function toNonIPFSImage(url?: string) { - if (!url) return '' - if (url.startsWith('http') || url.startsWith('data')) return url - if (url.startsWith('ipfs://')) return resolveIPFSLink(decodeURIComponent(url).replace('ipfs://', '')) - return resolveIPFSLink(url) -} diff --git a/packages/web3-providers/src/rarible/index.ts b/packages/web3-providers/src/rarible/index.ts index 37b80dbbf416..257a50fe1fe7 100644 --- a/packages/web3-providers/src/rarible/index.ts +++ b/packages/web3-providers/src/rarible/index.ts @@ -6,6 +6,7 @@ import { ERC721TokenDetailed, EthereumTokenType, FungibleTokenDetailed, + resolveResourceLink, } from '@masknet/web3-shared-evm' import { Ownership, @@ -16,7 +17,6 @@ import { RaribleProfileResponse, } from './types' import { RaribleUserURL, RaribleRopstenUserURL, RaribleMainnetURL, RaribleChainURL, RaribleURL } from './constants' -import { toRaribleImage } from './utils' import { NonFungibleTokenAPI } from '..' import { isProxyENV } from '../helpers' @@ -51,7 +51,7 @@ function createERC721TokenFromAsset( tokenId: string, asset?: RaribleNFTItemMapResponse, ): ERC721TokenDetailed { - const imageURL = toRaribleImage(asset?.meta.image?.url.ORIGINAL ?? asset?.meta.image?.url.PREVIEW ?? '') + const imageURL = resolveResourceLink(asset?.meta.image?.url.ORIGINAL ?? asset?.meta.image?.url.PREVIEW ?? '') return { contractDetailed: { type: EthereumTokenType.ERC721, @@ -64,7 +64,7 @@ function createERC721TokenFromAsset( name: asset?.meta.name ?? '', description: asset?.meta.description ?? '', mediaUrl: - toRaribleImage(asset?.meta.animation?.url.ORIGINAL ?? asset?.meta.animation?.url.PREVIEW ?? '') || + resolveResourceLink(asset?.meta.animation?.url.ORIGINAL ?? asset?.meta.animation?.url.PREVIEW ?? '') || imageURL, imageURL, owner: asset?.owners[0], @@ -80,7 +80,7 @@ function createNFTAsset(asset: RaribleNFTItemMapResponse, chainId: ChainId): Non is_verified: false, is_auction: false, token_address: asset.contract, - image_url: toRaribleImage(asset?.meta.image?.url.ORIGINAL), + image_url: resolveResourceLink(asset?.meta.image?.url.ORIGINAL ?? ''), asset_contract: null, owner: owner ? { @@ -213,7 +213,7 @@ export class RaribleAPI implements NonFungibleTokenAPI.Provider { maker_account: { user: { username: ownerInfo?.name ?? '' }, address: ownerInfo?.id ?? '', - profile_img_url: toRaribleImage(ownerInfo?.image), + profile_img_url: resolveResourceLink(ownerInfo?.image ?? ''), link: `${resolveRaribleUserNetwork(chainId as number)}${ownerInfo?.id ?? ''}`, }, } @@ -244,7 +244,7 @@ export class RaribleAPI implements NonFungibleTokenAPI.Provider { maker_account: { user: { username: ownerInfo?.name ?? '' }, address: ownerInfo?.id ?? '', - profile_img_url: toRaribleImage(ownerInfo?.image), + profile_img_url: resolveResourceLink(ownerInfo?.image ?? ''), link: `${resolveRaribleUserNetwork(chainId as number)}${ownerInfo?.id ?? ''}`, }, } diff --git a/packages/web3-providers/src/rarible/utils.ts b/packages/web3-providers/src/rarible/utils.ts deleted file mode 100644 index 70f4b7d55166..000000000000 --- a/packages/web3-providers/src/rarible/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { resolveIPFSLink } from '@masknet/web3-shared-evm' -export function toRaribleImage(url?: string) { - if (!url) return '' - if (url.startsWith('ipfs://ipfs/')) return resolveIPFSLink(url.replace(/^ipfs:\/\/ipfs\//, '')) - return url -} diff --git a/packages/web3-shared/evm/pipes/index.ts b/packages/web3-shared/evm/pipes/index.ts index 220c857a797e..34a54a1a422b 100644 --- a/packages/web3-shared/evm/pipes/index.ts +++ b/packages/web3-shared/evm/pipes/index.ts @@ -175,6 +175,14 @@ export function resolveIPFSLink(ipfs: string): string { return urlcat('https://coldcdn.com/api/cdn/mipfsygtms/ipfs/:ipfs', { ipfs }) } +export function resolveResourceLink(originLink: string): string { + if (!originLink) return '' + if (originLink.startsWith('http') || originLink.startsWith('data')) return originLink + if (originLink.startsWith('ipfs://ipfs/')) return resolveIPFSLink(originLink.replace(/^ipfs:\/\/ipfs\//, '')) + if (originLink.startsWith('ipfs://')) return resolveIPFSLink(decodeURIComponent(originLink).replace('ipfs://', '')) + return resolveIPFSLink(originLink) +} + export function resolveDomainLink(domain?: string) { if (!domain) return '' return urlcat('https://app.ens.domains/name/:domain/details', { domain }) From 5584a5a4a73adb573f9197da6cf90ffdfaf65306 Mon Sep 17 00:00:00 2001 From: Lantt Date: Fri, 18 Feb 2022 12:21:07 +0800 Subject: [PATCH 15/18] fix: change collectible key for re-render --- .../options-page/DashboardComponents/CollectibleList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 46208ff456a3..1a84cf99ab22 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -196,7 +196,7 @@ function CollectibleListUI(props: CollectibleListUIProps) { provider={provider} wallet={wallet} readonly={readonly} - key={i} + key={x.tokenId + x.contractDetailed.address} /> ))} From 56ca96fab3161209556fd6878146df854488a220 Mon Sep 17 00:00:00 2001 From: Lantt Date: Fri, 18 Feb 2022 14:42:32 +0800 Subject: [PATCH 16/18] fix: style --- .../options-page/DashboardComponents/CollectibleList/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 1a84cf99ab22..55207735e544 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -58,11 +58,12 @@ const useStyles = makeStyles()((theme) => ({ overflow: 'auto', }, card: { + width: 172, display: 'flex', flexDirection: 'column', alignItems: 'center', position: 'relative', - padding: theme.spacing(1), + padding: theme.spacing(1, 0), }, description: { background: theme.palette.mode === 'light' ? '#F7F9FA' : '#2F3336', From b64d61472010f4013ddc4423a5a13cf867a47549 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Sat, 19 Feb 2022 16:59:08 +0800 Subject: [PATCH 17/18] fix: no self added nft for nft wall --- packages/web3-shared/evm/hooks/useCollectibles.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/web3-shared/evm/hooks/useCollectibles.ts b/packages/web3-shared/evm/hooks/useCollectibles.ts index d2da17606b45..bbd9f29b9a3b 100644 --- a/packages/web3-shared/evm/hooks/useCollectibles.ts +++ b/packages/web3-shared/evm/hooks/useCollectibles.ts @@ -33,7 +33,11 @@ export function useCollectibles(address: string, chainId: ChainId | null, depend const all = uniqWith( [ ...(data ?? []), - ...erc721Tokens.getCurrentValue().filter((x) => !chainId || x.contractDetailed.chainId === chainId), + ...erc721Tokens + .getCurrentValue() + .filter( + (x) => (!chainId || x.contractDetailed.chainId === chainId) && isSameAddress(x.info.owner, address), + ), ], (a, b) => isSameAddress(a.contractDetailed.address, b.contractDetailed.address) && a.tokenId === b.tokenId, ) From b631073ff543765ca5670ed833ceba36b08a6a16 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Mon, 21 Feb 2022 15:03:31 +0800 Subject: [PATCH 18/18] chore: ipfs resource --- packages/web3-shared/evm/pipes/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-shared/evm/pipes/index.ts b/packages/web3-shared/evm/pipes/index.ts index 34a54a1a422b..070d3a080d36 100644 --- a/packages/web3-shared/evm/pipes/index.ts +++ b/packages/web3-shared/evm/pipes/index.ts @@ -172,7 +172,7 @@ export function resolveBlockLinkOnExplorer(chainId: ChainId, block: string): str } export function resolveIPFSLink(ipfs: string): string { - return urlcat('https://coldcdn.com/api/cdn/mipfsygtms/ipfs/:ipfs', { ipfs }) + return urlcat('https://ipfs.fleek.co/ipfs/:ipfs', { ipfs }) } export function resolveResourceLink(originLink: string): string {