From dcfe80c255d14f17961dbeb8ca054a5a9866a01c Mon Sep 17 00:00:00 2001 From: Matthew Epps Date: Tue, 13 Sep 2022 06:41:58 -0700 Subject: [PATCH] Add entry point for metalabs dapp into metamask home page (#15407) Co-authored-by: Dan Miller --- .metamaskrc.dist | 1 + app/_locales/en/messages.json | 15 ++++ app/scripts/controllers/app-state.js | 10 +++ app/scripts/metamask-controller.js | 2 + development/build/scripts.js | 1 + shared/constants/metametrics.js | 1 + test/e2e/fixtures/address-entry/state.json | 3 +- test/e2e/fixtures/connected-state/state.json | 3 +- test/e2e/fixtures/custom-rpc/state.json | 3 +- test/e2e/fixtures/custom-token/state.json | 3 +- test/e2e/fixtures/eip-1559-v2-dapp/state.json | 3 +- test/e2e/fixtures/eip-1559-v2/state.json | 3 +- test/e2e/fixtures/import-ui/state.json | 3 +- test/e2e/fixtures/imported-account/state.json | 3 +- test/e2e/fixtures/localization/state.json | 3 +- test/e2e/fixtures/metrics-enabled/state.json | 3 +- .../fixtures/navigate-transactions/state.json | 3 +- test/e2e/fixtures/send-edit-v2/state.json | 3 +- test/e2e/fixtures/send-edit/state.json | 3 +- test/e2e/fixtures/special-settings/state.json | 3 +- test/e2e/fixtures/threebox-enabled/state.json | 3 +- ui/components/ui/icon/icon-chart.js | 45 ++++++++++ ui/components/ui/tabs/tabs.component.js | 5 +- ui/components/ui/tooltip/tooltip.js | 4 + ui/ducks/app/app.js | 17 ++++ ui/pages/home/home.component.js | 82 ++++++++++++++++++- ui/pages/home/home.container.js | 10 +++ ui/pages/home/index.scss | 52 ++++++++++++ ui/selectors/selectors.js | 4 + ui/store/actionConstants.js | 3 +- ui/store/actions.js | 4 + 31 files changed, 281 insertions(+), 20 deletions(-) create mode 100644 ui/components/ui/icon/icon-chart.js 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 9cee321cc..38b0f4537 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" }, @@ -1779,6 +1782,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" }, @@ -2165,6 +2171,9 @@ "nevermind": { "message": "Nevermind" }, + "new": { + "message": "New!" + }, "newAccount": { "message": "New account" }, @@ -2660,6 +2669,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" @@ -4075,6 +4087,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 0f678d8bd..163907f3a 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 481be663a..ee8e87503 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 3c1aa0039..4d7b3b9cf 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 28ca1894a..52c765397 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 4546a6ede..2ae8e876b 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 373645f1f..d6e8e116e 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 1346dea32..1c77ce95d 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 3d0c40c08..eecdb45ed 100644 --- a/test/e2e/fixtures/import-ui/state.json +++ b/test/e2e/fixtures/import-ui/state.json @@ -259,7 +259,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 4506bac2d..5dfea2b0f 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 80f442a04..d53df2904 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 a6c7d7be0..5b3924103 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 1d654f7ac..86f4563f1 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 14bc11d12..cc30d04aa 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 5606126f8..b9168e40d 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 668c4143f..4a1102d2b 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 44bc352a9..37e3490bb 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 (
    {this.renderTabs()}
+ {subHeader}
{this.renderActiveTabContent()}
); diff --git a/ui/components/ui/tooltip/tooltip.js b/ui/components/ui/tooltip/tooltip.js index b05a0acf1..b819f6b9e 100644 --- a/ui/components/ui/tooltip/tooltip.js +++ b/ui/components/ui/tooltip/tooltip.js @@ -12,6 +12,7 @@ export default class Tooltip extends PureComponent { onHidden: null, position: 'left', offset: 0, + open: undefined, size: 'small', title: null, trigger: 'mouseenter focus', @@ -29,6 +30,7 @@ export default class Tooltip extends PureComponent { interactive: PropTypes.bool, offset: PropTypes.number, onHidden: PropTypes.func, + open: PropTypes.bool, position: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), size: PropTypes.oneOf(['small', 'regular', 'big']), title: PropTypes.string, @@ -54,6 +56,7 @@ export default class Tooltip extends PureComponent { trigger, onHidden, offset, + open, wrapperClassName, style, theme, @@ -82,6 +85,7 @@ export default class Tooltip extends PureComponent { style={style} title={disabled ? '' : title} trigger={trigger} + open={open} theme={`tippy-tooltip--mm-custom ${theme}`} // Required for correct theming tabIndex={tabIndex || 0} tag={tag} diff --git a/ui/ducks/app/app.js b/ui/ducks/app/app.js index 94c3bb6f2..186af52f0 100644 --- a/ui/ducks/app/app.js +++ b/ui/ducks/app/app.js @@ -58,6 +58,7 @@ export default function reduceApp(state = {}, action) { ledgerTransportStatus: TRANSPORT_STATES.NONE, newNetworkAdded: '', newCollectibleAddedMessage: '', + portfolioTooltipWasShownInThisSession: false, sendInputCurrencySwitched: false, newTokensImported: '', newCustomNetworkAdded: {}, @@ -321,6 +322,12 @@ export default function reduceApp(state = {}, action) { newCollectibleAddedMessage: action.value, }; + case actionConstants.PORTFOLIO_TOOLTIP_WAS_SHOWN_IN_THIS_SESSION: + return { + ...appState, + portfolioTooltipWasShownInThisSession: true, + }; + case actionConstants.LOADING_METHOD_DATA_STARTED: return { ...appState, @@ -418,6 +425,12 @@ export function hideWhatsNewPopup() { }; } +export function setPortfolioTooltipWasShownInThisSession() { + return { + type: actionConstants.PORTFOLIO_TOOLTIP_WAS_SHOWN_IN_THIS_SESSION, + }; +} + export function toggleGasLoadingAnimation(value) { return { type: actionConstants.TOGGLE_GAS_LOADING_ANIMATION, value }; } @@ -447,6 +460,10 @@ export function getLedgerTransportStatus(state) { return state.appState.ledgerTransportStatus; } +export function getPortfolioTooltipWasShownInThisSession(state) { + return state.appState.portfolioTooltipWasShownInThisSession; +} + export function toggleCurrencySwitch() { return { type: actionConstants.TOGGLE_CURRENCY_INPUT_SWITCH }; } diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 3b7a446c7..ccd454eed 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -3,12 +3,12 @@ import PropTypes from 'prop-types'; import { Redirect, Route } from 'react-router-dom'; ///: BEGIN:ONLY_INCLUDE_IN(main) import { SUPPORT_LINK } from '../../helpers/constants/common'; +///: END:ONLY_INCLUDE_IN import { EVENT, EVENT_NAMES, CONTEXT_PROPS, } from '../../../shared/constants/metametrics'; -///: END:ONLY_INCLUDE_IN import { formatDate } from '../../helpers/utils/util'; import AssetList from '../../components/app/asset-list'; import CollectiblesTab from '../../components/app/collectibles-tab'; @@ -27,6 +27,7 @@ import WhatsNewPopup from '../../components/app/whats-new-popup'; import RecoveryPhraseReminder from '../../components/app/recovery-phrase-reminder'; import ActionableMessage from '../../components/ui/actionable-message/actionable-message'; import Typography from '../../components/ui/typography/typography'; +import IconChart from '../../components/ui/icon/icon-chart'; import { TYPOGRAPHY, FONT_WEIGHT, @@ -50,6 +51,7 @@ import { ADD_COLLECTIBLE_ROUTE, } from '../../helpers/constants/routes'; import ZENDESK_URLS from '../../helpers/constants/zendesk-url'; +import Tooltip from '../../components/ui/tooltip'; ///: BEGIN:ONLY_INCLUDE_IN(beta) import BetaHomeFooter from './beta/beta-home-footer.component'; ///: END:ONLY_INCLUDE_IN @@ -115,6 +117,10 @@ export default class Home extends PureComponent { infuraBlocked: PropTypes.bool.isRequired, showWhatsNewPopup: PropTypes.bool.isRequired, hideWhatsNewPopup: PropTypes.func.isRequired, + showPortfolioTooltip: PropTypes.bool.isRequired, + hidePortfolioTooltip: PropTypes.func.isRequired, + portfolioTooltipWasShownInThisSession: PropTypes.bool.isRequired, + setPortfolioTooltipWasShownInThisSession: PropTypes.func.isRequired, announcementsToShow: PropTypes.bool.isRequired, ///: BEGIN:ONLY_INCLUDE_IN(flask) errorsToShow: PropTypes.object.isRequired, @@ -213,7 +219,12 @@ export default class Home extends PureComponent { } componentDidMount() { + const { setPortfolioTooltipWasShownInThisSession, showPortfolioTooltip } = + this.props; this.checkStatusAndNavigate(); + if (showPortfolioTooltip) { + setPortfolioTooltipWasShownInThisSession(); + } } static getDerivedStateFromProps(props) { @@ -594,6 +605,9 @@ export default class Home extends PureComponent { announcementsToShow, showWhatsNewPopup, hideWhatsNewPopup, + showPortfolioTooltip, + hidePortfolioTooltip, + portfolioTooltipWasShownInThisSession, seedPhraseBackedUp, showRecoveryPhraseReminder, firstTimeFlowType, @@ -610,8 +624,9 @@ export default class Home extends PureComponent { ((completedOnboarding && firstTimeFlowType === 'import') || !completedOnboarding) && announcementsToShow && - showWhatsNewPopup; - + showWhatsNewPopup && + !showPortfolioTooltip && + !portfolioTooltipWasShownInThisSession; return (
@@ -640,6 +655,67 @@ export default class Home extends PureComponent { defaultActiveTabName={defaultHomeActiveTabName} onTabClick={onTabClick} tabsClassName="home__tabs" + subHeader={ + +
+
+ {t('new')} +
+ +
+
+ {t('tryOur')}  + + {t('betaPortfolioSite')} + +  {t('keepTapsOnTokens')} +
+
+ } + > +
{ + const portfolioUrl = process.env.PORTFOLIO_URL; + global.platform.openTab({ + url: `${portfolioUrl}?metamaskEntry=ext`, + }); + this.context.trackEvent( + { + category: EVENT.CATEGORIES.HOME, + event: EVENT_NAMES.PORTFOLIO_LINK_CLICKED, + properties: { + url: portfolioUrl, + }, + }, + { + contextPropsIntoEventProperties: [ + CONTEXT_PROPS.PAGE_TITLE, + ], + }, + ); + }} + > + +
+ {t('portfolioSite')} +
+
+ + } > { shouldShowErrors: Object.entries(metamask.snapErrors || []).length > 0, ///: END:ONLY_INCLUDE_IN showWhatsNewPopup: getShowWhatsNewPopup(state), + showPortfolioTooltip: getShowPortfolioTooltip(state), + portfolioTooltipWasShownInThisSession: + getPortfolioTooltipWasShownInThisSession(state), showRecoveryPhraseReminder: getShowRecoveryPhraseReminder(state), seedPhraseBackedUp, newNetworkAdded: getNewNetworkAdded(state), @@ -185,6 +192,7 @@ const mapDispatchToProps = (dispatch) => ({ disableWeb3ShimUsageAlert: () => setAlertEnabledness(ALERT_TYPES.web3ShimUsage, false), hideWhatsNewPopup: () => dispatch(hideWhatsNewPopup()), + hidePortfolioTooltip, setRecoveryPhraseReminderHasBeenShown: () => dispatch(setRecoveryPhraseReminderHasBeenShown()), setRecoveryPhraseReminderLastShown: (lastShown) => @@ -204,6 +212,8 @@ const mapDispatchToProps = (dispatch) => ({ setRpcTarget: (rpcUrl, chainId, ticker, nickname) => { dispatch(setRpcTarget(rpcUrl, chainId, ticker, nickname)); }, + setPortfolioTooltipWasShownInThisSession: () => + dispatch(setPortfolioTooltipWasShownInThisSession()), }); export default compose( diff --git a/ui/pages/home/index.scss b/ui/pages/home/index.scss index b4accb829..cee94a943 100644 --- a/ui/pages/home/index.scss +++ b/ui/pages/home/index.scss @@ -221,4 +221,56 @@ margin-bottom: 16px; } } + + &__subheader-link { + display: flex; + padding: 12px 0; + justify-content: center; + color: var(--color-primary-default); + align-items: center; + cursor: pointer; + + &--tooltip-content { + &-header { + display: flex; + justify-content: space-between; + margin-bottom: 8px; + + &-text { + font-size: 18px; + line-height: 22.82px; + font-weight: 700; + } + + &-button { + background-color: var(--color-primary-default); + color: var(--color-primary-inverse); + border: 0; + } + } + + &-text-bold { + font-weight: 700; + } + } + + &--tooltip-theme { + background-color: var(--color-primary-default) !important; + + & .tippy-tooltip-content { + color: var(--color-primary-inverse) !important; + } + + & .arrow-regular { + border-bottom-color: var(--color-primary-default) !important; + } + } + + &--text { + margin-left: 8px; + font-weight: 400; + font-size: 12px; + line-height: 140.62%; + } + } } diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index c9e3b9a6d..59e4dd70d 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -878,6 +878,10 @@ export function getShowRecoveryPhraseReminder(state) { return currentTime - recoveryPhraseReminderLastShown >= frequency; } +export function getShowPortfolioTooltip(state) { + return state.metamask.showPortfolioTooltip; +} + /** * To get the useTokenDetection flag which determines whether a static or dynamic token list is used * diff --git a/ui/store/actionConstants.js b/ui/store/actionConstants.js index c9e673afa..2ec9e212c 100644 --- a/ui/store/actionConstants.js +++ b/ui/store/actionConstants.js @@ -106,7 +106,8 @@ export const SET_OPEN_METAMASK_TAB_IDS = 'SET_OPEN_METAMASK_TAB_IDS'; // Home Screen export const HIDE_WHATS_NEW_POPUP = 'HIDE_WHATS_NEW_POPUP'; - +export const PORTFOLIO_TOOLTIP_WAS_SHOWN_IN_THIS_SESSION = + 'PORTFOLIO_TOOLTIP_WAS_SHOWN_IN_THIS_SESSION'; export const TOGGLE_GAS_LOADING_ANIMATION = 'TOGGLE_GAS_LOADING_ANIMATION'; // Smart Transactions diff --git a/ui/store/actions.js b/ui/store/actions.js index 108f1b316..1b71f7fbb 100644 --- a/ui/store/actions.js +++ b/ui/store/actions.js @@ -3854,6 +3854,10 @@ export function hideTestNetMessage() { return submitRequestToBackground('setShowTestnetMessageInDropdown', [false]); } +export function hidePortfolioTooltip() { + return submitRequestToBackground('setShowPortfolioTooltip', [false]); +} + export function setCollectiblesDetectionNoticeDismissed() { return submitRequestToBackground('setCollectiblesDetectionNoticeDismissed', [ true,