Initial new UI source code import (#2607)
* address -> name mappings * expanding, loading all coin details * send use only actual BasicCoin tokens registered (any reg) * sending token & accounts * form styling updates * send form layout in place * coin send working as expected * api subscriptions on multiple addresses * bring in events * simplify * basic events display in-place, functionally complete * basic functionality in-place * fix horrible event address issue * rwork display of events slightly * test TLA availability * table for owner -> tokens * fix signature lookup address * fix signature lookup address * basic overview styling * txhash links * page layout adjustments * background import * adjust colors * no global registration, simplify color selection * updated styling * connection dialog for "busy connecting" * initial token connection - WIP * init token updates take place * basic test for manual token * rework connection display * allow updates of the secure token * first stab at making the build build * update runner tags * fix linting issues * skip tests requiring network (should be e2e, TODO) * re-enable javascript tag/runner * release push does the trick * push to any branch, CI name * javscript-test runner as well * swap dependencies build requires test * revert stages swap * retrieve images associated with tokens * remove js build deps order * null image when hash = 0x0 * 6x64 images (hashes for registries) * don't pass tokens as prop to IdentityIcon * check images against content hash pictures * cleanup signer after connection changes * fix naming typo * display unknownImages for balances (not available as content hash) * unknownImage for transfer dialog * basic githubhint layout * single input for commit/filename * ethcore_hashContent call * lookup hash * registration in place * fixes * events is using a proper table * pass value through as-is * stop wrongly using main app IdentityIcon * NEVER export class instance functions * alignment back to normal * typo in definition * set & get images working (mostly) * show content retrieval info * set exitcode via || * use javascript:latest images * disable npm progress bar * rename phase I * rename phase II * only send build output to GitHub on major branches * also run the build step as part of the test (until comprehensive) * ci-specific build (no webpack progress) * allow for account creation via recovery phrase * display account uuid (where available), closes #2546 * connection dialog now shows up in dapps as well, closes #2538 * token images show up as expected * IdentityName component added and deployed * fix padding tests * adjust tests to map to stricter 0x-prefixed hex * render names via common component for the address -> name * split lint into seperate script (early exit) * test phases changed to lint, test & pack * pack part of test phase * remove files marked for deletion (cleanup) * Signer cleanups, start moving in the direction of the rest * add personal signer methods * basic signer request subscription * don't poll blockNumber when not connected * missing return, creating massive ws queue backlogs * ΞTH -> ETH * fix failing tests * registry uses setAddress to actually set addresses now * bytes mapping operates on lowerCase hex strings * sha3 ids for each application * add dappreg to list of contracts * adjust alignment of queries * show gas estimation log * abi with payable for register function * add key as required * image retrieval from dappreg * use proper Image urls * embed and link apps from Parity, retrieved via /api/apps * filter apps that has been replaced * proxy entry for parity-utils * add basiccoin abi * add support for fallback abi type * capture constructor paramaters * merge master into js * move images to assets/images/ * add font assets * import fonts as part of build * don't inline woff files * Revert "merge master into js" This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe. * remove unused npm packages * information on gas estimates (like almost everywhere else) * don't pass gas & gasPrice to estimation * display account passwordhint when available * signer subscriptions based on polling & function trapping * pending requests retrieved via jsapi * update signer middleware * remove all web3 instances * remove web3 package * last web3 dependencies removed * no need to toChecksumAddress - api takes care of it * expand description for personal_confirmRequest * Signer conversion from web3 -> parity.js completed * explicit in no return * green circle background * remove generated background * convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary) * change dapps to load from localhost:8080/ui/* * remove dangling web3 files * update manager test for signer * /api/ping -> / * additional token images * additional token images * add missing styles.css for 8180 error pages * cater for txhash returning null/empty object * adjust output directories * Release merge with origin with ours strategy * additional token images * cater for development server * s/localhost/127.0.0.1/ (cater for origin) * Fix address selection for contract deployment * Adjust z-index for error overlay * better text on unique background pattern * fix signer rejections * Don't allow gavcoin transfer with no balance * fix txhash rendering in signer * remove unnecessary ParityBackground * script to update js-precompiled * Redirect from :8080 to :8180 * Remove extra return * Dapp logo images
This commit is contained in:
43
js/src/views/Account/Header/header.css
Normal file
43
js/src/views/Account/Header/header.css
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.balances {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.editicon {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.floatleft {
|
||||
float: left;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.addressline,
|
||||
.infoline,
|
||||
.uuidline {
|
||||
line-height: 1.618em;
|
||||
}
|
||||
|
||||
.infoline,
|
||||
.uuidline {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.uuidline {
|
||||
display: inline-block;
|
||||
}
|
||||
121
js/src/views/Account/Header/header.js
Normal file
121
js/src/views/Account/Header/header.js
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName } from '../../../ui';
|
||||
|
||||
import styles from './header.css';
|
||||
|
||||
export default class Header extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
account: PropTypes.object,
|
||||
balance: PropTypes.object,
|
||||
isTest: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
name: null
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this.setName();
|
||||
}
|
||||
|
||||
componentWillReceiveProps () {
|
||||
this.setName();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { account, balance } = this.props;
|
||||
const { address, meta, uuid } = account;
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const uuidText = !uuid
|
||||
? null
|
||||
: <div className={ styles.uuidline }>uuid: { uuid }</div>;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<IdentityIcon
|
||||
address={ address } />
|
||||
<div className={ styles.floatleft }>
|
||||
<ContainerTitle title={ <IdentityName address={ address } unknown /> } />
|
||||
<div className={ styles.addressline }>
|
||||
{ address }
|
||||
</div>
|
||||
{ uuidText }
|
||||
<div className={ styles.infoline }>
|
||||
{ meta.description }
|
||||
</div>
|
||||
{ this.renderTxCount() }
|
||||
</div>
|
||||
<div className={ styles.balances }>
|
||||
<Balance
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderTxCount () {
|
||||
const { isTest, balance } = this.props;
|
||||
|
||||
if (!balance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const txCount = balance.txCount.sub(isTest ? 0x100000 : 0);
|
||||
|
||||
return (
|
||||
<div className={ styles.infoline }>
|
||||
{ txCount.toFormat() } outgoing transactions
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onSubmitName = (name) => {
|
||||
const { api } = this.context;
|
||||
const { account } = this.props;
|
||||
|
||||
this.setState({ name }, () => {
|
||||
api.personal
|
||||
.setAccountName(account.address, name)
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setName () {
|
||||
const { account } = this.props;
|
||||
|
||||
if (account && account.name !== this.propName) {
|
||||
this.propName = account.name;
|
||||
this.setState({
|
||||
name: account.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
17
js/src/views/Account/Header/index.js
Normal file
17
js/src/views/Account/Header/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './header';
|
||||
17
js/src/views/Account/Transactions/Transaction/index.js
Normal file
17
js/src/views/Account/Transactions/Transaction/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transaction';
|
||||
193
js/src/views/Account/Transactions/Transaction/transaction.js
Normal file
193
js/src/views/Account/Transactions/Transaction/transaction.js
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { IdentityIcon, IdentityName, MethodDecoding } from '../../../../ui';
|
||||
|
||||
import styles from '../transactions.css';
|
||||
|
||||
export default class Transaction extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
transaction: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
isTest: PropTypes.bool.isRequired
|
||||
}
|
||||
|
||||
state = {
|
||||
info: null,
|
||||
isContract: false,
|
||||
isReceived: false
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { address, transaction } = this.props;
|
||||
|
||||
this.lookup(address, transaction);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { transaction, isTest } = this.props;
|
||||
const { block } = this.state;
|
||||
|
||||
const prefix = `https://${isTest ? 'testnet.' : ''}etherscan.io/`;
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className={ styles.timestamp }>
|
||||
<div>{ this.formatBlockTimestamp(block) }</div>
|
||||
<div>{ this.formatNumber(transaction.blockNumber) }</div>
|
||||
</td>
|
||||
{ this.renderAddress(prefix, transaction.from) }
|
||||
{ this.renderTransaction() }
|
||||
{ this.renderAddress(prefix, transaction.to) }
|
||||
<td className={ styles.method }>
|
||||
{ this.renderMethod() }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
renderMethod () {
|
||||
const { address } = this.props;
|
||||
const { info } = this.state;
|
||||
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<MethodDecoding
|
||||
historic
|
||||
address={ address }
|
||||
transaction={ info } />
|
||||
);
|
||||
}
|
||||
|
||||
renderTransaction () {
|
||||
const { transaction, isTest } = this.props;
|
||||
|
||||
const prefix = `https://${isTest ? 'testnet.' : ''}etherscan.io/`;
|
||||
const hashLink = `${prefix}tx/${transaction.hash}`;
|
||||
|
||||
return (
|
||||
<td className={ styles.transaction }>
|
||||
{ this.renderEtherValue() }
|
||||
<div>⇒</div>
|
||||
<div>
|
||||
<a href={ hashLink } target='_blank' className={ styles.link }>
|
||||
{ this.formatHash(transaction.hash) }
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
renderAddress (prefix, address) {
|
||||
const eslink = address ? (
|
||||
<a
|
||||
href={ `${prefix}address/${address}` }
|
||||
target='_blank'
|
||||
className={ styles.link }>
|
||||
<IdentityName address={ address } shorten />
|
||||
</a>
|
||||
) : 'DEPLOY';
|
||||
|
||||
return (
|
||||
<td className={ styles.address }>
|
||||
<div className={ styles.center }>
|
||||
<IdentityIcon
|
||||
center
|
||||
className={ styles.icon }
|
||||
address={ address } />
|
||||
</div>
|
||||
<div className={ styles.center }>
|
||||
{ eslink }
|
||||
</div>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
renderEtherValue () {
|
||||
const { api } = this.context;
|
||||
const { info } = this.state;
|
||||
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = api.util.fromWei(info.value);
|
||||
|
||||
if (value.eq(0)) {
|
||||
return <div className={ styles.value }>{ ' ' }</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.value }>
|
||||
{ value.toFormat(5) }<small>ETH</small>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
formatHash (hash) {
|
||||
if (!hash || hash.length <= 16) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
return `${hash.substr(2, 6)}...${hash.slice(-6)}`;
|
||||
}
|
||||
|
||||
formatNumber (number) {
|
||||
return new BigNumber(number).toFormat();
|
||||
}
|
||||
|
||||
formatBlockTimestamp (block) {
|
||||
if (!block) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return moment(block.timestamp).fromNow();
|
||||
}
|
||||
|
||||
lookup (address, transaction) {
|
||||
const { api } = this.context;
|
||||
const { info } = this.state;
|
||||
|
||||
if (info) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ isReceived: address === transaction.to });
|
||||
|
||||
Promise
|
||||
.all([
|
||||
api.eth.getBlockByNumber(transaction.blockNumber),
|
||||
api.eth.getTransactionByHash(transaction.hash)
|
||||
])
|
||||
.then(([block, info]) => {
|
||||
this.setState({ block, info });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('lookup', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Account/Transactions/index.js
Normal file
17
js/src/views/Account/Transactions/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactions';
|
||||
101
js/src/views/Account/Transactions/transactions.css
Normal file
101
js/src/views/Account/Transactions/transactions.css
Normal file
@@ -0,0 +1,101 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.transactions {
|
||||
}
|
||||
|
||||
.transactions table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.transactions tr {
|
||||
line-height: 32px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.transactions tr:nth-child(even) {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.transactions th {
|
||||
color: #aaa;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.transactions td {
|
||||
vertical-align: top;
|
||||
padding: 0.75em 0.75em;
|
||||
}
|
||||
|
||||
.transactions .link {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.infonone {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.etherscan {
|
||||
text-align: right;
|
||||
padding-top: 1em;
|
||||
font-size: 0.75em;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.address {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.transaction {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.transactions td.transaction {
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
.transaction div {
|
||||
line-height: 1.25em;
|
||||
min-height: 1.25em;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.method {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.transactions td.timestamp {
|
||||
padding-top: 1.5em;
|
||||
text-align: right;
|
||||
line-height: 1.5em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
148
js/src/views/Account/Transactions/transactions.js
Normal file
148
js/src/views/Account/Transactions/transactions.js
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import LinearProgress from 'material-ui/LinearProgress';
|
||||
|
||||
import etherscan from '../../../3rdparty/etherscan';
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
|
||||
import Transaction from './Transaction';
|
||||
|
||||
import styles from './transactions.css';
|
||||
|
||||
class Transactions extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
address: PropTypes.string.isRequired,
|
||||
accounts: PropTypes.object,
|
||||
contacts: PropTypes.object,
|
||||
contracts: PropTypes.object,
|
||||
tokens: PropTypes.object,
|
||||
isTest: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
transactions: [],
|
||||
loading: true,
|
||||
callInfo: {}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.getTransactions();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='transactions' />
|
||||
{ this.renderTransactions() }
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderTransactions () {
|
||||
const { loading, transactions } = this.state;
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<LinearProgress mode='indeterminate' />
|
||||
);
|
||||
} else if (!transactions.length) {
|
||||
return (
|
||||
<div className={ styles.infonone }>
|
||||
No transactions were found for this account
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.transactions }>
|
||||
<table>
|
||||
<tbody>
|
||||
{ this.renderRows() }
|
||||
</tbody>
|
||||
</table>
|
||||
<div className={ styles.etherscan }>
|
||||
Transaction list powered by <a href='https://etherscan.io/' target='_blank'>etherscan.io</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderRows () {
|
||||
const { address, accounts, contacts, contracts, tokens, isTest } = this.props;
|
||||
const { transactions } = this.state;
|
||||
|
||||
return (transactions || []).map((transaction, index) => {
|
||||
return (
|
||||
<Transaction
|
||||
key={ index }
|
||||
transaction={ transaction }
|
||||
address={ address }
|
||||
accounts={ accounts }
|
||||
contacts={ contacts }
|
||||
contracts={ contracts }
|
||||
tokens={ tokens }
|
||||
isTest={ isTest } />
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getTransactions = () => {
|
||||
const { isTest, address } = this.props;
|
||||
|
||||
return etherscan.account
|
||||
.transactions(address, 0, isTest)
|
||||
.then((transactions) => {
|
||||
this.setState({
|
||||
transactions,
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('getTransactions', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { isTest } = state.nodeStatus;
|
||||
const { accounts, contacts, contracts } = state.personal;
|
||||
const { tokens } = state.balances;
|
||||
|
||||
return {
|
||||
isTest,
|
||||
accounts,
|
||||
contacts,
|
||||
contracts,
|
||||
tokens
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Transactions);
|
||||
23
js/src/views/Account/account.css
Normal file
23
js/src/views/Account/account.css
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.account {
|
||||
}
|
||||
|
||||
.btnicon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
207
js/src/views/Account/account.js
Normal file
207
js/src/views/Account/account.js
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentCreate from 'material-ui/svg-icons/content/create';
|
||||
import ContentSend from 'material-ui/svg-icons/content/send';
|
||||
|
||||
import { EditMeta, Shapeshift, Transfer } from '../../modals';
|
||||
import { Actionbar, Button, Page } from '../../ui';
|
||||
|
||||
import shapeshiftBtn from '../../../assets/images/shapeshift-btn.png';
|
||||
|
||||
import Header from './Header';
|
||||
import Transactions from './Transactions';
|
||||
|
||||
import styles from './account.css';
|
||||
|
||||
class Account extends Component {
|
||||
static propTypes = {
|
||||
params: PropTypes.object,
|
||||
accounts: PropTypes.object,
|
||||
balances: PropTypes.object,
|
||||
images: PropTypes.object.isRequired,
|
||||
isTest: PropTypes.bool
|
||||
}
|
||||
|
||||
propName = null
|
||||
|
||||
state = {
|
||||
showEditDialog: false,
|
||||
showFundDialog: false,
|
||||
showTransferDialog: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { accounts, balances, isTest } = this.props;
|
||||
const { address } = this.props.params;
|
||||
|
||||
const account = (accounts || {})[address];
|
||||
const balance = (balances || {})[address];
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.account }>
|
||||
{ this.renderEditDialog(account) }
|
||||
{ this.renderFundDialog() }
|
||||
{ this.renderTransferDialog() }
|
||||
{ this.renderActionbar() }
|
||||
<Page>
|
||||
<Header
|
||||
isTest={ isTest }
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
<Transactions
|
||||
accounts={ accounts }
|
||||
address={ address } />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar () {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='transferFunds'
|
||||
icon={ <ContentSend /> }
|
||||
label='transfer'
|
||||
onClick={ this.onTransferClick } />,
|
||||
<Button
|
||||
key='shapeshift'
|
||||
icon={ <img src={ shapeshiftBtn } className={ styles.btnicon } /> }
|
||||
label='shapeshift'
|
||||
onClick={ this.onShapeshiftAccountClick } />,
|
||||
<Button
|
||||
key='editmeta'
|
||||
icon={ <ContentCreate /> }
|
||||
label='edit'
|
||||
onClick={ this.onEditClick } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
title='Account Management'
|
||||
buttons={ buttons } />
|
||||
);
|
||||
}
|
||||
|
||||
renderEditDialog (account) {
|
||||
const { showEditDialog } = this.state;
|
||||
|
||||
if (!showEditDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EditMeta
|
||||
account={ account }
|
||||
keys={ ['description', 'passwordHint'] }
|
||||
onClose={ this.onEditClick } />
|
||||
);
|
||||
}
|
||||
|
||||
renderFundDialog () {
|
||||
const { showFundDialog } = this.state;
|
||||
|
||||
if (!showFundDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { address } = this.props.params;
|
||||
|
||||
return (
|
||||
<Shapeshift
|
||||
address={ address }
|
||||
onClose={ this.onShapeshiftAccountClose } />
|
||||
);
|
||||
}
|
||||
|
||||
renderTransferDialog () {
|
||||
const { showTransferDialog } = this.state;
|
||||
|
||||
if (!showTransferDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { address } = this.props.params;
|
||||
const { accounts, balances, images } = this.props;
|
||||
const account = accounts[address];
|
||||
const balance = balances[address];
|
||||
|
||||
return (
|
||||
<Transfer
|
||||
account={ account }
|
||||
balance={ balance }
|
||||
balances={ balances }
|
||||
images={ images }
|
||||
onClose={ this.onTransferClose } />
|
||||
);
|
||||
}
|
||||
|
||||
onEditClick = () => {
|
||||
this.setState({
|
||||
showEditDialog: !this.state.showEditDialog
|
||||
});
|
||||
}
|
||||
|
||||
onShapeshiftAccountClick = () => {
|
||||
this.setState({
|
||||
showFundDialog: !this.state.showFundDialog
|
||||
});
|
||||
}
|
||||
|
||||
onShapeshiftAccountClose = () => {
|
||||
this.onShapeshiftAccountClick();
|
||||
}
|
||||
|
||||
onTransferClick = () => {
|
||||
this.setState({
|
||||
showTransferDialog: !this.state.showTransferDialog
|
||||
});
|
||||
}
|
||||
|
||||
onTransferClose = () => {
|
||||
this.onTransferClick();
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
const { balances } = state.balances;
|
||||
const { images } = state;
|
||||
const { isTest } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
isTest,
|
||||
accounts,
|
||||
balances,
|
||||
images
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Account);
|
||||
17
js/src/views/Account/index.js
Normal file
17
js/src/views/Account/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './account';
|
||||
17
js/src/views/Accounts/List/index.js
Normal file
17
js/src/views/Accounts/List/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './list';
|
||||
45
js/src/views/Accounts/List/list.css
Normal file
45
js/src/views/Accounts/List/list.css
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 0 1 50%;
|
||||
width: 50%;
|
||||
position: relative;
|
||||
padding-bottom: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.item:nth-child(odd) {
|
||||
padding-right: 0.125em;
|
||||
}
|
||||
|
||||
.item:nth-child(even) {
|
||||
padding-left: 0.125em;
|
||||
}
|
||||
|
||||
.empty {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.empty div {
|
||||
color: #aaa;
|
||||
}
|
||||
69
js/src/views/Accounts/List/list.js
Normal file
69
js/src/views/Accounts/List/list.js
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Container } from '../../../ui';
|
||||
|
||||
import Summary from '../Summary';
|
||||
import styles from './list.css';
|
||||
|
||||
export default class List extends Component {
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object,
|
||||
balances: PropTypes.object,
|
||||
link: PropTypes.string,
|
||||
empty: PropTypes.bool
|
||||
};
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className={ styles.list }>
|
||||
{ this.renderAccounts() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderAccounts () {
|
||||
const { accounts, balances, link, empty } = this.props;
|
||||
|
||||
if (empty) {
|
||||
return (
|
||||
<Container className={ styles.empty }>
|
||||
<div>
|
||||
There are currently no accounts or addresses to display.
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
return Object.keys(accounts).map((address, idx) => {
|
||||
const account = accounts[address] || {};
|
||||
const balance = balances[address] || {};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={ styles.item }
|
||||
key={ address }>
|
||||
<Summary
|
||||
link={ link }
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Accounts/Summary/index.js
Normal file
17
js/src/views/Accounts/Summary/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './summary';
|
||||
60
js/src/views/Accounts/Summary/summary.js
Normal file
60
js/src/views/Accounts/Summary/summary.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName } from '../../../ui';
|
||||
|
||||
export default class Summary extends Component {
|
||||
static contextTypes = {
|
||||
api: React.PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
account: PropTypes.object.isRequired,
|
||||
balance: PropTypes.object.isRequired,
|
||||
link: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
state = {
|
||||
name: 'Unnamed'
|
||||
}
|
||||
|
||||
render () {
|
||||
const { account, balance, children, link } = this.props;
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const viewLink = `/${link || 'account'}/${account.address}`;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<IdentityIcon
|
||||
address={ account.address } />
|
||||
<ContainerTitle
|
||||
title={ <Link to={ viewLink }>{ <IdentityName address={ account.address } unknown /> }</Link> }
|
||||
byline={ account.address } />
|
||||
<Balance
|
||||
balance={ balance } />
|
||||
{ children }
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
32
js/src/views/Accounts/accounts.css
Normal file
32
js/src/views/Accounts/accounts.css
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.accounts {
|
||||
}
|
||||
|
||||
.accountTooltip {
|
||||
top: 13.3em;
|
||||
left: 7em;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toolbarTooltip {
|
||||
right: 1em;
|
||||
top: 4em;
|
||||
}
|
||||
134
js/src/views/Accounts/accounts.js
Normal file
134
js/src/views/Accounts/accounts.js
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
|
||||
import List from './List';
|
||||
import { CreateAccount } from '../../modals';
|
||||
import { Actionbar, Button, Page, Tooltip } from '../../ui';
|
||||
|
||||
import styles from './accounts.css';
|
||||
|
||||
class Accounts extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object,
|
||||
hasAccounts: PropTypes.bool,
|
||||
balances: PropTypes.object
|
||||
}
|
||||
|
||||
state = {
|
||||
addressBook: false,
|
||||
newDialog: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { accounts, hasAccounts, balances } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.accounts }>
|
||||
{ this.renderNewDialog() }
|
||||
{ this.renderActionbar() }
|
||||
<Page>
|
||||
<List
|
||||
accounts={ accounts }
|
||||
balances={ balances }
|
||||
empty={ !hasAccounts } />
|
||||
<Tooltip
|
||||
className={ styles.accountTooltip }
|
||||
text='your accounts are visible for easy access, allowing you to edit the meta information, make transfers, view transactions and fund the account' />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar () {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='newAccount'
|
||||
icon={ <ContentAdd /> }
|
||||
label='new account'
|
||||
onClick={ this.onNewAccountClick } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
className={ styles.toolbar }
|
||||
title='Accounts Overview'
|
||||
buttons={ buttons }>
|
||||
<Tooltip
|
||||
className={ styles.toolbarTooltip }
|
||||
right
|
||||
text='actions relating to the current view are available on the toolbar for quick access, be it for performing actions or creating a new item' />
|
||||
</Actionbar>
|
||||
);
|
||||
}
|
||||
|
||||
renderNewDialog () {
|
||||
const { accounts } = this.props;
|
||||
const { newDialog } = this.state;
|
||||
|
||||
if (!newDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<CreateAccount
|
||||
accounts={ accounts }
|
||||
onClose={ this.onNewAccountClose }
|
||||
onUpdate={ this.onNewAccountUpdate } />
|
||||
);
|
||||
}
|
||||
|
||||
onNewAccountClick = () => {
|
||||
this.setState({
|
||||
newDialog: !this.state.newDialog
|
||||
});
|
||||
}
|
||||
|
||||
onNewAccountClose = () => {
|
||||
this.onNewAccountClick();
|
||||
}
|
||||
|
||||
onNewAccountUpdate = () => {
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts, hasAccounts } = state.personal;
|
||||
const { balances } = state.balances;
|
||||
|
||||
return {
|
||||
accounts,
|
||||
hasAccounts,
|
||||
balances
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Accounts);
|
||||
17
js/src/views/Accounts/index.js
Normal file
17
js/src/views/Accounts/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './accounts';
|
||||
113
js/src/views/Address/Delete/delete.js
Normal file
113
js/src/views/Address/Delete/delete.js
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { ConfirmDialog, IdentityIcon, IdentityName } from '../../../ui';
|
||||
import { newError } from '../../../redux/actions';
|
||||
|
||||
import styles from '../address.css';
|
||||
|
||||
class Delete extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
router: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
address: PropTypes.string,
|
||||
account: PropTypes.object,
|
||||
route: PropTypes.string.isRequired,
|
||||
visible: PropTypes.bool,
|
||||
onClose: PropTypes.func,
|
||||
newError: PropTypes.func
|
||||
}
|
||||
|
||||
render () {
|
||||
const { account, visible } = this.props;
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfirmDialog
|
||||
className={ styles.delete }
|
||||
title='confirm removal'
|
||||
visible
|
||||
onDeny={ this.closeDeleteDialog }
|
||||
onConfirm={ this.onDeleteConfirmed }>
|
||||
<div className={ styles.hero }>
|
||||
Are you sure you want to remove the following address from your addressbook?
|
||||
</div>
|
||||
<div className={ styles.info }>
|
||||
<IdentityIcon
|
||||
className={ styles.icon }
|
||||
address={ account.address } />
|
||||
<div className={ styles.nameinfo }>
|
||||
<div className={ styles.header }>
|
||||
<IdentityName address={ account.address } unknown />
|
||||
</div>
|
||||
<div className={ styles.address }>
|
||||
{ account.address }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.description }>
|
||||
{ account.meta.description }
|
||||
</div>
|
||||
</ConfirmDialog>
|
||||
);
|
||||
}
|
||||
|
||||
onDeleteConfirmed = () => {
|
||||
const { api, router } = this.context;
|
||||
const { account, route, newError } = this.props;
|
||||
|
||||
account.meta.deleted = true;
|
||||
|
||||
api.personal
|
||||
.setAccountMeta(account.address, account.meta)
|
||||
.then(() => {
|
||||
router.push(route);
|
||||
this.closeDeleteDialog();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('onDeleteConfirmed', error);
|
||||
newError(new Error(`Deletion failed: ${error.message}`));
|
||||
this.closeDeleteDialog();
|
||||
});
|
||||
}
|
||||
|
||||
closeDeleteDialog = () => {
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ newError }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Delete);
|
||||
17
js/src/views/Address/Delete/index.js
Normal file
17
js/src/views/Address/Delete/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './delete';
|
||||
50
js/src/views/Address/address.css
Normal file
50
js/src/views/Address/address.css
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.address {
|
||||
}
|
||||
|
||||
.delete .hero {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.delete .info {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.delete .icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.delete .nameinfo {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.delete .header {
|
||||
text-transform: uppercase;
|
||||
font-size: 1.25em;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.delete .address {
|
||||
}
|
||||
|
||||
.delete .description {
|
||||
padding-top: 1em;
|
||||
font-size: 0.75em;
|
||||
color: #aaa;
|
||||
}
|
||||
153
js/src/views/Address/address.js
Normal file
153
js/src/views/Address/address.js
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ActionDelete from 'material-ui/svg-icons/action/delete';
|
||||
import ContentCreate from 'material-ui/svg-icons/content/create';
|
||||
|
||||
import { EditMeta } from '../../modals';
|
||||
import { Actionbar, Button, Page } from '../../ui';
|
||||
|
||||
import Header from '../Account/Header';
|
||||
import Transactions from '../Account/Transactions';
|
||||
import Delete from './Delete';
|
||||
|
||||
import styles from './address.css';
|
||||
|
||||
class Address extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
router: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
contacts: PropTypes.object,
|
||||
balances: PropTypes.object,
|
||||
isTest: PropTypes.bool,
|
||||
params: PropTypes.object
|
||||
}
|
||||
|
||||
state = {
|
||||
showDeleteDialog: false,
|
||||
showEditDialog: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { contacts, balances, isTest } = this.props;
|
||||
const { address } = this.props.params;
|
||||
const { showDeleteDialog } = this.state;
|
||||
|
||||
const contact = (contacts || {})[address];
|
||||
const balance = (balances || {})[address];
|
||||
|
||||
if (!contact) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.address }>
|
||||
{ this.renderEditDialog(contact) }
|
||||
{ this.renderActionbar(contact) }
|
||||
<Delete
|
||||
account={ contact }
|
||||
visible={ showDeleteDialog }
|
||||
route='/addresses'
|
||||
onClose={ this.closeDeleteDialog } />
|
||||
<Page>
|
||||
<Header
|
||||
isTest={ isTest }
|
||||
account={ contact }
|
||||
balance={ balance } />
|
||||
<Transactions
|
||||
address={ address } />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar (contact) {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='editmeta'
|
||||
icon={ <ContentCreate /> }
|
||||
label='edit'
|
||||
onClick={ this.onEditClick } />,
|
||||
<Button
|
||||
key='delete'
|
||||
icon={ <ActionDelete /> }
|
||||
label='delete address'
|
||||
onClick={ this.showDeleteDialog } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
title='Address Information'
|
||||
buttons={ !contact || contact.meta.deleted ? [] : buttons } />
|
||||
);
|
||||
}
|
||||
|
||||
renderEditDialog (contact) {
|
||||
const { showEditDialog } = this.state;
|
||||
|
||||
if (!showEditDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EditMeta
|
||||
account={ contact }
|
||||
keys={ ['description'] }
|
||||
onClose={ this.onEditClick } />
|
||||
);
|
||||
}
|
||||
|
||||
onEditClick = () => {
|
||||
this.setState({
|
||||
showEditDialog: !this.state.showEditDialog
|
||||
});
|
||||
}
|
||||
|
||||
closeDeleteDialog = () => {
|
||||
this.setState({ showDeleteDialog: false });
|
||||
}
|
||||
|
||||
showDeleteDialog = () => {
|
||||
this.setState({ showDeleteDialog: true });
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { contacts } = state.personal;
|
||||
const { balances } = state.balances;
|
||||
const { isTest } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
isTest,
|
||||
contacts,
|
||||
balances
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Address);
|
||||
17
js/src/views/Address/index.js
Normal file
17
js/src/views/Address/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './address';
|
||||
46
js/src/views/Addresses/addresses.css
Normal file
46
js/src/views/Addresses/addresses.css
Normal file
@@ -0,0 +1,46 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.addresses {
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.address {
|
||||
flex: 0 1 50%;
|
||||
width: 50%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.address:nth-child(odd)>div {
|
||||
padding-right: 0.5em !important;
|
||||
}
|
||||
|
||||
.address:nth-child(even)>div {
|
||||
padding-left: 0.5em !important;
|
||||
}
|
||||
|
||||
.empty {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.empty div {
|
||||
color: #aaa;
|
||||
}
|
||||
122
js/src/views/Addresses/addresses.js
Normal file
122
js/src/views/Addresses/addresses.js
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
|
||||
import List from '../Accounts/List';
|
||||
import { AddAddress } from '../../modals';
|
||||
import { Actionbar, Button, Page } from '../../ui';
|
||||
|
||||
import styles from './addresses.css';
|
||||
|
||||
class Addresses extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
balances: PropTypes.object,
|
||||
contacts: PropTypes.object,
|
||||
hasContacts: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
showAdd: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { balances, contacts, hasContacts } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.addresses }>
|
||||
{ this.renderActionbar() }
|
||||
{ this.renderAddAddress() }
|
||||
<Page>
|
||||
<List
|
||||
link='address'
|
||||
accounts={ contacts }
|
||||
balances={ balances }
|
||||
empty={ !hasContacts } />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar () {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='newAddress'
|
||||
icon={ <ContentAdd /> }
|
||||
label='new address'
|
||||
onClick={ this.onOpenAdd } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
className={ styles.toolbar }
|
||||
title='Saved Addresses'
|
||||
buttons={ buttons } />
|
||||
);
|
||||
}
|
||||
|
||||
renderAddAddress () {
|
||||
const { contacts } = this.props;
|
||||
const { showAdd } = this.state;
|
||||
|
||||
if (!showAdd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<AddAddress
|
||||
contacts={ contacts }
|
||||
onClose={ this.onCloseAdd } />
|
||||
);
|
||||
}
|
||||
|
||||
onOpenAdd = () => {
|
||||
this.setState({
|
||||
showAdd: true
|
||||
});
|
||||
}
|
||||
|
||||
onCloseAdd = () => {
|
||||
this.setState({ showAdd: false });
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { balances } = state.balances;
|
||||
const { contacts, hasContacts } = state.personal;
|
||||
|
||||
return {
|
||||
balances,
|
||||
contacts,
|
||||
hasContacts
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Addresses);
|
||||
17
js/src/views/Addresses/index.js
Normal file
17
js/src/views/Addresses/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './addresses';
|
||||
45
js/src/views/Application/Container/container.js
Normal file
45
js/src/views/Application/Container/container.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { FirstRun } from '../../../modals';
|
||||
import { Errors, ParityBackground, Tooltips } from '../../../ui';
|
||||
|
||||
import styles from '../application.css';
|
||||
|
||||
export default class Container extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
showFirstRun: PropTypes.bool,
|
||||
onCloseFirstRun: PropTypes.func
|
||||
};
|
||||
|
||||
render () {
|
||||
const { children, showFirstRun, onCloseFirstRun } = this.props;
|
||||
|
||||
return (
|
||||
<ParityBackground className={ styles.container }>
|
||||
<FirstRun
|
||||
visible={ showFirstRun }
|
||||
onClose={ onCloseFirstRun } />
|
||||
<Tooltips />
|
||||
<Errors />
|
||||
{ children }
|
||||
</ParityBackground>
|
||||
);
|
||||
}
|
||||
}
|
||||
17
js/src/views/Application/Container/index.js
Normal file
17
js/src/views/Application/Container/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './container';
|
||||
35
js/src/views/Application/DappContainer/dappContainer.js
Normal file
35
js/src/views/Application/DappContainer/dappContainer.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import styles from '../application.css';
|
||||
|
||||
export default class DappContainer extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired
|
||||
};
|
||||
|
||||
render () {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
17
js/src/views/Application/DappContainer/index.js
Normal file
17
js/src/views/Application/DappContainer/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './dappContainer';
|
||||
21
js/src/views/Application/FrameError/frameError.css
Normal file
21
js/src/views/Application/FrameError/frameError.css
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.error {
|
||||
padding: 2em;
|
||||
background: red;
|
||||
color: white;
|
||||
}
|
||||
29
js/src/views/Application/FrameError/frameError.js
Normal file
29
js/src/views/Application/FrameError/frameError.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import styles from './frameError.css';
|
||||
|
||||
export default class FrameError extends Component {
|
||||
render () {
|
||||
return (
|
||||
<div className={ styles.error }>
|
||||
ERROR: This application cannot and should not be loaded in an embedded iFrame
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
17
js/src/views/Application/FrameError/index.js
Normal file
17
js/src/views/Application/FrameError/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './frameError';
|
||||
17
js/src/views/Application/Status/index.js
Normal file
17
js/src/views/Application/Status/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './status';
|
||||
65
js/src/views/Application/Status/status.css
Normal file
65
js/src/views/Application/Status/status.css
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.status {
|
||||
clear: both;
|
||||
padding: 1.5em;
|
||||
text-align: right;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 0.5em 0 2em;
|
||||
}
|
||||
|
||||
.block {
|
||||
}
|
||||
|
||||
.netinfo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.netinfo>div {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.network {
|
||||
padding: 0.25em 0.5em;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
text-transform: uppercase;
|
||||
height: 1.25em;
|
||||
margin-top: 0.25em;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.networklive {
|
||||
background: rgb(75, 255, 75);
|
||||
}
|
||||
|
||||
.networktest {
|
||||
background: rgb(255, 75, 75);
|
||||
}
|
||||
|
||||
.peers {
|
||||
}
|
||||
|
||||
.version {
|
||||
}
|
||||
82
js/src/views/Application/Status/status.js
Normal file
82
js/src/views/Application/Status/status.js
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import styles from './status.css';
|
||||
|
||||
class Status extends Component {
|
||||
static propTypes = {
|
||||
blockNumber: PropTypes.object,
|
||||
clientVersion: PropTypes.string,
|
||||
netPeers: PropTypes.object,
|
||||
netChain: PropTypes.string,
|
||||
isTest: PropTypes.bool
|
||||
}
|
||||
|
||||
render () {
|
||||
const { clientVersion, blockNumber, netChain, netPeers, isTest } = this.props;
|
||||
const netStyle = `${styles.network} ${styles[isTest ? 'networktest' : 'networklive']}`;
|
||||
|
||||
if (!blockNumber) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.status }>
|
||||
<div className={ styles.version }>
|
||||
{ clientVersion }
|
||||
</div>
|
||||
<div className={ styles.netinfo }>
|
||||
<div>
|
||||
<div className={ styles.block }>
|
||||
{ blockNumber.toFormat() } blocks
|
||||
</div>
|
||||
<div className={ styles.peers }>
|
||||
{ netPeers.active.toFormat() }/{ netPeers.connected.toFormat() }/{ netPeers.max.toFormat() } peers
|
||||
</div>
|
||||
</div>
|
||||
<div className={ netStyle }>
|
||||
{ isTest ? 'test' : netChain }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { blockNumber, clientVersion, netPeers, netChain, isTest } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
blockNumber,
|
||||
clientVersion,
|
||||
netPeers,
|
||||
netChain,
|
||||
isTest
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Status);
|
||||
17
js/src/views/Application/TabBar/index.js
Normal file
17
js/src/views/Application/TabBar/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './tabBar';
|
||||
84
js/src/views/Application/TabBar/tabBar.css
Normal file
84
js/src/views/Application/TabBar/tabBar.css
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.toolbar {
|
||||
background: none !important;
|
||||
height: 72px !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tabs button,
|
||||
.settings,
|
||||
.logo,
|
||||
.last {
|
||||
background: rgba(0, 0, 0, 0.5) !important; /* rgba(0, 0, 0, 0.25) !important; */
|
||||
}
|
||||
|
||||
.tabs button:hover {
|
||||
background: rgba(0, 0, 0, 0.4) !important;
|
||||
}
|
||||
|
||||
button.tabactive,
|
||||
button.tabactive:hover {
|
||||
background: rgba(0, 0, 0, 0.25) !important;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.tabbarTooltip {
|
||||
left: 3.3em;
|
||||
top: 0.5em;
|
||||
}
|
||||
|
||||
.label {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.labelBubble {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
right: -12px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0 0 0 -24px;
|
||||
padding: 22px 24px 0 24px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.logo div {
|
||||
display: inline-block;
|
||||
text-transform: uppercase;
|
||||
line-height: 32px;
|
||||
vertical-align: top;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin: 0 -24px 0 0;
|
||||
padding: 22px 12px 0 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
187
js/src/views/Application/TabBar/tabBar.js
Normal file
187
js/src/views/Application/TabBar/tabBar.js
Normal file
@@ -0,0 +1,187 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
|
||||
import { Tabs, Tab } from 'material-ui/Tabs';
|
||||
|
||||
import { Badge, Tooltip } from '../../../ui';
|
||||
|
||||
import styles from './tabBar.css';
|
||||
import imagesEthcoreBlock from '../../../../assets/images/ethcore-block.png';
|
||||
|
||||
const TABMAP = {
|
||||
accounts: 'account',
|
||||
addresses: 'address',
|
||||
apps: 'app',
|
||||
contracts: 'contract'
|
||||
};
|
||||
|
||||
class TabBar extends Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
pending: PropTypes.array,
|
||||
isTest: PropTypes.bool,
|
||||
netChain: PropTypes.string,
|
||||
settings: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
state = {
|
||||
activeRoute: '/accounts'
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Toolbar
|
||||
className={ styles.toolbar }>
|
||||
{ this.renderLogo() }
|
||||
{ this.renderTabs() }
|
||||
{ this.renderLast() }
|
||||
</Toolbar>
|
||||
);
|
||||
}
|
||||
|
||||
renderLogo () {
|
||||
return (
|
||||
<ToolbarGroup>
|
||||
<div className={ styles.logo }>
|
||||
<img src={ imagesEthcoreBlock } />
|
||||
<div>Parity</div>
|
||||
</div>
|
||||
</ToolbarGroup>
|
||||
);
|
||||
}
|
||||
|
||||
renderLast () {
|
||||
return (
|
||||
<ToolbarGroup>
|
||||
<div className={ styles.last }>
|
||||
<div></div>
|
||||
</div>
|
||||
</ToolbarGroup>
|
||||
);
|
||||
}
|
||||
|
||||
renderTabs () {
|
||||
const { settings } = this.props;
|
||||
const windowHash = (window.location.hash || '').split('?')[0].split('/')[1];
|
||||
const hash = TABMAP[windowHash] || windowHash;
|
||||
|
||||
const items = Object.keys(settings.views)
|
||||
.filter((id) => settings.views[id].fixed || settings.views[id].active)
|
||||
.map((id) => {
|
||||
const view = settings.views[id];
|
||||
let label = this.renderLabel(view.label);
|
||||
let body = null;
|
||||
|
||||
if (id === 'accounts') {
|
||||
body = (
|
||||
<Tooltip className={ styles.tabbarTooltip } text='navigate between the different parts and views of the application, switching between an account view, token view and distributed application view' />
|
||||
);
|
||||
} else if (id === 'signer') {
|
||||
label = this.renderSignerLabel(label);
|
||||
} else if (id === 'status') {
|
||||
label = this.renderStatusLabel(label);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tab
|
||||
className={ hash === view.value ? styles.tabactive : '' }
|
||||
value={ view.value }
|
||||
icon={ view.icon }
|
||||
key={ id }
|
||||
label={ label }
|
||||
onActive={ this.onActivate(view.route) }>
|
||||
{ body }
|
||||
</Tab>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
className={ styles.tabs }
|
||||
value={ hash }>
|
||||
{ items }
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
renderLabel = (name, bubble) => {
|
||||
return (
|
||||
<div className={ styles.label }>
|
||||
{ name }
|
||||
{ bubble }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderSignerLabel = (label) => {
|
||||
const { pending } = this.props;
|
||||
let bubble = null;
|
||||
|
||||
if (pending && pending.length) {
|
||||
bubble = (
|
||||
<Badge
|
||||
color='red'
|
||||
className={ styles.labelBubble }
|
||||
value={ pending.length } />
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderLabel(label, bubble);
|
||||
}
|
||||
|
||||
renderStatusLabel = (label) => {
|
||||
const { isTest, netChain } = this.props;
|
||||
const bubble = (
|
||||
<Badge
|
||||
color={ isTest ? 'red' : 'default' }
|
||||
className={ styles.labelBubble }
|
||||
value={ isTest ? 'TEST' : netChain } />
|
||||
);
|
||||
|
||||
return this.renderLabel(label, bubble);
|
||||
}
|
||||
|
||||
onActivate = (activeRoute) => {
|
||||
const { router } = this.context;
|
||||
|
||||
return (event) => {
|
||||
router.push(activeRoute);
|
||||
this.setState({ activeRoute });
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { settings } = state;
|
||||
|
||||
return { settings };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TabBar);
|
||||
21
js/src/views/Application/application.css
Normal file
21
js/src/views/Application/application.css
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.outer,
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
146
js/src/views/Application/application.js
Normal file
146
js/src/views/Application/application.js
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import Connection from '../Connection';
|
||||
import ParityBar from '../ParityBar';
|
||||
|
||||
import Container from './Container';
|
||||
import DappContainer from './DappContainer';
|
||||
import FrameError from './FrameError';
|
||||
import Status from './Status';
|
||||
import TabBar from './TabBar';
|
||||
|
||||
import styles from './application.css';
|
||||
|
||||
const inFrame = window.parent !== window && window.parent.frames.length !== 0;
|
||||
const showFirstRun = window.localStorage.getItem('showFirstRun') === '1';
|
||||
|
||||
class Application extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
background: PropTypes.string
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
netChain: PropTypes.string,
|
||||
isTest: PropTypes.bool,
|
||||
pending: PropTypes.array
|
||||
}
|
||||
|
||||
state = {
|
||||
showFirstRun: false
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this.checkAccounts();
|
||||
}
|
||||
|
||||
render () {
|
||||
const [root] = (window.location.hash || '').replace('#/', '').split('/');
|
||||
const isDapp = root === 'app';
|
||||
|
||||
if (inFrame) {
|
||||
return (
|
||||
<FrameError />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.outer }>
|
||||
{ isDapp ? this.renderDapp() : this.renderApp() }
|
||||
<Connection />
|
||||
<ParityBar dapp={ isDapp } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderApp () {
|
||||
const { children, pending, netChain, isTest } = this.props;
|
||||
const { showFirstRun } = this.state;
|
||||
|
||||
return (
|
||||
<Container
|
||||
showFirstRun={ showFirstRun }
|
||||
onCloseFirstRun={ this.onCloseFirstRun }>
|
||||
<TabBar
|
||||
netChain={ netChain }
|
||||
isTest={ isTest }
|
||||
pending={ pending } />
|
||||
{ children }
|
||||
<Status />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderDapp () {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<DappContainer>
|
||||
{ children }
|
||||
</DappContainer>
|
||||
);
|
||||
}
|
||||
|
||||
checkAccounts () {
|
||||
const { api } = this.context;
|
||||
|
||||
api.personal
|
||||
.listAccounts()
|
||||
.then((accounts) => {
|
||||
this.setState({
|
||||
showFirstRun: showFirstRun || accounts.length === 0
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('checkAccounts', error);
|
||||
});
|
||||
}
|
||||
|
||||
onCloseFirstRun = () => {
|
||||
window.localStorage.setItem('showFirstRun', '0');
|
||||
this.setState({
|
||||
showFirstRun: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { netChain, isTest } = state.nodeStatus;
|
||||
const { hasAccounts } = state.personal;
|
||||
const { pending } = state.signer;
|
||||
|
||||
return {
|
||||
hasAccounts,
|
||||
netChain,
|
||||
isTest,
|
||||
pending
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Application);
|
||||
17
js/src/views/Application/index.js
Normal file
17
js/src/views/Application/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './application';
|
||||
113
js/src/views/Connection/connection.css
Normal file
113
js/src/views/Connection/connection.css
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Copyright 2015; 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation; either version 3 of the License; or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful;
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not; see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
z-index: 20000
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 20001
|
||||
}
|
||||
|
||||
.body {
|
||||
margin: 0 auto;
|
||||
padding: 2em 4em;
|
||||
text-align: center;
|
||||
max-width: 40em;
|
||||
background: rgba(25, 25, 25, 0.75);
|
||||
color: rgb(208, 208, 208);
|
||||
box-shadow: rgba(0, 0, 0, 0.25) 0px 14px 45px, rgba(0, 0, 0, 0.22) 0px 10px 18px
|
||||
}
|
||||
|
||||
.header {
|
||||
fontSize: 1.25em
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-top: 2em;
|
||||
line-height: 1.618em
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: 0.75em;
|
||||
padding: 0 4em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.btnrow {
|
||||
text-align: right;
|
||||
padding: 0 4em;
|
||||
}
|
||||
|
||||
.icons {
|
||||
}
|
||||
|
||||
.icon,
|
||||
.iconSmall {
|
||||
display: inline-block;
|
||||
padding: 1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.iconName {
|
||||
}
|
||||
|
||||
.icon .svg {
|
||||
width: 6em !important;
|
||||
height: 6em !important;
|
||||
}
|
||||
|
||||
.iconSmall .svg {
|
||||
width: 3em !important;
|
||||
height: 3em !important;
|
||||
}
|
||||
|
||||
.console {
|
||||
font-family: 'Roboto Mono';
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
fill: rgb(0, 200, 0);
|
||||
}
|
||||
50% {
|
||||
fill: rgb(150, 200, 150);
|
||||
}
|
||||
100% {
|
||||
fill: rgb(0, 200, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.pulse {
|
||||
fill: red;
|
||||
animation-name: pulse;
|
||||
animation-duration: 1.5s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
150
js/src/views/Connection/connection.js
Normal file
150
js/src/views/Connection/connection.js
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ActionCompareArrows from 'material-ui/svg-icons/action/compare-arrows';
|
||||
import ActionDashboard from 'material-ui/svg-icons/action/dashboard';
|
||||
// import CommunicationVpnKey from 'material-ui/svg-icons/communication/vpn-key';
|
||||
import HardwareDesktopMac from 'material-ui/svg-icons/hardware/desktop-mac';
|
||||
import NotificationVpnLock from 'material-ui/svg-icons/notification/vpn-lock';
|
||||
|
||||
import { Input } from '../../ui';
|
||||
|
||||
import styles from './connection.css';
|
||||
|
||||
class Connection extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
isConnected: PropTypes.bool,
|
||||
isConnecting: PropTypes.bool,
|
||||
isPingable: PropTypes.bool,
|
||||
needsToken: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
token: '',
|
||||
validToken: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { isConnected, isConnecting, isPingable } = this.props;
|
||||
const isOk = !isConnecting && isConnected && isPingable;
|
||||
|
||||
if (isOk) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const typeIcon = isPingable
|
||||
? <NotificationVpnLock className={ styles.svg } />
|
||||
: <ActionDashboard className={ styles.svg } />;
|
||||
const description = isPingable
|
||||
? this.renderSigner()
|
||||
: this.renderPing();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ styles.overlay } />
|
||||
<div className={ styles.modal }>
|
||||
<div className={ styles.body }>
|
||||
<div className={ styles.icons }>
|
||||
<div className={ styles.icon }>
|
||||
<HardwareDesktopMac className={ styles.svg } />
|
||||
</div>
|
||||
<div className={ styles.iconSmall }>
|
||||
<ActionCompareArrows className={ styles.svg + ' ' + styles.pulse } />
|
||||
</div>
|
||||
<div className={ styles.icon }>
|
||||
{ typeIcon }
|
||||
</div>
|
||||
</div>
|
||||
{ description }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderSigner () {
|
||||
const { api } = this.context;
|
||||
const { token, validToken } = this.state;
|
||||
const { needsToken, isConnecting } = api;
|
||||
|
||||
if (needsToken && !isConnecting) {
|
||||
return (
|
||||
<div className={ styles.info }>
|
||||
<div>Unable to make a connection to the Parity Secure API. To update your secure token or to generate a new one, run <span className={ styles.console }>parity signer new-token</span> and supply the token below</div>
|
||||
<div className={ styles.form }>
|
||||
<Input
|
||||
label='secure token'
|
||||
hint='a generated token from Parity'
|
||||
error={ validToken || (!token || !token.length) ? null : 'invalid signer token' }
|
||||
value={ token }
|
||||
onChange={ this.onChangeToken } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.info }>
|
||||
Connecting to the Parity Secure API.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderPing () {
|
||||
return (
|
||||
<div className={ styles.info }>
|
||||
Connecting to the Parity Node. If this informational message persists, please ensure that your Parity node is running and reachable on the network.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onChangeToken = (event, token) => {
|
||||
const validToken = /[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}/.test(token);
|
||||
this.setState({ token, validToken }, () => {
|
||||
validToken && this.setToken();
|
||||
});
|
||||
}
|
||||
|
||||
setToken = () => {
|
||||
const { api } = this.context;
|
||||
const { token } = this.state;
|
||||
|
||||
api.updateToken(token);
|
||||
this.setState({ token: '', validToken: false });
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { isConnected, isConnecting, isPingable, needsToken } = state.nodeStatus;
|
||||
|
||||
return { isConnected, isConnecting, isPingable, needsToken };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Connection);
|
||||
17
js/src/views/Connection/index.js
Normal file
17
js/src/views/Connection/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './connection';
|
||||
132
js/src/views/Contract/Events/events.js
Normal file
132
js/src/views/Contract/Events/events.js
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
|
||||
import styles from '../contract.css';
|
||||
|
||||
export default class Events extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
events: PropTypes.array,
|
||||
isTest: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
transactions: {}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.componentWillReceiveProps(this.props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (newProps) {
|
||||
this.retrieveTransactions(newProps.events);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { events, isTest } = this.props;
|
||||
const { transactions } = this.state;
|
||||
|
||||
if (!events || !events.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rows = events.map((event) => {
|
||||
const transaction = transactions[event.transactionHash] || {};
|
||||
const classes = `${styles.event} ${styles[event.state]}`;
|
||||
const url = `https://${isTest ? 'testnet.' : ''}etherscan.io/tx/${event.transactionHash}`;
|
||||
const keys = Object.keys(event.params).map((key, index) => {
|
||||
return <div className={ styles.key } key={ `${event.key}_key_${index}` }>{ key }</div>;
|
||||
});
|
||||
const values = Object.values(event.params).map((value, index) => {
|
||||
return (
|
||||
<div className={ styles.value } key={ `${event.key}_val_${index}` }>
|
||||
{ this.renderValue(value) }
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<tr className={ classes } key={ event.key }>
|
||||
<td>{ event.state === 'pending' ? 'pending' : event.blockNumber.toFormat(0) }</td>
|
||||
<td className={ styles.txhash }>
|
||||
<div>{ transaction.from }</div>
|
||||
<a href={ url } target='_blank'>{ event.transactionHash }</a>
|
||||
</td>
|
||||
<td>
|
||||
<div>{ event.type } =></div>
|
||||
{ keys }
|
||||
</td>
|
||||
<td>
|
||||
<div> </div>
|
||||
{ values }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='events' />
|
||||
<table className={ styles.events }>
|
||||
<tbody>{ rows }</tbody>
|
||||
</table>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue (value) {
|
||||
const { api } = this.context;
|
||||
|
||||
if (api.util.isInstanceOf(value, BigNumber)) {
|
||||
return value.toFormat(0);
|
||||
} else if (api.util.isArray(value)) {
|
||||
return api.util.bytesToHex(value);
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
retrieveTransactions (events) {
|
||||
const { api } = this.context;
|
||||
const { transactions } = this.state;
|
||||
const hashes = {};
|
||||
|
||||
events.forEach((event) => {
|
||||
if (!hashes[event.transactionHash] && !transactions[event.transactionHash]) {
|
||||
hashes[event.transactionHash] = true;
|
||||
}
|
||||
});
|
||||
|
||||
Promise
|
||||
.all(Object.keys(hashes).map((hash) => api.eth.getTransactionByHash(hash)))
|
||||
.then((newTransactions) => {
|
||||
this.setState({
|
||||
transactions: newTransactions.reduce((store, transaction) => {
|
||||
transactions[transaction.hash] = transaction;
|
||||
return transactions;
|
||||
}, transactions)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Contract/Events/index.js
Normal file
17
js/src/views/Contract/Events/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './events';
|
||||
17
js/src/views/Contract/Queries/index.js
Normal file
17
js/src/views/Contract/Queries/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './queries';
|
||||
186
js/src/views/Contract/Queries/inputQuery.js
Normal file
186
js/src/views/Contract/Queries/inputQuery.js
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import Chip from 'material-ui/Chip';
|
||||
import LinearProgress from 'material-ui/LinearProgress';
|
||||
import { Card, CardActions, CardTitle, CardText } from 'material-ui/Card';
|
||||
|
||||
import { Button, Input } from '../../../ui';
|
||||
|
||||
import styles from './queries.css';
|
||||
|
||||
export default class InputQuery extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
contract: PropTypes.object.isRequired,
|
||||
inputs: PropTypes.array.isRequired,
|
||||
outputs: PropTypes.array.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
state = {
|
||||
isValid: true,
|
||||
results: [],
|
||||
values: {}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { name, className } = this.props;
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={ className }
|
||||
>
|
||||
<CardTitle
|
||||
className={ styles.methodTitle }
|
||||
title={ name }
|
||||
/>
|
||||
{ this.renderContent() }
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent () {
|
||||
const { inputs } = this.props;
|
||||
|
||||
const { isValid } = this.state;
|
||||
|
||||
const inputsFields = inputs
|
||||
.map(input => this.renderInput(input));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<CardText
|
||||
className={ styles.methodContent }
|
||||
>
|
||||
<div className={ styles.methodResults }>
|
||||
{ this.renderResults() }
|
||||
</div>
|
||||
{ inputsFields }
|
||||
</CardText>
|
||||
<CardActions>
|
||||
<Button
|
||||
label='Execute'
|
||||
disabled={ !isValid }
|
||||
onClick={ this.onClick } />
|
||||
</CardActions>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderResults () {
|
||||
const { results, isLoading } = this.state;
|
||||
const { outputs } = this.props;
|
||||
|
||||
if (isLoading) {
|
||||
return (<LinearProgress mode='indeterminate' />);
|
||||
}
|
||||
|
||||
if (!results || results.length < 1) return null;
|
||||
|
||||
return outputs
|
||||
.map((out, index) => ({
|
||||
name: out.name,
|
||||
value: results[index],
|
||||
display: this.renderValue(results[index])
|
||||
}))
|
||||
.sort((outA, outB) => outA.display.length - outB.display.length)
|
||||
.map((out, index) => (<div key={ index }>
|
||||
<div className={ styles.queryResultName }>{ out.name }</div>
|
||||
<Chip className={ styles.queryValue }>
|
||||
{ out.display }
|
||||
</Chip>
|
||||
<br />
|
||||
</div>));
|
||||
}
|
||||
|
||||
renderInput (input) {
|
||||
const { name, type } = input;
|
||||
const label = `${name}: ${type}`;
|
||||
|
||||
const onChange = (event) => {
|
||||
const value = event.target.value;
|
||||
const { values } = this.state;
|
||||
|
||||
this.setState({
|
||||
values: {
|
||||
...values,
|
||||
[ name ]: value
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={ name }>
|
||||
<Input
|
||||
hint={ type }
|
||||
label={ label }
|
||||
required
|
||||
onChange={ onChange }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue (value) {
|
||||
if (!value) return 'no data';
|
||||
|
||||
const { api } = this.context;
|
||||
|
||||
if (api.util.isInstanceOf(value, BigNumber)) {
|
||||
return value.toFormat(0);
|
||||
} else if (api.util.isArray(value)) {
|
||||
return api.util.bytesToHex(value);
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
onClick = () => {
|
||||
const { values } = this.state;
|
||||
const { inputs, contract, name, outputs } = this.props;
|
||||
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
results: []
|
||||
});
|
||||
|
||||
const inputValues = inputs.map(input => values[input.name]);
|
||||
|
||||
contract
|
||||
.instance[name]
|
||||
.call({}, inputValues)
|
||||
.then(results => {
|
||||
if (outputs.length === 1) {
|
||||
results = [ results ];
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
results
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(`sending ${name} with params`, inputValues, e);
|
||||
});
|
||||
};
|
||||
}
|
||||
87
js/src/views/Contract/Queries/queries.css
Normal file
87
js/src/views/Contract/Queries/queries.css
Normal file
@@ -0,0 +1,87 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.vMethods, .hMethods, .methods {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.container {
|
||||
align-items: flex-start;
|
||||
display: border-box;
|
||||
}
|
||||
|
||||
.container .method {
|
||||
background-color: rgba(255, 255, 255, 0.05) !important;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
.vMethods {
|
||||
flex-direction: column;
|
||||
width: 33.3333%;
|
||||
}
|
||||
|
||||
.hMethods {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
width: 66.6666%;
|
||||
}
|
||||
|
||||
.hMethods .container {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.methodTitle {
|
||||
padding-bottom: 8px !important;
|
||||
padding-top: 8px !important;
|
||||
}
|
||||
|
||||
.methodContent {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.methodResults {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: 24rem;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.methodResults > div {
|
||||
margin: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.queryValue, .queryValue * {
|
||||
user-select: text !important;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
white-space: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.queryValue:hover {
|
||||
cursor: text !important;
|
||||
}
|
||||
|
||||
.queryResultName {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
132
js/src/views/Contract/Queries/queries.js
Normal file
132
js/src/views/Contract/Queries/queries.js
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import Chip from 'material-ui/Chip';
|
||||
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
||||
|
||||
import InputQuery from './inputQuery';
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
|
||||
import styles from './queries.css';
|
||||
|
||||
export default class Queries extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
contract: PropTypes.object,
|
||||
values: PropTypes.object
|
||||
}
|
||||
|
||||
render () {
|
||||
const { contract } = this.props;
|
||||
|
||||
if (!contract) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const queries = contract.functions
|
||||
.filter((fn) => fn.constant)
|
||||
.sort(this._sortEntries);
|
||||
|
||||
const noInputQueries = queries
|
||||
.slice()
|
||||
.filter((fn) => fn.inputs.length === 0)
|
||||
.map((fn) => this.renderQuery(fn));
|
||||
|
||||
const withInputQueries = queries
|
||||
.slice()
|
||||
.filter((fn) => fn.inputs.length > 0)
|
||||
.map((fn) => this.renderInputQuery(fn));
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='queries' />
|
||||
<div className={ styles.methods }>
|
||||
<div className={ styles.vMethods }>
|
||||
{ noInputQueries }
|
||||
</div>
|
||||
<div className={ styles.hMethods }>
|
||||
{ withInputQueries }
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderInputQuery (fn) {
|
||||
const { abi, name } = fn;
|
||||
const { contract } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.container } key={ fn.signature }>
|
||||
<InputQuery
|
||||
className={ styles.method }
|
||||
inputs={ abi.inputs }
|
||||
outputs={ abi.outputs }
|
||||
name={ name }
|
||||
contract={ contract }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderQuery (fn) {
|
||||
const { values } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.container } key={ fn.signature }>
|
||||
<Card className={ styles.method }>
|
||||
<CardTitle
|
||||
className={ styles.methodTitle }
|
||||
title={ fn.name }
|
||||
/>
|
||||
<CardText
|
||||
className={ styles.methodContent }
|
||||
>
|
||||
{ this.renderValue(values[fn.name]) }
|
||||
</CardText>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue (value) {
|
||||
if (!value) return null;
|
||||
|
||||
const { api } = this.context;
|
||||
let valueToDisplay = value.toString();
|
||||
|
||||
if (api.util.isInstanceOf(value, BigNumber)) {
|
||||
valueToDisplay = value.toFormat(0);
|
||||
} else if (api.util.isArray(value)) {
|
||||
valueToDisplay = api.util.bytesToHex(value);
|
||||
}
|
||||
|
||||
return (
|
||||
<Chip className={ styles.queryValue }>
|
||||
{ valueToDisplay }
|
||||
</Chip>
|
||||
);
|
||||
}
|
||||
|
||||
_sortEntries (a, b) {
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
}
|
||||
58
js/src/views/Contract/contract.css
Normal file
58
js/src/views/Contract/contract.css
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.contract {
|
||||
}
|
||||
|
||||
.events {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.event {
|
||||
vertical-align: top;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.event td {
|
||||
vertical-align: top;
|
||||
padding: 1em 0.5em;
|
||||
}
|
||||
|
||||
.txhash {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.key {
|
||||
text-align: right;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.value {
|
||||
}
|
||||
|
||||
.event td div {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mined {
|
||||
}
|
||||
|
||||
.pending {
|
||||
opacity: 0.5;
|
||||
}
|
||||
365
js/src/views/Contract/contract.js
Normal file
365
js/src/views/Contract/contract.js
Normal file
@@ -0,0 +1,365 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ActionDelete from 'material-ui/svg-icons/action/delete';
|
||||
import AvPlayArrow from 'material-ui/svg-icons/av/play-arrow';
|
||||
import ContentCreate from 'material-ui/svg-icons/content/create';
|
||||
|
||||
import { newError } from '../../redux/actions';
|
||||
import { EditMeta, ExecuteContract } from '../../modals';
|
||||
import { Actionbar, Button, Page } from '../../ui';
|
||||
|
||||
import Header from '../Account/Header';
|
||||
import Delete from '../Address/Delete';
|
||||
|
||||
import Events from './Events';
|
||||
import Queries from './Queries';
|
||||
|
||||
import styles from './contract.css';
|
||||
|
||||
class Contract extends Component {
|
||||
static contextTypes = {
|
||||
api: React.PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object,
|
||||
balances: PropTypes.object,
|
||||
contracts: PropTypes.object,
|
||||
isTest: PropTypes.bool,
|
||||
params: PropTypes.object
|
||||
}
|
||||
|
||||
state = {
|
||||
contract: null,
|
||||
fromAddress: '',
|
||||
showDeleteDialog: false,
|
||||
showEditDialog: false,
|
||||
showExecuteDialog: false,
|
||||
subscriptionId: -1,
|
||||
blockSubscriptionId: -1,
|
||||
allEvents: [],
|
||||
minedEvents: [],
|
||||
pendingEvents: [],
|
||||
queryValues: {}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { api } = this.context;
|
||||
|
||||
this.attachContract(this.props);
|
||||
this.setBaseAccount(this.props);
|
||||
|
||||
api
|
||||
.subscribe('eth_blockNumber', this.queryContract)
|
||||
.then(blockSubscriptionId => this.setState({ blockSubscriptionId }));
|
||||
}
|
||||
|
||||
componentWillReceiveProps (newProps) {
|
||||
const { accounts, contracts } = newProps;
|
||||
|
||||
if (Object.keys(contracts).length !== Object.keys(this.props.contracts).length) {
|
||||
this.attachContract(newProps);
|
||||
}
|
||||
|
||||
if (Object.keys(accounts).length !== Object.keys(this.props.accounts).length) {
|
||||
this.setBaseAccount(newProps);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const { api } = this.context;
|
||||
const { subscriptionId, blockSubscriptionId, contract } = this.state;
|
||||
|
||||
api.unsubscribe('eth_blockNumber', blockSubscriptionId);
|
||||
contract.unsubscribe(subscriptionId);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { balances, contracts, params, isTest } = this.props;
|
||||
const { allEvents, contract, queryValues } = this.state;
|
||||
const account = contracts[params.address];
|
||||
const balance = balances[params.address];
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.contract }>
|
||||
{ this.renderActionbar(account) }
|
||||
{ this.renderDeleteDialog(account) }
|
||||
{ this.renderEditDialog(account) }
|
||||
{ this.renderExecuteDialog() }
|
||||
<Page>
|
||||
<Header
|
||||
isTest={ isTest }
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
<Queries
|
||||
contract={ contract }
|
||||
values={ queryValues } />
|
||||
<Events
|
||||
isTest={ isTest }
|
||||
events={ allEvents } />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar (account) {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='execute'
|
||||
icon={ <AvPlayArrow /> }
|
||||
label='execute'
|
||||
onClick={ this.showExecuteDialog } />,
|
||||
<Button
|
||||
key='editmeta'
|
||||
icon={ <ContentCreate /> }
|
||||
label='edit'
|
||||
onClick={ this.onEditClick } />,
|
||||
<Button
|
||||
key='delete'
|
||||
icon={ <ActionDelete /> }
|
||||
label='delete contract'
|
||||
onClick={ this.showDeleteDialog } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
title='Contract Information'
|
||||
buttons={ !account || account.meta.deleted ? [] : buttons } />
|
||||
);
|
||||
}
|
||||
|
||||
renderDeleteDialog (account) {
|
||||
const { showDeleteDialog } = this.state;
|
||||
|
||||
return (
|
||||
<Delete
|
||||
account={ account }
|
||||
visible={ showDeleteDialog }
|
||||
route='/contracts'
|
||||
onClose={ this.closeDeleteDialog } />
|
||||
);
|
||||
}
|
||||
|
||||
renderEditDialog (account) {
|
||||
const { showEditDialog } = this.state;
|
||||
|
||||
if (!showEditDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EditMeta
|
||||
account={ account }
|
||||
keys={ ['description'] }
|
||||
onClose={ this.onEditClick } />
|
||||
);
|
||||
}
|
||||
|
||||
renderExecuteDialog () {
|
||||
const { contract, fromAddress, showExecuteDialog } = this.state;
|
||||
const { accounts } = this.props;
|
||||
|
||||
if (!showExecuteDialog) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ExecuteContract
|
||||
accounts={ accounts }
|
||||
contract={ contract }
|
||||
fromAddress={ fromAddress }
|
||||
onClose={ this.closeExecuteDialog }
|
||||
onFromAddressChange={ this.onFromAddressChange } />
|
||||
);
|
||||
}
|
||||
|
||||
queryContract = () => {
|
||||
const { contract } = this.state;
|
||||
|
||||
if (!contract) {
|
||||
return;
|
||||
}
|
||||
|
||||
const queries = contract.functions
|
||||
.filter((fn) => fn.constant)
|
||||
.filter((fn) => !fn.inputs.length);
|
||||
|
||||
Promise
|
||||
.all(queries.map((query) => query.call()))
|
||||
.then(results => {
|
||||
const values = queries.reduce((object, fn, idx) => {
|
||||
const key = fn.name;
|
||||
object[key] = results[idx];
|
||||
return object;
|
||||
}, {});
|
||||
|
||||
this.setState({ queryValues: values });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('queryContract', error);
|
||||
});
|
||||
}
|
||||
|
||||
onEditClick = () => {
|
||||
this.setState({
|
||||
showEditDialog: !this.state.showEditDialog
|
||||
});
|
||||
}
|
||||
|
||||
closeDeleteDialog = () => {
|
||||
this.setState({ showDeleteDialog: false });
|
||||
}
|
||||
|
||||
showDeleteDialog = () => {
|
||||
this.setState({ showDeleteDialog: true });
|
||||
}
|
||||
|
||||
closeExecuteDialog = () => {
|
||||
this.setState({ showExecuteDialog: false });
|
||||
}
|
||||
|
||||
showExecuteDialog = () => {
|
||||
this.setState({ showExecuteDialog: true });
|
||||
}
|
||||
|
||||
_sortEvents = (a, b) => {
|
||||
return b.blockNumber.cmp(a.blockNumber) || b.logIndex.cmp(a.logIndex);
|
||||
}
|
||||
|
||||
_logToEvent = (log) => {
|
||||
const { api } = this.context;
|
||||
const key = api.util.sha3(JSON.stringify(log));
|
||||
const { address, blockNumber, logIndex, transactionHash, transactionIndex, params, type } = log;
|
||||
|
||||
return {
|
||||
type: log.event,
|
||||
state: type,
|
||||
address,
|
||||
blockNumber,
|
||||
logIndex,
|
||||
transactionHash,
|
||||
transactionIndex,
|
||||
params,
|
||||
key
|
||||
};
|
||||
}
|
||||
|
||||
_receiveEvents = (error, logs) => {
|
||||
if (error) {
|
||||
console.error('_receiveEvents', error);
|
||||
return;
|
||||
}
|
||||
|
||||
const events = logs.map(this._logToEvent);
|
||||
const minedEvents = events
|
||||
.filter((event) => event.state === 'mined')
|
||||
.reverse()
|
||||
.concat(this.state.minedEvents)
|
||||
.sort(this._sortEvents);
|
||||
const pendingEvents = events
|
||||
.filter((event) => event.state === 'pending')
|
||||
.reverse()
|
||||
.concat(this.state.pendingEvents.filter((pending) => {
|
||||
return !events.find((event) => {
|
||||
const isMined = (event.state === 'mined') && (event.transactionHash === pending.transactionHash);
|
||||
const isPending = (event.state === 'pending') && (event.key === pending.key);
|
||||
|
||||
return isMined || isPending;
|
||||
});
|
||||
}))
|
||||
.sort(this._sortEvents);
|
||||
const allEvents = pendingEvents.concat(minedEvents);
|
||||
|
||||
this.setState({
|
||||
allEvents,
|
||||
minedEvents,
|
||||
pendingEvents
|
||||
});
|
||||
}
|
||||
|
||||
attachContract (props) {
|
||||
if (!props) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { api } = this.context;
|
||||
const { contracts, params } = props;
|
||||
const account = contracts[params.address];
|
||||
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
const contract = api.newContract(account.meta.abi, params.address);
|
||||
contract
|
||||
.subscribe(null, { limit: 50, fromBlock: 0, toBlock: 'pending' }, this._receiveEvents)
|
||||
.then((subscriptionId) => {
|
||||
this.setState({ subscriptionId });
|
||||
});
|
||||
|
||||
this.setState({ contract }, this.queryContract);
|
||||
}
|
||||
|
||||
setBaseAccount (props) {
|
||||
const { fromAccount } = this.state;
|
||||
|
||||
if (!props || fromAccount) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { accounts } = props;
|
||||
|
||||
this.setState({
|
||||
fromAddress: Object.keys(accounts)[0]
|
||||
});
|
||||
}
|
||||
|
||||
onFromAddressChange = (event, fromAddress) => {
|
||||
this.setState({
|
||||
fromAddress
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts, contracts } = state.personal;
|
||||
const { balances } = state.balances;
|
||||
const { isTest } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
isTest,
|
||||
accounts,
|
||||
contracts,
|
||||
balances
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ newError }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Contract);
|
||||
17
js/src/views/Contract/index.js
Normal file
17
js/src/views/Contract/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './contract';
|
||||
17
js/src/views/Contracts/Summary/index.js
Normal file
17
js/src/views/Contracts/Summary/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './summary';
|
||||
52
js/src/views/Contracts/Summary/summary.js
Normal file
52
js/src/views/Contracts/Summary/summary.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { Container, ContainerTitle, IdentityIcon, IdentityName } from '../../../ui';
|
||||
|
||||
export default class Summary extends Component {
|
||||
static contextTypes = {
|
||||
api: React.PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
contract: PropTypes.object.isRequired,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
render () {
|
||||
const contract = this.props.contract;
|
||||
|
||||
if (!contract) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const viewLink = `/app/${contract.address}`;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<IdentityIcon
|
||||
address={ contract.address } />
|
||||
<ContainerTitle
|
||||
title={ <Link to={ viewLink }>{ <IdentityName address={ contract.address } unknown /> }</Link> }
|
||||
byline={ contract.address } />
|
||||
{ this.props.children }
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
18
js/src/views/Contracts/contracts.css
Normal file
18
js/src/views/Contracts/contracts.css
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.contracts {
|
||||
}
|
||||
154
js/src/views/Contracts/contracts.js
Normal file
154
js/src/views/Contracts/contracts.js
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentAdd from 'material-ui/svg-icons/content/add';
|
||||
|
||||
import { Actionbar, Button, Page } from '../../ui';
|
||||
import { AddContract, DeployContract } from '../../modals';
|
||||
|
||||
import List from '../Accounts/List';
|
||||
|
||||
import styles from './contracts.css';
|
||||
|
||||
class Contracts extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
balances: PropTypes.object,
|
||||
accounts: PropTypes.object,
|
||||
contracts: PropTypes.object,
|
||||
hasContracts: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
addContract: false,
|
||||
deployContract: false
|
||||
}
|
||||
|
||||
render () {
|
||||
const { contracts, hasContracts, balances } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.contracts }>
|
||||
{ this.renderActionbar() }
|
||||
{ this.renderAddContract() }
|
||||
{ this.renderAddContract() }
|
||||
{ this.renderDeployContract() }
|
||||
<Page>
|
||||
<List
|
||||
link='contract'
|
||||
accounts={ contracts }
|
||||
balances={ balances }
|
||||
empty={ !hasContracts } />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionbar () {
|
||||
const buttons = [
|
||||
<Button
|
||||
key='addContract'
|
||||
icon={ <ContentAdd /> }
|
||||
label='watch contract'
|
||||
onClick={ this.onAddContract } />,
|
||||
<Button
|
||||
key='deployContract'
|
||||
icon={ <ContentAdd /> }
|
||||
label='deploy contract'
|
||||
onClick={ this.onDeployContract } />
|
||||
];
|
||||
|
||||
return (
|
||||
<Actionbar
|
||||
className={ styles.toolbar }
|
||||
title='Contracts'
|
||||
buttons={ buttons } />
|
||||
);
|
||||
}
|
||||
|
||||
renderAddContract () {
|
||||
const { contracts } = this.props;
|
||||
const { addContract } = this.state;
|
||||
|
||||
if (!addContract) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<AddContract
|
||||
contracts={ contracts }
|
||||
onClose={ this.onAddContractClose } />
|
||||
);
|
||||
}
|
||||
|
||||
renderDeployContract () {
|
||||
const { accounts } = this.props;
|
||||
const { deployContract } = this.state;
|
||||
|
||||
if (!deployContract) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<DeployContract
|
||||
accounts={ accounts }
|
||||
onClose={ this.onDeployContractClose } />
|
||||
);
|
||||
}
|
||||
|
||||
onDeployContractClose = () => {
|
||||
this.setState({ deployContract: false });
|
||||
}
|
||||
|
||||
onDeployContract = () => {
|
||||
this.setState({ deployContract: true });
|
||||
}
|
||||
|
||||
onAddContractClose = () => {
|
||||
this.setState({ addContract: false });
|
||||
}
|
||||
|
||||
onAddContract = () => {
|
||||
this.setState({ addContract: true });
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts, contracts, hasContracts } = state.personal;
|
||||
const { balances } = state.balances;
|
||||
|
||||
return {
|
||||
accounts,
|
||||
contracts,
|
||||
hasContracts,
|
||||
balances
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Contracts);
|
||||
17
js/src/views/Contracts/index.js
Normal file
17
js/src/views/Contracts/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './contracts';
|
||||
22
js/src/views/Dapp/dapp.css
Normal file
22
js/src/views/Dapp/dapp.css
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.frame {
|
||||
border: 0;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
48
js/src/views/Dapp/dapp.js
Normal file
48
js/src/views/Dapp/dapp.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import styles from './dapp.css';
|
||||
|
||||
const hostname = `${window.location.hostname}:${window.location.port}`;
|
||||
const dapphost = (hostname === 'localhost:3000') || (hostname === '127.0.0.1:3000')
|
||||
? hostname
|
||||
: '127.0.0.1:8080/ui';
|
||||
|
||||
export default class Dapp extends Component {
|
||||
static propTypes = {
|
||||
params: PropTypes.object
|
||||
};
|
||||
|
||||
render () {
|
||||
const { name, type } = this.props.params;
|
||||
const src = type === 'global'
|
||||
? `http://${dapphost}/${name}.html`
|
||||
: `http://127.0.0.1:8080/${name}/`;
|
||||
|
||||
return (
|
||||
<iframe
|
||||
className={ styles.frame }
|
||||
frameBorder={ 0 }
|
||||
name={ name }
|
||||
sandbox='allow-scripts'
|
||||
scrolling='auto'
|
||||
src={ src }>
|
||||
</iframe>
|
||||
);
|
||||
}
|
||||
}
|
||||
17
js/src/views/Dapp/index.js
Normal file
17
js/src/views/Dapp/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './dapp';
|
||||
17
js/src/views/Dapps/Summary/index.js
Normal file
17
js/src/views/Dapps/Summary/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './summary';
|
||||
43
js/src/views/Dapps/Summary/summary.css
Normal file
43
js/src/views/Dapps/Summary/summary.css
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
top: 1.5em;
|
||||
left: 1.5em;
|
||||
border-radius: 50%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-left: 72px;
|
||||
}
|
||||
|
||||
.title {
|
||||
mragin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.author, .version {
|
||||
font-size: 0.75em;
|
||||
opacity: 0.5;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
60
js/src/views/Dapps/Summary/summary.js
Normal file
60
js/src/views/Dapps/Summary/summary.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
|
||||
import styles from './summary.css';
|
||||
|
||||
export default class Summary extends Component {
|
||||
static contextTypes = {
|
||||
api: React.PropTypes.object
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
app: PropTypes.object.isRequired,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
render () {
|
||||
const { app } = this.props;
|
||||
|
||||
if (!app) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = `/app/${app.local ? 'local' : 'global'}/${app.url}`;
|
||||
const image = app.image
|
||||
? <img src={ app.image } className={ styles.image } />
|
||||
: <div className={ styles.image }> </div>;
|
||||
|
||||
return (
|
||||
<Container className={ styles.container }>
|
||||
{ image }
|
||||
<div className={ styles.description }>
|
||||
<ContainerTitle
|
||||
className={ styles.title }
|
||||
title={ <Link to={ url }>{ app.name }</Link> }
|
||||
byline={ app.description } />
|
||||
<div className={ styles.author }>{ app.author }, v{ app.version }</div>
|
||||
{ this.props.children }
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
40
js/src/views/Dapps/dapps.css
Normal file
40
js/src/views/Dapps/dapps.css
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.list+.list {
|
||||
margin-top: -0.25em;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 0 1 50%;
|
||||
width: 50%;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.item:nth-child(odd) {
|
||||
padding-right: 0.125em;
|
||||
}
|
||||
|
||||
.item:nth-child(even) {
|
||||
padding-left: 0.125em;
|
||||
}
|
||||
168
js/src/views/Dapps/dapps.js
Normal file
168
js/src/views/Dapps/dapps.js
Normal file
@@ -0,0 +1,168 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { sha3 } from '../../api/util/sha3';
|
||||
import Contracts from '../../contracts';
|
||||
import { hashToImageUrl } from '../../redux/util';
|
||||
import { Actionbar, Page } from '../../ui';
|
||||
|
||||
import Summary from './Summary';
|
||||
|
||||
import styles from './dapps.css';
|
||||
|
||||
const APPS = [
|
||||
{
|
||||
name: 'Token Deployment',
|
||||
description: 'Deploy new basic tokens that you are able to send around',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'basiccoin',
|
||||
version: '1.0.0'
|
||||
},
|
||||
{
|
||||
name: 'GAVcoin',
|
||||
description: 'Manage your GAVcoins, the hottest new property in crypto',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'gavcoin',
|
||||
version: '1.0.0'
|
||||
},
|
||||
{
|
||||
name: 'Registry',
|
||||
description: 'A global registry of addresses on the network',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'registry',
|
||||
version: '1.0.0'
|
||||
},
|
||||
{
|
||||
name: 'Token Registry',
|
||||
description: 'A registry of transactable tokens on the network',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'tokenreg',
|
||||
version: '1.0.0'
|
||||
},
|
||||
{
|
||||
name: 'Method Registry',
|
||||
description: 'A registry of method signatures for lookups on transactions',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'signaturereg',
|
||||
version: '1.0.0'
|
||||
},
|
||||
{
|
||||
name: 'GitHub Hint',
|
||||
description: 'A mapping of GitHub URLs to hashes for use in contracts as references',
|
||||
author: 'Ethcore <admin@ethcore.io>',
|
||||
url: 'githubhint',
|
||||
version: '1.0.0'
|
||||
}
|
||||
];
|
||||
|
||||
APPS.forEach((app) => {
|
||||
app.id = sha3(app.url);
|
||||
console.log(`dapps ${app.id} -> ${app.url}`);
|
||||
});
|
||||
|
||||
export default class Dapps extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
state = {
|
||||
globalApps: APPS,
|
||||
localApps: []
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.loadLocalApps();
|
||||
this.loadImages();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<Actionbar
|
||||
title='Decentralized Applications' />
|
||||
<Page>
|
||||
<div className={ styles.list }>
|
||||
{ this.renderGlobalApps() }
|
||||
</div>
|
||||
<div className={ styles.list }>
|
||||
{ this.renderLocalApps() }
|
||||
</div>
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderApp = (app) => {
|
||||
return (
|
||||
<div
|
||||
className={ styles.item }
|
||||
key={ app.url }>
|
||||
<Summary app={ app } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderGlobalApps () {
|
||||
const { globalApps } = this.state;
|
||||
|
||||
return globalApps.map(this.renderApp);
|
||||
}
|
||||
|
||||
renderLocalApps () {
|
||||
const { localApps } = this.state;
|
||||
|
||||
return localApps.map(this.renderApp);
|
||||
}
|
||||
|
||||
loadLocalApps () {
|
||||
fetch('http://127.0.0.1:8080/api/apps', { method: 'GET' })
|
||||
.then((response) => response.ok ? response.json() : [])
|
||||
.then((_localApps) => {
|
||||
const localApps = _localApps
|
||||
.filter((app) => !['home', 'status', 'parity', 'wallet'].includes(app.id))
|
||||
.map((app) => {
|
||||
app.image = `/app/${app.id}/${app.iconUrl}`;
|
||||
app.url = app.id;
|
||||
app.local = true;
|
||||
return app;
|
||||
});
|
||||
console.log('loadLocalApps', localApps);
|
||||
this.setState({ localApps });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('loadLocalApps', error);
|
||||
});
|
||||
}
|
||||
|
||||
loadImages () {
|
||||
const { globalApps } = this.state;
|
||||
const { dappReg } = Contracts.get();
|
||||
|
||||
Promise
|
||||
.all(globalApps.map((app) => dappReg.getImage(app.id)))
|
||||
.then((images) => {
|
||||
globalApps.forEach((app, index) => {
|
||||
app.image = hashToImageUrl(images[index]);
|
||||
});
|
||||
this.setState({ globalApps });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('loadImages', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Dapps/index.js
Normal file
17
js/src/views/Dapps/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './dapps';
|
||||
17
js/src/views/ParityBar/index.js
Normal file
17
js/src/views/ParityBar/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './parityBar';
|
||||
153
js/src/views/ParityBar/parityBar.css
Normal file
153
js/src/views/ParityBar/parityBar.css
Normal file
@@ -0,0 +1,153 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.bar, .expanded {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.bar {
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.expanded {
|
||||
right: 16px;
|
||||
width: 964px;
|
||||
height: 288px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.expanded .content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.corner {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 16px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.cornercolor {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
.link {
|
||||
white-space: nowrap;
|
||||
border: none;
|
||||
outline: none !important;
|
||||
color: white !important;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.link img, .link svg {
|
||||
height: 24px !important;
|
||||
width: 24px !important;
|
||||
margin: 2px 0.5em 0 0;
|
||||
}
|
||||
|
||||
.link+.link {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.button {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.label {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.labelText {
|
||||
text-transform: uppercase;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.labelBubble {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: -10px;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 36px;
|
||||
padding: 0.5em 1em;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.header:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.header button,
|
||||
.corner button {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.header svg ,
|
||||
.coner svg {
|
||||
fill: white !important;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.actions {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.actions div {
|
||||
margin-left: 1em;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.parityIcon, .signerIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
vertical-align: middle;
|
||||
margin-left: 12px;
|
||||
}
|
||||
170
js/src/views/ParityBar/parityBar.js
Normal file
170
js/src/views/ParityBar/parityBar.js
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import ContentClear from 'material-ui/svg-icons/content/clear';
|
||||
|
||||
import { Badge, Button, ContainerTitle, ParityBackground, SignerIcon } from '../../ui';
|
||||
import { Embedded as Signer } from '../Signer';
|
||||
|
||||
import imagesEthcoreBlock from '../../../assets/images/ethcore-block.png';
|
||||
import styles from './parityBar.css';
|
||||
|
||||
class ParityBar extends Component {
|
||||
static propTypes = {
|
||||
pending: PropTypes.array,
|
||||
dapp: PropTypes.bool
|
||||
}
|
||||
|
||||
state = {
|
||||
opened: false
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const count = this.props.pending.length;
|
||||
const newCount = nextProps.pending.length;
|
||||
|
||||
if (count === newCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count < newCount) {
|
||||
this.setState({ opened: true });
|
||||
} else if (newCount === 0 && count === 1) {
|
||||
this.setState({ opened: false });
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { opened } = this.state;
|
||||
|
||||
return opened
|
||||
? this.renderExpanded()
|
||||
: this.renderBar();
|
||||
}
|
||||
|
||||
renderBar () {
|
||||
const { dapp } = this.props;
|
||||
|
||||
if (!dapp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parityIcon = (
|
||||
<img
|
||||
src={ imagesEthcoreBlock }
|
||||
className={ styles.parityIcon } />
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={ styles.bar }>
|
||||
<ParityBackground className={ styles.corner }>
|
||||
<div className={ styles.cornercolor }>
|
||||
<Link to='/apps'>
|
||||
<Button
|
||||
className={ styles.button }
|
||||
icon={ parityIcon }
|
||||
label={ this.renderLabel('Parity') } />
|
||||
</Link>
|
||||
<Button
|
||||
className={ styles.button }
|
||||
icon={ <SignerIcon className={ styles.signerIcon } /> }
|
||||
label={ this.renderSignerLabel() }
|
||||
onClick={ this.toggleDisplay } />
|
||||
</div>
|
||||
</ParityBackground>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderExpanded () {
|
||||
return (
|
||||
<div className={ styles.overlay }>
|
||||
<ParityBackground className={ styles.expanded }>
|
||||
<div className={ styles.header }>
|
||||
<div className={ styles.title }>
|
||||
<ContainerTitle title='Parity Signer: Pending' />
|
||||
</div>
|
||||
<div className={ styles.actions }>
|
||||
<Button
|
||||
icon={ <ContentClear /> }
|
||||
label='Close'
|
||||
onClick={ this.toggleDisplay } />
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.content }>
|
||||
<Signer />
|
||||
</div>
|
||||
</ParityBackground>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderLabel (name, bubble) {
|
||||
return (
|
||||
<div className={ styles.label }>
|
||||
<div className={ styles.labelText }>
|
||||
{ name }
|
||||
</div>
|
||||
{ bubble }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderSignerLabel () {
|
||||
const { pending } = this.props;
|
||||
let bubble = null;
|
||||
|
||||
if (pending && pending.length) {
|
||||
bubble = (
|
||||
<Badge
|
||||
color='red'
|
||||
className={ styles.labelBubble }
|
||||
value={ pending.length } />
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderLabel('Signer', bubble);
|
||||
}
|
||||
|
||||
toggleDisplay = () => {
|
||||
const { opened } = this.state;
|
||||
|
||||
this.setState({
|
||||
opened: !opened
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { pending } = state.signer;
|
||||
|
||||
return {
|
||||
pending
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ParityBar);
|
||||
46
js/src/views/Settings/Background/background.css
Normal file
46
js/src/views/Settings/Background/background.css
Normal file
@@ -0,0 +1,46 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.bgcontainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.bgflex {
|
||||
flex-basis: 25%;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
padding: 0 0.5em 1em 0.5em;
|
||||
}
|
||||
|
||||
.bgseed {
|
||||
background: black;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.seed,
|
||||
.seedactive {
|
||||
height: 10em;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.seed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
142
js/src/views/Settings/Background/background.js
Normal file
142
js/src/views/Settings/Background/background.js
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import NavigationRefresh from 'material-ui/svg-icons/navigation/refresh';
|
||||
|
||||
import { Button, Container, ContainerTitle, ParityBackground } from '../../../ui';
|
||||
|
||||
import { updateBackground } from '../actions';
|
||||
|
||||
import layout from '../layout.css';
|
||||
import styles from './background.css';
|
||||
|
||||
let counter = 0;
|
||||
|
||||
class Background extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired,
|
||||
muiTheme: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
settings: PropTypes.object.isRequired,
|
||||
updateBackground: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
state = {
|
||||
seeds: []
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { settings } = this.props;
|
||||
|
||||
this.setState({
|
||||
seeds: [settings.backgroundSeed]
|
||||
}, () => this.addSeeds(19));
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Background Pattern' />
|
||||
<div className={ layout.layout }>
|
||||
<div className={ layout.overview }>
|
||||
<p><strong>The background pattern you can see right now is unique to your Parity installation. It will change every time you create a new Signer token.</strong> This is so that decentralized applications cannot pretend to be trustworthy.</p>
|
||||
<p>Pick a pattern you like and memorize it. This Pattern will always be shown from now on, unless you clear your browser's cache or use a new Signer token.</p>
|
||||
</div>
|
||||
<div className={ layout.details }>
|
||||
<div className={ styles.bgcontainer }>
|
||||
{ this.renderBackgrounds() }
|
||||
</div>
|
||||
<Button
|
||||
icon={ <NavigationRefresh /> }
|
||||
label='generate more'
|
||||
onClick={ this.generateMore } />
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderBackgrounds () {
|
||||
const { settings } = this.props;
|
||||
const { seeds } = this.state;
|
||||
|
||||
return seeds.map((seed) => {
|
||||
return (
|
||||
<div className={ styles.bgflex } key={ seed }>
|
||||
<div className={ styles.bgseed }>
|
||||
<ParityBackground
|
||||
className={ settings.backgroundSeed === seed ? styles.seedactive : styles.seed }
|
||||
seed={ seed }
|
||||
onClick={ this.onSelect(seed) } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
onSelect = (seed) => {
|
||||
const { muiTheme } = this.context;
|
||||
const { updateBackground } = this.props;
|
||||
|
||||
return (event) => {
|
||||
muiTheme.parity.setBackgroundSeed(seed);
|
||||
updateBackground(seed);
|
||||
};
|
||||
}
|
||||
|
||||
generateMore = () => {
|
||||
this.addSeeds(20);
|
||||
}
|
||||
|
||||
addSeeds (count) {
|
||||
const { seeds } = this.state;
|
||||
const newSeeds = [];
|
||||
|
||||
for (let index = 0; index < count; index++) {
|
||||
newSeeds.push(this.generateSeed());
|
||||
}
|
||||
|
||||
this.setState({
|
||||
seeds: seeds.concat(newSeeds)
|
||||
});
|
||||
}
|
||||
|
||||
generateSeed () {
|
||||
const { api, muiTheme } = this.context;
|
||||
|
||||
return api.util.sha3(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { settings } = state;
|
||||
|
||||
return { settings };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ updateBackground }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Background);
|
||||
17
js/src/views/Settings/Background/index.js
Normal file
17
js/src/views/Settings/Background/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './background';
|
||||
97
js/src/views/Settings/Views/defaults.js
Normal file
97
js/src/views/Settings/Views/defaults.js
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from 'react';
|
||||
import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet';
|
||||
import ActionTrackChanges from 'material-ui/svg-icons/action/track-changes';
|
||||
import ActionSettings from 'material-ui/svg-icons/action/settings';
|
||||
import CommunicationContacts from 'material-ui/svg-icons/communication/contacts';
|
||||
import ImageGridOn from 'material-ui/svg-icons/image/grid-on';
|
||||
import NavigationApps from 'material-ui/svg-icons/navigation/apps';
|
||||
|
||||
import { SignerIcon } from '../../../ui';
|
||||
|
||||
import styles from './views.css';
|
||||
|
||||
const defaultViews = {
|
||||
accounts: {
|
||||
active: true,
|
||||
fixed: true,
|
||||
icon: <ActionAccountBalanceWallet />,
|
||||
label: 'Accounts',
|
||||
route: '/accounts',
|
||||
value: 'account',
|
||||
description: 'A list of all the accounts associated to and imported into this Parity instance. Send transactions, receive incoming values, manage your balances and fund your accounts.'
|
||||
},
|
||||
|
||||
addresses: {
|
||||
active: true,
|
||||
icon: <CommunicationContacts />,
|
||||
label: 'Addressbook',
|
||||
route: '/addresses',
|
||||
value: 'address',
|
||||
description: 'A list of all contacts and address book entries that is managed by this Parity instance. Watch accounts and have the details available at the click of a button when transacting.'
|
||||
},
|
||||
|
||||
apps: {
|
||||
active: true,
|
||||
icon: <NavigationApps />,
|
||||
label: 'Applications',
|
||||
route: '/apps',
|
||||
value: 'app',
|
||||
description: 'Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and interact with application from around the newtork.'
|
||||
},
|
||||
|
||||
contracts: {
|
||||
active: false,
|
||||
icon: <ImageGridOn />,
|
||||
label: 'Contracts',
|
||||
route: '/contracts',
|
||||
value: 'contract',
|
||||
description: 'Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focussed environment, specifically for advanced users that understand the inner working of certain contracts.'
|
||||
},
|
||||
|
||||
status: {
|
||||
active: false,
|
||||
icon: <ActionTrackChanges />,
|
||||
label: 'Status',
|
||||
route: '/status',
|
||||
value: 'status',
|
||||
description: 'See how the Parity node is performing in terms of connections to the network, logs from the actual running instance and details of mining (if enabled and configured).'
|
||||
},
|
||||
|
||||
signer: {
|
||||
active: true,
|
||||
fixed: true,
|
||||
icon: <SignerIcon className={ styles.signerIcon } />,
|
||||
label: 'Signer',
|
||||
route: '/signer',
|
||||
value: 'signer',
|
||||
description: 'The security focussed area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by distributed applications.'
|
||||
},
|
||||
|
||||
settings: {
|
||||
active: true,
|
||||
fixed: true,
|
||||
icon: <ActionSettings />,
|
||||
label: 'Settings',
|
||||
route: '/settings',
|
||||
value: 'settings',
|
||||
description: 'This view. Allows you to customize the application in term of options, operation and look and feel.'
|
||||
}
|
||||
};
|
||||
|
||||
export default defaultViews;
|
||||
23
js/src/views/Settings/Views/index.js
Normal file
23
js/src/views/Settings/Views/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import defaultViews from './defaults';
|
||||
|
||||
export default from './views';
|
||||
|
||||
export {
|
||||
defaultViews
|
||||
};
|
||||
49
js/src/views/Settings/Views/views.css
Normal file
49
js/src/views/Settings/Views/views.css
Normal file
@@ -0,0 +1,49 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.signerIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.view {
|
||||
}
|
||||
|
||||
.view+.view {
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
.header {
|
||||
}
|
||||
|
||||
.labelicon {
|
||||
display: inline-block;
|
||||
margin-right: 0.75em;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
line-height: 24px;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #aaa;
|
||||
padding-left: 4.75em;
|
||||
}
|
||||
101
js/src/views/Settings/Views/views.js
Normal file
101
js/src/views/Settings/Views/views.js
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Checkbox } from 'material-ui';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
|
||||
import { toggleView } from '../actions';
|
||||
|
||||
import layout from '../layout.css';
|
||||
import styles from './views.css';
|
||||
|
||||
class Views extends Component {
|
||||
static propTypes = {
|
||||
settings: PropTypes.object.isRequired,
|
||||
toggleView: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Views' />
|
||||
<div className={ layout.layout }>
|
||||
<div className={ layout.overview }>
|
||||
<div>Manage the available application views, using only the parts of the application that is applicable to you.</div>
|
||||
<div>Are you an end-user? The defaults are setups for both beginner and advanced users alike.</div>
|
||||
<div>Are you a developer? Add some features to manage contracts are interact with application develoyments.</div>
|
||||
<div>Are you a miner or run a large-scale node? Add the features to give you all the information needed to watch the node operation.</div>
|
||||
</div>
|
||||
<div className={ layout.details }>
|
||||
{ this.renderViews() }
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderViews () {
|
||||
const { settings, toggleView } = this.props;
|
||||
|
||||
return Object.keys(settings.views).map((id) => {
|
||||
const toggle = () => toggleView(id);
|
||||
const view = settings.views[id];
|
||||
const label = (
|
||||
<div className={ styles.header }>
|
||||
<div className={ styles.labelicon }>
|
||||
{ view.icon }
|
||||
</div>
|
||||
<div className={ styles.label }>
|
||||
{ view.label }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={ styles.view } key={ id }>
|
||||
<Checkbox
|
||||
disabled={ view.fixed }
|
||||
label={ label }
|
||||
onCheck={ toggle }
|
||||
checked={ view.active }
|
||||
value={ view.active } />
|
||||
<div className={ styles.info }>
|
||||
{ view.description }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { settings } = state;
|
||||
|
||||
return { settings };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ toggleView }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Views);
|
||||
29
js/src/views/Settings/actions.js
Normal file
29
js/src/views/Settings/actions.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export function toggleView (viewId) {
|
||||
return {
|
||||
type: 'toggleView',
|
||||
viewId
|
||||
};
|
||||
}
|
||||
|
||||
export function updateBackground (backgroundSeed) {
|
||||
return {
|
||||
type: 'updateBackground',
|
||||
backgroundSeed
|
||||
};
|
||||
}
|
||||
31
js/src/views/Settings/index.js
Normal file
31
js/src/views/Settings/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import settingsReducer from './reducers';
|
||||
import { toggleView, updateBackground } from './actions';
|
||||
import SettingsBackground from './Background';
|
||||
import SettingsViews, { defaultViews } from './Views';
|
||||
|
||||
export default from './settings';
|
||||
|
||||
export {
|
||||
SettingsBackground,
|
||||
SettingsViews,
|
||||
defaultViews,
|
||||
settingsReducer,
|
||||
toggleView,
|
||||
updateBackground
|
||||
};
|
||||
54
js/src/views/Settings/layout.css
Normal file
54
js/src/views/Settings/layout.css
Normal file
@@ -0,0 +1,54 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.layout {
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
.layout::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.overview, .details {
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.overview {
|
||||
width: 33.33333%;
|
||||
width: -webkit-calc(100% / 12 * 4);
|
||||
width: -moz-calc(100% / 12 * 4);
|
||||
width: calc(100% / 12 * 4);
|
||||
}
|
||||
|
||||
.overview {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.overview>div+div {
|
||||
padding-top: 1.25em;
|
||||
}
|
||||
|
||||
.details {
|
||||
width: 66.66665%;
|
||||
width: -webkit-calc(100% / 12 * 8);
|
||||
width: -moz-calc(100% / 12 * 8);
|
||||
width: calc(100% / 12 * 8);
|
||||
padding-left: 3em;
|
||||
}
|
||||
125
js/src/views/Settings/middleware.js
Normal file
125
js/src/views/Settings/middleware.js
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import defaultViews from './Views/defaults';
|
||||
|
||||
function initBackground (store, api) {
|
||||
const backgroundSeed = loadBackground() || api.util.sha3(`${Date.now()}`);
|
||||
|
||||
store.dispatch({
|
||||
type: 'updateBackground',
|
||||
backgroundSeed
|
||||
});
|
||||
}
|
||||
|
||||
function loadBackground () {
|
||||
return window.localStorage.getItem('backgroundSeed');
|
||||
}
|
||||
|
||||
function saveBackground (backgroundSeed) {
|
||||
window.localStorage.setItem('backgroundSeed', backgroundSeed);
|
||||
}
|
||||
|
||||
function initViews (store) {
|
||||
const { settings } = store.getState();
|
||||
const data = loadViews();
|
||||
const viewIds = Object.keys(data).filter((viewId) => {
|
||||
return settings.views[viewId] && data[viewId].active !== settings.views[viewId].active;
|
||||
});
|
||||
|
||||
if (viewIds.length) {
|
||||
store.dispatch({ type: 'toggleViews', viewIds });
|
||||
}
|
||||
}
|
||||
|
||||
function getFixedViews () {
|
||||
const views = {};
|
||||
|
||||
Object.keys(defaultViews).forEach((id) => {
|
||||
if (defaultViews[id].fixed) {
|
||||
views[id] = { active: true };
|
||||
}
|
||||
});
|
||||
|
||||
return views;
|
||||
}
|
||||
|
||||
function getDefaultViews () {
|
||||
const views = {};
|
||||
|
||||
Object.keys(defaultViews).forEach((id) => {
|
||||
views[id] = {
|
||||
active: defaultViews[id].active || false
|
||||
};
|
||||
});
|
||||
|
||||
return views;
|
||||
}
|
||||
|
||||
function loadViews () {
|
||||
const fixed = getFixedViews();
|
||||
const defaults = getDefaultViews();
|
||||
let data;
|
||||
|
||||
try {
|
||||
const json = window.localStorage.getItem('views') || '{}';
|
||||
|
||||
data = Object.assign(defaults, JSON.parse(json), fixed);
|
||||
} catch (e) {
|
||||
data = defaults;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function saveViews (store) {
|
||||
window.localStorage.setItem('views', JSON.stringify(getDefaultViews()));
|
||||
}
|
||||
|
||||
function toggleViews (store, viewIds) {
|
||||
viewIds.forEach((id) => {
|
||||
defaultViews[id].active = !defaultViews[id].active;
|
||||
});
|
||||
|
||||
saveViews(store);
|
||||
}
|
||||
|
||||
export default class SettingsMiddleware {
|
||||
toMiddleware () {
|
||||
return (store) => (next) => (action) => {
|
||||
switch (action.type) {
|
||||
case 'initAll':
|
||||
initBackground(store, action.api);
|
||||
initViews(store);
|
||||
break;
|
||||
|
||||
case 'toggleView':
|
||||
toggleViews(store, [action.viewId]);
|
||||
break;
|
||||
|
||||
case 'toggleViews':
|
||||
toggleViews(store, action.viewIds);
|
||||
break;
|
||||
|
||||
case 'updateBackground':
|
||||
saveBackground(action.backgroundSeed);
|
||||
break;
|
||||
}
|
||||
|
||||
next(action);
|
||||
};
|
||||
}
|
||||
}
|
||||
40
js/src/views/Settings/reducers.js
Normal file
40
js/src/views/Settings/reducers.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { handleActions } from 'redux-actions';
|
||||
|
||||
import views from './Views/defaults';
|
||||
|
||||
const initialState = {
|
||||
views,
|
||||
backgroundSeed: `${Date.now()}`
|
||||
};
|
||||
|
||||
export default handleActions({
|
||||
toggleView (state, action) {
|
||||
return Object.assign({}, state, { views });
|
||||
},
|
||||
|
||||
toggleViews (state, action) {
|
||||
return Object.assign({}, state, { views });
|
||||
},
|
||||
|
||||
updateBackground (state, action) {
|
||||
const { backgroundSeed } = action;
|
||||
|
||||
return Object.assign({}, state, { backgroundSeed });
|
||||
}
|
||||
}, initialState);
|
||||
62
js/src/views/Settings/settings.css
Normal file
62
js/src/views/Settings/settings.css
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.layout {
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bar {
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
margin-left: 3em;
|
||||
}
|
||||
|
||||
.tab,
|
||||
.tabactive {
|
||||
padding: 16px 2em !important;
|
||||
line-height: 24px !important;
|
||||
}
|
||||
|
||||
.tabactive {
|
||||
}
|
||||
|
||||
.tab>div,
|
||||
.tabactive>div {
|
||||
height: 24px !important;
|
||||
}
|
||||
|
||||
.tab>div>div,
|
||||
.tabactive>div>div {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.tab svg,
|
||||
.tabactive svg {
|
||||
margin-right: 0.5em;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.tab .menu,
|
||||
.tabactive .menu {
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
82
js/src/views/Settings/settings.js
Normal file
82
js/src/views/Settings/settings.js
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// 0xecf69634885f27a8f78161e530f15a8d3b57d39e755c222c92cf297b6e25aaaa
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Tab, Tabs } from 'material-ui';
|
||||
import ImageBlurOn from 'material-ui/svg-icons/image/blur-on';
|
||||
import ImageRemoveRedEye from 'material-ui/svg-icons/image/remove-red-eye';
|
||||
|
||||
import { Actionbar, Page } from '../../ui';
|
||||
|
||||
import styles from './settings.css';
|
||||
|
||||
export default class Settings extends Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.layout }>
|
||||
<Actionbar title='settings' className={ styles.bar }>
|
||||
{ this.renderTabs() }
|
||||
</Actionbar>
|
||||
<Page>
|
||||
{ children }
|
||||
</Page>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTabs () {
|
||||
const hash = (window.location.hash || '').split('?')[0].split('/')[2];
|
||||
|
||||
return (
|
||||
<Tabs className={ styles.tabs } value={ hash }>
|
||||
<Tab
|
||||
className={ hash === 'views' ? styles.tabactive : styles.tab }
|
||||
value='views'
|
||||
key='views'
|
||||
icon={ <ImageRemoveRedEye /> }
|
||||
label={ <div className={ styles.menu }>views</div> }
|
||||
onActive={ this.onActivate('views') } />
|
||||
<Tab
|
||||
className={ hash === 'background' ? styles.tabactive : styles.tab }
|
||||
value='background'
|
||||
key='background'
|
||||
icon={ <ImageBlurOn /> }
|
||||
label={ <div className={ styles.menu }>background</div> }
|
||||
onActive={ this.onActivate('background') } />
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
onActivate = (section) => {
|
||||
const { router } = this.context;
|
||||
|
||||
return (event) => {
|
||||
router.push(`/settings/${section}`);
|
||||
};
|
||||
}
|
||||
}
|
||||
44
js/src/views/Signer/components/Account/Account.css
Normal file
44
js/src/views/Signer/components/Account/Account.css
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.acc {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.acc > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.address {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.acc img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
vertical-align: middle;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.name {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
display: lock;
|
||||
vertical-align: middle;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
109
js/src/views/Signer/components/Account/Account.js
Normal file
109
js/src/views/Signer/components/Account/Account.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { IdentityIcon, IdentityName } from '../../../../ui';
|
||||
import AccountLink from './AccountLink';
|
||||
|
||||
import styles from './Account.css';
|
||||
|
||||
export default class Account extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
address: PropTypes.string.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
balance: PropTypes.object // eth BigNumber, not required since it mght take time to fetch
|
||||
};
|
||||
|
||||
state = {
|
||||
balanceDisplay: '?'
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
this.updateBalanceDisplay(this.props.balance);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.balance === this.props.balance) {
|
||||
return;
|
||||
}
|
||||
this.updateBalanceDisplay(nextProps.balance);
|
||||
}
|
||||
|
||||
updateBalanceDisplay (balance) {
|
||||
this.setState({
|
||||
balanceDisplay: balance ? balance.div(1e18).toFormat(3) : '?'
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { address, chain, className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.acc} ${className}` }>
|
||||
<AccountLink address={ address } chain={ chain }>
|
||||
<IdentityIcon
|
||||
center
|
||||
address={ address } />
|
||||
</AccountLink>
|
||||
{ this.renderName() }
|
||||
{ this.renderBalance() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBalance () {
|
||||
const { balanceDisplay } = this.state;
|
||||
return (
|
||||
<span> <strong>{ balanceDisplay }</strong> <small>ETH</small></span>
|
||||
);
|
||||
}
|
||||
|
||||
renderName () {
|
||||
const { address } = this.props;
|
||||
const name = <IdentityName address={ address } empty />;
|
||||
|
||||
if (!name) {
|
||||
return (
|
||||
<AccountLink address={ address } chain={ this.props.chain }>
|
||||
[{ this.shortAddress(address) }]
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountLink address={ address } chain={ this.props.chain } >
|
||||
<span>
|
||||
<span className={ styles.name }>{ name }</span>
|
||||
<span className={ styles.address }>[{ this.tinyAddress(address) }]</span>
|
||||
</span>
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
tinyAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
return address.slice(2, 4) + '..' + address.slice(len - 2);
|
||||
}
|
||||
|
||||
shortAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
return address.slice(2, 8) + '..' + address.slice(len - 7);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { getAccountLink } from '../../util/account';
|
||||
import styles from './AccountLink.css';
|
||||
|
||||
export default class AccountLink extends Component {
|
||||
static propTypes = {
|
||||
chain: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
}
|
||||
|
||||
state = {
|
||||
link: null
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { address, chain } = this.props;
|
||||
|
||||
this.updateLink(address, chain);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { address, chain } = nextProps;
|
||||
|
||||
this.updateLink(address, chain);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, address, className } = this.props;
|
||||
return (
|
||||
<a
|
||||
href={ this.state.link }
|
||||
target='_blank'
|
||||
className={ `${styles.container} ${className}` }
|
||||
>
|
||||
{ children || address }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
updateLink (address, chain) {
|
||||
const link = getAccountLink(address, chain);
|
||||
|
||||
this.setState({
|
||||
link
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/Account/AccountLink/index.js
Normal file
17
js/src/views/Signer/components/Account/AccountLink/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './AccountLink';
|
||||
17
js/src/views/Signer/components/Account/index.js
Normal file
17
js/src/views/Signer/components/Account/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './Account';
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionFinishedWeb3 from '../TransactionFinishedWeb3';
|
||||
import SignWeb3 from '../SignRequestWeb3';
|
||||
|
||||
export default class RequestFinishedWeb3 extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
result: PropTypes.any.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
msg: PropTypes.string,
|
||||
status: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
render () {
|
||||
const { payload, id, result, msg, status, error, date, className } = this.props;
|
||||
|
||||
if (payload.sign) {
|
||||
const { sign } = payload;
|
||||
return (
|
||||
<SignWeb3
|
||||
className={ className }
|
||||
isFinished
|
||||
id={ id }
|
||||
address={ sign.address }
|
||||
hash={ sign.hash }
|
||||
result={ result }
|
||||
msg={ msg }
|
||||
status={ status }
|
||||
error={ error }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
return (
|
||||
<TransactionFinishedWeb3
|
||||
className={ className }
|
||||
txHash={ result }
|
||||
id={ id }
|
||||
gasPrice={ transaction.gasPrice }
|
||||
gas={ transaction.gas }
|
||||
from={ transaction.from }
|
||||
to={ transaction.to }
|
||||
value={ transaction.value }
|
||||
msg={ msg }
|
||||
date={ date }
|
||||
status={ status }
|
||||
error={ error }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Unknown payload
|
||||
return null;
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/RequestFinishedWeb3/index.js
Normal file
17
js/src/views/Signer/components/RequestFinishedWeb3/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './RequestFinishedWeb3';
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import TransactionPendingWeb3 from '../TransactionPendingWeb3';
|
||||
import SignRequestWeb3 from '../SignRequestWeb3';
|
||||
|
||||
export default class RequestPendingWeb3 extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
render () {
|
||||
const { payload, id, className, isSending, date, onConfirm, onReject } = this.props;
|
||||
|
||||
if (payload.sign) {
|
||||
const { sign } = payload;
|
||||
return (
|
||||
<SignRequestWeb3
|
||||
className={ className }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
isFinished={ false }
|
||||
id={ id }
|
||||
address={ sign.address }
|
||||
hash={ sign.hash }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
return (
|
||||
<TransactionPendingWeb3
|
||||
className={ className }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
id={ id }
|
||||
gasPrice={ transaction.gasPrice }
|
||||
gas={ transaction.gas }
|
||||
data={ transaction.data }
|
||||
from={ transaction.from }
|
||||
to={ transaction.to }
|
||||
value={ transaction.value }
|
||||
date={ date }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Unknown payload
|
||||
return null;
|
||||
}
|
||||
}
|
||||
17
js/src/views/Signer/components/RequestPendingWeb3/index.js
Normal file
17
js/src/views/Signer/components/RequestPendingWeb3/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './RequestPendingWeb3';
|
||||
74
js/src/views/Signer/components/SignRequest/SignRequest.css
Normal file
74
js/src/views/Signer/components/SignRequest/SignRequest.css
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
padding: 25px 0 15px;
|
||||
}
|
||||
|
||||
.actions, .signDetails {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.signDetails {
|
||||
border-right: 1px solid #eee;
|
||||
margin-right: 2rem;
|
||||
/* TODO [todr] mess - just to align with transaction */
|
||||
width: 430px;
|
||||
}
|
||||
|
||||
.address, .info {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 0 30px;
|
||||
width: 250px;
|
||||
color: #E53935;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.info p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* TODO [todr] copy&paste from transactions */
|
||||
.isConfirmed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.isRejected {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.txHash {
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.actions {
|
||||
width: 180px;
|
||||
display: inline-block;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.signDetails img {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
}
|
||||
113
js/src/views/Signer/components/SignRequest/SignRequest.js
Normal file
113
js/src/views/Signer/components/SignRequest/SignRequest.js
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import Account from '../Account';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
import TxHashLink from '../TxHashLink';
|
||||
|
||||
import styles from './SignRequest.css';
|
||||
|
||||
export default class SignRequest extends Component {
|
||||
|
||||
// TODO [todr] re-use proptypes?
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
hash: PropTypes.string.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
chain: PropTypes.string.isRequired,
|
||||
balance: PropTypes.object,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
status: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
render () {
|
||||
const className = this.props.className || '';
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderDetails() }
|
||||
{ this.renderActions() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDetails () {
|
||||
const { address, balance, chain, hash } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.signDetails }>
|
||||
<div className={ styles.address }>
|
||||
<Account address={ address } balance={ balance } chain={ chain } />
|
||||
</div>
|
||||
<div className={ styles.info } title={ hash }>
|
||||
<p>Dapp is requesting to sign arbitrary transaction using this account.</p>
|
||||
<p><strong>Confirm the transaction only if you trust the app.</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { address, isFinished, status } = this.props;
|
||||
|
||||
if (isFinished) {
|
||||
if (status === 'confirmed') {
|
||||
const { chain, hash } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isConfirmed }>Confirmed</span>
|
||||
<div>
|
||||
Transaction hash:
|
||||
<TxHashLink chain={ chain } txHash={ hash } className={ styles.txHash } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isRejected }>Rejected</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingForm
|
||||
address={ address }
|
||||
isSending={ this.props.isSending }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
className={ styles.actions }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = password => {
|
||||
const { id } = this.props;
|
||||
this.props.onConfirm({ id, password });
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
|
||||
}
|
||||
17
js/src/views/Signer/components/SignRequest/index.js
Normal file
17
js/src/views/Signer/components/SignRequest/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './SignRequest';
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import SignRequest from '../SignRequest';
|
||||
|
||||
export default class SignRequestWeb3 extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
hash: PropTypes.string.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
status: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
chain: 'homestead',
|
||||
balance: null // avoid required prop loading warning
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.fetchChain();
|
||||
this.fetchBalance();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { balance, chain } = this.state;
|
||||
const { address, onConfirm, onReject, isSending, isFinished, hash, className, id, status } = this.props;
|
||||
|
||||
return (
|
||||
<SignRequest
|
||||
address={ address }
|
||||
hash={ hash }
|
||||
balance={ balance }
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
isSending={ isSending }
|
||||
isFinished={ isFinished }
|
||||
id={ id }
|
||||
chain={ chain }
|
||||
status={ status }
|
||||
className={ className }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
fetchChain () {
|
||||
const { api } = this.context;
|
||||
|
||||
api.ethcore
|
||||
.getNetChain()
|
||||
.then((chain) => {
|
||||
this.setState({ chain });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchChain', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchBalance () {
|
||||
const { api } = this.context;
|
||||
const { address } = this.props;
|
||||
|
||||
api.eth
|
||||
.getBalance(address)
|
||||
.then((balance) => {
|
||||
this.setState({ balance });
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('fetchBalance', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user