diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/views/SelectCollectibles.tsx b/packages/plugins/RedPacket/src/SiteAdaptor/views/SelectCollectibles.tsx index 98d0ed2de575..ef6a0420c3bc 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/views/SelectCollectibles.tsx +++ b/packages/plugins/RedPacket/src/SiteAdaptor/views/SelectCollectibles.tsx @@ -1,3 +1,4 @@ +import { t } from '@lingui/core/macro' import { Trans } from '@lingui/react/macro' import { AddCollectiblesModal, CollectionList, useAssetsNetworks, UserAssetsProvider } from '@masknet/shared' import { NetworkPluginID } from '@masknet/shared-base' @@ -5,7 +6,7 @@ import { makeStyles } from '@masknet/theme' import type { Web3Helper } from '@masknet/web3-helpers' import { useChainContext, useNetworkContext, useWeb3Connection, useWeb3Hub } from '@masknet/web3-hooks-base' import { isSameAddress } from '@masknet/web3-shared-base' -import type { ChainId } from '@masknet/web3-shared-evm' +import { SchemaType, type ChainId } from '@masknet/web3-shared-evm' import { alpha, Box, Button, DialogActions } from '@mui/material' import { compact, uniqBy } from 'lodash-es' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -125,6 +126,9 @@ export function SelectCollectibles() { unsubscribe() } }, [handleAddCollectibles]) + const assetDisableRule = useCallback((asset: Web3Helper.NonFungibleCollectionAll) => { + return asset.schema !== SchemaType.ERC721 + }, []) return ( @@ -139,7 +143,9 @@ export function SelectCollectibles() { The maximum number of NFTs to be sold in one collection lucky drop contract is 255. } selectedAssets={pendingNfts} - disableReport> + disableReport + assetDisableRule={assetDisableRule} + assetDisableDescription={t`This NFT contract cannot be modified now.`}> boolean + assetDisableDescription?: string | ReactNode } const AssetsContext = createContext({ @@ -95,6 +101,8 @@ export interface AssetsProviderProps | 'maxSelection' | 'maxSelectionDescription' | 'disableReport' + | 'assetDisableRule' + | 'assetDisableDescription' > { /** blocked ids in format of `${chainid}.${address}.${tokenId}` */ blockedIds?: string[] @@ -109,6 +117,8 @@ export const AssetsProvider = memo(function AssetsProvider( selectedAsset, selectedAssets, disableReport, + assetDisableRule, + assetDisableDescription, }) { const [{ assetsMap, verifiedMap }, dispatch] = useReducer(assetsReducer, initialAssetsState) const indicatorMapRef = useRef>(new Map()) @@ -307,6 +317,8 @@ export const AssetsProvider = memo(function AssetsProvider( searchKeyword, setSearchKeyword, disableReport, + assetDisableRule, + assetDisableDescription, } }, [ getAssets, @@ -324,6 +336,8 @@ export const AssetsProvider = memo(function AssetsProvider( selectedAssets, selectedAsset, disableReport, + assetDisableRule, + assetDisableDescription, ]) return {children} diff --git a/packages/shared/src/UI/components/AssetsManagement/CollectibleItem.tsx b/packages/shared/src/UI/components/AssetsManagement/CollectibleItem.tsx index c07e036ebddf..734ed9e2cff2 100644 --- a/packages/shared/src/UI/components/AssetsManagement/CollectibleItem.tsx +++ b/packages/shared/src/UI/components/AssetsManagement/CollectibleItem.tsx @@ -26,6 +26,10 @@ const useStyles = makeStyles()((the zIndex: 0, willChange: 'opacity', }, + assetDisabled: { + cursor: 'not-allowed !important', + opacity: 0.5, + }, withAction: { '&:hover': { transform: 'translateY(19px)', @@ -112,6 +116,8 @@ export interface CollectibleItemProps extends HTMLProps, Collect disableAction?: boolean actionLabel?: ReactNode verifiedBy?: string[] + assetDisabled?: boolean + assetDisableDescription?: string | ReactNode onActionClick?(asset: CollectibleCardProps['asset']): void onItemClick?(asset: CollectibleCardProps['asset']): void } @@ -129,6 +135,8 @@ export const CollectibleItem = memo((props: CollectibleItemProps) => { isSelected, hideIndicator, selectable, + assetDisabled, + assetDisableDescription, onActionClick, onItemClick, ...rest @@ -137,8 +145,9 @@ export const CollectibleItem = memo((props: CollectibleItemProps) => { const name = asset.collection?.name ?? '' const popperProps = useBoundedPopperProps() const handleClick = useCallback(() => { + if (assetDisabled) return onItemClick?.(asset) - }, [onItemClick, asset]) + }, [onItemClick, asset, assetDisabled]) const assetName = useMemo(() => { if (!asset.collection) return @@ -155,7 +164,8 @@ export const CollectibleItem = memo((props: CollectibleItemProps) => { const [nameOverflow, nameRef] = useDetectOverflow() const [identityOverflow, identityRef] = useDetectOverflow() const tooltip = - nameOverflow || identityOverflow ? + assetDisabled ? assetDisableDescription + : nameOverflow || identityOverflow ? {disableName ? null :
{name}
} {assetName} @@ -165,7 +175,13 @@ export const CollectibleItem = memo((props: CollectibleItemProps) => { return (
()((theme, { compact }) => ({ backgroundColor: theme.palette.maskColor.bg, borderRadius: 8, }, + assetDisabled: { + cursor: 'not-allowed !important', + opacity: 0.5, + '& *': { + cursor: 'not-allowed !important', + }, + }, grid: { display: 'grid', overflow: 'auto', @@ -116,7 +123,7 @@ export const Collection = memo( const { compact, containerRef } = useCompactDetection() const popperProps = useBoundedPopperProps() const { classes, cx } = useStyles({ compact }) - const { multiple, selectedAsset, selectedAssets } = useUserAssets() + const { multiple, selectedAsset, selectedAssets, assetDisableRule, assetDisableDescription } = useUserAssets() useLayoutEffect(() => { onInitialRender?.(collection) @@ -137,6 +144,7 @@ export const Collection = memo( const hasExtra = count > 4 && !expanded const assetsSlice = hasExtra ? assets.slice(0, 3) : assets + const assetDisabled = assetDisableRule?.(collection) if (collection.balance! <= 2 || (!loading && assets.length < 2) || expanded) { const renderAssets = assetsSlice.map((asset) => ( )) return <>{renderAssets} @@ -178,14 +188,20 @@ export const Collection = memo( return (
{ + if (assetDisabled) return onExpand?.(collection.id!) }} ref={containerRef}> diff --git a/packages/shared/src/UI/components/AssetsManagement/UserAssetsContext.tsx b/packages/shared/src/UI/components/AssetsManagement/UserAssetsContext.tsx index 474963f0410c..4706205cf844 100644 --- a/packages/shared/src/UI/components/AssetsManagement/UserAssetsContext.tsx +++ b/packages/shared/src/UI/components/AssetsManagement/UserAssetsContext.tsx @@ -18,6 +18,8 @@ interface UserAssetsProviderProps | 'maxSelection' | 'maxSelectionDescription' | 'disableReport' + | 'assetDisableRule' + | 'assetDisableDescription' > {} export const UserAssetsProvider = memo>(function UserAssetsProvider({ @@ -35,6 +37,8 @@ export const UserAssetsProvider = memo + disableReport={disableReport} + assetDisableRule={assetDisableRule} + assetDisableDescription={assetDisableDescription}> {children} diff --git a/packages/web3-providers/src/SimpleHash/apis/EVM.ts b/packages/web3-providers/src/SimpleHash/apis/EVM.ts index 1d1b74c9285b..78eb00bee6f7 100644 --- a/packages/web3-providers/src/SimpleHash/apis/EVM.ts +++ b/packages/web3-providers/src/SimpleHash/apis/EVM.ts @@ -395,30 +395,32 @@ class SimpleHashAPI_EVM implements NonFungibleTokenAPI.Provider x.nft_ids?.[0] || '').filter(Boolean) - while (nftIdList.length) { - const batchAssetsPath = urlcat('/api/v0/nfts/assets', { - nft_ids: nftIdList.splice(0, 50).join(','), - }) - - const batchAssetsResponse = await fetchFromSimpleHash<{ - nfts: SimpleHash.Asset[] - }>(batchAssetsPath) - - erc721CollectionIdList = erc721CollectionIdList.concat( - batchAssetsResponse.nfts - .filter((x) => x.contract.type === 'ERC721') - .map((x) => x.collection.collection_id), - ) - } + const nftIdList = filteredCollections.map((x) => x.nft_ids?.[0] || '').filter(Boolean) + while (nftIdList.length) { + const batchAssetsPath = urlcat('/api/v0/nfts/assets', { + nft_ids: nftIdList.splice(0, 50).join(','), + }) + + const batchAssetsResponse = await fetchFromSimpleHash<{ + nfts: SimpleHash.Asset[] + }>(batchAssetsPath) + + erc721CollectionIdList = erc721CollectionIdList.concat( + batchAssetsResponse.nfts + .filter((x) => x.contract.type === 'ERC721') + .map((x) => x.collection.collection_id), + ) } - const collections = filteredCollections - .filter((x) => !isERC712Only || erc721CollectionIdList.includes(x.id)) - .map((x) => createNonFungibleCollection(x)) + const collections = filteredCollections.map((x) => { + const schema = erc721CollectionIdList.includes(x.id) ? SchemaType.ERC721 : SchemaType.ERC1155 + return createNonFungibleCollection(x, schema) + }) - return createPageable(collections, createIndicator(indicator)) + return createPageable( + isERC712Only ? collections.filter((x) => x.schema === SchemaType.ERC721) : collections, + createIndicator(indicator), + ) } async getAssetsByCollectionAndOwner( diff --git a/packages/web3-providers/src/SimpleHash/helpers.ts b/packages/web3-providers/src/SimpleHash/helpers.ts index 33ffaf807020..6a10113b7ecd 100644 --- a/packages/web3-providers/src/SimpleHash/helpers.ts +++ b/packages/web3-providers/src/SimpleHash/helpers.ts @@ -121,6 +121,7 @@ export function createNonFungibleAsset(asset: SimpleHash.Asset): NonFungibleAsse export function createNonFungibleCollection( collection: SimpleHash.Collection, + schema: SchemaType, ): NonFungibleCollection { const chainId = resolveChainId(collection.chain)! @@ -130,7 +131,7 @@ export function createNonFungibleCollection( chainId, name: collection.name || '', slug: collection.name, - schema: SchemaType.ERC721, + schema, balance: collection.distinct_nfts_owned, iconURL: collection.image_url, ownersTotal: collection.total_quantity,