From 6363ddbe9b5b69508dc4ec13964a49b87fc30741 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 10:17:45 -0700 Subject: [PATCH 1/9] Correct version number --- app/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/manifest.json b/app/manifest.json index c3417103e..5b1be504d 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "Metamask", - "version": "2.0.1", + "version": "2.1.0", "manifest_version": 2, "description": "__MSG_appDescription__", "icons": { From d489b3192355079ed0d95efdbd2ab04125ff206f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 13:06:29 -0700 Subject: [PATCH 2/9] Center wallet nickname under identicon in tx confirmation screen --- ui/app/css/index.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/app/css/index.css b/ui/app/css/index.css index 8e25c1f88..650c52cef 100644 --- a/ui/app/css/index.css +++ b/ui/app/css/index.css @@ -296,6 +296,8 @@ input.large-input { .identity-panel .identicon-wrapper { margin: 4px; margin-top: 8px; + display: flex; + align-items: center; } .identity-panel .identicon-wrapper span { From d31189b2066d0225eb57e86d077d579cf223658c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:12:41 -0700 Subject: [PATCH 3/9] Add pending messages to sign to tx list --- .../components/transaction-list-item-icon.js | 46 +++++++++ ui/app/components/transaction-list-item.js | 98 +++++++++---------- ui/app/components/transaction-list.js | 4 +- ui/app/css/lib.css | 19 ++++ 4 files changed, 113 insertions(+), 54 deletions(-) create mode 100644 ui/app/components/transaction-list-item-icon.js diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js new file mode 100644 index 000000000..fbee4b218 --- /dev/null +++ b/ui/app/components/transaction-list-item-icon.js @@ -0,0 +1,46 @@ +const Component = require('react').Component +const h = require('react-hyperscript') +const inherits = require('util').inherits + +const Identicon = require('./identicon') + +module.exports = TransactionIcon + + +inherits(TransactionIcon, Component) +function TransactionIcon() { + Component.call(this) +} + +TransactionIcon.prototype.render = function() { + const { transaction, txParams, isTx, isMsg } = this.props + + if (transaction.status === 'rejected') { + return h('i.fa.fa-exclamation-triangle.fa-lg.error', { + style: { + width: '24px', + } + }) + } + + if (isMsg) { + return h('i.fa.fa-certificate.fa-lg', { + style: { + width: '24px', + } + }) + } + + if (txParams.to) { + return h(Identicon, { + diameter: 24, + address: txParams.to || transaction.hash, + }) + } else { + return h('i.fa.fa-file-text-o.fa-lg', { + style: { + width: '24px', + } + }) + } +} diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index a0715db0b..cff9a47b2 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -2,13 +2,14 @@ const Component = require('react').Component const h = require('react-hyperscript') const inherits = require('util').inherits -const Identicon = require('./identicon') const EtherBalance = require('./eth-balance') const addressSummary = require('../util').addressSummary const explorerLink = require('../../lib/explorer-link') const formatBalance = require('../util').formatBalance const vreme = new (require('vreme')) +const TransactionIcon = require('./transaction-list-item-icon') + module.exports = TransactionListItem @@ -25,7 +26,12 @@ TransactionListItem.prototype.render = function() { var isMsg = ('msgParams' in transaction) var isTx = ('txParams' in transaction) - var txParams = transaction.txParams + let txParams + if (isTx) { + txParams = transaction.txParams + } else if (isMsg) { + txParams = transaction.msgParams + } return ( h(`.transaction-list-item.flex-row.flex-space-between${transaction.hash ? '.pointer' : ''}`, { @@ -42,49 +48,55 @@ TransactionListItem.prototype.render = function() { // large identicon h('.identicon-wrapper.flex-column.flex-center.select-none', [ - identicon(txParams, transaction), + transaction.status === 'unconfirmed' ? h('.red-dot', ' ') : + h(TransactionIcon, { txParams, transaction, isTx, isMsg }), ]), h('.flex-column', [ - + domainField(txParams), h('div', date), - - recipientField(txParams, transaction), - + recipientField(txParams, transaction, isTx, isMsg), ]), - h(EtherBalance, { + isTx ? h(EtherBalance, { value: txParams.value, - }), + }) : h('.flex-column'), ]) ) } +function domainField(txParams) { + return h('div', { + style: { + fontSize: 'small', + color: '#ABA9AA', + }, + },[ + txParams.origin, + ]) +} -function recipientField(txParams, transaction) { - if (txParams.to) { - return h('div', { - style: { - fontSize: 'small', - color: '#ABA9AA', - }, - }, [ - addressSummary(txParams.to), - failIfFailed(transaction), - ]) +function recipientField(txParams, transaction, isTx, isMsg) { + let message + if (isMsg) { + message = 'Signature Requested' + } else if (txParams.to) { + message = addressSummary(txParams.to) } else { - - return h('div', { - style: { - fontSize: 'small', - color: '#ABA9AA', - }, - },[ - 'Contract Published', - failIfFailed(transaction), - ]) + message = 'Contract Published' } + + return h('div', { + style: { + fontSize: 'small', + color: '#ABA9AA', + }, + },[ + message, + failIfFailed(transaction), + ]) + } TransactionListItem.prototype.renderMessage = function() { @@ -96,31 +108,11 @@ function formatDate(date){ return vreme.format(new Date(date), 'March 16 2014 14:30') } -function identicon(txParams, transaction) { - if (transaction.status === 'rejected') { - return h('i.fa.fa-exclamation-triangle.fa-lg.error', { - style: { - width: '24px', - } - }) - } - - if (txParams.to) { - return h(Identicon, { - diameter: 24, - address: txParams.to || transaction.hash, - }) - } else { - return h('i.fa.fa-file-text-o.fa-lg', { - style: { - width: '24px', - } - }) - } -} - function failIfFailed(transaction) { if (transaction.status === 'rejected') { + return h('span.error', ' (Rejected)') + } + if (transaction.status === 'failed') { return h('span.error', ' (Failed)') } } diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js index 86abd9709..3c778b19d 100644 --- a/ui/app/components/transaction-list.js +++ b/ui/app/components/transaction-list.js @@ -14,7 +14,9 @@ function TransactionList() { TransactionList.prototype.render = function() { const { txsToRender, network, unconfTxs, unconfMsgs } = this.props - const transactions = txsToRender + const transactions = txsToRender.concat(unconfMsgs) + .sort((a, b) => b.time - a.time) + console.dir(transactions) return ( diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css index 73be4023e..865d8060c 100644 --- a/ui/app/css/lib.css +++ b/ui/app/css/lib.css @@ -167,6 +167,20 @@ hr.horizontal-line { background: white; } +.red-dot { + position: inherit; + background: red; + color: white; + border-radius: 10px; + height: 12px; + min-width: 12px; + margin-left: 6px; + display: flex; + align-items: center; + justify-content: center; + padding: 4px; +} + .pending-dot { background: red; left: 57px; @@ -180,3 +194,8 @@ hr.horizontal-line { justify-content: center; padding: 4px; } + +.ether-balance { + display: flex; + align-items: center; +} From 5da6fd5ab18812929cbf790527a3029fd8d7123c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:32:45 -0700 Subject: [PATCH 4/9] Add clicking txs in list shows tx conf screen --- ui/app/account-detail.js | 3 +++ ui/app/actions.js | 9 +++++++ ui/app/components/transaction-list-item.js | 9 ++++++- ui/app/components/transaction-list.js | 6 +++-- ui/app/reducers/app.js | 28 ++++++++++++++++++++-- 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js index 1dcce1d08..2f412c5be 100644 --- a/ui/app/account-detail.js +++ b/ui/app/account-detail.js @@ -201,6 +201,9 @@ AccountDetailScreen.prototype.transactionList = function() { network, unconfTxs, unconfMsgs, + viewPendingTx:(txId) => { + this.props.dispatch(actions.viewPendingTx(txId)) + } }) } diff --git a/ui/app/actions.js b/ui/app/actions.js index 5b058aaed..ae6125b20 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -76,6 +76,8 @@ var actions = { txError: txError, nextTx: nextTx, previousTx: previousTx, + viewPendingTx: viewPendingTx, + VIEW_PENDING_TX: 'VIEW_PENDING_TX', // app messages showAccountDetail: showAccountDetail, BACK_TO_ACCOUNT_DETAIL: 'BACK_TO_ACCOUNT_DETAIL', @@ -387,6 +389,13 @@ function nextTx() { } } +function viewPendingTx(txId) { + return { + type: actions.VIEW_PENDING_TX, + value: txId, + } +} + function previousTx() { return { type: actions.PREVIOUS_TX, diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index cff9a47b2..ac74046f3 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -25,6 +25,7 @@ TransactionListItem.prototype.render = function() { var isMsg = ('msgParams' in transaction) var isTx = ('txParams' in transaction) + var isPending = transaction.status === 'unconfirmed' let txParams if (isTx) { @@ -33,10 +34,16 @@ TransactionListItem.prototype.render = function() { txParams = transaction.msgParams } + const isClickable = ('hash' in transaction) || isPending + return ( - h(`.transaction-list-item.flex-row.flex-space-between${transaction.hash ? '.pointer' : ''}`, { + h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, { key: `tx-${transaction.id + i}`, onClick: (event) => { + if (isPending) { + this.props.showTx(transaction.id) + } + if (!transaction.hash) return var url = explorerLink(transaction.hash, parseInt(network)) chrome.tabs.create({ url }) diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js index 3c778b19d..5ebb3e563 100644 --- a/ui/app/components/transaction-list.js +++ b/ui/app/components/transaction-list.js @@ -16,7 +16,6 @@ TransactionList.prototype.render = function() { const { txsToRender, network, unconfTxs, unconfMsgs } = this.props const transactions = txsToRender.concat(unconfMsgs) .sort((a, b) => b.time - a.time) - console.dir(transactions) return ( @@ -53,7 +52,10 @@ TransactionList.prototype.render = function() { transactions.length ? transactions.map((transaction, i) => { return h(TransactionListItem, { - transaction, i + transaction, i, + showTx:(txId) => { + this.props.viewPendingTx(txId) + }, }) }) : diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index a98b809d6..08c2268c1 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -12,10 +12,10 @@ function reduceApp(state, action) { const pendingTxs = hasPendingTxs(state) let name = 'accounts' if (selectedAccount) { - defaultView = 'accountDetail' + name = 'accountDetail' } if (pendingTxs) { - defaultView = 'confTx' + name = 'confTx' } var defaultView = { @@ -270,6 +270,17 @@ function reduceApp(state, action) { } }) + case actions.VIEW_PENDING_TX: + const context = indexForPending(state, action.value) + return extend(appState, { + transForward: true, + currentView: { + name: 'confTx', + context, + warning: null, + } + }) + case actions.PREVIOUS_TX: return extend(appState, { transForward: false, @@ -366,3 +377,16 @@ function hasPendingTxs (state) { var unconfTxList = txHelper(unconfTxs, unconfMsgs) return unconfTxList.length > 0 } + +function indexForPending(state, txId) { + var unconfTxs = state.metamask.unconfTxs + var unconfMsgs = state.metamask.unconfMsgs + var unconfTxList = txHelper(unconfTxs, unconfMsgs) + let idx + unconfTxList.forEach((tx, i) => { + if (tx.id === txId) { + idx = i + } + }) + return idx +} From f69721a98ddcbd65fb41c1fd0fa1ce6001e75ab5 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:34:04 -0700 Subject: [PATCH 5/9] Bump changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b0469b19..e59f7ded3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Current Master +- Added pending transactions to transaction list on account screen. +- Clicking a pending transaction takes you back to the transaction approval screen. + ## 2.1.0 2016-05-26 - Added copy address button to account list. From 12d89eb647ba8450ef86d9a2897fa820a8f1fe18 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:41:11 -0700 Subject: [PATCH 6/9] Fix network reference --- ui/app/components/transaction-list-item.js | 2 +- ui/app/components/transaction-list.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index ac74046f3..fdb970f07 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -107,7 +107,7 @@ function recipientField(txParams, transaction, isTx, isMsg) { } TransactionListItem.prototype.renderMessage = function() { - const { transaction, i } = this.props + const { transaction, i, network } = this.props return h('div', 'wowie, thats a message') } diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js index 5ebb3e563..ed2e1ee0a 100644 --- a/ui/app/components/transaction-list.js +++ b/ui/app/components/transaction-list.js @@ -52,7 +52,7 @@ TransactionList.prototype.render = function() { transactions.length ? transactions.map((transaction, i) => { return h(TransactionListItem, { - transaction, i, + transaction, i, network, showTx:(txId) => { this.props.viewPendingTx(txId) }, From 4d468d806479ae1a4b50b6cfceecb4df066280c0 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:50:01 -0700 Subject: [PATCH 7/9] Fix network reference part 2 --- ui/app/components/transaction-list-item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index fdb970f07..22f0ce1e3 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -19,7 +19,7 @@ function TransactionListItem() { } TransactionListItem.prototype.render = function() { - const { transaction, i } = this.props + const { transaction, i, network } = this.props var date = formatDate(transaction.time) From 5001547386deff98b0b96a3d2a45c0d7ec822362 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 14:59:05 -0700 Subject: [PATCH 8/9] Remove etherscan links from non standard blockchains --- ui/app/components/transaction-list-item.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index 22f0ce1e3..beff93272 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -23,6 +23,13 @@ TransactionListItem.prototype.render = function() { var date = formatDate(transaction.time) + let isLinkable = false + try { + const numericNet = parseInt(network) + isLinkable = numericNet === 1 || numericNet === 2 + } + catch() {} + var isMsg = ('msgParams' in transaction) var isTx = ('txParams' in transaction) var isPending = transaction.status === 'unconfirmed' @@ -34,7 +41,7 @@ TransactionListItem.prototype.render = function() { txParams = transaction.msgParams } - const isClickable = ('hash' in transaction) || isPending + const isClickable = ('hash' in transaction && isLinkable) || isPending return ( h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, { @@ -44,7 +51,7 @@ TransactionListItem.prototype.render = function() { this.props.showTx(transaction.id) } - if (!transaction.hash) return + if (!transaction.hash || !isLinkable) return var url = explorerLink(transaction.hash, parseInt(network)) chrome.tabs.create({ url }) }, From 01e5bc25a9e03ab2d9c72dad29b5d7fa03933009 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 26 May 2016 15:00:37 -0700 Subject: [PATCH 9/9] Fix build error --- ui/app/components/transaction-list-item.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js index beff93272..fc1c3c630 100644 --- a/ui/app/components/transaction-list-item.js +++ b/ui/app/components/transaction-list-item.js @@ -24,11 +24,8 @@ TransactionListItem.prototype.render = function() { var date = formatDate(transaction.time) let isLinkable = false - try { - const numericNet = parseInt(network) - isLinkable = numericNet === 1 || numericNet === 2 - } - catch() {} + const numericNet = parseInt(network) + isLinkable = numericNet === 1 || numericNet === 2 var isMsg = ('msgParams' in transaction) var isTx = ('txParams' in transaction)