mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #554 from MetaMask/PopupNotifications
Replace chrome notifications with windows.create
This commit is contained in:
commit
78f73038e7
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Current Master
|
## Current Master
|
||||||
|
|
||||||
|
- Changed transaction approval from notifications system to popup system.
|
||||||
- Forms now retain their values even when closing the popup and reopening it.
|
- Forms now retain their values even when closing the popup and reopening it.
|
||||||
|
|
||||||
## 2.9.2 2016-08-24
|
## 2.9.2 2016-08-24
|
||||||
|
16
app/notification.html
Normal file
16
app/notification.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>MetaMask Notification</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app-content"></div>
|
||||||
|
<script src="./scripts/popup.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -3,9 +3,7 @@ const extend = require('xtend')
|
|||||||
const Dnode = require('dnode')
|
const Dnode = require('dnode')
|
||||||
const eos = require('end-of-stream')
|
const eos = require('end-of-stream')
|
||||||
const PortStream = require('./lib/port-stream.js')
|
const PortStream = require('./lib/port-stream.js')
|
||||||
const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification
|
const notification = require('./lib/notifications.js')
|
||||||
const createTxNotification = require('./lib/notifications.js').createTxNotification
|
|
||||||
const createMsgNotification = require('./lib/notifications.js').createMsgNotification
|
|
||||||
const messageManager = require('./lib/message-manager')
|
const messageManager = require('./lib/message-manager')
|
||||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||||
const MetamaskController = require('./metamask-controller')
|
const MetamaskController = require('./metamask-controller')
|
||||||
@ -26,41 +24,15 @@ const controller = new MetamaskController({
|
|||||||
const idStore = controller.idStore
|
const idStore = controller.idStore
|
||||||
|
|
||||||
function unlockAccountMessage () {
|
function unlockAccountMessage () {
|
||||||
createUnlockRequestNotification({
|
notification.show()
|
||||||
title: 'Account Unlock Request',
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUnconfirmedMessage (msgParams, msgId) {
|
function showUnconfirmedMessage (msgParams, msgId) {
|
||||||
var controllerState = controller.getState()
|
notification.show()
|
||||||
|
|
||||||
createMsgNotification({
|
|
||||||
imageifyIdenticons: false,
|
|
||||||
txData: {
|
|
||||||
msgParams: msgParams,
|
|
||||||
time: (new Date()).getTime(),
|
|
||||||
},
|
|
||||||
identities: controllerState.identities,
|
|
||||||
accounts: controllerState.accounts,
|
|
||||||
onConfirm: idStore.approveMessage.bind(idStore, msgId, noop),
|
|
||||||
onCancel: idStore.cancelMessage.bind(idStore, msgId),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
|
function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
|
||||||
var controllerState = controller.getState()
|
notification.show()
|
||||||
|
|
||||||
createTxNotification({
|
|
||||||
imageifyIdenticons: false,
|
|
||||||
txData: {
|
|
||||||
txParams: txParams,
|
|
||||||
time: (new Date()).getTime(),
|
|
||||||
},
|
|
||||||
identities: controllerState.identities,
|
|
||||||
accounts: controllerState.accounts,
|
|
||||||
onConfirm: idStore.approveTransaction.bind(idStore, txData.id, noop),
|
|
||||||
onCancel: idStore.cancelTransaction.bind(idStore, txData.id),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -69,7 +41,7 @@ function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
|
|||||||
|
|
||||||
extension.runtime.onConnect.addListener(connectRemote)
|
extension.runtime.onConnect.addListener(connectRemote)
|
||||||
function connectRemote (remotePort) {
|
function connectRemote (remotePort) {
|
||||||
var isMetaMaskInternalProcess = (remotePort.name === 'popup')
|
var isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
|
||||||
var portStream = new PortStream(remotePort)
|
var portStream = new PortStream(remotePort)
|
||||||
if (isMetaMaskInternalProcess) {
|
if (isMetaMaskInternalProcess) {
|
||||||
// communication with popup
|
// communication with popup
|
||||||
@ -109,7 +81,7 @@ function setupControllerConnection (stream) {
|
|||||||
dnode.on('remote', (remote) => {
|
dnode.on('remote', (remote) => {
|
||||||
// push updates to popup
|
// push updates to popup
|
||||||
controller.ethStore.on('update', controller.sendUpdate.bind(controller))
|
controller.ethStore.on('update', controller.sendUpdate.bind(controller))
|
||||||
controller.remote = remote
|
controller.listeners.push(remote)
|
||||||
idStore.on('update', controller.sendUpdate.bind(controller))
|
idStore.on('update', controller.sendUpdate.bind(controller))
|
||||||
|
|
||||||
// teardown on disconnect
|
// teardown on disconnect
|
||||||
@ -189,4 +161,3 @@ function setData (data) {
|
|||||||
window.localStorage[STORAGE_KEY] = JSON.stringify(data)
|
window.localStorage[STORAGE_KEY] = JSON.stringify(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function noop () {}
|
|
||||||
|
@ -41,6 +41,12 @@ function Extension () {
|
|||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (browser[api]) {
|
||||||
|
_this[api] = browser[api]
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_this.api = browser.extension[api]
|
_this.api = browser.extension[api]
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
8
app/scripts/lib/is-popup-or-notification.js
Normal file
8
app/scripts/lib/is-popup-or-notification.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module.exports = function isPopupOrNotification() {
|
||||||
|
const url = window.location.href
|
||||||
|
if (url.match(/popup.html$/)) {
|
||||||
|
return 'popup'
|
||||||
|
} else {
|
||||||
|
return 'notification'
|
||||||
|
}
|
||||||
|
}
|
@ -1,159 +1,48 @@
|
|||||||
const createId = require('hat')
|
|
||||||
const extend = require('xtend')
|
|
||||||
const unmountComponentAtNode = require('react-dom').unmountComponentAtNode
|
|
||||||
const findDOMNode = require('react-dom').findDOMNode
|
|
||||||
const render = require('react-dom').render
|
|
||||||
const h = require('react-hyperscript')
|
|
||||||
const PendingTxDetails = require('../../../ui/app/components/pending-tx-details')
|
|
||||||
const PendingMsgDetails = require('../../../ui/app/components/pending-msg-details')
|
|
||||||
const MetaMaskUiCss = require('../../../ui/css')
|
|
||||||
const extension = require('./extension')
|
const extension = require('./extension')
|
||||||
var notificationHandlers = {}
|
|
||||||
|
|
||||||
const notifications = {
|
const notifications = {
|
||||||
createUnlockRequestNotification: createUnlockRequestNotification,
|
show,
|
||||||
createTxNotification: createTxNotification,
|
getPopup,
|
||||||
createMsgNotification: createMsgNotification,
|
closePopup,
|
||||||
}
|
}
|
||||||
module.exports = notifications
|
module.exports = notifications
|
||||||
window.METAMASK_NOTIFIER = notifications
|
window.METAMASK_NOTIFIER = notifications
|
||||||
|
|
||||||
setupListeners()
|
function show () {
|
||||||
|
getPopup((popup) => {
|
||||||
function setupListeners () {
|
if (popup) {
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
return extension.windows.update(popup.id, { focused: true })
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...')
|
|
||||||
|
|
||||||
// notification button press
|
|
||||||
extension.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
|
|
||||||
var handlers = notificationHandlers[notificationId]
|
|
||||||
if (buttonIndex === 0) {
|
|
||||||
handlers.confirm()
|
|
||||||
} else {
|
|
||||||
handlers.cancel()
|
|
||||||
}
|
}
|
||||||
extension.notifications.clear(notificationId)
|
|
||||||
})
|
|
||||||
|
|
||||||
// notification teardown
|
extension.windows.create({
|
||||||
extension.notifications.onClosed.addListener(function (notificationId) {
|
url: 'notification.html',
|
||||||
delete notificationHandlers[notificationId]
|
type: 'detached_panel',
|
||||||
|
focused: true,
|
||||||
|
width: 360,
|
||||||
|
height: 500,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// creation helper
|
function getPopup(cb) {
|
||||||
function createUnlockRequestNotification (opts) {
|
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...')
|
|
||||||
var message = 'An Ethereum app has requested a signature. Please unlock your account.'
|
|
||||||
|
|
||||||
var id = createId()
|
// Ignore in test environment
|
||||||
extension.notifications.create(id, {
|
if (!extension.windows) {
|
||||||
type: 'basic',
|
return cb(null)
|
||||||
iconUrl: '/images/icon-128.png',
|
}
|
||||||
title: opts.title,
|
|
||||||
message: message,
|
extension.windows.getAll({}, (windows) => {
|
||||||
|
let popup = windows.find((win) => {
|
||||||
|
return win.type === 'popup'
|
||||||
|
})
|
||||||
|
|
||||||
|
cb(popup)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTxNotification (state) {
|
function closePopup() {
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
getPopup((popup) => {
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...')
|
if (!popup) return
|
||||||
|
extension.windows.remove(popup.id, console.error)
|
||||||
renderTxNotificationSVG(state, function (err, notificationSvgSource) {
|
|
||||||
if (err) throw err
|
|
||||||
|
|
||||||
showNotification(extend(state, {
|
|
||||||
title: 'New Unsigned Transaction',
|
|
||||||
imageUrl: toSvgUri(notificationSvgSource),
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMsgNotification (state) {
|
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...')
|
|
||||||
|
|
||||||
renderMsgNotificationSVG(state, function (err, notificationSvgSource) {
|
|
||||||
if (err) throw err
|
|
||||||
|
|
||||||
showNotification(extend(state, {
|
|
||||||
title: 'New Unsigned Message',
|
|
||||||
imageUrl: toSvgUri(notificationSvgSource),
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function showNotification (state) {
|
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...')
|
|
||||||
|
|
||||||
var id = createId()
|
|
||||||
extension.notifications.create(id, {
|
|
||||||
type: 'image',
|
|
||||||
requireInteraction: true,
|
|
||||||
iconUrl: '/images/icon-128.png',
|
|
||||||
imageUrl: state.imageUrl,
|
|
||||||
title: state.title,
|
|
||||||
message: '',
|
|
||||||
buttons: [{
|
|
||||||
title: 'Approve',
|
|
||||||
}, {
|
|
||||||
title: 'Reject',
|
|
||||||
}],
|
|
||||||
})
|
|
||||||
notificationHandlers[id] = {
|
|
||||||
confirm: state.onConfirm,
|
|
||||||
cancel: state.onCancel,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTxNotificationSVG (state, cb) {
|
|
||||||
var content = h(PendingTxDetails, state)
|
|
||||||
renderNotificationSVG(content, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMsgNotificationSVG (state, cb) {
|
|
||||||
var content = h(PendingMsgDetails, state)
|
|
||||||
renderNotificationSVG(content, cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderNotificationSVG (content, cb) {
|
|
||||||
var container = document.createElement('div')
|
|
||||||
var confirmView = h('div.app-primary', {
|
|
||||||
style: {
|
|
||||||
width: '360px',
|
|
||||||
height: '240px',
|
|
||||||
padding: '16px',
|
|
||||||
// background: '#F7F7F7',
|
|
||||||
background: 'white',
|
|
||||||
},
|
|
||||||
}, [
|
|
||||||
h('style', MetaMaskUiCss()),
|
|
||||||
content,
|
|
||||||
])
|
|
||||||
|
|
||||||
render(confirmView, container, function ready() {
|
|
||||||
var rootElement = findDOMNode(this)
|
|
||||||
var viewSource = rootElement.outerHTML
|
|
||||||
unmountComponentAtNode(container)
|
|
||||||
var svgSource = svgWrapper(viewSource)
|
|
||||||
// insert content into svg wrapper
|
|
||||||
cb(null, svgSource)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function svgWrapper (content) {
|
|
||||||
var wrapperSource = `
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="240">
|
|
||||||
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml" height="100%">{{content}}</body>
|
|
||||||
</foreignObject>
|
|
||||||
</svg>
|
|
||||||
`
|
|
||||||
return wrapperSource.split('{{content}}').join(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
function toSvgUri (content) {
|
|
||||||
return 'data:image/svg+xml;utf8,' + encodeURIComponent(content)
|
|
||||||
}
|
|
||||||
|
@ -12,6 +12,7 @@ module.exports = class MetamaskController {
|
|||||||
|
|
||||||
constructor (opts) {
|
constructor (opts) {
|
||||||
this.opts = opts
|
this.opts = opts
|
||||||
|
this.listeners = []
|
||||||
this.configManager = new ConfigManager(opts)
|
this.configManager = new ConfigManager(opts)
|
||||||
this.idStore = new IdentityStore({
|
this.idStore = new IdentityStore({
|
||||||
configManager: this.configManager,
|
configManager: this.configManager,
|
||||||
@ -112,9 +113,9 @@ module.exports = class MetamaskController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendUpdate () {
|
sendUpdate () {
|
||||||
if (this.remote) {
|
this.listeners.forEach((remote) => {
|
||||||
this.remote.sendUpdate(this.getState())
|
remote.sendUpdate(this.getState())
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeProvider (opts) {
|
initializeProvider (opts) {
|
||||||
@ -130,10 +131,17 @@ module.exports = class MetamaskController {
|
|||||||
},
|
},
|
||||||
// tx signing
|
// tx signing
|
||||||
approveTransaction: this.newUnsignedTransaction.bind(this),
|
approveTransaction: this.newUnsignedTransaction.bind(this),
|
||||||
signTransaction: idStore.signTransaction.bind(idStore),
|
signTransaction: (...args) => {
|
||||||
|
idStore.signTransaction(...args)
|
||||||
|
this.sendUpdate()
|
||||||
|
},
|
||||||
|
|
||||||
// msg signing
|
// msg signing
|
||||||
approveMessage: this.newUnsignedMessage.bind(this),
|
approveMessage: this.newUnsignedMessage.bind(this),
|
||||||
signMessage: idStore.signMessage.bind(idStore),
|
signMessage: (...args) => {
|
||||||
|
idStore.signMessage(...args)
|
||||||
|
this.sendUpdate()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var provider = MetaMaskProvider(providerOpts)
|
var provider = MetaMaskProvider(providerOpts)
|
||||||
@ -193,6 +201,8 @@ module.exports = class MetamaskController {
|
|||||||
|
|
||||||
// It's locked
|
// It's locked
|
||||||
if (!state.isUnlocked) {
|
if (!state.isUnlocked) {
|
||||||
|
|
||||||
|
// Allow the environment to define an unlock message.
|
||||||
this.opts.unlockAccountMessage()
|
this.opts.unlockAccountMessage()
|
||||||
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, noop)
|
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, noop)
|
||||||
|
|
||||||
@ -200,6 +210,7 @@ module.exports = class MetamaskController {
|
|||||||
} else {
|
} else {
|
||||||
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
|
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
|
||||||
if (err) return onTxDoneCb(err)
|
if (err) return onTxDoneCb(err)
|
||||||
|
this.sendUpdate()
|
||||||
this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb)
|
this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -212,6 +223,7 @@ module.exports = class MetamaskController {
|
|||||||
this.opts.unlockAccountMessage()
|
this.opts.unlockAccountMessage()
|
||||||
} else {
|
} else {
|
||||||
this.addUnconfirmedMessage(msgParams, cb)
|
this.addUnconfirmedMessage(msgParams, cb)
|
||||||
|
this.sendUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,9 @@ const injectCss = require('inject-css')
|
|||||||
const PortStream = require('./lib/port-stream.js')
|
const PortStream = require('./lib/port-stream.js')
|
||||||
const StreamProvider = require('web3-stream-provider')
|
const StreamProvider = require('web3-stream-provider')
|
||||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||||
|
const isPopupOrNotification = require('./lib/is-popup-or-notification')
|
||||||
const extension = require('./lib/extension')
|
const extension = require('./lib/extension')
|
||||||
|
const notification = require('./lib/notifications')
|
||||||
|
|
||||||
// setup app
|
// setup app
|
||||||
var css = MetaMaskUiCss()
|
var css = MetaMaskUiCss()
|
||||||
@ -22,7 +24,11 @@ async.parallel({
|
|||||||
|
|
||||||
function connectToAccountManager (cb) {
|
function connectToAccountManager (cb) {
|
||||||
// setup communication with background
|
// setup communication with background
|
||||||
var pluginPort = extension.runtime.connect({name: 'popup'})
|
|
||||||
|
var name = isPopupOrNotification()
|
||||||
|
closePopupIfOpen(name)
|
||||||
|
window.METAMASK_UI_TYPE = name
|
||||||
|
var pluginPort = extension.runtime.connect({ name })
|
||||||
var portStream = new PortStream(pluginPort)
|
var portStream = new PortStream(pluginPort)
|
||||||
// setup multiplexing
|
// setup multiplexing
|
||||||
var mx = setupMultiplex(portStream)
|
var mx = setupMultiplex(portStream)
|
||||||
@ -93,3 +99,9 @@ function setupApp (err, opts) {
|
|||||||
networkVersion: opts.networkVersion,
|
networkVersion: opts.networkVersion,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closePopupIfOpen(name) {
|
||||||
|
if (name !== 'notification') {
|
||||||
|
notification.closePopup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -96,6 +96,11 @@ App.prototype.render = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
App.prototype.renderAppBar = function () {
|
App.prototype.renderAppBar = function () {
|
||||||
|
|
||||||
|
if (window.METAMASK_UI_TYPE === 'notification') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const state = this.state || {}
|
const state = this.state || {}
|
||||||
const isNetworkMenuOpen = state.isNetworkMenuOpen || false
|
const isNetworkMenuOpen = state.isNetworkMenuOpen || false
|
||||||
|
@ -5,6 +5,7 @@ const h = require('react-hyperscript')
|
|||||||
const connect = require('react-redux').connect
|
const connect = require('react-redux').connect
|
||||||
const actions = require('./actions')
|
const actions = require('./actions')
|
||||||
const txHelper = require('../lib/tx-helper')
|
const txHelper = require('../lib/tx-helper')
|
||||||
|
const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
|
||||||
|
|
||||||
const PendingTx = require('./components/pending-tx')
|
const PendingTx = require('./components/pending-tx')
|
||||||
const PendingMsg = require('./components/pending-msg')
|
const PendingMsg = require('./components/pending-msg')
|
||||||
@ -36,6 +37,7 @@ ConfirmTxScreen.prototype.render = function () {
|
|||||||
var unconfTxList = txHelper(unconfTxs, unconfMsgs)
|
var unconfTxList = txHelper(unconfTxs, unconfMsgs)
|
||||||
var index = state.index !== undefined ? state.index : 0
|
var index = state.index !== undefined ? state.index : 0
|
||||||
var txData = unconfTxList[index] || unconfTxList[0] || {}
|
var txData = unconfTxList[index] || unconfTxList[0] || {}
|
||||||
|
var isNotification = isPopupOrNotification() === 'notification'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
@ -43,9 +45,9 @@ ConfirmTxScreen.prototype.render = function () {
|
|||||||
|
|
||||||
// subtitle and nav
|
// subtitle and nav
|
||||||
h('.section-title.flex-row.flex-center', [
|
h('.section-title.flex-row.flex-center', [
|
||||||
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
|
!isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
|
||||||
onClick: this.goHome.bind(this),
|
onClick: this.goHome.bind(this),
|
||||||
}),
|
}) : null,
|
||||||
h('h2.page-subtitle', 'Confirm Transaction'),
|
h('h2.page-subtitle', 'Confirm Transaction'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const extend = require('xtend')
|
const extend = require('xtend')
|
||||||
const actions = require('../actions')
|
const actions = require('../actions')
|
||||||
const txHelper = require('../../lib/tx-helper')
|
const txHelper = require('../../lib/tx-helper')
|
||||||
|
const notification = require('../../../app/scripts/lib/notifications')
|
||||||
|
|
||||||
module.exports = reduceApp
|
module.exports = reduceApp
|
||||||
|
|
||||||
@ -250,6 +251,9 @@ function reduceApp (state, action) {
|
|||||||
warning: null,
|
warning: null,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
notification.closePopup()
|
||||||
|
|
||||||
return extend(appState, {
|
return extend(appState, {
|
||||||
transForward: false,
|
transForward: false,
|
||||||
warning: null,
|
warning: null,
|
||||||
@ -515,4 +519,3 @@ function indexForPending (state, txId) {
|
|||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user