mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Add web3 shim usage notification (#10039)
* Add web3 shim usage alert background state and logic * Cleanup alert background state, constants * Implement web3 shim usage notification and settings * nodeify alert controller background hooks * Remove svg icon, again * Tweak alert controller initialization * Add support article URL * Un-thunk alert UI "actions" * Delete connect.svg file (unused)
This commit is contained in:
parent
db004d4486
commit
54e9c53b27
@ -95,7 +95,13 @@
|
||||
"message": "Browsing a website with an unconnected account selected"
|
||||
},
|
||||
"alertSettingsUnconnectedAccountDescription": {
|
||||
"message": "This alert is shown in the popup when you are browsing a connected Web3 site, but the currently selected account is not connected."
|
||||
"message": "This alert is shown in the popup when you are browsing a connected web3 site, but the currently selected account is not connected."
|
||||
},
|
||||
"alertSettingsWeb3ShimUsage": {
|
||||
"message": "When a website tries to use the removed window.web3 API"
|
||||
},
|
||||
"alertSettingsWeb3ShimUsageDescription": {
|
||||
"message": "This alert is shown in the popup when you are browsing a site that tries to use the removed window.web3 API, and may be broken as a result."
|
||||
},
|
||||
"alerts": {
|
||||
"message": "Alerts"
|
||||
@ -233,6 +239,9 @@
|
||||
"bytes": {
|
||||
"message": "Bytes"
|
||||
},
|
||||
"canToggleInSettings": {
|
||||
"message": "You can re-enable this notification in Settings -> Alerts."
|
||||
},
|
||||
"cancel": {
|
||||
"message": "Cancel"
|
||||
},
|
||||
@ -2095,6 +2104,10 @@
|
||||
"walletSeed": {
|
||||
"message": "Seed phrase"
|
||||
},
|
||||
"web3ShimUsageNotification": {
|
||||
"message": "We noticed that the current website tried to use the removed window.web3 API. If the site appears to be broken, please click $1 for more information.",
|
||||
"description": "$1 is a clickable link."
|
||||
},
|
||||
"welcome": {
|
||||
"message": "Welcome to MetaMask"
|
||||
},
|
||||
|
@ -1 +0,0 @@
|
||||
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="m8.00002 9.57037c.93765 0 1.69776-.76011 1.69776-1.69777 0-.93765-.76011-1.69776-1.69776-1.69776-.93766 0-1.69777.76011-1.69777 1.69776 0 .93766.76011 1.69777 1.69777 1.69777z"/><path d="m11.0582 11.6586c-.1862 0-.3725-.071-.5145-.2131-.2842-.2841-.2842-.7448 0-1.029.6795-.67946 1.0538-1.58294 1.0538-2.54391 0-.96098-.3743-1.86446-1.0538-2.54394-.2842-.28417-.2842-.74484 0-1.02901.2841-.2841.7449-.2841 1.029 0 .9543.95434 1.48 2.22329 1.48 3.57295 0 1.34965-.5257 2.61861-1.48 3.57291-.1421.1421-.3283.2131-.5145.2131z"/><path d="m4.94175 11.6586c-.18622 0-.37246-.071-.51451-.2131-.95434-.9543-1.47997-2.22326-1.47997-3.57291 0-1.34966.52563-2.61861 1.47997-3.57295.28411-.2841.74491-.2841 1.02902 0 .28417.28417.28417.74484 0 1.02901-.67954.67948-1.05376 1.58296-1.05376 2.54394 0 .96097.37422 1.86445 1.05376 2.54391.28417.2842.28417.7449 0 1.029-.14206.1421-.32828.2131-.51451.2131z"/><path d="m13.1451 13.7453c-.1862 0-.3724-.0711-.5145-.2131-.2842-.2842-.2842-.7449 0-1.0291 2.5533-2.55325 2.5533-6.70772 0-9.26101-.2842-.28417-.2842-.74484 0-1.02901.2841-.28411.7449-.28411 1.029 0 3.1207 3.12066 3.1207 8.19842 0 11.31912-.142.142-.3283.2131-.5145.2131z"/><path d="m2.855 13.7453c-.18622 0-.37245-.0711-.5145-.2131-3.120666-3.1207-3.120666-8.19846 0-11.31912.28411-.28411.74491-.28411 1.02901 0 .28417.28417.28417.74484 0 1.02901-2.553289 2.55329-2.553289 6.70776 0 9.26101.28417.2842.28417.7449 0 1.0291-.14206.142-.32828.2131-.51451.2131z"/></g></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,4 +1,8 @@
|
||||
import ObservableStore from 'obs-store'
|
||||
import {
|
||||
TOGGLEABLE_ALERT_TYPES,
|
||||
WEB3_SHIM_USAGE_ALERT_STATES,
|
||||
} from '../../../shared/constants/alerts'
|
||||
|
||||
/**
|
||||
* @typedef {Object} AlertControllerInitState
|
||||
@ -14,14 +18,8 @@ import ObservableStore from 'obs-store'
|
||||
* @property {AlertControllerInitState} initState - The initial controller state
|
||||
*/
|
||||
|
||||
export const ALERT_TYPES = {
|
||||
unconnectedAccount: 'unconnectedAccount',
|
||||
// enumerated here but has no background state
|
||||
invalidCustomNetwork: 'invalidCustomNetwork',
|
||||
}
|
||||
|
||||
const defaultState = {
|
||||
alertEnabledness: Object.keys(ALERT_TYPES).reduce(
|
||||
alertEnabledness: TOGGLEABLE_ALERT_TYPES.reduce(
|
||||
(alertEnabledness, alertType) => {
|
||||
alertEnabledness[alertType] = true
|
||||
return alertEnabledness
|
||||
@ -29,11 +27,11 @@ const defaultState = {
|
||||
{},
|
||||
),
|
||||
unconnectedAccountAlertShownOrigins: {},
|
||||
web3ShimUsageOrigins: {},
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller responsible for maintaining
|
||||
* alert related state
|
||||
* Controller responsible for maintaining alert-related state.
|
||||
*/
|
||||
export default class AlertController {
|
||||
/**
|
||||
@ -41,11 +39,13 @@ export default class AlertController {
|
||||
* @param {AlertControllerOptions} [opts] - Controller configuration parameters
|
||||
*/
|
||||
constructor(opts = {}) {
|
||||
const { initState, preferencesStore } = opts
|
||||
const { initState = {}, preferencesStore } = opts
|
||||
const state = {
|
||||
...defaultState,
|
||||
...initState,
|
||||
unconnectedAccountAlertShownOrigins: {},
|
||||
alertEnabledness: {
|
||||
...defaultState.alertEnabledness,
|
||||
...initState.alertEnabledness,
|
||||
},
|
||||
}
|
||||
|
||||
this.store = new ObservableStore(state)
|
||||
@ -83,4 +83,48 @@ export default class AlertController {
|
||||
unconnectedAccountAlertShownOrigins[origin] = true
|
||||
this.store.updateState({ unconnectedAccountAlertShownOrigins })
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the web3 shim usage state for the given origin.
|
||||
*
|
||||
* @param {string} origin - The origin to get the web3 shim usage state for.
|
||||
* @returns {undefined | 1 | 2} The web3 shim usage state for the given
|
||||
* origin, or undefined.
|
||||
*/
|
||||
getWeb3ShimUsageState(origin) {
|
||||
return this.store.getState().web3ShimUsageOrigins[origin]
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the web3 shim usage state for the given origin to RECORDED.
|
||||
*
|
||||
* @param {string} origin - The origin the that used the web3 shim.
|
||||
*/
|
||||
setWeb3ShimUsageRecorded(origin) {
|
||||
this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.RECORDED)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the web3 shim usage state for the given origin to DISMISSED.
|
||||
*
|
||||
* @param {string} origin - The origin that the web3 shim notification was
|
||||
* dismissed for.
|
||||
*/
|
||||
setWeb3ShimUsageAlertDismissed(origin) {
|
||||
this._setWeb3ShimUsageState(origin, WEB3_SHIM_USAGE_ALERT_STATES.DISMISSED)
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {string} origin - The origin to set the state for.
|
||||
* @param {number} value - The state value to set.
|
||||
*/
|
||||
_setWeb3ShimUsageState(origin, value) {
|
||||
let { web3ShimUsageOrigins } = this.store.getState()
|
||||
web3ShimUsageOrigins = {
|
||||
...web3ShimUsageOrigins,
|
||||
}
|
||||
web3ShimUsageOrigins[origin] = value
|
||||
this.store.updateState({ web3ShimUsageOrigins })
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,13 @@ const logWeb3ShimUsage = {
|
||||
}
|
||||
export default logWeb3ShimUsage
|
||||
|
||||
const recordedWeb3ShimUsage = {}
|
||||
|
||||
/**
|
||||
* @typedef {Object} LogWeb3ShimUsageOptions
|
||||
* @property {Function} sendMetrics - A function that registers a metrics event.
|
||||
* @property {Function} getWeb3ShimUsageState - A function that gets web3 shim
|
||||
* usage state for the given origin.
|
||||
* @property {Function} setWeb3ShimUsageRecorded - A function that records web3 shim
|
||||
* usage for a particular origin.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -27,10 +29,16 @@ const recordedWeb3ShimUsage = {}
|
||||
* @param {Function} end - The json-rpc-engine 'end' callback.
|
||||
* @param {LogWeb3ShimUsageOptions} options
|
||||
*/
|
||||
function logWeb3ShimUsageHandler(req, res, _next, end, { sendMetrics }) {
|
||||
function logWeb3ShimUsageHandler(
|
||||
req,
|
||||
res,
|
||||
_next,
|
||||
end,
|
||||
{ sendMetrics, getWeb3ShimUsageState, setWeb3ShimUsageRecorded },
|
||||
) {
|
||||
const { origin } = req
|
||||
if (!recordedWeb3ShimUsage[origin]) {
|
||||
recordedWeb3ShimUsage[origin] = true
|
||||
if (getWeb3ShimUsageState(origin) === undefined) {
|
||||
setWeb3ShimUsageRecorded(origin)
|
||||
|
||||
sendMetrics({
|
||||
event: `Website Accessed window.web3 Shim`,
|
||||
|
@ -514,16 +514,16 @@ export default class MetamaskController extends EventEmitter {
|
||||
*/
|
||||
getApi() {
|
||||
const {
|
||||
alertController,
|
||||
keyringController,
|
||||
metaMetricsController,
|
||||
networkController,
|
||||
onboardingController,
|
||||
alertController,
|
||||
permissionsController,
|
||||
preferencesController,
|
||||
swapsController,
|
||||
threeBoxController,
|
||||
txController,
|
||||
swapsController,
|
||||
metaMetricsController,
|
||||
} = this
|
||||
|
||||
return {
|
||||
@ -706,8 +706,12 @@ export default class MetamaskController extends EventEmitter {
|
||||
alertController,
|
||||
),
|
||||
setUnconnectedAccountAlertShown: nodeify(
|
||||
this.alertController.setUnconnectedAccountAlertShown,
|
||||
this.alertController,
|
||||
alertController.setUnconnectedAccountAlertShown,
|
||||
alertController,
|
||||
),
|
||||
setWeb3ShimUsageAlertDismissed: nodeify(
|
||||
alertController.setWeb3ShimUsageAlertDismissed,
|
||||
alertController,
|
||||
),
|
||||
|
||||
// 3Box
|
||||
@ -1979,6 +1983,12 @@ export default class MetamaskController extends EventEmitter {
|
||||
handleWatchAssetRequest: this.preferencesController.requestWatchAsset.bind(
|
||||
this.preferencesController,
|
||||
),
|
||||
getWeb3ShimUsageState: this.alertController.getWeb3ShimUsageState.bind(
|
||||
this.alertController,
|
||||
),
|
||||
setWeb3ShimUsageRecorded: this.alertController.setWeb3ShimUsageRecorded.bind(
|
||||
this.alertController,
|
||||
),
|
||||
}),
|
||||
)
|
||||
// filter and subscription polyfills
|
||||
|
18
shared/constants/alerts.js
Normal file
18
shared/constants/alerts.js
Normal file
@ -0,0 +1,18 @@
|
||||
export const ALERT_TYPES = {
|
||||
unconnectedAccount: 'unconnectedAccount',
|
||||
web3ShimUsage: 'web3ShimUsage',
|
||||
invalidCustomNetwork: 'invalidCustomNetwork',
|
||||
}
|
||||
|
||||
/**
|
||||
* Alerts that can be enabled or disabled by the user.
|
||||
*/
|
||||
export const TOGGLEABLE_ALERT_TYPES = [
|
||||
ALERT_TYPES.unconnectedAccount,
|
||||
ALERT_TYPES.web3ShimUsage,
|
||||
]
|
||||
|
||||
export const WEB3_SHIM_USAGE_ALERT_STATES = {
|
||||
RECORDED: 1,
|
||||
DISMISSED: 2,
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
import React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import classnames from 'classnames'
|
||||
import PropTypes from 'prop-types'
|
||||
import Button from '../../ui/button'
|
||||
import Checkbox from '../../ui/check-box'
|
||||
import Tooltip from '../../ui/tooltip'
|
||||
|
||||
const HomeNotification = ({
|
||||
acceptText,
|
||||
checkboxText,
|
||||
checkboxTooltipText,
|
||||
classNames = [],
|
||||
descriptionText,
|
||||
ignoreText,
|
||||
@ -13,6 +16,17 @@ const HomeNotification = ({
|
||||
onAccept,
|
||||
onIgnore,
|
||||
}) => {
|
||||
const [checkboxState, setCheckBoxState] = useState(false)
|
||||
|
||||
const checkboxElement = checkboxText && (
|
||||
<Checkbox
|
||||
id="homeNotification_checkbox"
|
||||
checked={checkboxState}
|
||||
className="home-notification__checkbox"
|
||||
onClick={() => setCheckBoxState((checked) => !checked)}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={classnames('home-notification', ...classNames)}>
|
||||
<div className="home-notification__content">
|
||||
@ -43,11 +57,34 @@ const HomeNotification = ({
|
||||
<Button
|
||||
type="secondary"
|
||||
className="home-notification__ignore-button"
|
||||
onClick={onIgnore}
|
||||
// Some onIgnore handlers use the checkboxState to determine whether
|
||||
// to disable the notification
|
||||
onClick={() => onIgnore(checkboxState)}
|
||||
>
|
||||
{ignoreText}
|
||||
</Button>
|
||||
) : null}
|
||||
{checkboxText ? (
|
||||
<div className="home-notification__checkbox-wrapper">
|
||||
{checkboxTooltipText ? (
|
||||
<Tooltip
|
||||
position="top"
|
||||
title={checkboxTooltipText}
|
||||
wrapperClassName="home-notification__checkbox-label-tooltip"
|
||||
>
|
||||
{checkboxElement}
|
||||
</Tooltip>
|
||||
) : (
|
||||
checkboxElement
|
||||
)}
|
||||
<label
|
||||
className="home-notification__checkbox-label"
|
||||
htmlFor="homeNotification_checkbox"
|
||||
>
|
||||
{checkboxText}
|
||||
</label>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@ -55,6 +92,8 @@ const HomeNotification = ({
|
||||
|
||||
HomeNotification.propTypes = {
|
||||
acceptText: PropTypes.node,
|
||||
checkboxText: PropTypes.node,
|
||||
checkboxTooltipText: PropTypes.node,
|
||||
classNames: PropTypes.array,
|
||||
descriptionText: PropTypes.node.isRequired,
|
||||
ignoreText: PropTypes.node,
|
||||
|
@ -28,10 +28,46 @@
|
||||
color: $white;
|
||||
}
|
||||
|
||||
&__text-link {
|
||||
@include H7;
|
||||
|
||||
color: $primary-blue;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fa-info-circle {
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
& &__checkbox-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
& &__checkbox {
|
||||
height: 13px;
|
||||
width: 13px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& &__checkbox-label {
|
||||
@include H7;
|
||||
|
||||
color: $white;
|
||||
margin-left: 10px;
|
||||
margin-top: 1px;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& &__ignore-button {
|
||||
border-color: #6a737d;
|
||||
box-sizing: border-box;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../../../../shared/constants/alerts'
|
||||
import { ALERT_STATE } from './enums'
|
||||
|
||||
// Constants
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { captureException } from '@sentry/browser'
|
||||
|
||||
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../../../../shared/constants/alerts'
|
||||
import * as actionConstants from '../../store/actionConstants'
|
||||
import {
|
||||
addPermittedAccount,
|
||||
@ -101,7 +101,7 @@ export const dismissAndDisableAlert = () => {
|
||||
return async (dispatch) => {
|
||||
try {
|
||||
await dispatch(disableAlertRequested())
|
||||
await dispatch(setAlertEnabledness(name, false))
|
||||
await setAlertEnabledness(name, false)
|
||||
await dispatch(disableAlertSucceeded())
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { combineReducers } from 'redux'
|
||||
import { ALERT_TYPES } from '../../../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../../../shared/constants/alerts'
|
||||
import metamaskReducer from './metamask/metamask'
|
||||
import localeMessagesReducer from './locale/locale'
|
||||
import sendReducer from './send/send.duck'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as actionConstants from '../../store/actionConstants'
|
||||
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../../../../shared/constants/alerts'
|
||||
|
||||
export default function reduceMetamask(state = {}, action) {
|
||||
const metamaskState = {
|
||||
@ -375,12 +375,12 @@ export const getCurrentLocale = (state) => state.metamask.currentLocale
|
||||
|
||||
export const getAlertEnabledness = (state) => state.metamask.alertEnabledness
|
||||
|
||||
export const getInvalidCustomNetworkAlertEnabledness = (state) =>
|
||||
getAlertEnabledness(state)[ALERT_TYPES.invalidCustomNetwork]
|
||||
|
||||
export const getUnconnectedAccountAlertEnabledness = (state) =>
|
||||
getAlertEnabledness(state)[ALERT_TYPES.unconnectedAccount]
|
||||
|
||||
export const getWeb3ShimUsageAlertEnabledness = (state) =>
|
||||
getAlertEnabledness(state)[ALERT_TYPES.web3ShimUsage]
|
||||
|
||||
export const getUnconnectedAccountAlertShown = (state) =>
|
||||
state.metamask.unconnectedAccountAlertShownOrigins
|
||||
|
||||
|
@ -31,6 +31,8 @@ import {
|
||||
|
||||
const LEARN_MORE_URL =
|
||||
'https://metamask.zendesk.com/hc/en-us/articles/360045129011-Intro-to-MetaMask-v8-extension'
|
||||
const LEGACY_WEB3_URL =
|
||||
'https://metamask.zendesk.com/hc/en-us/articles/360053147012'
|
||||
|
||||
export default class Home extends PureComponent {
|
||||
static contextTypes = {
|
||||
@ -42,7 +44,7 @@ export default class Home extends PureComponent {
|
||||
forgottenPassword: PropTypes.bool,
|
||||
suggestedTokens: PropTypes.object,
|
||||
unconfirmedTransactionsCount: PropTypes.number,
|
||||
shouldShowSeedPhraseReminder: PropTypes.bool,
|
||||
shouldShowSeedPhraseReminder: PropTypes.bool.isRequired,
|
||||
isPopup: PropTypes.bool,
|
||||
isNotification: PropTypes.bool.isRequired,
|
||||
threeBoxSynced: PropTypes.bool,
|
||||
@ -66,6 +68,10 @@ export default class Home extends PureComponent {
|
||||
swapsFetchParams: PropTypes.object,
|
||||
swapsEnabled: PropTypes.bool,
|
||||
isMainnet: PropTypes.bool,
|
||||
shouldShowWeb3ShimUsageNotification: PropTypes.bool.isRequired,
|
||||
setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired,
|
||||
originOfCurrentTab: PropTypes.string,
|
||||
disableWeb3ShimUsageAlert: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
state = {
|
||||
@ -161,10 +167,39 @@ export default class Home extends PureComponent {
|
||||
setShowRestorePromptToFalse,
|
||||
showRestorePrompt,
|
||||
threeBoxLastUpdated,
|
||||
shouldShowWeb3ShimUsageNotification,
|
||||
setWeb3ShimUsageAlertDismissed,
|
||||
originOfCurrentTab,
|
||||
disableWeb3ShimUsageAlert,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<MultipleNotifications>
|
||||
{shouldShowWeb3ShimUsageNotification ? (
|
||||
<HomeNotification
|
||||
descriptionText={t('web3ShimUsageNotification', [
|
||||
<span
|
||||
key="web3ShimUsageNotificationLink"
|
||||
className="home-notification__text-link"
|
||||
onClick={() =>
|
||||
global.platform.openTab({ url: LEGACY_WEB3_URL })
|
||||
}
|
||||
>
|
||||
{t('here')}
|
||||
</span>,
|
||||
])}
|
||||
ignoreText={t('dismiss')}
|
||||
onIgnore={(disable) => {
|
||||
setWeb3ShimUsageAlertDismissed(originOfCurrentTab)
|
||||
if (disable) {
|
||||
disableWeb3ShimUsageAlert()
|
||||
}
|
||||
}}
|
||||
checkboxText={t('dontShowThisAgain')}
|
||||
checkboxTooltipText={t('canToggleInSettings')}
|
||||
key="home-web3ShimUsageNotification"
|
||||
/>
|
||||
) : null}
|
||||
{shouldShowSeedPhraseReminder ? (
|
||||
<HomeNotification
|
||||
descriptionText={t('backupApprovalNotice')}
|
||||
|
@ -2,11 +2,14 @@ import { compose } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import {
|
||||
unconfirmedTransactionsCountSelector,
|
||||
activeTabHasPermissions,
|
||||
getCurrentEthBalance,
|
||||
getFirstPermissionRequest,
|
||||
getTotalUnapprovedCount,
|
||||
getIsMainnet,
|
||||
getOriginOfCurrentTab,
|
||||
getTotalUnapprovedCount,
|
||||
getWeb3ShimUsageStateForOrigin,
|
||||
unconfirmedTransactionsCountSelector,
|
||||
} from '../../selectors'
|
||||
|
||||
import {
|
||||
@ -17,8 +20,11 @@ import {
|
||||
setConnectedStatusPopoverHasBeenShown,
|
||||
setDefaultHomeActiveTabName,
|
||||
setSwapsWelcomeMessageHasBeenShown,
|
||||
setWeb3ShimUsageAlertDismissed,
|
||||
setAlertEnabledness,
|
||||
} from '../../store/actions'
|
||||
import { setThreeBoxLastUpdated } from '../../ducks/app/app'
|
||||
import { getWeb3ShimUsageAlertEnabledness } from '../../ducks/metamask/metamask'
|
||||
import {
|
||||
getSwapsWelcomeMessageSeenStatus,
|
||||
getSwapsFeatureLiveness,
|
||||
@ -28,6 +34,10 @@ import {
|
||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
ENVIRONMENT_TYPE_POPUP,
|
||||
} from '../../../../app/scripts/lib/enums'
|
||||
import {
|
||||
ALERT_TYPES,
|
||||
WEB3_SHIM_USAGE_ALERT_STATES,
|
||||
} from '../../../../shared/constants/alerts'
|
||||
import Home from './home.component'
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
@ -58,6 +68,14 @@ const mapStateToProps = (state) => {
|
||||
? firstPermissionsRequest.metadata.id
|
||||
: null
|
||||
|
||||
const originOfCurrentTab = getOriginOfCurrentTab(state)
|
||||
const shouldShowWeb3ShimUsageNotification =
|
||||
isPopup &&
|
||||
getWeb3ShimUsageAlertEnabledness(state) &&
|
||||
activeTabHasPermissions(state) &&
|
||||
getWeb3ShimUsageStateForOrigin(state, originOfCurrentTab) ===
|
||||
WEB3_SHIM_USAGE_ALERT_STATES.RECORDED
|
||||
|
||||
return {
|
||||
forgottenPassword,
|
||||
suggestedTokens,
|
||||
@ -81,6 +99,8 @@ const mapStateToProps = (state) => {
|
||||
swapsFetchParams: swapsState.fetchParams,
|
||||
showAwaitingSwapScreen: swapsState.routeState === 'awaiting',
|
||||
isMainnet: getIsMainnet(state),
|
||||
originOfCurrentTab,
|
||||
shouldShowWeb3ShimUsageNotification,
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +123,10 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
onTabClick: (name) => dispatch(setDefaultHomeActiveTabName(name)),
|
||||
setSwapsWelcomeMessageHasBeenShown: () =>
|
||||
dispatch(setSwapsWelcomeMessageHasBeenShown()),
|
||||
setWeb3ShimUsageAlertDismissed: (origin) =>
|
||||
setWeb3ShimUsageAlertDismissed(origin),
|
||||
disableWeb3ShimUsageAlert: () =>
|
||||
setAlertEnabledness(ALERT_TYPES.web3ShimUsage, false),
|
||||
})
|
||||
|
||||
export default compose(
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import { ALERT_TYPES } from '../../../../../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../../../../../shared/constants/alerts'
|
||||
import Tooltip from '../../../components/ui/tooltip'
|
||||
import ToggleButton from '../../../components/ui/toggle-button'
|
||||
import { setAlertEnabledness } from '../../../store/actions'
|
||||
@ -11,7 +11,6 @@ import { useI18nContext } from '../../../hooks/useI18nContext'
|
||||
|
||||
const AlertSettingsEntry = ({ alertId, description, title }) => {
|
||||
const t = useI18nContext()
|
||||
const dispatch = useDispatch()
|
||||
const isEnabled = useSelector((state) => getAlertEnabledness(state)[alertId])
|
||||
|
||||
return (
|
||||
@ -27,7 +26,7 @@ const AlertSettingsEntry = ({ alertId, description, title }) => {
|
||||
<ToggleButton
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
onToggle={() => dispatch(setAlertEnabledness(alertId, !isEnabled))}
|
||||
onToggle={() => setAlertEnabledness(alertId, !isEnabled)}
|
||||
value={isEnabled}
|
||||
/>
|
||||
</>
|
||||
@ -48,6 +47,10 @@ const AlertsTab = () => {
|
||||
title: t('alertSettingsUnconnectedAccount'),
|
||||
description: t('alertSettingsUnconnectedAccountDescription'),
|
||||
},
|
||||
[ALERT_TYPES.web3ShimUsage]: {
|
||||
title: t('alertSettingsWeb3ShimUsage'),
|
||||
description: t('alertSettingsWeb3ShimUsageDescription'),
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -244,6 +244,13 @@ export function getPermissionsForActiveTab(state) {
|
||||
})
|
||||
}
|
||||
|
||||
export function activeTabHasPermissions(state) {
|
||||
const { activeTab, metamask } = state
|
||||
const { domains = {} } = metamask
|
||||
|
||||
return Boolean(domains[activeTab.origin]?.permissions?.length > 0)
|
||||
}
|
||||
|
||||
export function getLastConnectedInfo(state) {
|
||||
const { permissionsHistory = {} } = state.metamask
|
||||
return Object.keys(permissionsHistory).reduce((acc, origin) => {
|
||||
|
@ -356,3 +356,7 @@ export function getIpfsGateway(state) {
|
||||
export function getUSDConversionRate(state) {
|
||||
return state.metamask.usdConversionRate
|
||||
}
|
||||
|
||||
export function getWeb3ShimUsageStateForOrigin(state, origin) {
|
||||
return state.metamask.web3ShimUsageOrigins[origin]
|
||||
}
|
||||
|
@ -2481,16 +2481,18 @@ export function setSwapsWelcomeMessageHasBeenShown() {
|
||||
}
|
||||
}
|
||||
|
||||
export function setAlertEnabledness(alertId, enabledness) {
|
||||
return async () => {
|
||||
export async function setAlertEnabledness(alertId, enabledness) {
|
||||
await promisifiedBackground.setAlertEnabledness(alertId, enabledness)
|
||||
}
|
||||
}
|
||||
|
||||
export async function setUnconnectedAccountAlertShown(origin) {
|
||||
await promisifiedBackground.setUnconnectedAccountAlertShown(origin)
|
||||
}
|
||||
|
||||
export async function setWeb3ShimUsageAlertDismissed(origin) {
|
||||
await promisifiedBackground.setWeb3ShimUsageAlertDismissed(origin)
|
||||
}
|
||||
|
||||
export function loadingMethodDataStarted() {
|
||||
return {
|
||||
type: actionConstants.LOADING_METHOD_DATA_STARTED,
|
||||
|
@ -4,7 +4,7 @@ import { clone } from 'lodash'
|
||||
import React from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { getEnvironmentType } from '../app/scripts/lib/util'
|
||||
import { ALERT_TYPES } from '../app/scripts/controllers/alert'
|
||||
import { ALERT_TYPES } from '../shared/constants/alerts'
|
||||
import { SENTRY_STATE } from '../app/scripts/lib/setupSentry'
|
||||
import { ENVIRONMENT_TYPE_POPUP } from '../app/scripts/lib/enums'
|
||||
import Root from './app/pages'
|
||||
|
Loading…
Reference in New Issue
Block a user