1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-26 20:39:08 +01:00
metamask-extension/ui/index.js
Mark Stacey 53ec42d95f
Add switch to connected account alert (#8532)
Add alert suggesting that the user switch to a connected account. This
alert is displayed when the popup is opened over an active tab that is
connected to some account, but not the current selected account. The
user can choose to switch to a connected account, or dismiss the alert.

This alert is only shown once per account switch. So if the user
repeatedly opens the popup on a dapp without switching accounts, it'll
only be shown the first time. The alert also won't be shown if the user
has just dismissed an "Unconnected account" alert on this same dapp
and account, as that would be redundant.

The alert has a "Don't show me this again" checkbox that allows the
user to disable the alert. It can be re-enabled again on the Alerts
settings page.
2020-05-12 10:01:52 -03:00

169 lines
4.9 KiB
JavaScript

import copyToClipboard from 'copy-to-clipboard'
import log from 'loglevel'
import { clone } from 'lodash'
import React from 'react'
import { render } from 'react-dom'
import Root from './app/pages'
import * as actions from './app/store/actions'
import configureStore from './app/store/store'
import txHelper from './lib/tx-helper'
import { getEnvironmentType } from '../app/scripts/lib/util'
import { ALERT_TYPES } from '../app/scripts/controllers/alert'
import { ENVIRONMENT_TYPE_POPUP } from '../app/scripts/lib/enums'
import { fetchLocale } from './app/helpers/utils/i18n-helper'
import switchDirection from './app/helpers/utils/switch-direction'
import { getPermittedAccountsForCurrentTab, getSelectedAddress } from './app/selectors'
import { ALERT_STATE } from './app/ducks/alerts/switch-to-connected'
import {
getSwitchToConnectedAlertEnabledness,
getSwitchToConnectedAlertShown,
} from './app/ducks/metamask/metamask'
log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
export default function launchMetamaskUi (opts, cb) {
const { backgroundConnection } = opts
actions._setBackgroundConnection(backgroundConnection)
// check if we are unlocked first
backgroundConnection.getState(function (err, metamaskState) {
if (err) {
return cb(err)
}
startApp(metamaskState, backgroundConnection, opts)
.then((store) => {
setupDebuggingHelpers(store)
cb(null, store)
})
})
}
async function startApp (metamaskState, backgroundConnection, opts) {
// parse opts
if (!metamaskState.featureFlags) {
metamaskState.featureFlags = {}
}
const currentLocaleMessages = metamaskState.currentLocale
? await fetchLocale(metamaskState.currentLocale)
: {}
const enLocaleMessages = await fetchLocale('en')
if (metamaskState.textDirection === 'rtl') {
await switchDirection('rtl')
}
const draftInitialState = {
activeTab: opts.activeTab,
// metamaskState represents the cross-tab state
metamask: metamaskState,
// appState represents the current tab's popup state
appState: {},
localeMessages: {
current: currentLocaleMessages,
en: enLocaleMessages,
},
}
if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) {
const origin = draftInitialState.activeTab.origin
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(draftInitialState)
const selectedAddress = getSelectedAddress(draftInitialState)
const switchToConnectedAlertShown = getSwitchToConnectedAlertShown(draftInitialState)
const switchToConnectedAlertIsEnabled = getSwitchToConnectedAlertEnabledness(draftInitialState)
if (
origin &&
switchToConnectedAlertIsEnabled &&
!switchToConnectedAlertShown[origin] &&
permittedAccountsForCurrentTab.length > 0 &&
!permittedAccountsForCurrentTab.includes(selectedAddress)
) {
draftInitialState[ALERT_TYPES.switchToConnected] = { state: ALERT_STATE.OPEN }
actions.setSwitchToConnectedAlertShown(origin)
}
}
const store = configureStore(draftInitialState)
// if unconfirmed txs, start on txConf page
const unapprovedTxsAll = txHelper(
metamaskState.unapprovedTxs,
metamaskState.unapprovedMsgs,
metamaskState.unapprovedPersonalMsgs,
metamaskState.unapprovedDecryptMsgs,
metamaskState.unapprovedEncryptionPublicKeyMsgs,
metamaskState.unapprovedTypedMessages,
metamaskState.network
)
const numberOfUnapprivedTx = unapprovedTxsAll.length
if (numberOfUnapprivedTx > 0) {
store.dispatch(actions.showConfTxPage({
id: unapprovedTxsAll[0].id,
}))
}
backgroundConnection.on('update', function (metamaskState) {
store.dispatch(actions.updateMetamaskState(metamaskState))
})
// global metamask api - used by tooling
global.metamask = {
updateCurrentLocale: (code) => {
store.dispatch(actions.updateCurrentLocale(code))
},
setProviderType: (type) => {
store.dispatch(actions.setProviderType(type))
},
setFeatureFlag: (key, value) => {
store.dispatch(actions.setFeatureFlag(key, value))
},
}
// start app
render(
<Root
store={store}
/>,
opts.container,
)
return store
}
function setupDebuggingHelpers (store) {
window.getCleanAppState = function () {
const state = clone(store.getState())
state.version = global.platform.getVersion()
state.browser = window.navigator.userAgent
return state
}
}
window.logStateString = function (cb) {
const state = window.getCleanAppState()
global.platform.getPlatformInfo((err, platform) => {
if (err) {
return cb(err)
}
state.platform = platform
const stateString = JSON.stringify(state, null, 2)
cb(null, stateString)
})
}
window.logState = function (toClipboard) {
return window.logStateString((err, result) => {
if (err) {
console.error(err.message)
} else if (toClipboard) {
copyToClipboard(result)
console.log('State log copied')
} else {
console.log(result)
}
})
}