import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { isEqual } from 'lodash'; import Box from '../../ui/box'; import Typography from '../../ui/typography/typography'; import Card from '../../ui/card'; import { Color, TypographyVariant, JustifyContent, FLEX_DIRECTION, AlignItems, DISPLAY, BLOCK_SIZES, FLEX_WRAP, } from '../../../helpers/constants/design-system'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { getCurrentChainId, getIpfsGateway, getSelectedAddress, } from '../../../selectors'; import { ASSET_ROUTE } from '../../../helpers/constants/routes'; import { getAssetImageURL } from '../../../helpers/utils/util'; import { getNftImageAlt } from '../../../helpers/utils/nfts'; import { updateNftDropDownState } from '../../../store/actions'; import { usePrevious } from '../../../hooks/usePrevious'; import { getNftsDropdownState } from '../../../ducks/metamask/metamask'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; import NftDefaultImage from '../nft-default-image'; const width = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? BLOCK_SIZES.ONE_THIRD : BLOCK_SIZES.ONE_SIXTH; const PREVIOUSLY_OWNED_KEY = 'previouslyOwned'; export default function NftsItems({ collections = {}, previouslyOwnedCollection = {}, }) { const dispatch = useDispatch(); const collectionsKeys = Object.keys(collections); const nftsDropdownState = useSelector(getNftsDropdownState); const previousCollectionKeys = usePrevious(collectionsKeys); const selectedAddress = useSelector(getSelectedAddress); const chainId = useSelector(getCurrentChainId); const t = useI18nContext(); useEffect(() => { if ( chainId !== undefined && selectedAddress !== undefined && !isEqual(previousCollectionKeys, collectionsKeys) && (nftsDropdownState?.[selectedAddress]?.[chainId] === undefined || Object.keys(nftsDropdownState?.[selectedAddress]?.[chainId]).length === 0) ) { const initState = {}; collectionsKeys.forEach((key) => { initState[key] = true; }); const newNftDropdownState = { ...nftsDropdownState, [selectedAddress]: { ...nftsDropdownState?.[selectedAddress], [chainId]: initState, }, }; dispatch(updateNftDropDownState(newNftDropdownState)); } }, [ collectionsKeys, previousCollectionKeys, nftsDropdownState, selectedAddress, chainId, dispatch, ]); const ipfsGateway = useSelector(getIpfsGateway); const history = useHistory(); const renderCollectionImage = (collectionImage, collectionName) => { if (collectionImage) { return ( {collectionName} ); } return (
{collectionName?.[0]?.toUpperCase() ?? null}
); }; const updateNftDropDownStateKey = (key, isExpanded) => { const newCurrentAccountState = { ...nftsDropdownState[selectedAddress][chainId], [key]: !isExpanded, }; const newState = { ...nftsDropdownState, [selectedAddress]: { [chainId]: newCurrentAccountState, }, }; dispatch(updateNftDropDownState(newState)); }; const renderCollection = ({ nfts, collectionName, collectionImage, key }) => { if (!nfts.length) { return null; } const isExpanded = nftsDropdownState[selectedAddress]?.[chainId]?.[key]; return (
{isExpanded ? ( {nfts.map((nft, i) => { const { image, address, tokenId, backgroundColor, name } = nft; const nftImage = getAssetImageURL(image, ipfsGateway); const nftImageAlt = getNftImageAlt(nft); const handleImageClick = () => history.push(`${ASSET_ROUTE}/${address}/${tokenId}`); return ( {nftImage ? ( ) : ( )} ); })} ) : null}
); }; return (
<> {collectionsKeys.map((key) => { const { nfts, collectionName, collectionImage } = collections[key]; return renderCollection({ nfts, collectionName, collectionImage, key, isPreviouslyOwnedCollection: false, }); })} {renderCollection({ nfts: previouslyOwnedCollection.nfts, collectionName: previouslyOwnedCollection.collectionName, collectionImage: previouslyOwnedCollection.nfts[0]?.image, isPreviouslyOwnedCollection: true, key: PREVIOUSLY_OWNED_KEY, })}
); } NftsItems.propTypes = { previouslyOwnedCollection: PropTypes.shape({ nfts: PropTypes.arrayOf( PropTypes.shape({ address: PropTypes.string.isRequired, tokenId: PropTypes.string.isRequired, name: PropTypes.string, description: PropTypes.string, image: PropTypes.string, standard: PropTypes.string, imageThumbnail: PropTypes.string, imagePreview: PropTypes.string, creator: PropTypes.shape({ address: PropTypes.string, config: PropTypes.string, profile_img_url: PropTypes.string, }), }), ), collectionName: PropTypes.string, collectionImage: PropTypes.string, }), collections: PropTypes.shape({ nfts: PropTypes.arrayOf( PropTypes.shape({ address: PropTypes.string.isRequired, tokenId: PropTypes.string.isRequired, name: PropTypes.string, description: PropTypes.string, image: PropTypes.string, standard: PropTypes.string, imageThumbnail: PropTypes.string, imagePreview: PropTypes.string, creator: PropTypes.shape({ address: PropTypes.string, config: PropTypes.string, profile_img_url: PropTypes.string, }), }), ), collectionImage: PropTypes.string, collectionName: PropTypes.string, }), };