@@ -36,7 +36,7 @@
|
||||
"ci:build:npm": "NODE_ENV=production webpack --config webpack/npm",
|
||||
"start": "npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
||||
"start:app": "node webpack/dev.server",
|
||||
"clean": "rm -rf ./build ./coverage",
|
||||
"clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build",
|
||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||
"lint": "npm run lint:css && npm run lint:js",
|
||||
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
||||
|
||||
@@ -110,7 +110,8 @@ export function outPeers (peers) {
|
||||
return {
|
||||
active: outNumber(peers.active),
|
||||
connected: outNumber(peers.connected),
|
||||
max: outNumber(peers.max)
|
||||
max: outNumber(peers.max),
|
||||
peers: peers.peers.map(p => { Object.keys(p.protocols).forEach(k => { p.protocols[k].difficulty = outNumber(p.protocols[k].difficulty); }); return p; })
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -147,10 +147,50 @@ describe('api/format/output', () => {
|
||||
|
||||
describe('outPeers', () => {
|
||||
it('converts all internal numbers to BigNumbers', () => {
|
||||
expect(outPeers({ active: 789, connected: '456', max: 0x7b })).to.deep.equal({
|
||||
expect(outPeers({
|
||||
active: 789,
|
||||
connected: '456',
|
||||
max: 0x7b,
|
||||
peers: [
|
||||
{
|
||||
caps: ['par/1'],
|
||||
id: '0x01',
|
||||
name: 'Parity',
|
||||
network: {
|
||||
localAddress: '10.0.0.1',
|
||||
remoteAddress: '10.0.0.1'
|
||||
},
|
||||
protocols: {
|
||||
par: {
|
||||
difficulty: '0x0f',
|
||||
head: '0x02',
|
||||
version: 63
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})).to.deep.equal({
|
||||
active: new BigNumber(789),
|
||||
connected: new BigNumber(456),
|
||||
max: new BigNumber(123)
|
||||
max: new BigNumber(123),
|
||||
peers: [
|
||||
{
|
||||
caps: ['par/1'],
|
||||
id: '0x01',
|
||||
name: 'Parity',
|
||||
network: {
|
||||
localAddress: '10.0.0.1',
|
||||
remoteAddress: '10.0.0.1'
|
||||
},
|
||||
protocols: {
|
||||
par: {
|
||||
difficulty: new BigNumber(15),
|
||||
head: '0x02',
|
||||
version: 63
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,6 +54,11 @@ export default class Parity {
|
||||
.execute('parity_checkRequest', inNumber16(requestId));
|
||||
}
|
||||
|
||||
consensusCapability () {
|
||||
return this._transport
|
||||
.execute('parity_consensusCapability');
|
||||
}
|
||||
|
||||
dappsPort () {
|
||||
return this._transport
|
||||
.execute('parity_dappsPort')
|
||||
@@ -90,6 +95,11 @@ export default class Parity {
|
||||
.execute('parity_enode');
|
||||
}
|
||||
|
||||
executeUpgrade () {
|
||||
return this._transport
|
||||
.execute('parity_executeUpgrade');
|
||||
}
|
||||
|
||||
extraData () {
|
||||
return this._transport
|
||||
.execute('parity_extraData');
|
||||
@@ -243,6 +253,11 @@ export default class Parity {
|
||||
.then(outAddress);
|
||||
}
|
||||
|
||||
releasesInfo () {
|
||||
return this._transport
|
||||
.execute('parity_releasesInfo');
|
||||
}
|
||||
|
||||
removeReservedPeer (encode) {
|
||||
return this._transport
|
||||
.execute('parity_removeReservedPeer', encode);
|
||||
@@ -315,4 +330,14 @@ export default class Parity {
|
||||
.execute('parity_unsignedTransactionsCount')
|
||||
.then(outNumber);
|
||||
}
|
||||
|
||||
upgradeReady () {
|
||||
return this._transport
|
||||
.execute('parity_upgradeReady');
|
||||
}
|
||||
|
||||
versionInfo () {
|
||||
return this._transport
|
||||
.execute('parity_versionInfo');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ describe('api/rpc/parity', () => {
|
||||
|
||||
describe('newPeers', () => {
|
||||
it('returns the peer structure, formatted', () => {
|
||||
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789 } } }]);
|
||||
mockHttp([{ method: 'parity_netPeers', reply: { result: { active: 123, connected: 456, max: 789, peers: [] } } }]);
|
||||
|
||||
return instance.netPeers().then((peers) => {
|
||||
expect(peers.active.eq(123)).to.be.true;
|
||||
|
||||
@@ -100,6 +100,15 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
consensusCapability: {
|
||||
desc: 'Returns an object or string detailing the state of parity capability of maintaining consensus',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Object,
|
||||
desc: 'Either "capable", {"capableUntil":N}, {"incapableSince":N} or "unknown" (N is a block number)'
|
||||
}
|
||||
},
|
||||
|
||||
dappsPort: {
|
||||
desc: 'Returns the port the dapps are running on, error if not enabled',
|
||||
params: [],
|
||||
@@ -163,6 +172,15 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
executeUpgrade: {
|
||||
desc: 'Performs an upgrade',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Boolean,
|
||||
desc: 'returns true if the upgrade to the release specified in parity_upgradeReady was successfully executed, false if not'
|
||||
}
|
||||
},
|
||||
|
||||
extraData: {
|
||||
desc: 'Returns currently set extra data',
|
||||
params: [],
|
||||
@@ -468,6 +486,15 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
releasesInfo: {
|
||||
desc: 'returns a ReleasesInfo object describing the current status of releases',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Object,
|
||||
desc: '"fork":N,"minor":null,"this_fork":MN,"track":R} (N is a block number representing the latest known fork of this chain which may be in the future, MN is a block number representing the latest known fork that the currently running binary can sync past or null if not known, R is a ReleaseInfo object describing the latest release in this release track)'
|
||||
}
|
||||
},
|
||||
|
||||
removeReservedPeer: {
|
||||
desc: '?',
|
||||
params: [
|
||||
@@ -651,5 +678,23 @@ export default {
|
||||
type: Quantity,
|
||||
desc: 'Number of unsigned transactions'
|
||||
}
|
||||
},
|
||||
|
||||
upgradeReady: {
|
||||
desc: 'returns a ReleaseInfo object describing the release which is available for upgrade or null if none is available',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Object,
|
||||
desc: '{"binary":H,"fork":15100,"is_critical":true,"version":V} where H is the Keccak-256 checksum of the release parity binary and V is a VersionInfo object describing the release'
|
||||
}
|
||||
},
|
||||
|
||||
versionInfo: {
|
||||
desc: 'returns a VersionInfo object describing our current version',
|
||||
params: [],
|
||||
returns: {
|
||||
type: Object,
|
||||
desc: '{"hash":H,"track":T,"version":{"major":N,"minor":N,"patch":N}} (H is a 160-bit Git commit hash, T is a ReleaseTrack, either "stable", "beta", "nightly" or "unknown" and N is a version number)'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
17
js/src/modals/UpgradeParity/index.js
Normal file
17
js/src/modals/UpgradeParity/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Parity Technologies (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 './upgradeParity';
|
||||
146
js/src/modals/UpgradeParity/store.js
Normal file
146
js/src/modals/UpgradeParity/store.js
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2015, 2016 Parity Technologies (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 { action, computed, observable, transaction } from 'mobx';
|
||||
import store from 'store';
|
||||
|
||||
const LS_UPDATE = '_parity::update';
|
||||
|
||||
const A_MINUTE = 60 * 1000;
|
||||
const A_DAY = 24 * 60 * A_MINUTE;
|
||||
|
||||
const STEP_INFO = 0;
|
||||
const STEP_UPDATING = 1;
|
||||
const STEP_COMPLETED = 2;
|
||||
const STEP_ERROR = 2;
|
||||
|
||||
const CHECK_INTERVAL = 1 * A_MINUTE;
|
||||
|
||||
export default class Store {
|
||||
@observable available = null;
|
||||
@observable consensusCapability = null;
|
||||
@observable closed = true;
|
||||
@observable error = null;
|
||||
@observable remindAt = 0;
|
||||
@observable step = 0;
|
||||
@observable upgrading = null;
|
||||
@observable version = null;
|
||||
|
||||
constructor (api) {
|
||||
this._api = api;
|
||||
|
||||
this.loadStorage();
|
||||
this.checkUpgrade();
|
||||
|
||||
setInterval(this.checkUpgrade, CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
@computed get isVisible () {
|
||||
return !this.closed && Date.now() >= this.remindAt;
|
||||
}
|
||||
|
||||
@action closeModal = () => {
|
||||
transaction(() => {
|
||||
this.closed = true;
|
||||
this.setStep(0, null);
|
||||
});
|
||||
}
|
||||
|
||||
@action loadStorage = () => {
|
||||
const values = store.get(LS_UPDATE) || {};
|
||||
|
||||
this.remindAt = values.remindAt ? values.remindAt : 0;
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@action openModal = () => {
|
||||
this.closed = false;
|
||||
}
|
||||
|
||||
@action setStep = (step, error = null) => {
|
||||
transaction(() => {
|
||||
this.error = error;
|
||||
this.step = step;
|
||||
});
|
||||
}
|
||||
|
||||
@action setUpgrading () {
|
||||
transaction(() => {
|
||||
this.upgrading = this.available;
|
||||
this.setStep(STEP_UPDATING, null);
|
||||
});
|
||||
}
|
||||
|
||||
@action setVersions (available, version, consensusCapability) {
|
||||
transaction(() => {
|
||||
this.available = available;
|
||||
this.consensusCapability = consensusCapability;
|
||||
this.version = version;
|
||||
});
|
||||
}
|
||||
|
||||
@action snoozeTillTomorrow = () => {
|
||||
this.remindAt = Date.now() + A_DAY;
|
||||
store.set(LS_UPDATE, Object.assign(this.loadStorage(), { remindAt: this.remindAt }));
|
||||
}
|
||||
|
||||
@action upgradeNow = () => {
|
||||
this.setUpgrading();
|
||||
|
||||
return this._api.parity
|
||||
.executeUpgrade()
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
throw new Error('Unable to complete update');
|
||||
}
|
||||
|
||||
this.setStep(STEP_COMPLETED, null);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('upgradeNow', error);
|
||||
|
||||
this.setStep(STEP_ERROR, error);
|
||||
});
|
||||
}
|
||||
|
||||
checkUpgrade = () => {
|
||||
if (!this._api) {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise
|
||||
.all([
|
||||
this._api.parity.upgradeReady(),
|
||||
this._api.parity.consensusCapability(),
|
||||
this._api.parity.versionInfo()
|
||||
])
|
||||
.then(([available, consensusCapability, version]) => {
|
||||
console.log('[checkUpgrade]', 'available:', available, 'version:', version, 'consensusCapability:', consensusCapability);
|
||||
this.setVersions(available, version, consensusCapability);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('checkUpgrade', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
STEP_COMPLETED,
|
||||
STEP_ERROR,
|
||||
STEP_INFO,
|
||||
STEP_UPDATING
|
||||
};
|
||||
58
js/src/modals/UpgradeParity/store.spec.js
Normal file
58
js/src/modals/UpgradeParity/store.spec.js
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2015, 2016 Parity Technologies (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 Store from './store';
|
||||
|
||||
let store;
|
||||
|
||||
describe('modals/UpgradeParity/store', () => {
|
||||
describe('@actions', () => {
|
||||
beforeEach(() => {
|
||||
store = new Store();
|
||||
});
|
||||
|
||||
describe('openModal & closeModal', () => {
|
||||
it('toggles between the closed states', () => {
|
||||
expect(store.closed).to.be.true;
|
||||
store.openModal();
|
||||
expect(store.closed).to.be.false;
|
||||
store.closeModal();
|
||||
expect(store.closed).to.be.true;
|
||||
});
|
||||
|
||||
it('resets the step state upon closing', () => {
|
||||
store.setStep(5, 'soem error');
|
||||
store.closeModal();
|
||||
expect(store.step).to.equal(0);
|
||||
expect(store.error).to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('setStep', () => {
|
||||
it('sets the step as provided', () => {
|
||||
expect(store.step).to.equal(0);
|
||||
store.setStep(3);
|
||||
expect(store.step).to.equal(3);
|
||||
});
|
||||
|
||||
it('sets the error when provided', () => {
|
||||
expect(store.error).to.be.null;
|
||||
store.setStep(3, new Error('some error'));
|
||||
expect(store.error).to.match(/some error/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
32
js/src/modals/UpgradeParity/upgradeParity.css
Normal file
32
js/src/modals/UpgradeParity/upgradeParity.css
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2015, 2016 Parity Technologies (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-top: 1.25em;
|
||||
}
|
||||
|
||||
.infoStep {
|
||||
div+div {
|
||||
padding-top: 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.version {
|
||||
display: inline;
|
||||
opacity: 0.5;
|
||||
white-space: normal;
|
||||
}
|
||||
257
js/src/modals/UpgradeParity/upgradeParity.js
Normal file
257
js/src/modals/UpgradeParity/upgradeParity.js
Normal file
@@ -0,0 +1,257 @@
|
||||
// Copyright 2015, 2016 Parity Technologies (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 { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Button } from '~/ui';
|
||||
import { CancelIcon, DoneIcon, NextIcon } from '~/ui/Icons';
|
||||
import Modal, { Busy, Completed } from '~/ui/Modal';
|
||||
|
||||
import { STEP_COMPLETED, STEP_ERROR, STEP_INFO, STEP_UPDATING } from './store';
|
||||
import styles from './upgradeParity.css';
|
||||
|
||||
@observer
|
||||
export default class UpgradeParity extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
store: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { store } = this.props;
|
||||
|
||||
if (!store.isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
actions={ this.renderActions() }
|
||||
current={ store.step }
|
||||
steps={ [
|
||||
<FormattedMessage
|
||||
id='upgradeParity.step.info'
|
||||
key='info'
|
||||
defaultMessage='upgrade available' />,
|
||||
<FormattedMessage
|
||||
key='updating'
|
||||
id='upgradeParity.step.updating'
|
||||
defaultMessage='upgrading parity' />,
|
||||
store.step === STEP_ERROR
|
||||
? <FormattedMessage
|
||||
id='upgradeParity.step.error'
|
||||
key='error'
|
||||
defaultMessage='error' />
|
||||
: <FormattedMessage
|
||||
id='upgradeParity.step.completed'
|
||||
key='completed'
|
||||
defaultMessage='upgrade completed' />
|
||||
] }
|
||||
visible>
|
||||
{ this.renderStep() }
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { store } = this.props;
|
||||
|
||||
const closeButton =
|
||||
<Button
|
||||
icon={ <CancelIcon /> }
|
||||
key='close'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='upgradeParity.button.close'
|
||||
defaultMessage='close' />
|
||||
}
|
||||
onClick={ store.closeModal } />;
|
||||
const doneButton =
|
||||
<Button
|
||||
icon={ <DoneIcon /> }
|
||||
key='done'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='upgradeParity.button.done'
|
||||
defaultMessage='done' />
|
||||
}
|
||||
onClick={ store.closeModal } />;
|
||||
|
||||
switch (store.step) {
|
||||
case STEP_INFO:
|
||||
return [
|
||||
<Button
|
||||
icon={ <NextIcon /> }
|
||||
key='upgrade'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='upgradeParity.button.upgrade'
|
||||
defaultMessage='upgrade now' />
|
||||
}
|
||||
onClick={ store.upgradeNow } />,
|
||||
closeButton
|
||||
];
|
||||
|
||||
case STEP_UPDATING:
|
||||
return [
|
||||
closeButton
|
||||
];
|
||||
|
||||
case STEP_COMPLETED:
|
||||
case STEP_ERROR:
|
||||
return [
|
||||
doneButton
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
renderStep () {
|
||||
const { store } = this.props;
|
||||
|
||||
const currentversion = this.formatVersion(store);
|
||||
const newversion = store.upgrading
|
||||
? this.formatVersion(store.upgrading)
|
||||
: this.formatVersion(store.available);
|
||||
|
||||
switch (store.step) {
|
||||
case STEP_INFO:
|
||||
return (
|
||||
<div className={ styles.infoStep }>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.info.upgrade'
|
||||
defaultMessage='A new version of Parity, version {newversion} is available as an upgrade from your current version {currentversion}'
|
||||
values={ {
|
||||
currentversion: <div className={ styles.version }>{ currentversion }</div>,
|
||||
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||
} } />
|
||||
</div>
|
||||
{ this.renderConsensusInfo() }
|
||||
</div>
|
||||
);
|
||||
|
||||
case STEP_UPDATING:
|
||||
return (
|
||||
<Busy
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='upgradeParity.busy'
|
||||
defaultMessage='Your upgrade to Parity {newversion} is currently in progress'
|
||||
values={ {
|
||||
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||
} } />
|
||||
} />
|
||||
);
|
||||
|
||||
case STEP_COMPLETED:
|
||||
case STEP_ERROR:
|
||||
if (store.error) {
|
||||
return (
|
||||
<Completed>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.failed'
|
||||
defaultMessage='Your upgrade to Parity {newversion} has failed with an error.'
|
||||
values={ {
|
||||
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||
} } />
|
||||
</div>
|
||||
<div className={ styles.error }>
|
||||
{ store.error.message }
|
||||
</div>
|
||||
</Completed>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Completed>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.completed'
|
||||
defaultMessage='Your upgrade to Parity {newversion} has been successfully completed.'
|
||||
values={ {
|
||||
newversion: <div className={ styles.version }>{ newversion }</div>
|
||||
} } />
|
||||
</Completed>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderConsensusInfo () {
|
||||
const { store } = this.props;
|
||||
const { consensusCapability } = store;
|
||||
|
||||
if (consensusCapability) {
|
||||
if (consensusCapability === 'capable') {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.consensus.capable'
|
||||
defaultMessage='Your current Parity version is capable of handling the network requirements.' />
|
||||
</div>
|
||||
);
|
||||
} else if (consensusCapability.capableUntil) {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.consensus.capableUntil'
|
||||
defaultMessage='Your current Parity version is capable of handling the network requirements until block {blockNumber}'
|
||||
values={ {
|
||||
blockNumber: consensusCapability.capableUntil
|
||||
} } />
|
||||
</div>
|
||||
);
|
||||
} else if (consensusCapability.incapableSince) {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.consensus.incapableSince'
|
||||
defaultMessage='Your current Parity version is incapable of handling the network requirements since block {blockNumber}'
|
||||
values={ {
|
||||
blockNumber: consensusCapability.incapableSince
|
||||
} } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='upgradeParity.consensus.unknown'
|
||||
defaultMessage='Your current Parity version is capable of handling the network requirements.' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
formatVersion (struct) {
|
||||
if (!struct || !struct.version) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='upgradeParity.version.unknown'
|
||||
defaultMessage='unknown' />
|
||||
);
|
||||
}
|
||||
|
||||
const { track, version } = struct.version;
|
||||
|
||||
return `${version.major}.${version.minor}.${version.patch}-${track}`;
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,13 @@ import DeployContract from './DeployContract';
|
||||
import EditMeta from './EditMeta';
|
||||
import ExecuteContract from './ExecuteContract';
|
||||
import FirstRun from './FirstRun';
|
||||
import LoadContract from './LoadContract';
|
||||
import SaveContract from './SaveContract';
|
||||
import Shapeshift from './Shapeshift';
|
||||
import Verification from './Verification';
|
||||
import Transfer from './Transfer';
|
||||
import PasswordManager from './PasswordManager';
|
||||
import SaveContract from './SaveContract';
|
||||
import LoadContract from './LoadContract';
|
||||
import UpgradeParity from './UpgradeParity';
|
||||
import WalletSettings from './WalletSettings';
|
||||
|
||||
export {
|
||||
@@ -41,11 +42,12 @@ export {
|
||||
EditMeta,
|
||||
ExecuteContract,
|
||||
FirstRun,
|
||||
LoadContract,
|
||||
SaveContract,
|
||||
Shapeshift,
|
||||
Verification,
|
||||
Transfer,
|
||||
PasswordManager,
|
||||
LoadContract,
|
||||
SaveContract,
|
||||
UpgradeParity,
|
||||
WalletSettings
|
||||
};
|
||||
|
||||
31
js/src/ui/Icons/index.js
Normal file
31
js/src/ui/Icons/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2015, 2016 Parity Technologies (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 AddIcon from 'material-ui/svg-icons/content/add';
|
||||
import CancelIcon from 'material-ui/svg-icons/content/clear';
|
||||
import DoneIcon from 'material-ui/svg-icons/action/done-all';
|
||||
import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
|
||||
import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward';
|
||||
import SnoozeIcon from 'material-ui/svg-icons/av/snooze';
|
||||
|
||||
export {
|
||||
AddIcon,
|
||||
CancelIcon,
|
||||
DoneIcon,
|
||||
PrevIcon,
|
||||
NextIcon,
|
||||
SnoozeIcon
|
||||
};
|
||||
@@ -16,17 +16,19 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import styles from './busy.css';
|
||||
|
||||
export default class Busy extends Component {
|
||||
static propTypes = {
|
||||
title: PropTypes.string,
|
||||
state: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
children: PropTypes.node,
|
||||
state: nodeOrStringProptype(),
|
||||
title: nodeOrStringProptype()
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, title, state } = this.props;
|
||||
const { children, state, title } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.center }>
|
||||
|
||||
@@ -36,7 +36,13 @@ export default class Title extends Component {
|
||||
|
||||
return (
|
||||
<div className={ styles.title }>
|
||||
<h3>{ steps ? steps[current] : title }</h3>
|
||||
<h3>
|
||||
{
|
||||
steps
|
||||
? steps[current]
|
||||
: title
|
||||
}
|
||||
</h3>
|
||||
{ this.renderSteps() }
|
||||
{ this.renderWaiting() }
|
||||
</div>
|
||||
@@ -63,10 +69,10 @@ export default class Title extends Component {
|
||||
renderTimeline () {
|
||||
const { steps } = this.props;
|
||||
|
||||
return steps.map((label) => {
|
||||
return steps.map((label, index) => {
|
||||
return (
|
||||
<Step
|
||||
key={ label }>
|
||||
key={ label.key || index }>
|
||||
<StepLabel>
|
||||
{ label }
|
||||
</StepLabel>
|
||||
|
||||
@@ -14,16 +14,17 @@
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.actions {
|
||||
background: rgba(0, 0, 0, 0.25) !important;
|
||||
}
|
||||
|
||||
.actions button:not([disabled]) {
|
||||
color: white !important;
|
||||
}
|
||||
button:not([disabled]) {
|
||||
color: white !important;
|
||||
|
||||
.actions button:not([disabled]) svg {
|
||||
fill: white !important;
|
||||
svg {
|
||||
fill: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
@@ -36,26 +37,26 @@
|
||||
.content {
|
||||
transform: translate(0px, 0px) !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.content>div {
|
||||
background: rgba(0, 0, 0, 0.5) !important;
|
||||
transition: none !important;
|
||||
&>div {
|
||||
background: rgba(0, 0, 0, 0.5) !important;
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
background: rgba(0, 0, 0, 0.25) !important;
|
||||
padding: 1em;
|
||||
margin-bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.25) !important;
|
||||
}
|
||||
|
||||
.title h3 {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h3 {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.title .steps {
|
||||
margin-bottom: -1em;
|
||||
.steps {
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
}
|
||||
|
||||
.waiting {
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Dialog } from 'material-ui';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Dialog } from 'material-ui';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
@@ -51,7 +51,7 @@ class Modal extends Component {
|
||||
|
||||
render () {
|
||||
const { muiTheme } = this.context;
|
||||
const { actions, busy, className, current, children, compact, steps, waiting, title, visible, settings } = this.props;
|
||||
const { actions, busy, children, className, current, compact, settings, steps, title, visible, waiting } = this.props;
|
||||
const contentStyle = muiTheme.parity.getBackgroundStyle(null, settings.backgroundSeed);
|
||||
const header = (
|
||||
<Title
|
||||
|
||||
@@ -33,6 +33,7 @@ import Errors from './Errors';
|
||||
import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form';
|
||||
import GasPriceEditor from './GasPriceEditor';
|
||||
import GasPriceSelector from './GasPriceSelector';
|
||||
import Icons from './Icons';
|
||||
import IdentityIcon from './IdentityIcon';
|
||||
import IdentityName from './IdentityName';
|
||||
import LanguageSelector from './LanguageSelector';
|
||||
@@ -72,6 +73,7 @@ export {
|
||||
FormWrap,
|
||||
GasPriceEditor,
|
||||
GasPriceSelector,
|
||||
Icons,
|
||||
Input,
|
||||
InputAddress,
|
||||
InputAddressSelect,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { FirstRun } from '~/modals';
|
||||
import { FirstRun, UpgradeParity } from '~/modals';
|
||||
import { Errors, ParityBackground, Tooltips } from '~/ui';
|
||||
|
||||
import styles from '../application.css';
|
||||
@@ -28,20 +28,24 @@ export default class Container extends Component {
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onCloseFirstRun: PropTypes.func,
|
||||
showFirstRun: PropTypes.bool,
|
||||
onCloseFirstRun: PropTypes.func
|
||||
upgradeStore: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
render () {
|
||||
const { children, showFirstRun, onCloseFirstRun } = this.props;
|
||||
const { muiTheme } = this.context;
|
||||
const { children, onCloseFirstRun, showFirstRun, upgradeStore } = this.props;
|
||||
|
||||
return (
|
||||
<ParityBackground className={ styles.container } muiTheme={ muiTheme }>
|
||||
<ParityBackground
|
||||
className={ styles.container }
|
||||
muiTheme={ muiTheme }>
|
||||
<FirstRun
|
||||
visible={ showFirstRun }
|
||||
onClose={ onCloseFirstRun } />
|
||||
onClose={ onCloseFirstRun }
|
||||
visible={ showFirstRun } />
|
||||
<Tooltips />
|
||||
<UpgradeParity store={ upgradeStore } />
|
||||
<Errors />
|
||||
{ children }
|
||||
</ParityBackground>
|
||||
|
||||
@@ -14,55 +14,52 @@
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.status {
|
||||
position: fixed;
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
bottom: 0;
|
||||
color: #ccc;
|
||||
display: flex;
|
||||
font-size: 0.75em;
|
||||
left: 0;
|
||||
padding: .4em .5em;
|
||||
position: fixed;
|
||||
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.8);
|
||||
}
|
||||
|
||||
.enode {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.enode > * {
|
||||
display: inline-block;
|
||||
margin: 0 .25em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.enode > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.netinfo {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
color: #ddd;
|
||||
}
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
|
||||
.netinfo > * {
|
||||
margin-left: 1em;
|
||||
div {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.network {
|
||||
padding: 0.25em 0.5em;
|
||||
border-radius: .4em;
|
||||
border-radius: 0.4em;
|
||||
line-height: 1.2;
|
||||
padding: 0.25em 0.5em;
|
||||
text-transform: uppercase;
|
||||
|
||||
&.live {
|
||||
background: rgb(0, 136, 0);
|
||||
}
|
||||
|
||||
&.test {
|
||||
background: rgb(136, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.networklive {
|
||||
background: rgb(0, 136, 0);
|
||||
}
|
||||
|
||||
.networktest {
|
||||
background: rgb(136, 0, 0);
|
||||
.upgrade {
|
||||
div {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,78 +15,118 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { BlockStatus } from '~/ui';
|
||||
import CopyToClipboard from '~/ui/CopyToClipboard';
|
||||
|
||||
import styles from './status.css';
|
||||
|
||||
class Status extends Component {
|
||||
static propTypes = {
|
||||
blockNumber: PropTypes.object.isRequired,
|
||||
clientVersion: PropTypes.string,
|
||||
enode: PropTypes.string,
|
||||
netPeers: PropTypes.object,
|
||||
isTest: PropTypes.bool,
|
||||
netChain: PropTypes.string,
|
||||
isTest: PropTypes.bool
|
||||
netPeers: PropTypes.object,
|
||||
upgradeStore: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { blockNumber, clientVersion, netChain, netPeers, isTest } = this.props;
|
||||
const netStyle = `${styles.network} ${styles[isTest ? 'networktest' : 'networklive']}`;
|
||||
|
||||
if (!blockNumber) {
|
||||
return null;
|
||||
}
|
||||
const { clientVersion, isTest, netChain, netPeers } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.status }>
|
||||
<div className={ styles.version }>
|
||||
{ clientVersion }
|
||||
</div>
|
||||
<div className={ styles.upgrade }>
|
||||
{ this.renderConsensus() }
|
||||
{ this.renderUpgradeButton() }
|
||||
</div>
|
||||
<div className={ styles.netinfo }>
|
||||
<BlockStatus />
|
||||
<div className={ netStyle }>
|
||||
{ isTest ? 'test' : netChain }
|
||||
<div className={ `${styles.network} ${styles[isTest ? 'test' : 'live']}` }>
|
||||
{ netChain }
|
||||
</div>
|
||||
<div className={ styles.peers }>
|
||||
{ netPeers.active.toFormat() }/{ netPeers.connected.toFormat() }/{ netPeers.max.toFormat() } peers
|
||||
</div>
|
||||
</div>
|
||||
{ this.renderEnode() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderEnode () {
|
||||
const { enode } = this.props;
|
||||
renderConsensus () {
|
||||
const { upgradeStore } = this.props;
|
||||
|
||||
if (!enode) {
|
||||
if (upgradeStore.consensusCapability === 'capable') {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='application.status.consensus.capable'
|
||||
defaultMessage='Capable' />
|
||||
</div>
|
||||
);
|
||||
} else if (upgradeStore.consensusCapability.capableUntil) {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='application.status.consensus.capableUntil'
|
||||
defaultMessage='Capable until #{blockNumber}'
|
||||
values={ {
|
||||
blockNumber: upgradeStore.consensusCapability.capableUntil
|
||||
} } />
|
||||
</div>
|
||||
);
|
||||
} else if (upgradeStore.consensusCapability.incapableSince) {
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='application.status.consensus.incapableSince'
|
||||
defaultMessage='Incapable since #{blockNumber}'
|
||||
values={ {
|
||||
blockNumber: upgradeStore.consensusCapability.incapableSince
|
||||
} } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='application.status.consensus.unknown'
|
||||
defaultMessage='Unknown capability' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderUpgradeButton () {
|
||||
const { upgradeStore } = this.props;
|
||||
|
||||
if (!upgradeStore.available) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [protocol, rest] = enode.split('://');
|
||||
const [id, host] = rest.split('@');
|
||||
const abbreviated = `${protocol}://${id.slice(0, 3)}…${id.slice(-3)}@${host}`;
|
||||
|
||||
return (
|
||||
<div className={ styles.enode }>
|
||||
<CopyToClipboard data={ enode } size={ 12 } />
|
||||
<div>{ abbreviated }</div>
|
||||
<div>
|
||||
<a
|
||||
href='javascript:void(0)'
|
||||
onClick={ upgradeStore.openModal }>
|
||||
<FormattedMessage
|
||||
id='application.status.upgrade'
|
||||
defaultMessage='Upgrade' />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { blockNumber, clientVersion, enode, netPeers, netChain, isTest } = state.nodeStatus;
|
||||
const { clientVersion, netPeers, netChain, isTest } = state.nodeStatus;
|
||||
|
||||
return {
|
||||
blockNumber,
|
||||
clientVersion,
|
||||
enode,
|
||||
netPeers,
|
||||
netChain,
|
||||
isTest
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-bottom: 1em;
|
||||
padding-bottom: 1.25em;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import UpgradeStore from '~/modals/UpgradeParity/store';
|
||||
|
||||
import Connection from '../Connection';
|
||||
import ParityBar from '../ParityBar';
|
||||
|
||||
@@ -42,14 +44,15 @@ class Application extends Component {
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
blockNumber: PropTypes.object,
|
||||
children: PropTypes.node,
|
||||
netChain: PropTypes.string,
|
||||
isTest: PropTypes.bool,
|
||||
pending: PropTypes.array,
|
||||
blockNumber: PropTypes.object
|
||||
netChain: PropTypes.string,
|
||||
pending: PropTypes.array
|
||||
}
|
||||
|
||||
store = new Store(this.context.api);
|
||||
upgradeStore = new UpgradeStore(this.context.api);
|
||||
|
||||
render () {
|
||||
const [root] = (window.location.hash || '').replace('#/', '').split('/');
|
||||
@@ -71,12 +74,13 @@ class Application extends Component {
|
||||
}
|
||||
|
||||
renderApp () {
|
||||
const { children, pending, netChain, isTest, blockNumber } = this.props;
|
||||
const { blockNumber, children, pending, netChain, isTest } = this.props;
|
||||
|
||||
return (
|
||||
<Container
|
||||
showFirstRun={ this.store.firstrunVisible }
|
||||
onCloseFirstRun={ this.store.closeFirstrun }>
|
||||
upgradeStore={ this.upgradeStore }
|
||||
onCloseFirstRun={ this.store.closeFirstrun }
|
||||
showFirstRun={ this.store.firstrunVisible }>
|
||||
<TabBar
|
||||
netChain={ netChain }
|
||||
isTest={ isTest }
|
||||
@@ -84,7 +88,11 @@ class Application extends Component {
|
||||
<div className={ styles.content }>
|
||||
{ children }
|
||||
</div>
|
||||
{ blockNumber ? (<Status />) : null }
|
||||
{
|
||||
blockNumber
|
||||
? <Status upgradeStore={ this.upgradeStore } />
|
||||
: null
|
||||
}
|
||||
<Snackbar />
|
||||
</Container>
|
||||
);
|
||||
@@ -102,16 +110,16 @@ class Application extends Component {
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { netChain, isTest, blockNumber } = state.nodeStatus;
|
||||
const { blockNumber, netChain, isTest } = state.nodeStatus;
|
||||
const { hasAccounts } = state.personal;
|
||||
const { pending } = state.signer;
|
||||
|
||||
return {
|
||||
blockNumber,
|
||||
hasAccounts,
|
||||
netChain,
|
||||
isTest,
|
||||
pending,
|
||||
blockNumber
|
||||
netChain,
|
||||
pending
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
.row {
|
||||
margin: 0 -1em;
|
||||
}
|
||||
|
||||
.row::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: '';
|
||||
&::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
|
||||
.blockInfo {
|
||||
@@ -44,7 +44,7 @@
|
||||
}
|
||||
|
||||
.col,
|
||||
.col1, .col2, .col3, .col4, .col5, .col6, .col7, .col8, .col9, .col10, .col11, .col12 {
|
||||
.col3, .col4_5, .col6, .col12 {
|
||||
float: left;
|
||||
padding: 0 1em;
|
||||
box-sizing: border-box;
|
||||
@@ -57,18 +57,11 @@
|
||||
width: calc(100% / 12 * 3);
|
||||
}
|
||||
|
||||
.col4 {
|
||||
width: 33.33333%;
|
||||
width: -webkit-calc(100% / 12 * 4);
|
||||
width: -moz-calc(100% / 12 * 4);
|
||||
width: calc(100% / 12 * 4);
|
||||
}
|
||||
|
||||
.col5 {
|
||||
width: 41.66665%;
|
||||
width: -webkit-calc(100% / 12 * 5);
|
||||
width: -moz-calc(100% / 12 * 5);
|
||||
width: calc(100% / 12 * 5);
|
||||
.col4_5 {
|
||||
width: 37.5%;
|
||||
width: -webkit-calc(100% / 12 * 4.5);
|
||||
width: -moz-calc(100% / 12 * 4.5);
|
||||
width: calc(100% / 12 * 4.5);
|
||||
}
|
||||
|
||||
.col6 {
|
||||
|
||||
@@ -68,13 +68,13 @@ export default class Status extends Component {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.col5 }>
|
||||
<div className={ styles.col4_5 }>
|
||||
<MiningSettings
|
||||
{ ...this._test('mining') }
|
||||
nodeStatus={ nodeStatus }
|
||||
actions={ this.props.actions } />
|
||||
</div>
|
||||
<div className={ styles.col4 }>
|
||||
<div className={ styles.col4_5 }>
|
||||
{ this.renderSettings() }
|
||||
</div>
|
||||
</div>
|
||||
@@ -102,6 +102,7 @@ export default class Status extends Component {
|
||||
<div { ...this._test('settings') }>
|
||||
<ContainerTitle title='network settings' />
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='chain'
|
||||
value={ nodeStatus.netChain }
|
||||
@@ -109,6 +110,7 @@ export default class Status extends Component {
|
||||
<div className={ styles.row }>
|
||||
<div className={ styles.col6 }>
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='peers'
|
||||
value={ peers }
|
||||
@@ -116,6 +118,7 @@ export default class Status extends Component {
|
||||
</div>
|
||||
<div className={ styles.col6 }>
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='network port'
|
||||
value={ nodeStatus.netPort.toString() }
|
||||
@@ -124,6 +127,7 @@ export default class Status extends Component {
|
||||
</div>
|
||||
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='rpc enabled'
|
||||
value={ rpcSettings.enabled ? 'yes' : 'no' }
|
||||
@@ -131,6 +135,7 @@ export default class Status extends Component {
|
||||
<div className={ styles.row }>
|
||||
<div className={ styles.col6 }>
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='rpc interface'
|
||||
value={ rpcSettings.interface }
|
||||
@@ -138,12 +143,24 @@ export default class Status extends Component {
|
||||
</div>
|
||||
<div className={ styles.col6 }>
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='rpc port'
|
||||
value={ rpcSettings.port.toString() }
|
||||
{ ...this._test('rpc-port') } />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={ styles.row }>
|
||||
<div className={ styles.col12 }>
|
||||
<Input
|
||||
allowCopy
|
||||
readOnly
|
||||
label='enode'
|
||||
value={ nodeStatus.enode }
|
||||
{ ...this._test('node-enode') } />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user