Merge pull request #326 from MetaMask/conf-tx-refactor

Tx/Msg Conf page + notifcation refactor
feature/default_network_editable
kumavis 8 years ago committed by GitHub
commit 36a183db94
  1. 6
      app/scripts/contentscript.js
  2. 126
      app/scripts/lib/notifications.js
  3. 2
      ui/app/components/account-panel.js
  4. 53
      ui/app/components/pending-msg-details.js
  5. 37
      ui/app/components/pending-msg.js
  6. 65
      ui/app/components/pending-tx-details.js
  7. 69
      ui/app/components/pending-tx.js
  8. 4
      ui/app/conf-tx.js

@ -1,7 +1,7 @@
const LocalMessageDuplexStream = require('./lib/local-message-stream.js')
const PortStream = require('./lib/port-stream.js')
const ObjectMultiplex = require('./lib/obj-multiplex')
const urlUtil = require('url')
// const urlUtil = require('url')
if (shouldInjectWeb3()) {
setupInjection()
@ -45,8 +45,6 @@ function setupInjection(){
}
function shouldInjectWeb3(){
var urlData = urlUtil.parse(window.location.href)
var extension = urlData.pathname.split('.').slice(-1)[0]
var shouldInject = (extension !== 'pdf')
var shouldInject = (window.location.href.indexOf('.pdf') === -1)
return shouldInject
}

@ -1,10 +1,11 @@
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 uiUtils = require('../../../ui/app/util')
const renderPendingTx = require('../../../ui/app/components/pending-tx').prototype.renderGeneric
const PendingTxDetails = require('../../../ui/app/components/pending-tx-details')
const PendingMsgDetails = require('../../../ui/app/components/pending-msg-details')
const MetaMaskUiCss = require('../../../ui/css')
var notificationHandlers = {}
@ -56,29 +57,29 @@ function createTxNotification (opts) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...')
renderTransactionNotificationSVG(opts, function(err, source){
var state = {
title: 'New Unsigned Transaction',
imageifyIdenticons: false,
txData: {
txParams: opts.txParams,
time: (new Date()).getTime(),
},
identities: {
},
accounts: {
},
onConfirm: opts.confirm,
onCancel: opts.cancel,
}
renderTxNotificationSVG(state, function(err, notificationSvgSource){
if (err) throw err
var imageUrl = 'data:image/svg+xml;utf8,' + encodeURIComponent(source)
var id = createId()
chrome.notifications.create(id, {
type: 'image',
// requireInteraction: true,
iconUrl: '/images/icon-128.png',
imageUrl: imageUrl,
title: opts.title,
message: '',
buttons: [{
title: 'confirm',
}, {
title: 'cancel',
}],
})
notificationHandlers[id] = {
confirm: opts.confirm,
cancel: opts.cancel,
}
showNotification(extend(state, {
imageUrl: toSvgUri(notificationSvgSource),
}))
})
}
@ -86,19 +87,46 @@ function createTxNotification (opts) {
function createMsgNotification (opts) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = [
'Submitted by ' + opts.msgParams.origin,
'to be signed by: ' + uiUtils.addressSummary(opts.msgParams.from),
'message:\n' + opts.msgParams.data,
].join('\n')
var state = {
title: 'New Unsigned Message',
imageifyIdenticons: false,
txData: {
msgParams: opts.msgParams,
time: (new Date()).getTime(),
},
identities: {
},
accounts: {
},
onConfirm: opts.confirm,
onCancel: opts.cancel,
}
renderMsgNotificationSVG(state, function(err, notificationSvgSource){
if (err) throw err
showNotification(extend(state, {
imageUrl: toSvgUri(notificationSvgSource),
}))
})
}
function showNotification (state) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var id = createId()
chrome.notifications.create(id, {
type: 'basic',
type: 'image',
requireInteraction: true,
iconUrl: '/images/icon-128.png',
title: opts.title,
message: message,
imageUrl: state.imageUrl,
title: state.title,
message: '',
buttons: [{
title: 'confirm',
}, {
@ -106,27 +134,23 @@ function createMsgNotification (opts) {
}],
})
notificationHandlers[id] = {
confirm: opts.confirm,
cancel: opts.cancel,
confirm: state.onConfirm,
cancel: state.onCancel,
}
}
function renderTransactionNotificationSVG(opts, cb){
var state = {
nonInteractive: true,
inlineIdenticons: true,
txData: {
txParams: opts.txParams,
time: (new Date()).getTime(),
},
identities: {
}
},
accounts: {
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: {
@ -138,7 +162,7 @@ function renderTransactionNotificationSVG(opts, cb){
},
}, [
h('style', MetaMaskUiCss()),
renderPendingTx(h, state),
content,
])
render(confirmView, container, function ready(){
@ -160,4 +184,8 @@ function svgWrapper(content){
</svg>
`
return wrapperSource.split('{{content}}').join(content)
}
function toSvgUri(content){
return 'data:image/svg+xml;utf8,' + encodeURIComponent(content)
}

@ -46,7 +46,7 @@ AccountPanel.prototype.render = function () {
h('.identicon-wrapper.flex-column.select-none', [
h(Identicon, {
address: panelState.identiconKey,
imageify: !state.inlineIdenticons,
imageify: state.imageifyIdenticons,
}),
h('span.font-small', panelState.identiconLabel),
]),

@ -0,0 +1,53 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountPanel = require('./account-panel')
const readableDate = require('../util').readableDate
module.exports = PendingMsgDetails
inherits(PendingMsgDetails, Component)
function PendingMsgDetails () {
Component.call(this)
}
PendingMsgDetails.prototype.render = function () {
var state = this.props
var msgData = state.txData
var msgParams = msgData.msgParams || {}
var address = msgParams.from || state.selectedAddress
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
return (
h('div', {
key: msgData.id,
}, [
// account that will sign
h(AccountPanel, {
showFullAddress: true,
identity: identity,
account: account,
imageifyIdenticons: state.imageifyIdenticons,
}),
// message data
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-row.flex-space-between', [
h('label.font-small', 'DATE'),
h('span.font-small', readableDate(msgData.time)),
]),
h('.flex-row.flex-space-between', [
h('label.font-small', 'MESSAGE'),
h('span.font-small', msgParams.data),
]),
]),
])
)
}

@ -1,9 +1,7 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountPanel = require('./account-panel')
const readableDate = require('../util').readableDate
const PendingTxDetails = require('./pending-msg-details')
module.exports = PendingMsg
@ -16,16 +14,13 @@ PendingMsg.prototype.render = function () {
var state = this.props
var msgData = state.txData
var msgParams = msgData.msgParams || {}
var address = msgParams.from || state.selectedAddress
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
return (
h('.transaction', {
h('div', {
key: msgData.id,
}, [
// header
h('h3', {
style: {
fontWeight: 'bold',
@ -33,27 +28,10 @@ PendingMsg.prototype.render = function () {
},
}, 'Sign Message'),
// account that will sign
h(AccountPanel, {
showFullAddress: true,
identity: identity,
account: account,
}),
// tx data
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-row.flex-space-between', [
h('label.font-small', 'DATE'),
h('span.font-small', readableDate(msgData.time)),
]),
// message details
h(PendingTxDetails, state),
h('.flex-row.flex-space-between', [
h('label.font-small', 'MESSAGE'),
h('span.font-small', msgParams.data),
]),
]),
// send + cancel
// sign + cancel
h('.flex-row.flex-space-around', [
h('button', {
onClick: state.cancelMessage,
@ -63,6 +41,7 @@ PendingMsg.prototype.render = function () {
}, 'Sign'),
]),
])
)
}

@ -0,0 +1,65 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountPanel = require('./account-panel')
const addressSummary = require('../util').addressSummary
const readableDate = require('../util').readableDate
const formatBalance = require('../util').formatBalance
module.exports = PendingTxDetails
inherits(PendingTxDetails, Component)
function PendingTxDetails () {
Component.call(this)
}
PendingTxDetails.prototype.render = function () {
var state = this.props
return this.renderGeneric(h, state)
}
PendingTxDetails.prototype.renderGeneric = function (h, state) {
var txData = state.txData
var txParams = txData.txParams || {}
var address = txParams.from || state.selectedAddress
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
return (
h('div', [
// account that will sign
h(AccountPanel, {
showFullAddress: true,
identity: identity,
account: account,
imageifyIdenticons: state.imageifyIdenticons,
}),
// tx data
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-row.flex-space-between', [
h('label.font-small', 'TO ADDRESS'),
h('span.font-small', addressSummary(txParams.to)),
]),
h('.flex-row.flex-space-between', [
h('label.font-small', 'DATE'),
h('span.font-small', readableDate(txData.time)),
]),
h('.flex-row.flex-space-between', [
h('label.font-small', 'AMOUNT'),
h('span.font-small', formatBalance(txParams.value)),
]),
]),
])
)
}

@ -1,11 +1,8 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const PendingTxDetails = require('./pending-tx-details')
const AccountPanel = require('./account-panel')
const addressSummary = require('../util').addressSummary
const readableDate = require('../util').readableDate
const formatBalance = require('../util').formatBalance
module.exports = PendingTx
@ -16,23 +13,15 @@ function PendingTx () {
PendingTx.prototype.render = function () {
var state = this.props
return this.renderGeneric(h, state)
}
PendingTx.prototype.renderGeneric = function (h, state) {
var txData = state.txData
var txParams = txData.txParams || {}
var address = txParams.from || state.selectedAddress
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
return (
h('.transaction', {
h('div', {
key: txData.id,
}, [
// header
h('h3', {
style: {
fontWeight: 'bold',
@ -40,53 +29,21 @@ PendingTx.prototype.renderGeneric = function (h, state) {
},
}, 'Submit Transaction'),
// account that will sign
h(AccountPanel, {
showFullAddress: true,
identity: identity,
account: account,
inlineIdenticons: state.inlineIdenticons,
}),
// tx data
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-row.flex-space-between', [
h('label.font-small', 'TO ADDRESS'),
h('span.font-small', addressSummary(txParams.to)),
]),
h('.flex-row.flex-space-between', [
h('label.font-small', 'DATE'),
h('span.font-small', readableDate(txData.time)),
]),
h('.flex-row.flex-space-between', [
h('label.font-small', 'AMOUNT'),
h('span.font-small', formatBalance(txParams.value)),
]),
]),
// tx info
h(PendingTxDetails, state),
// send + cancel
state.nonInteractive ? null : actionButtons(state),
h('.flex-row.flex-space-around', [
h('button', {
onClick: state.cancelTransaction,
}, 'Cancel'),
h('button', {
onClick: state.sendTransaction,
}, 'Send'),
]),
])
)
}
function actionButtons(state){
return (
h('.flex-row.flex-space-around', [
h('button', {
onClick: state.cancelTransaction,
}, 'Cancel'),
h('button', {
onClick: state.sendTransaction,
}, 'Send'),
])
)
}

@ -6,7 +6,7 @@ const connect = require('react-redux').connect
const actions = require('./actions')
const txHelper = require('../lib/tx-helper')
const ConfirmTx = require('./components/pending-tx')
const PendingTx = require('./components/pending-tx')
const PendingMsg = require('./components/pending-msg')
module.exports = connect(mapStateToProps)(ConfirmTxScreen)
@ -101,7 +101,7 @@ ConfirmTxScreen.prototype.render = function () {
function currentTxView (opts) {
if ('txParams' in opts.txData) {
// This is a pending transaction
return h(ConfirmTx, opts)
return h(PendingTx, opts)
} else if ('msgParams' in opts.txData) {
// This is a pending message to sign
return h(PendingMsg, opts)

Loading…
Cancel
Save