Skip to content

Commit

Permalink
Merge pull request #224 from MetaMask/PendingTxList
Browse files Browse the repository at this point in the history
Add pending txs to tx list
  • Loading branch information
danfinlay committed May 26, 2016
2 parents 7f4929a + 01e5bc2 commit f1fb7ff
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 62 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion app/manifest.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
3 changes: 3 additions & 0 deletions ui/app/account-detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ AccountDetailScreen.prototype.transactionList = function() {
network,
unconfTxs,
unconfMsgs,
viewPendingTx:(txId) => {
this.props.dispatch(actions.viewPendingTx(txId))
}
})
}

Expand Down
9 changes: 9 additions & 0 deletions ui/app/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -387,6 +389,13 @@ function nextTx() {
}
}

function viewPendingTx(txId) {
return {
type: actions.VIEW_PENDING_TX,
value: txId,
}
}

function previousTx() {
return {
type: actions.PREVIOUS_TX,
Expand Down
46 changes: 46 additions & 0 deletions ui/app/components/transaction-list-item-icon.js
Original file line number Diff line number Diff line change
@@ -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',
}
})
}
}
117 changes: 60 additions & 57 deletions ui/app/components/transaction-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -18,20 +19,36 @@ function TransactionListItem() {
}

TransactionListItem.prototype.render = function() {
const { transaction, i } = this.props
const { transaction, i, network } = this.props

var date = formatDate(transaction.time)

let isLinkable = false
const numericNet = parseInt(network)
isLinkable = numericNet === 1 || numericNet === 2

var isMsg = ('msgParams' in transaction)
var isTx = ('txParams' in transaction)
var isPending = transaction.status === 'unconfirmed'

let txParams
if (isTx) {
txParams = transaction.txParams
} else if (isMsg) {
txParams = transaction.msgParams
}

var txParams = transaction.txParams
const isClickable = ('hash' in transaction && isLinkable) || 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 (!transaction.hash) return
if (isPending) {
this.props.showTx(transaction.id)
}

if (!transaction.hash || !isLinkable) return
var url = explorerLink(transaction.hash, parseInt(network))
chrome.tabs.create({ url })
},
Expand All @@ -42,85 +59,71 @@ 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() {
const { transaction, i } = this.props
const { transaction, i, network } = this.props
return h('div', 'wowie, thats a message')
}

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)')
}
}
8 changes: 6 additions & 2 deletions ui/app/components/transaction-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ 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)

return (

Expand Down Expand Up @@ -51,7 +52,10 @@ TransactionList.prototype.render = function() {
transactions.length ?
transactions.map((transaction, i) => {
return h(TransactionListItem, {
transaction, i
transaction, i, network,
showTx:(txId) => {
this.props.viewPendingTx(txId)
},
})
})
:
Expand Down
2 changes: 2 additions & 0 deletions ui/app/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
19 changes: 19 additions & 0 deletions ui/app/css/lib.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -180,3 +194,8 @@ hr.horizontal-line {
justify-content: center;
padding: 4px;
}

.ether-balance {
display: flex;
align-items: center;
}
28 changes: 26 additions & 2 deletions ui/app/reducers/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
}

0 comments on commit f1fb7ff

Please sign in to comment.