diff --git a/ui/components/app/shield-entry-modal/shield-entry-modal.tsx b/ui/components/app/shield-entry-modal/shield-entry-modal.tsx index da9130766ca1..fbcffe73ba22 100644 --- a/ui/components/app/shield-entry-modal/shield-entry-modal.tsx +++ b/ui/components/app/shield-entry-modal/shield-entry-modal.tsx @@ -38,7 +38,14 @@ import { getShouldSubmitEventsForShieldEntryModal } from '../../../selectors'; // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 // eslint-disable-next-line @typescript-eslint/naming-convention -export default function ShieldEntryModal() { +export default function ShieldEntryModal({ + // Whether to skip event submission (e.g., when opened from a user action) + skipEventSubmission = false, + onClose, +}: { + skipEventSubmission?: boolean; + onClose?: () => void; +}) { const t = useI18nContext(); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -47,6 +54,10 @@ export default function ShieldEntryModal() { ); const handleOnClose = () => { + if (skipEventSubmission) { + onClose?.(); + return; + } if (shouldSubmitEvent) { dispatch( submitSubscriptionUserEvents({ diff --git a/ui/pages/settings/settings.component.js b/ui/pages/settings/settings.component.js index f917c9b4d548..ad288da9eba4 100644 --- a/ui/pages/settings/settings.component.js +++ b/ui/pages/settings/settings.component.js @@ -62,6 +62,7 @@ import { import { SnapIcon } from '../../components/app/snaps/snap-icon'; import { SnapSettingsRenderer } from '../../components/app/snaps/snap-settings-page'; import PasswordOutdatedModal from '../../components/app/password-outdated-modal'; +import ShieldEntryModal from '../../components/app/shield-entry-modal'; import SettingsTab from './settings-tab'; import AdvancedTab from './advanced-tab'; import InfoTab from './info-tab'; @@ -97,6 +98,7 @@ class SettingsPage extends PureComponent { backRoute: PropTypes.string, conversionDate: PropTypes.number, currentPath: PropTypes.string, + hasSubscribedToShield: PropTypes.bool, isAddressEntryPage: PropTypes.bool, isMetaMaskShieldFeatureEnabled: PropTypes.bool, isPasswordChangePage: PropTypes.bool, @@ -122,6 +124,7 @@ class SettingsPage extends PureComponent { lastFetchedConversionDate: null, searchResults: [], searchText: '', + showShieldEntryModal: false, }; componentDidMount() { @@ -184,6 +187,12 @@ class SettingsPage extends PureComponent { }, )} > + {this.state.showShieldEntryModal && ( + this.setState({ showShieldEntryModal: false })} + /> + )} {isSeedlessPasswordOutdated && } + onSelect={(key) => { + if (key === TRANSACTION_SHIELD_ROUTE && !hasSubscribedToShield) { + this.setState({ showShieldEntryModal: true }); + return; + } navigate(key, { state: { fromPage: currentPath }, - }) - } + }); + }} /> ); } diff --git a/ui/pages/settings/settings.container.js b/ui/pages/settings/settings.container.js index 8e457d50d391..00290ec69960 100644 --- a/ui/pages/settings/settings.container.js +++ b/ui/pages/settings/settings.container.js @@ -49,6 +49,7 @@ import { getSnapName } from '../../helpers/utils/util'; import { decodeSnapIdFromPathname } from '../../helpers/utils/snaps'; import { getIsSeedlessPasswordOutdated } from '../../ducks/metamask/metamask'; import { getIsMetaMaskShieldFeatureEnabled } from '../../../shared/modules/environment'; +import { getHasSubscribedToShield } from '../../selectors/subscription/subscription'; import Settings from './settings.component'; const ROUTES_TO_I18N_KEYS = { @@ -176,6 +177,7 @@ const mapStateToProps = (state, ownProps) => { backRoute, conversionDate, currentPath: pathname, + hasSubscribedToShield: getHasSubscribedToShield(state), isAddressEntryPage, isMetaMaskShieldFeatureEnabled: getIsMetaMaskShieldFeatureEnabled(), isPasswordChangePage, diff --git a/ui/selectors/subscription/subscription.ts b/ui/selectors/subscription/subscription.ts index fe5c91003f7a..1b6a67aaaab9 100644 --- a/ui/selectors/subscription/subscription.ts +++ b/ui/selectors/subscription/subscription.ts @@ -49,3 +49,8 @@ export function getLastUsedShieldSubscriptionPaymentDetails( ): CachedLastSelectedPaymentMethod | undefined { return state.metamask.lastSelectedPaymentMethod?.[PRODUCT_TYPES.SHIELD]; } + +export function getHasSubscribedToShield(state: SubscriptionState): boolean { + const hasSubscribedToShield = state.metamask.customerId; + return Boolean(hasSubscribedToShield); +}