diff --git a/.metamaskrc.dist b/.metamaskrc.dist index 0554ac85e..2cb654cfb 100644 --- a/.metamaskrc.dist +++ b/.metamaskrc.dist @@ -8,6 +8,7 @@ COLLECTIBLES_V1= PUBNUB_PUB_KEY= PUBNUB_SUB_KEY= TOKEN_ALLOWANCE_IMPROVEMENTS= +PORTFOLIO_URL= ; Set this to '1' to enable support for Sign-In with Ethereum [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) SIWE_V1= diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index a289f128e..6240896e7 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -451,6 +451,9 @@ "betaMetamaskVersion": { "message": "MetaMask Beta Version" }, + "betaPortfolioSite": { + "message": "beta portfolio site" + }, "betaWelcome": { "message": "Welcome to MetaMask Beta" }, @@ -1778,6 +1781,9 @@ "message": "JSON File", "description": "format for importing an account" }, + "keepTapsOnTokens": { + "message": "to keep tabs on your tokens and NFTs across accounts and networks." + }, "keystone": { "message": "Keystone" }, @@ -2164,6 +2170,9 @@ "nevermind": { "message": "Nevermind" }, + "new": { + "message": "New!" + }, "newAccount": { "message": "New account" }, @@ -2676,6 +2685,9 @@ "popularCustomNetworks": { "message": "Popular custom networks" }, + "portfolioSite": { + "message": "Portfolio site" + }, "preferredLedgerConnectionType": { "message": "Preferred Ledger connection type", "description": "A header for a dropdown in Settings > Advanced. Appears above the ledgerConnectionPreferenceDescription message" @@ -4097,6 +4109,9 @@ "tryAgain": { "message": "Try again" }, + "tryOur": { + "message": "Try our" + }, "turnOnTokenDetection": { "message": "Turn on enhanced token detection" }, diff --git a/app/scripts/controllers/app-state.js b/app/scripts/controllers/app-state.js index 4dee8a8c3..5dfdc2f70 100644 --- a/app/scripts/controllers/app-state.js +++ b/app/scripts/controllers/app-state.js @@ -33,6 +33,7 @@ export default class AppStateController extends EventEmitter { collectiblesDetectionNoticeDismissed: false, enableEIP1559V2NoticeDismissed: false, showTestnetMessageInDropdown: true, + showPortfolioTooltip: true, trezorModel: null, ...initState, qrHardware: {}, @@ -259,6 +260,15 @@ export default class AppStateController extends EventEmitter { this.store.updateState({ showTestnetMessageInDropdown }); } + /** + * Sets whether the portfolio site tooltip should be shown on the home page + * + * @param showPortfolioTooltip + */ + setShowPortfolioTooltip(showPortfolioTooltip) { + this.store.updateState({ showPortfolioTooltip }); + } + /** * Sets a property indicating the model of the user's Trezor hardware wallet * diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 4b115d834..453f6cd1e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1727,6 +1727,8 @@ export default class MetamaskController extends EventEmitter { appStateController.setShowTestnetMessageInDropdown.bind( appStateController, ), + setShowPortfolioTooltip: + appStateController.setShowPortfolioTooltip.bind(appStateController), setCollectiblesDetectionNoticeDismissed: appStateController.setCollectiblesDetectionNoticeDismissed.bind( appStateController, diff --git a/development/build/scripts.js b/development/build/scripts.js index 86a324ad4..eca8bee2c 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -1023,6 +1023,7 @@ async function getEnvironmentVariables({ buildTarget, buildType, version }) { environment, testing, }), + PORTFOLIO_URL: ENVIRONMENT.PORTFOLIO_URL || 'https://portfolio.metamask.io', METAMASK_DEBUG: devMode, METAMASK_ENVIRONMENT: environment, METAMASK_VERSION: version, diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index a994ec357..78990d81b 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -323,6 +323,7 @@ export const EVENT_NAMES = { PERMISSIONS_APPROVED: 'Permissions Approved', PERMISSIONS_REJECTED: 'Permissions Rejected', PERMISSIONS_REQUESTED: 'Permissions Requested', + PORTFOLIO_LINK_CLICKED: 'Portfolio Link Clicked', PUBLIC_ADDRESS_COPIED: 'Public Address Copied', PROVIDER_METHOD_CALLED: 'Provider Method Called', SIGNATURE_APPROVED: 'Signature Approved', diff --git a/test/e2e/fixtures/address-entry/state.json b/test/e2e/fixtures/address-entry/state.json index 03ed534bd..5fbf10276 100644 --- a/test/e2e/fixtures/address-entry/state.json +++ b/test/e2e/fixtures/address-entry/state.json @@ -15,7 +15,8 @@ }, "AppStateController": { "mkrMigrationReminderTimestamp": null, - "swapsWelcomeMessageHasBeenShown": true + "swapsWelcomeMessageHasBeenShown": true, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/connected-state/state.json b/test/e2e/fixtures/connected-state/state.json index e29020a90..28a206071 100644 --- a/test/e2e/fixtures/connected-state/state.json +++ b/test/e2e/fixtures/connected-state/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "connectedStatusPopoverHasBeenShown": false + "connectedStatusPopoverHasBeenShown": false, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/custom-rpc/state.json b/test/e2e/fixtures/custom-rpc/state.json index ecd4ea5dc..8088a1799 100644 --- a/test/e2e/fixtures/custom-rpc/state.json +++ b/test/e2e/fixtures/custom-rpc/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "mkrMigrationReminderTimestamp": null + "mkrMigrationReminderTimestamp": null, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/custom-token/state.json b/test/e2e/fixtures/custom-token/state.json index ea408f952..5f447420b 100644 --- a/test/e2e/fixtures/custom-token/state.json +++ b/test/e2e/fixtures/custom-token/state.json @@ -12,7 +12,8 @@ "connectedStatusPopoverHasBeenShown": true, "defaultHomeActiveTabName": null, "recoveryPhraseReminderHasBeenShown": true, - "recoveryPhraseReminderLastShown": "__FIXTURE_SUBSTITUTION__currentDateInMilliseconds" + "recoveryPhraseReminderLastShown": "__FIXTURE_SUBSTITUTION__currentDateInMilliseconds", + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/eip-1559-v2-dapp/state.json b/test/e2e/fixtures/eip-1559-v2-dapp/state.json index 1a6149f20..1b01bc077 100644 --- a/test/e2e/fixtures/eip-1559-v2-dapp/state.json +++ b/test/e2e/fixtures/eip-1559-v2-dapp/state.json @@ -2,7 +2,8 @@ "data": { "AppStateController": { "mkrMigrationReminderTimestamp": null, - "swapsWelcomeMessageHasBeenShown": true + "swapsWelcomeMessageHasBeenShown": true, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/eip-1559-v2/state.json b/test/e2e/fixtures/eip-1559-v2/state.json index e44ba2a37..0341d4ecb 100644 --- a/test/e2e/fixtures/eip-1559-v2/state.json +++ b/test/e2e/fixtures/eip-1559-v2/state.json @@ -2,7 +2,8 @@ "data": { "AppStateController": { "mkrMigrationReminderTimestamp": null, - "swapsWelcomeMessageHasBeenShown": true + "swapsWelcomeMessageHasBeenShown": true, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/import-ui/state.json b/test/e2e/fixtures/import-ui/state.json index 80ab5894a..9de1f31ff 100644 --- a/test/e2e/fixtures/import-ui/state.json +++ b/test/e2e/fixtures/import-ui/state.json @@ -265,7 +265,8 @@ "AppStateController": { "connectedStatusPopoverHasBeenShown": true, "swapsWelcomeMessageHasBeenShown": false, - "defaultHomeActiveTabName": "Activity" + "defaultHomeActiveTabName": "Activity", + "showPortfolioTooltip": false } }, "meta": { diff --git a/test/e2e/fixtures/imported-account/state.json b/test/e2e/fixtures/imported-account/state.json index 2a5849f2e..d89d6e2cf 100644 --- a/test/e2e/fixtures/imported-account/state.json +++ b/test/e2e/fixtures/imported-account/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "mkrMigrationReminderTimestamp": null + "mkrMigrationReminderTimestamp": null, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/localization/state.json b/test/e2e/fixtures/localization/state.json index 7b8d4ae27..d5ba38d28 100644 --- a/test/e2e/fixtures/localization/state.json +++ b/test/e2e/fixtures/localization/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "mkrMigrationReminderTimestamp": null + "mkrMigrationReminderTimestamp": null, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/metrics-enabled/state.json b/test/e2e/fixtures/metrics-enabled/state.json index 7a4c864a5..683f6cda6 100644 --- a/test/e2e/fixtures/metrics-enabled/state.json +++ b/test/e2e/fixtures/metrics-enabled/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "connectedStatusPopoverHasBeenShown": false + "connectedStatusPopoverHasBeenShown": false, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/navigate-transactions/state.json b/test/e2e/fixtures/navigate-transactions/state.json index a9faca5ba..8d4734d54 100644 --- a/test/e2e/fixtures/navigate-transactions/state.json +++ b/test/e2e/fixtures/navigate-transactions/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "mkrMigrationReminderTimestamp": null + "mkrMigrationReminderTimestamp": null, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/send-edit-v2/state.json b/test/e2e/fixtures/send-edit-v2/state.json index 830976631..b414cf8d3 100644 --- a/test/e2e/fixtures/send-edit-v2/state.json +++ b/test/e2e/fixtures/send-edit-v2/state.json @@ -2,7 +2,8 @@ "data": { "AppStateController": { "mkrMigrationReminderTimestamp": null, - "swapsWelcomeMessageHasBeenShown": true + "swapsWelcomeMessageHasBeenShown": true, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/send-edit/state.json b/test/e2e/fixtures/send-edit/state.json index 8c5a4658e..30eee4e90 100644 --- a/test/e2e/fixtures/send-edit/state.json +++ b/test/e2e/fixtures/send-edit/state.json @@ -2,7 +2,8 @@ "data": { "AppStateController": { "mkrMigrationReminderTimestamp": null, - "swapsWelcomeMessageHasBeenShown": true + "swapsWelcomeMessageHasBeenShown": true, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/special-settings/state.json b/test/e2e/fixtures/special-settings/state.json index 2f0297cc2..57a4cd2c9 100644 --- a/test/e2e/fixtures/special-settings/state.json +++ b/test/e2e/fixtures/special-settings/state.json @@ -1,7 +1,8 @@ { "data": { "AppStateController": { - "mkrMigrationReminderTimestamp": null + "mkrMigrationReminderTimestamp": null, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/test/e2e/fixtures/threebox-enabled/state.json b/test/e2e/fixtures/threebox-enabled/state.json index a2e4229a4..e7b7d10a4 100644 --- a/test/e2e/fixtures/threebox-enabled/state.json +++ b/test/e2e/fixtures/threebox-enabled/state.json @@ -2,7 +2,8 @@ "data": { "AppStateController": { "swapsWelcomeMessageHasBeenShown": true, - "connectedStatusPopoverHasBeenShown": false + "connectedStatusPopoverHasBeenShown": false, + "showPortfolioTooltip": false }, "CachedBalancesController": { "cachedBalances": { diff --git a/ui/components/ui/icon/icon-chart.js b/ui/components/ui/icon/icon-chart.js new file mode 100644 index 000000000..87cb780cc --- /dev/null +++ b/ui/components/ui/icon/icon-chart.js @@ -0,0 +1,45 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const IconChart = ({ + size = 12, + color = 'var(--color-primary-default)', + className, + ariaLabel, +}) => ( + +); + +IconChart.propTypes = { + /** + * The size of the Icon follows an 8px grid 2 = 16px, 3 = 24px etc + */ + size: PropTypes.number, + /** + * The color of the icon accepts design token css variables + */ + color: PropTypes.string, + /** + * An additional className to assign the Icon + */ + className: PropTypes.string, + /** + * The aria-label of the icon for accessibility purposes + */ + ariaLabel: PropTypes.string, +}; + +export default IconChart; diff --git a/ui/components/ui/tabs/tabs.component.js b/ui/components/ui/tabs/tabs.component.js index bce22ebf5..2357bfc35 100644 --- a/ui/components/ui/tabs/tabs.component.js +++ b/ui/components/ui/tabs/tabs.component.js @@ -7,6 +7,7 @@ export default class Tabs extends Component { defaultActiveTabName: null, onTabClick: null, tabsClassName: undefined, + subHeader: null, }; static propTypes = { @@ -14,6 +15,7 @@ export default class Tabs extends Component { onTabClick: PropTypes.func, children: PropTypes.node.isRequired, tabsClassName: PropTypes.string, + subHeader: PropTypes.node, }; state = { @@ -74,12 +76,13 @@ export default class Tabs extends Component { } render() { - const { tabsClassName } = this.props; + const { tabsClassName, subHeader } = this.props; return (