mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
Began reworking tx conf view
This commit is contained in:
parent
2c89cd722e
commit
7058dc4ee3
74
app/images/forward-carrat.svg
Normal file
74
app/images/forward-carrat.svg
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="4.2333331mm"
|
||||
height="12.800793mm"
|
||||
viewBox="0 0 14.999999 45.357139"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="forward-carrat.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="17.87049"
|
||||
inkscape:cy="17.678567"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
showguides="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1276"
|
||||
inkscape:window-height="755"
|
||||
inkscape:window-x="4"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136"
|
||||
originx="-180"
|
||||
originy="-602.14286" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-180,-404.8622)">
|
||||
<path
|
||||
style="fill:#f7861c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 180,404.8622 0,7.5 10,15 -10,15 0,7.85714 15,-22.85714 z"
|
||||
id="path4138"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
File diff suppressed because one or more lines are too long
1
development/states/confirm_tx.json
Normal file
1
development/states/confirm_tx.json
Normal file
File diff suppressed because one or more lines are too long
84
development/states/empty-account-detail.json
Normal file
84
development/states/empty-account-detail.json
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"metamask": {
|
||||
"isInitialized": true,
|
||||
"isUnlocked": true,
|
||||
"currentDomain": "example.com",
|
||||
"rpcTarget": "https://rawtestrpc.metamask.io/",
|
||||
"identities": {
|
||||
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
|
||||
"name": "Wallet 1",
|
||||
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"mayBeFauceting": false
|
||||
},
|
||||
"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": {
|
||||
"name": "Wallet 2",
|
||||
"address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b",
|
||||
"mayBeFauceting": false
|
||||
},
|
||||
"0xeb9e64b93097bc15f01f13eae97015c57ab64823": {
|
||||
"name": "Wallet 3",
|
||||
"address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823",
|
||||
"mayBeFauceting": false
|
||||
},
|
||||
"0x704107d04affddd9b66ab9de3dd7b095852e9b69": {
|
||||
"name": "Wallet 4",
|
||||
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69",
|
||||
"mayBeFauceting": false
|
||||
}
|
||||
},
|
||||
"unconfTxs": {},
|
||||
"accounts": {
|
||||
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
|
||||
"code": "0x",
|
||||
"balance": "0x01",
|
||||
"nonce": "0x0",
|
||||
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
|
||||
},
|
||||
"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": {
|
||||
"code": "0x",
|
||||
"nonce": "0x0",
|
||||
"balance": "0x01",
|
||||
"address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"
|
||||
},
|
||||
"0xeb9e64b93097bc15f01f13eae97015c57ab64823": {
|
||||
"code": "0x",
|
||||
"nonce": "0x0",
|
||||
"balance": "0x01",
|
||||
"address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823"
|
||||
},
|
||||
"0x704107d04affddd9b66ab9de3dd7b095852e9b69": {
|
||||
"code": "0x",
|
||||
"balance": "0x0",
|
||||
"nonce": "0x0",
|
||||
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69"
|
||||
}
|
||||
},
|
||||
"transactions": [],
|
||||
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
|
||||
"network": "2",
|
||||
"seedWords": null,
|
||||
"isConfirmed": true,
|
||||
"unconfMsgs": {},
|
||||
"messages": [],
|
||||
"provider": {
|
||||
"type": "testnet"
|
||||
},
|
||||
"selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
|
||||
},
|
||||
"appState": {
|
||||
"menuOpen": false,
|
||||
"currentView": {
|
||||
"name": "accountDetail",
|
||||
"detailView": null,
|
||||
"context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
|
||||
},
|
||||
"accountDetail": {
|
||||
"subview": "transactions"
|
||||
},
|
||||
"currentDomain": "127.0.0.1:9966",
|
||||
"transForward": true,
|
||||
"isLoading": false,
|
||||
"warning": null
|
||||
},
|
||||
"identities": {}
|
||||
}
|
1
development/states/pending_crash.json
Normal file
1
development/states/pending_crash.json
Normal file
File diff suppressed because one or more lines are too long
@ -52,6 +52,12 @@ describe('util', function() {
|
||||
var result = util.addressSummary(address)
|
||||
assert.equal(result, '0xFDEa65C8...b825')
|
||||
})
|
||||
|
||||
it('should accept arguments for firstseg, lastseg, and keepPrefix', function() {
|
||||
var address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825'
|
||||
var result = util.addressSummary(address, 4, 4, false)
|
||||
assert.equal(result, 'FDEa...b825')
|
||||
})
|
||||
})
|
||||
|
||||
describe('isValidAddress', function() {
|
||||
|
17
ui-dev.js
17
ui-dev.js
@ -1,3 +1,20 @@
|
||||
/* UI DEV
|
||||
*
|
||||
* This is a utility module.
|
||||
* It initializes a minimalist browserifiable project
|
||||
* that contains the Metamask UI, with a mocked state.
|
||||
*
|
||||
* Includes a state menu for switching between different
|
||||
* mocked states, along with query param support,
|
||||
* so those states are preserved when live-reloading.
|
||||
*
|
||||
* This is a convenient way to develop on the UI
|
||||
* without having to re-enter your password
|
||||
* every time the plugin rebuilds.
|
||||
*
|
||||
* To use, run `npm run ui`.
|
||||
*/
|
||||
|
||||
const render = require('react-dom').render
|
||||
const h = require('react-hyperscript')
|
||||
const Root = require('./ui/app/root')
|
||||
|
@ -22,7 +22,7 @@ AccountPanel.prototype.render = function () {
|
||||
var panelState = {
|
||||
key: `accountPanel${identity.address}`,
|
||||
identiconKey: identity.address,
|
||||
identiconLabel: identity.name,
|
||||
identiconLabel: identity.name || '',
|
||||
attributes: [
|
||||
{
|
||||
key: 'ADDRESS',
|
||||
|
105
ui/app/components/mini-account-panel.js
Normal file
105
ui/app/components/mini-account-panel.js
Normal file
@ -0,0 +1,105 @@
|
||||
const inherits = require('util').inherits
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const Identicon = require('./identicon')
|
||||
const formatBalance = require('../util').formatBalance
|
||||
const TransactionIcon = require('./transaction-list-item-icon')
|
||||
|
||||
module.exports = AccountPanel
|
||||
|
||||
|
||||
inherits(AccountPanel, Component)
|
||||
function AccountPanel () {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
AccountPanel.prototype.render = function () {
|
||||
var props = this.props
|
||||
var picOrder = props.picOrder || 'left'
|
||||
var isFauceting = props.isFauceting
|
||||
const { attrs, imageSeed } = props
|
||||
|
||||
return (
|
||||
|
||||
h('.identity-panel.flex-row.flex-left', {
|
||||
style: {
|
||||
cursor: props.onClick ? 'pointer' : undefined,
|
||||
},
|
||||
onClick: props.onClick,
|
||||
}, [
|
||||
|
||||
this.genIcon(imageSeed, picOrder),
|
||||
|
||||
h('div.flex-column.flex-justify-center', {
|
||||
style: {
|
||||
lineHeight: '15px',
|
||||
order: 2,
|
||||
display: 'flex',
|
||||
alignItems: picOrder === 'left' ? 'flex-begin' : 'flex-end',
|
||||
},
|
||||
}, [
|
||||
|
||||
props.attrs.map((attr) => {
|
||||
return h('span.font-small', {
|
||||
key: `mini-${attr}`,
|
||||
style: {
|
||||
fontFamily: 'Montserrat UltraLight, Montserrat Light, Montserrat',
|
||||
},
|
||||
}, attr)
|
||||
}),
|
||||
|
||||
]),
|
||||
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
AccountPanel.prototype.genIcon= function(seed, picOrder) {
|
||||
const props = this.props
|
||||
|
||||
// When there is no seed value, this is a contract creation.
|
||||
// We then show the contract icon.
|
||||
if (!seed) {
|
||||
return h('.identicon-wrapper.flex-column.select-none', {
|
||||
style: {
|
||||
order: picOrder === 'left' ? 1 : 3,
|
||||
},
|
||||
}, [
|
||||
h('i.fa.fa-file-text-o.fa-lg', {
|
||||
style: {
|
||||
fontSize: '42px',
|
||||
transform: 'translate(0px, -16px)',
|
||||
},
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
// If there was a seed, we return an identicon for that address.
|
||||
return h('.identicon-wrapper.flex-column.select-none', {
|
||||
style: {
|
||||
order: picOrder === 'left' ? 1 : 3,
|
||||
},
|
||||
}, [
|
||||
h(Identicon, {
|
||||
address: seed,
|
||||
imageify: props.imageifyIdenticons,
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
function balanceOrFaucetingIndication (account, isFauceting) {
|
||||
// Temporarily deactivating isFauceting indication
|
||||
// because it shows fauceting for empty restored accounts.
|
||||
if (/* isFauceting*/ false) {
|
||||
return {
|
||||
key: 'Account is auto-funding.',
|
||||
value: 'Please wait.',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
key: 'BALANCE',
|
||||
value: formatBalance(account.balance),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const inherits = require('util').inherits
|
||||
|
||||
const AccountPanel = require('./account-panel')
|
||||
const MiniAccountPanel = require('./mini-account-panel')
|
||||
const addressSummary = require('../util').addressSummary
|
||||
const readableDate = require('../util').readableDate
|
||||
const formatBalance = require('../util').formatBalance
|
||||
const nameForAddress = require('../../lib/contract-namer')
|
||||
|
||||
module.exports = PendingTxDetails
|
||||
|
||||
@ -14,12 +15,10 @@ function PendingTxDetails () {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
PendingTxDetails.prototype.render = function () {
|
||||
var state = this.props
|
||||
return this.renderGeneric(h, state)
|
||||
}
|
||||
const PTXP = PendingTxDetails.prototype
|
||||
|
||||
PendingTxDetails.prototype.renderGeneric = function (h, state) {
|
||||
PTXP.render = function () {
|
||||
var state = this.props
|
||||
var txData = state.txData
|
||||
|
||||
var txParams = txData.txParams || {}
|
||||
@ -27,18 +26,40 @@ PendingTxDetails.prototype.renderGeneric = function (h, state) {
|
||||
var identity = state.identities[address] || { address: address }
|
||||
var account = state.accounts[address] || { address: address }
|
||||
|
||||
return (
|
||||
var isContractDeploy = !('to' in txParams)
|
||||
|
||||
return (
|
||||
h('div', [
|
||||
|
||||
// account that will sign
|
||||
h(AccountPanel, {
|
||||
showFullAddress: true,
|
||||
identity: identity,
|
||||
account: account,
|
||||
h('.flex-row.flex-center', {
|
||||
style: {
|
||||
maxWidth: '100%',
|
||||
},
|
||||
}, [
|
||||
|
||||
h(MiniAccountPanel, {
|
||||
attrs: [
|
||||
identity.name,
|
||||
addressSummary(address, 6, 4, false),
|
||||
formatBalance(identity.balance),
|
||||
],
|
||||
imageSeed: address,
|
||||
imageifyIdenticons: state.imageifyIdenticons,
|
||||
picOrder: 'right',
|
||||
}),
|
||||
|
||||
h('img', {
|
||||
src: 'images/forward-carrat.svg',
|
||||
style: {
|
||||
padding: '5px 6px 0px 10px',
|
||||
height: '48px',
|
||||
},
|
||||
}),
|
||||
|
||||
this.miniAccountPanelForRecipient(),
|
||||
|
||||
]),
|
||||
|
||||
// tx data
|
||||
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
|
||||
|
||||
@ -59,7 +80,39 @@ PendingTxDetails.prototype.renderGeneric = function (h, state) {
|
||||
]),
|
||||
|
||||
])
|
||||
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
PTXP.miniAccountPanelForRecipient = function() {
|
||||
var state = this.props
|
||||
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 }
|
||||
|
||||
var isContractDeploy = !('to' in txParams)
|
||||
|
||||
// If it's not a contract deploy, send to the account
|
||||
if (!isContractDeploy) {
|
||||
return h(MiniAccountPanel, {
|
||||
attrs: [
|
||||
nameForAddress(txParams.to),
|
||||
addressSummary(txParams.to, 6, 4, false),
|
||||
],
|
||||
imageSeed: address,
|
||||
imageifyIdenticons: state.imageifyIdenticons,
|
||||
picOrder: 'left',
|
||||
})
|
||||
} else {
|
||||
return h(MiniAccountPanel, {
|
||||
attrs: [
|
||||
'New Contract'
|
||||
],
|
||||
imageifyIdenticons: state.imageifyIdenticons,
|
||||
picOrder: 'left',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,3 +220,9 @@ hr.horizontal-line {
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.one-line-concat {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ function rootReducer (state, action) {
|
||||
|
||||
state.appState = reduceApp(state, action)
|
||||
|
||||
console.log(JSON.stringify(state))
|
||||
return state
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ for (var currency in valueTable) {
|
||||
module.exports = {
|
||||
valuesFor: valuesFor,
|
||||
addressSummary: addressSummary,
|
||||
miniAddressSummary: miniAddressSummary,
|
||||
isAllOneCase: isAllOneCase,
|
||||
isValidAddress: isValidAddress,
|
||||
numericBalance: numericBalance,
|
||||
@ -43,10 +44,19 @@ function valuesFor (obj) {
|
||||
.map(function (key) { return obj[key] })
|
||||
}
|
||||
|
||||
function addressSummary (address) {
|
||||
function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includeHex = true) {
|
||||
if (!address) return ''
|
||||
let checked = ethUtil.toChecksumAddress(address)
|
||||
if (!includeHex) {
|
||||
checked = ethUtil.stripHexPrefix(checked)
|
||||
}
|
||||
return checked ? checked.slice(0, firstSegLength) + '...' + checked.slice(checked.length - lastSegLength) : '...'
|
||||
}
|
||||
|
||||
function miniAddressSummary (address) {
|
||||
if (!address) return ''
|
||||
var checked = ethUtil.toChecksumAddress(address)
|
||||
return checked ? checked.slice(0, 2 + 8) + '...' + checked.slice(-4) : '...'
|
||||
return checked ? checked.slice(0, 4) + '...' + checked.slice(-4) : '...'
|
||||
}
|
||||
|
||||
function isValidAddress (address) {
|
||||
|
17
ui/lib/contract-namer.js
Normal file
17
ui/lib/contract-namer.js
Normal file
@ -0,0 +1,17 @@
|
||||
/* CONTRACT NAMER
|
||||
*
|
||||
* Takes an address,
|
||||
* Returns a nicname if we have one stored,
|
||||
* otherwise returns null.
|
||||
*/
|
||||
|
||||
const nicknames = {}
|
||||
|
||||
module.exports = function(address) {
|
||||
|
||||
if (address in nicknames) {
|
||||
return nicknames[address]
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
Loading…
Reference in New Issue
Block a user