diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 9ab00d821..6bc15f393 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -82,6 +82,9 @@ "addFriendsAndAddresses": { "message": "Add friends and addresses you trust" }, + "addNFT": { + "message": "Add NFT" + }, "addNetwork": { "message": "Add Network" }, @@ -1542,6 +1545,9 @@ "message": "Nonce is higher than suggested nonce of $1", "description": "The next nonce according to MetaMask's internal logic" }, + "nfts": { + "message": "NFTs" + }, "noAccountsFound": { "message": "No accounts found for the given search query" }, @@ -1554,6 +1560,12 @@ "noConversionRateAvailable": { "message": "No Conversion Rate Available" }, + "noNFTs": { + "message": "No NFTs to show" + }, + "noNFTsDetails": { + "message": "Your NFTs will show up here. If you don't see your NFT, try importing manually." + }, "noThanks": { "message": "No Thanks" }, diff --git a/app/images/diamond.png b/app/images/diamond.png new file mode 100644 index 000000000..5c04fae08 Binary files /dev/null and b/app/images/diamond.png differ diff --git a/development/build/scripts.js b/development/build/scripts.js index 6d0128639..bfdac3840 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -33,6 +33,7 @@ const metamaskrc = require('rc')('metamask', { INFURA_FLASK_PROJECT_ID: process.env.INFURA_FLASK_PROJECT_ID, INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID, ONBOARDING_V2: process.env.ONBOARDING_V2, + COLLECTIBLES_V1: process.env.COLLECTIBLES_V1, SEGMENT_HOST: process.env.SEGMENT_HOST, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY, @@ -726,6 +727,7 @@ function getEnvironmentVariables({ buildType, devMode, testing }) { SEGMENT_WRITE_KEY: getSegmentWriteKey({ buildType, environment }), SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1', ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1', + COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1', }; } diff --git a/ui/components/app/collectibles-list/collectibles-list.component.js b/ui/components/app/collectibles-list/collectibles-list.component.js new file mode 100644 index 000000000..b0c0161c7 --- /dev/null +++ b/ui/components/app/collectibles-list/collectibles-list.component.js @@ -0,0 +1,84 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Box from '../../ui/box'; +import Button from '../../ui/button'; +import Typography from '../../ui/typography/typography'; +import { + COLORS, + TYPOGRAPHY, + TEXT_ALIGN, + BLOCK_SIZES, + JUSTIFY_CONTENT, + FLEX_DIRECTION, +} from '../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { getEnvironmentType } from '../../../../app/scripts/lib/util'; +import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; + +export default function CollectiblesList({ onAddNFT }) { + const collectibles = []; + const t = useI18nContext(); + const blockSizes = { + copy: + getEnvironmentType() === ENVIRONMENT_TYPE_POPUP + ? BLOCK_SIZES.TWO_THIRDS + : BLOCK_SIZES.ONE_THIRD, + button: + getEnvironmentType() === ENVIRONMENT_TYPE_POPUP + ? BLOCK_SIZES.HALF + : BLOCK_SIZES.ONE_FIFTH, + }; + + return ( +
+ {collectibles.length > 0 ? ( + {JSON.stringify(collectibles)} + ) : ( + + + + + + {t('noNFTs')} + + + + + {t('noNFTsDetails')} + + + + + + + + + + + + + )} +
+ ); +} + +CollectiblesList.propTypes = { + onAddNFT: PropTypes.func.isRequired, +}; diff --git a/ui/components/app/collectibles-list/index.js b/ui/components/app/collectibles-list/index.js new file mode 100644 index 000000000..ab3fb9b56 --- /dev/null +++ b/ui/components/app/collectibles-list/index.js @@ -0,0 +1 @@ +export { default } from './collectibles-list.component'; diff --git a/ui/components/ui/tabs/tabs.component.js b/ui/components/ui/tabs/tabs.component.js index 6c091e5a2..c0f9dc923 100644 --- a/ui/components/ui/tabs/tabs.component.js +++ b/ui/components/ui/tabs/tabs.component.js @@ -42,9 +42,9 @@ export default class Tabs extends Component { } renderTabs() { - const numberOfTabs = React.Children.count(this.props.children); + const numberOfTabs = React.Children.count(this._getValidChildren()); - return React.Children.map(this.props.children, (child, index) => { + return React.Children.map(this._getValidChildren(), (child, index) => { const tabName = child?.props.name; return ( child && @@ -58,7 +58,7 @@ export default class Tabs extends Component { } renderActiveTabContent() { - const { children } = this.props; + const children = this._getValidChildren(); const { activeTabIndex } = this.state; if ( @@ -92,8 +92,12 @@ export default class Tabs extends Component { * @private */ _findChildByName(name) { - return React.Children.toArray(this.props.children).findIndex( - (c) => c?.props.name === name, - ); + return this._getValidChildren().findIndex((c) => c?.props.name === name); + } + + // This ignores any 'null' child elements that are a result of a conditional + // based on a feature flag setting. + _getValidChildren() { + return React.Children.toArray(this.props.children).filter(Boolean); } } diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index a6e91ba88..c46449cfd 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Redirect, Route } from 'react-router-dom'; import { formatDate } from '../../helpers/utils/util'; import AssetList from '../../components/app/asset-list'; +import CollectiblesList from '../../components/app/collectibles-list'; import HomeNotification from '../../components/app/home-notification'; import MultipleNotifications from '../../components/app/multiple-notifications'; import TransactionList from '../../components/app/transaction-list'; @@ -428,6 +429,20 @@ export default class Home extends PureComponent { } /> + {process.env.COLLECTIBLES_V1 ? ( + + { + console.log('Added NFT'); + }} + /> + + ) : null}