Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pending txs to tx list #224

Merged
merged 9 commits into from
May 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}