Merge branch 'master' into jg-signer-decoding
# Conflicts: # js/src/views/Signer/components/RequestFinished/requestFinished.js
This commit is contained in:
@@ -144,7 +144,8 @@ export function outSignerRequest (request) {
|
||||
break;
|
||||
|
||||
case 'payload':
|
||||
request[key].transaction = outTransaction(request[key].transaction);
|
||||
request[key].signTransaction = outTransaction(request[key].signTransaction);
|
||||
request[key].sendTransaction = outTransaction(request[key].sendTransaction);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
1
js/src/contracts/abi/badgereg.json
Normal file
1
js/src/contracts/abi/badgereg.json
Normal file
@@ -0,0 +1 @@
|
||||
[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"fromName","outputs":[{"name":"id","type":"uint256"},{"name":"addr","type":"address"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"badgeCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"}],"name":"meta","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"}],"name":"unregister","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"fromAddress","outputs":[{"name":"id","type":"uint256"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"badge","outputs":[{"name":"addr","type":"address"},{"name":"name","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"},{"name":"_value","type":"bytes32"}],"name":"setMeta","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_name","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"registerAs","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"addr","type":"address"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"id","type":"uint256"}],"name":"Unregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"key","type":"bytes32"},{"indexed":false,"name":"value","type":"bytes32"}],"name":"MetaChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
|
||||
1
js/src/contracts/abi/certifier.json
Normal file
1
js/src/contracts/abi/certifier.json
Normal file
@@ -0,0 +1 @@
|
||||
[{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"}]
|
||||
@@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import badgereg from './badgereg.json';
|
||||
import basiccoin from './basiccoin.json';
|
||||
import basiccoinmanager from './basiccoinmanager.json';
|
||||
import dappreg from './dappreg.json';
|
||||
@@ -28,6 +29,7 @@ import tokenreg from './tokenreg.json';
|
||||
import wallet from './wallet.json';
|
||||
|
||||
export {
|
||||
badgereg,
|
||||
basiccoin,
|
||||
basiccoinmanager,
|
||||
dappreg,
|
||||
|
||||
66
js/src/contracts/badgereg.js
Normal file
66
js/src/contracts/badgereg.js
Normal file
@@ -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 { bytesToHex, hex2Ascii } from '../api/util/format';
|
||||
|
||||
import ABI from './abi/certifier.json';
|
||||
|
||||
const ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
export default class BadgeReg {
|
||||
constructor (api, registry) {
|
||||
this._api = api;
|
||||
this._registry = registry;
|
||||
|
||||
registry.getContract('badgereg');
|
||||
this.certifiers = {}; // by name
|
||||
this.contracts = {}; // by name
|
||||
}
|
||||
|
||||
fetchCertifier (name) {
|
||||
if (this.certifiers[name]) {
|
||||
return Promise.resolve(this.certifiers[name]);
|
||||
}
|
||||
return this._registry.getContract('badgereg')
|
||||
.then((badgeReg) => {
|
||||
return badgeReg.instance.fromName.call({}, [name])
|
||||
.then(([ id, address ]) => {
|
||||
return Promise.all([
|
||||
badgeReg.instance.meta.call({}, [id, 'TITLE']),
|
||||
badgeReg.instance.meta.call({}, [id, 'IMG'])
|
||||
])
|
||||
.then(([ title, img ]) => {
|
||||
title = bytesToHex(title);
|
||||
title = title === ZERO ? null : hex2Ascii(title);
|
||||
if (bytesToHex(img) === ZERO) img = null;
|
||||
|
||||
const data = { address, name, title, icon: img };
|
||||
this.certifiers[name] = data;
|
||||
return data;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
checkIfCertified (certifier, address) {
|
||||
if (!this.contracts[certifier]) {
|
||||
this.contracts[certifier] = this._api.newContract(ABI, certifier);
|
||||
}
|
||||
const contract = this.contracts[certifier];
|
||||
|
||||
return contract.instance.certified.call({}, [address]);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import SignatureReg from './signaturereg';
|
||||
import TokenReg from './tokenreg';
|
||||
import GithubHint from './githubhint';
|
||||
import * as smsVerification from './sms-verification';
|
||||
import BadgeReg from './badgereg';
|
||||
|
||||
let instance = null;
|
||||
|
||||
@@ -33,6 +34,7 @@ export default class Contracts {
|
||||
this._signaturereg = new SignatureReg(api, this._registry);
|
||||
this._tokenreg = new TokenReg(api, this._registry);
|
||||
this._githubhint = new GithubHint(api, this._registry);
|
||||
this.badgeReg = new BadgeReg(api, this._registry);
|
||||
}
|
||||
|
||||
get registry () {
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import injectTapEventPlugin from 'react-tap-event-plugin';
|
||||
import { useStrict } from 'mobx';
|
||||
|
||||
injectTapEventPlugin();
|
||||
useStrict(true);
|
||||
|
||||
import Application from './dappreg/Application';
|
||||
|
||||
|
||||
@@ -11,28 +11,23 @@
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
font-family: Roboto;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: #ddd;
|
||||
background: white;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.loading {
|
||||
font-size: 4em;
|
||||
text-align: center;
|
||||
padding-top: 5em;
|
||||
font-size: 2em;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div class="loading-container">
|
||||
<span class="loading">Loading...</span>
|
||||
</div>
|
||||
<div class="loading">Loading</div>
|
||||
</div>
|
||||
<script src="vendor.js"></script>
|
||||
<% if (!htmlWebpackPlugin.options.secure) { %>
|
||||
|
||||
@@ -11,28 +11,23 @@
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
font-family: Roboto;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: #ddd;
|
||||
background: white;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.loading {
|
||||
font-size: 4em;
|
||||
text-align: center;
|
||||
padding-top: 5em;
|
||||
font-size: 2em;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div class="loading-container">
|
||||
<span class="loading">Loading...</span>
|
||||
</div>
|
||||
<div class="loading">Loading</span>
|
||||
</div>
|
||||
<script src="vendor.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -20,6 +20,7 @@ import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
|
||||
import ContentClear from 'material-ui/svg-icons/content/clear';
|
||||
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
import PrintIcon from 'material-ui/svg-icons/action/print';
|
||||
|
||||
import { Button, Modal } from '../../ui';
|
||||
|
||||
@@ -32,6 +33,11 @@ import NewImport from './NewImport';
|
||||
import RawKey from './RawKey';
|
||||
import RecoveryPhrase from './RecoveryPhrase';
|
||||
|
||||
import { createIdentityImg } from '../../api/util/identity';
|
||||
import print from './print';
|
||||
import recoveryPage from './recovery-page.ejs';
|
||||
import ParityLogo from '../../../assets/images/parity-logo-black-no-text.svg';
|
||||
|
||||
const TITLES = {
|
||||
type: 'creation type',
|
||||
create: 'create account',
|
||||
@@ -179,12 +185,18 @@ export default class CreateAccount extends Component {
|
||||
];
|
||||
|
||||
case 2:
|
||||
return (
|
||||
return [
|
||||
createType === 'fromNew' || createType === 'fromPhrase' ? (
|
||||
<Button
|
||||
icon={ <PrintIcon /> }
|
||||
label='Print Phrase'
|
||||
onClick={ this.printPhrase } />
|
||||
) : null,
|
||||
<Button
|
||||
icon={ <ActionDoneAll /> }
|
||||
label='Close'
|
||||
onClick={ this.onClose } />
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,4 +389,11 @@ export default class CreateAccount extends Component {
|
||||
|
||||
store.dispatch({ type: 'newError', error });
|
||||
}
|
||||
|
||||
printPhrase = () => {
|
||||
const { address, phrase, name } = this.state;
|
||||
const identity = createIdentityImg(address);
|
||||
|
||||
print(recoveryPage({ phrase, name, identity, address, logo: ParityLogo }));
|
||||
}
|
||||
}
|
||||
|
||||
63
js/src/modals/CreateAccount/print.js
Normal file
63
js/src/modals/CreateAccount/print.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 const onPrint = (window, cb) => {
|
||||
let called = false; let query, queryFn;
|
||||
|
||||
const onPrint = () => {
|
||||
if (queryFn) {
|
||||
query.removeListener(queryFn);
|
||||
}
|
||||
window.removeEventListener('afterprint', onPrint, false);
|
||||
if (!called) {
|
||||
called = true;
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
if (window.matchMedia) {
|
||||
queryFn = (query) => {
|
||||
if (!query.matches) {
|
||||
onPrint();
|
||||
}
|
||||
};
|
||||
query = window.matchMedia('print');
|
||||
query.addListener(queryFn);
|
||||
}
|
||||
window.addEventListener('afterprint', onPrint, false);
|
||||
};
|
||||
|
||||
export default (html) => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('sandbox', 'allow-modals allow-same-origin allow-scripts');
|
||||
iframe.setAttribute('src', '/');
|
||||
iframe.setAttribute('style', 'display: none');
|
||||
document.body.appendChild(iframe);
|
||||
const teardown = () => {
|
||||
// Safari crashes without a timeout.
|
||||
setTimeout(() => document.body.removeChild(iframe), 0);
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
iframe.contentDocument.write(html);
|
||||
|
||||
setTimeout(() => {
|
||||
onPrint(iframe.contentWindow, teardown);
|
||||
iframe.contentWindow.focus();
|
||||
iframe.contentWindow.print();
|
||||
}, 20);
|
||||
}, 0);
|
||||
};
|
||||
49
js/src/modals/CreateAccount/recovery-page.ejs
Normal file
49
js/src/modals/CreateAccount/recovery-page.ejs
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Recovery phrase for <%= name %></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<style>
|
||||
body {
|
||||
margin: 2em auto;
|
||||
max-width: 30em;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
font-size: 110%;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
#logo {
|
||||
max-width: 4rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
figure {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
figure.address img {
|
||||
border-radius: 100%;
|
||||
}
|
||||
pre code {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
line-height: 1.3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img id="logo" src="<%= logo %>" alt="Parity Logo" />
|
||||
<p>This is your account <em><%= name %></em>:</p>
|
||||
<figure class="address">
|
||||
<img src="<%= identity %>" alt="symbol for the address of the account" />
|
||||
<figcaption><code><%= address %></code></figcaption>
|
||||
</figure>
|
||||
<p>This is the recovery phrase:</p>
|
||||
<pre><code><%= phrase %></code></pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import ActionDone from 'material-ui/svg-icons/action/done';
|
||||
import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
|
||||
import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
import PrintIcon from 'material-ui/svg-icons/action/print';
|
||||
|
||||
import { Button, Modal } from '../../ui';
|
||||
|
||||
@@ -27,6 +28,11 @@ import Completed from './Completed';
|
||||
import TnC from './TnC';
|
||||
import Welcome from './Welcome';
|
||||
|
||||
import { createIdentityImg } from '../../api/util/identity';
|
||||
import print from '../CreateAccount/print';
|
||||
import recoveryPage from '../CreateAccount/recovery-page.ejs';
|
||||
import ParityLogo from '../../../assets/images/parity-logo-black-no-text.svg';
|
||||
|
||||
const STAGE_NAMES = ['welcome', 'terms', 'new account', 'recovery', 'completed'];
|
||||
|
||||
export default class FirstRun extends Component {
|
||||
@@ -107,7 +113,6 @@ export default class FirstRun extends Component {
|
||||
|
||||
switch (stage) {
|
||||
case 0:
|
||||
case 3:
|
||||
return (
|
||||
<Button
|
||||
icon={ <NavigationArrowForward /> }
|
||||
@@ -133,6 +138,20 @@ export default class FirstRun extends Component {
|
||||
onClick={ this.onCreate } />
|
||||
);
|
||||
|
||||
case 3:
|
||||
return [
|
||||
<Button
|
||||
icon={ <PrintIcon /> }
|
||||
label='Print Phrase'
|
||||
onClick={ this.printPhrase }
|
||||
/>,
|
||||
<Button
|
||||
icon={ <NavigationArrowForward /> }
|
||||
label='Next'
|
||||
onClick={ this.onNext }
|
||||
/>
|
||||
];
|
||||
|
||||
case 4:
|
||||
return (
|
||||
<Button
|
||||
@@ -205,4 +224,11 @@ export default class FirstRun extends Component {
|
||||
|
||||
store.dispatch({ type: 'newError', error });
|
||||
}
|
||||
|
||||
printPhrase = () => {
|
||||
const { address, phrase, name } = this.state;
|
||||
const identity = createIdentityImg(address);
|
||||
|
||||
print(recoveryPage({ phrase, name, identity, address, logo: ParityLogo }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,20 @@ import SettingsMiddleware from '../views/Settings/middleware';
|
||||
import SignerMiddleware from './providers/signerMiddleware';
|
||||
|
||||
import statusMiddleware from '../views/Status/middleware';
|
||||
import CertificationsMiddleware from './providers/certifications/middleware';
|
||||
|
||||
export default function (api) {
|
||||
const errors = new ErrorsMiddleware();
|
||||
const signer = new SignerMiddleware(api);
|
||||
const settings = new SettingsMiddleware();
|
||||
const status = statusMiddleware();
|
||||
const certifications = new CertificationsMiddleware();
|
||||
|
||||
const middleware = [
|
||||
settings.toMiddleware(),
|
||||
signer.toMiddleware(),
|
||||
errors.toMiddleware()
|
||||
errors.toMiddleware(),
|
||||
certifications.toMiddleware()
|
||||
];
|
||||
|
||||
return middleware.concat(status, thunk);
|
||||
|
||||
23
js/src/redux/providers/certifications/actions.js
Normal file
23
js/src/redux/providers/certifications/actions.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/>.
|
||||
|
||||
export const fetchCertifications = (address) => ({
|
||||
type: 'fetchCertifications', address
|
||||
});
|
||||
|
||||
export const addCertification = (address, name, title, icon) => ({
|
||||
type: 'addCertification', address, name, title, icon
|
||||
});
|
||||
51
js/src/redux/providers/certifications/middleware.js
Normal file
51
js/src/redux/providers/certifications/middleware.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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 Contracts from '../../../contracts';
|
||||
import { addCertification } from './actions';
|
||||
|
||||
const knownCertifiers = [ 'smsverification' ];
|
||||
|
||||
export default class CertificationsMiddleware {
|
||||
toMiddleware () {
|
||||
return (store) => (next) => (action) => {
|
||||
if (action.type !== 'fetchCertifications') {
|
||||
return next(action);
|
||||
}
|
||||
|
||||
const { address } = action;
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
|
||||
knownCertifiers.forEach((name) => {
|
||||
badgeReg.fetchCertifier(name)
|
||||
.then((cert) => {
|
||||
return badgeReg.checkIfCertified(cert.address, address)
|
||||
.then((isCertified) => {
|
||||
if (isCertified) {
|
||||
const { name, title, icon } = cert;
|
||||
store.dispatch(addCertification(address, name, title, icon));
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err) {
|
||||
console.error(`Failed to check if ${address} certified by ${name}:`, err);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
33
js/src/redux/providers/certifications/reducer.js
Normal file
33
js/src/redux/providers/certifications/reducer.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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/>.
|
||||
|
||||
const initialState = {};
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
if (action.type !== 'addCertification') {
|
||||
return state;
|
||||
}
|
||||
|
||||
const { address, name, icon, title } = action;
|
||||
const certifications = state[address] || [];
|
||||
|
||||
if (certifications.some((c) => c.name === name)) {
|
||||
return state;
|
||||
}
|
||||
const newCertifications = certifications.concat({ name, icon, title });
|
||||
|
||||
return { ...state, [address]: newCertifications };
|
||||
};
|
||||
@@ -72,9 +72,8 @@ export default class SignerMiddleware {
|
||||
};
|
||||
|
||||
// Sign request in-browser
|
||||
if (wallet && payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
|
||||
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||
if (wallet && transaction) {
|
||||
(transaction.nonce.isZero()
|
||||
? this._api.parity.nextNonce(transaction.from)
|
||||
: Promise.resolve(transaction.nonce)
|
||||
|
||||
@@ -18,6 +18,7 @@ import { combineReducers } from 'redux';
|
||||
import { routerReducer } from 'react-router-redux';
|
||||
|
||||
import { apiReducer, balancesReducer, blockchainReducer, compilerReducer, imagesReducer, personalReducer, signerReducer, statusReducer as nodeStatusReducer, snackbarReducer } from './providers';
|
||||
import certificationsReducer from './providers/certifications/reducer';
|
||||
|
||||
import errorReducer from '../ui/Errors/reducers';
|
||||
import settingsReducer from '../views/Settings/reducers';
|
||||
@@ -32,6 +33,7 @@ export default function () {
|
||||
settings: settingsReducer,
|
||||
|
||||
balances: balancesReducer,
|
||||
certifications: certificationsReducer,
|
||||
blockchain: blockchainReducer,
|
||||
compiler: compilerReducer,
|
||||
images: imagesReducer,
|
||||
|
||||
46
js/src/ui/Certifications/certifications.css
Normal file
46
js/src/ui/Certifications/certifications.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/>.
|
||||
*/
|
||||
|
||||
.certifications {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.certification {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-right: .5em;
|
||||
padding: .3em .6em .2em 2.6em;
|
||||
border-radius: 1em;
|
||||
line-height: 1em;
|
||||
text-transform: uppercase;
|
||||
background-color: rgba(255, 255, 255, 0.07);
|
||||
}
|
||||
|
||||
.certification:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: -.25em;
|
||||
left: 0;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-radius: 1em;
|
||||
}
|
||||
87
js/src/ui/Certifications/certifications.js
Normal file
87
js/src/ui/Certifications/certifications.js
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/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { hashToImageUrl } from '../../redux/providers/imagesReducer';
|
||||
import { fetchCertifications } from '../../redux/providers/certifications/actions';
|
||||
|
||||
import defaultIcon from '../../../assets/images/certifications/unknown.svg';
|
||||
|
||||
import styles from './certifications.css';
|
||||
|
||||
class Certifications extends Component {
|
||||
static propTypes = {
|
||||
account: PropTypes.string.isRequired,
|
||||
certifications: PropTypes.array.isRequired,
|
||||
dappsUrl: PropTypes.string.isRequired,
|
||||
|
||||
fetchCertifications: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
const { account, fetchCertifications } = this.props;
|
||||
fetchCertifications(account);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { certifications } = this.props;
|
||||
|
||||
if (certifications.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.certifications }>
|
||||
{ certifications.map(this.renderCertification) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderCertification = (certification) => {
|
||||
const { name, title, icon } = certification;
|
||||
const { dappsUrl } = this.props;
|
||||
|
||||
const classNames = `${styles.certification} ${!icon ? styles.noIcon : ''}`;
|
||||
const img = icon ? dappsUrl + hashToImageUrl(icon) : defaultIcon;
|
||||
return (
|
||||
<div className={ classNames } key={ name }>
|
||||
<img className={ styles.icon } src={ img } />
|
||||
<div className={ styles.text }>{ title || name }</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (_, initProps) {
|
||||
const { account } = initProps;
|
||||
|
||||
return (state) => {
|
||||
const certifications = state.certifications[account] || [];
|
||||
return { certifications };
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ fetchCertifications }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Certifications);
|
||||
17
js/src/ui/Certifications/index.js
Normal file
17
js/src/ui/Certifications/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 './certifications';
|
||||
@@ -92,7 +92,9 @@ export default class Store {
|
||||
|
||||
Promise
|
||||
.all(txhashes.map((txhash) => this._api.eth.getTransactionByHash(txhash)))
|
||||
.then((transactions) => {
|
||||
.then((_transactions) => {
|
||||
const transactions = _transactions.filter((tx) => tx);
|
||||
|
||||
this.addTransactions(
|
||||
transactions.reduce((transactions, tx, index) => {
|
||||
transactions[txhashes[index]] = tx;
|
||||
|
||||
@@ -23,6 +23,7 @@ import Badge from './Badge';
|
||||
import Balance from './Balance';
|
||||
import BlockStatus from './BlockStatus';
|
||||
import Button from './Button';
|
||||
import Certifications from './Certifications';
|
||||
import ConfirmDialog from './ConfirmDialog';
|
||||
import Container, { Title as ContainerTitle } from './Container';
|
||||
import ContextProvider from './ContextProvider';
|
||||
@@ -55,6 +56,7 @@ export {
|
||||
Balance,
|
||||
BlockStatus,
|
||||
Button,
|
||||
Certifications,
|
||||
ConfirmDialog,
|
||||
Container,
|
||||
ContainerTitle,
|
||||
|
||||
@@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags } from '../../../ui';
|
||||
import CopyToClipboard from '../../../ui/CopyToClipboard';
|
||||
import Certifications from '../../../ui/Certifications';
|
||||
|
||||
import styles from './header.css';
|
||||
|
||||
@@ -32,6 +33,7 @@ export default class Header extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { api } = this.context;
|
||||
const { account, balance } = this.props;
|
||||
const { address, meta, uuid } = account;
|
||||
|
||||
@@ -67,6 +69,10 @@ export default class Header extends Component {
|
||||
<Balance
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
<Certifications
|
||||
account={ account.address }
|
||||
dappsUrl={ api.dappsUrl }
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
|
||||
@@ -64,12 +64,6 @@ class Account extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { api } = this.context;
|
||||
const { address } = this.props.params;
|
||||
const { isTestnet } = this.props;
|
||||
|
||||
const verificationStore = new VerificationStore(api, address, isTestnet);
|
||||
this.setState({ verificationStore });
|
||||
this.setVisibleAccounts();
|
||||
}
|
||||
|
||||
@@ -80,6 +74,15 @@ class Account extends Component {
|
||||
if (prevAddress !== nextAddress) {
|
||||
this.setVisibleAccounts(nextProps);
|
||||
}
|
||||
|
||||
const { isTestnet } = nextProps;
|
||||
if (typeof isTestnet === 'boolean' && !this.state.verificationStore) {
|
||||
const { api } = this.context;
|
||||
const { address } = nextProps.params;
|
||||
this.setState({
|
||||
verificationStore: new VerificationStore(api, address, isTestnet)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
@@ -115,7 +118,8 @@ class Account extends Component {
|
||||
<Page>
|
||||
<Header
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
balance={ balance }
|
||||
/>
|
||||
<Transactions
|
||||
accounts={ accounts }
|
||||
address={ address } />
|
||||
|
||||
@@ -19,10 +19,17 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { Snackbar as SnackbarMUI } from 'material-ui';
|
||||
import { darkBlack } from 'material-ui/styles/colors';
|
||||
import { darkBlack, grey800 } from 'material-ui/styles/colors';
|
||||
|
||||
import { closeSnackbar } from '../../../redux/providers/snackbarActions';
|
||||
|
||||
const bodyStyle = {
|
||||
backgroundColor: darkBlack,
|
||||
borderStyle: 'solid',
|
||||
borderColor: grey800,
|
||||
borderWidth: '1px 1px 0 1px'
|
||||
};
|
||||
|
||||
class Snackbar extends Component {
|
||||
static propTypes = {
|
||||
closeSnackbar: PropTypes.func.isRequired,
|
||||
@@ -40,7 +47,7 @@ class Snackbar extends Component {
|
||||
open={ open }
|
||||
message={ message }
|
||||
autoHideDuration={ cooldown }
|
||||
bodyStyle={ { backgroundColor: darkBlack } }
|
||||
bodyStyle={ bodyStyle }
|
||||
onRequestClose={ this.handleClose }
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -15,45 +15,46 @@
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.status {
|
||||
padding: 0.5em;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .4em .5em;
|
||||
font-size: x-small;
|
||||
color: #ccc;
|
||||
background-color: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 0.5em 0 2em;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.enode {
|
||||
word-wrap: break-word;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.enode > * {
|
||||
display: inline-block;
|
||||
margin: 0.25em 0.5em;
|
||||
vertical-align: top;
|
||||
margin: 0 .25em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.block {
|
||||
.enode > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.netinfo {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
color: #ddd;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.netinfo > * {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.network {
|
||||
padding: 0.25em 0.5em;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
border-radius: .4em;
|
||||
line-height: 1.2;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -65,14 +66,3 @@
|
||||
.networktest {
|
||||
background: rgb(136, 0, 0);
|
||||
}
|
||||
|
||||
.peers {
|
||||
}
|
||||
|
||||
.version {
|
||||
padding: 0.25em 0.5em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.syncing {
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ class Status extends Component {
|
||||
<div className={ styles.version }>
|
||||
{ clientVersion }
|
||||
</div>
|
||||
{ this.renderEnode() }
|
||||
<div className={ styles.netinfo }>
|
||||
<BlockStatus />
|
||||
<div className={ netStyle }>
|
||||
@@ -56,6 +55,7 @@ class Status extends Component {
|
||||
{ netPeers.active.toFormat() }/{ netPeers.connected.toFormat() }/{ netPeers.max.toFormat() } peers
|
||||
</div>
|
||||
</div>
|
||||
{ this.renderEnode() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ class Status extends Component {
|
||||
|
||||
return (
|
||||
<div className={ styles.enode }>
|
||||
<CopyToClipboard data={ enode } />
|
||||
<CopyToClipboard data={ enode } size={ 12 } />
|
||||
<div>{ abbreviated }</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -59,7 +59,7 @@ class Tab extends Component {
|
||||
selected={ active }
|
||||
icon={ view.icon }
|
||||
label={ label }
|
||||
onClick={ this.handleClick }
|
||||
onTouchTap={ this.handleClick }
|
||||
>
|
||||
{ children }
|
||||
</MUITab>
|
||||
|
||||
@@ -21,3 +21,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-bottom: 1.6em;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
import { Container } from '../../../ui';
|
||||
|
||||
import Event from './Event';
|
||||
import styles from '../contract.css';
|
||||
@@ -48,8 +48,7 @@ export default class Events extends Component {
|
||||
});
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='events' />
|
||||
<Container title='events'>
|
||||
<table className={ styles.events }>
|
||||
<tbody>{ list }</tbody>
|
||||
</table>
|
||||
|
||||
@@ -19,7 +19,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
||||
|
||||
import InputQuery from './inputQuery';
|
||||
import { Container, ContainerTitle, Input, InputAddress } from '../../../ui';
|
||||
import { Container, Input, InputAddress } from '../../../ui';
|
||||
|
||||
import styles from './queries.css';
|
||||
|
||||
@@ -55,8 +55,7 @@ export default class Queries extends Component {
|
||||
.map((fn) => this.renderInputQuery(fn));
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='queries' />
|
||||
<Container title='queries'>
|
||||
<div className={ styles.methods }>
|
||||
<div className={ styles.vMethods }>
|
||||
{ noInputQueries }
|
||||
|
||||
@@ -132,7 +132,8 @@ class Contract extends Component {
|
||||
<Page>
|
||||
<Header
|
||||
account={ account }
|
||||
balance={ balance } />
|
||||
balance={ balance }
|
||||
/>
|
||||
<Queries
|
||||
contract={ contract }
|
||||
values={ queryValues } />
|
||||
@@ -447,7 +448,10 @@ function mapStateToProps (state) {
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ newError, setVisibleAccounts }, dispatch);
|
||||
return bindActionCreators({
|
||||
newError,
|
||||
setVisibleAccounts
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
|
||||
@@ -42,25 +42,26 @@
|
||||
}
|
||||
|
||||
.expanded {
|
||||
right: 16px;
|
||||
max-height: 300px;
|
||||
right: 1em;
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 19em;
|
||||
}
|
||||
|
||||
.expanded .content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
min-height: 16em;
|
||||
}
|
||||
|
||||
.corner {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 16px;
|
||||
right: 1em;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 36px;
|
||||
height: 2em;
|
||||
padding: 0.5em 1em;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
margin-bottom: 0;
|
||||
@@ -148,6 +149,7 @@
|
||||
|
||||
.actions {
|
||||
float: right;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.actions div {
|
||||
|
||||
@@ -19,7 +19,7 @@ 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 { Button, Container, ParityBackground } from '../../../ui';
|
||||
|
||||
import { updateBackground } from '../actions';
|
||||
|
||||
@@ -55,8 +55,7 @@ class Background extends Component {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Background Pattern' />
|
||||
<Container title='Background Pattern'>
|
||||
<div className={ layout.layout }>
|
||||
<div className={ layout.overview }>
|
||||
<div>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. This is so that decentralized applications cannot pretend to be trustworthy.</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { MenuItem } from 'material-ui';
|
||||
|
||||
import { Select, Container, ContainerTitle } from '../../../ui';
|
||||
import { Select, Container } from '../../../ui';
|
||||
|
||||
import layout from '../layout.css';
|
||||
|
||||
@@ -43,8 +43,7 @@ export default class Parity extends Component {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Parity' />
|
||||
<Container title='Parity'>
|
||||
<div className={ layout.layout }>
|
||||
<div className={ layout.overview }>
|
||||
<div>Control the Parity node settings and mode of operation via this interface.</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
import { Container } from '../../../ui';
|
||||
|
||||
import layout from '../layout.css';
|
||||
import styles from './proxy.css';
|
||||
@@ -31,8 +31,7 @@ export default class Proxy extends Component {
|
||||
const proxyurl = `${dappsUrl}/proxy/proxy.pac`;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Proxy' />
|
||||
<Container title='Proxy'>
|
||||
<div className={ layout.layout }>
|
||||
<div className={ layout.overview }>
|
||||
<div>The proxy setup allows you to access Parity and all associated decentralized applications via memorable addresses.</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Checkbox } from 'material-ui';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../ui';
|
||||
import { Container } from '../../../ui';
|
||||
|
||||
import { toggleView } from '../actions';
|
||||
|
||||
@@ -34,8 +34,7 @@ class Views extends Component {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle title='Views' />
|
||||
<Container 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>
|
||||
|
||||
@@ -27,7 +27,8 @@ export default class RequestPending extends Component {
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ transaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ signTransaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
className: PropTypes.string,
|
||||
@@ -64,9 +65,8 @@ export default class RequestPending extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.transaction) {
|
||||
const { transaction } = payload;
|
||||
|
||||
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||
if (transaction) {
|
||||
return (
|
||||
<TransactionPending
|
||||
className={ className }
|
||||
|
||||
@@ -20,7 +20,7 @@ import AvPlay from 'material-ui/svg-icons/av/play-arrow';
|
||||
import AvReplay from 'material-ui/svg-icons/av/replay';
|
||||
import ReorderIcon from 'material-ui/svg-icons/action/reorder';
|
||||
|
||||
import { Container, ContainerTitle } from '../../../../ui';
|
||||
import { Container } from '../../../../ui';
|
||||
|
||||
import styles from './Debug.css';
|
||||
|
||||
@@ -42,9 +42,7 @@ export default class Debug extends Component {
|
||||
const { devLogsLevels } = nodeStatus;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<ContainerTitle
|
||||
title='Node Logs' />
|
||||
<Container title='Node Logs'>
|
||||
{ this.renderActions() }
|
||||
<h2 className={ styles.subheader }>
|
||||
{ devLogsLevels || '-' }
|
||||
|
||||
Reference in New Issue
Block a user