Merge branch 'master' into ng-ui-fixes
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "parity.js",
|
||||
"version": "0.2.105",
|
||||
"version": "0.2.107",
|
||||
"main": "release/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
@@ -146,6 +146,7 @@
|
||||
"mobx-react-devtools": "4.2.10",
|
||||
"moment": "2.17.0",
|
||||
"phoneformat.js": "1.0.3",
|
||||
"push.js": "0.0.11",
|
||||
"qs": "6.3.0",
|
||||
"react": "15.4.1",
|
||||
"react-ace": "4.1.0",
|
||||
|
||||
@@ -67,7 +67,7 @@ if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) {
|
||||
const api = new SecureApi(`ws://${parityUrl}`, token);
|
||||
ContractInstances.create(api);
|
||||
|
||||
const store = initStore(api);
|
||||
const store = initStore(api, hashHistory);
|
||||
store.dispatch({ type: 'initAll', api });
|
||||
store.dispatch(setApi(api));
|
||||
|
||||
|
||||
@@ -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 thunk from 'redux-thunk';
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
|
||||
import ErrorsMiddleware from '~/ui/Errors/middleware';
|
||||
import SettingsMiddleware from '~/views/Settings/middleware';
|
||||
@@ -22,12 +23,13 @@ import SignerMiddleware from './providers/signerMiddleware';
|
||||
import statusMiddleware from '~/views/Status/middleware';
|
||||
import CertificationsMiddleware from './providers/certifications/middleware';
|
||||
|
||||
export default function (api) {
|
||||
export default function (api, browserHistory) {
|
||||
const errors = new ErrorsMiddleware();
|
||||
const signer = new SignerMiddleware(api);
|
||||
const settings = new SettingsMiddleware();
|
||||
const status = statusMiddleware();
|
||||
const certifications = new CertificationsMiddleware();
|
||||
const routeMiddleware = routerMiddleware(browserHistory);
|
||||
|
||||
const middleware = [
|
||||
settings.toMiddleware(),
|
||||
@@ -36,5 +38,5 @@ export default function (api) {
|
||||
certifications.toMiddleware()
|
||||
];
|
||||
|
||||
return middleware.concat(status, thunk);
|
||||
return middleware.concat(status, routeMiddleware, thunk);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { range, uniq, isEqual } from 'lodash';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { push } from 'react-router-redux';
|
||||
|
||||
import { hashToImageUrl } from './imagesReducer';
|
||||
import { setAddressImage } from './imagesActions';
|
||||
|
||||
import * as ABIS from '~/contracts/abi';
|
||||
import { notifyTransaction } from '~/util/notifications';
|
||||
import imagesEthereum from '../../../assets/images/contracts/ethereum-black-64x64.png';
|
||||
|
||||
const ETH = {
|
||||
@@ -28,7 +31,64 @@ const ETH = {
|
||||
image: imagesEthereum
|
||||
};
|
||||
|
||||
export function setBalances (balances) {
|
||||
function setBalances (_balances) {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
||||
const accounts = state.personal.accounts;
|
||||
const nextBalances = _balances;
|
||||
const prevBalances = state.balances.balances;
|
||||
const balances = { ...prevBalances };
|
||||
|
||||
Object.keys(nextBalances).forEach((address) => {
|
||||
if (!balances[address]) {
|
||||
balances[address] = Object.assign({}, nextBalances[address]);
|
||||
return;
|
||||
}
|
||||
|
||||
const balance = Object.assign({}, balances[address]);
|
||||
const { tokens, txCount = balance.txCount } = nextBalances[address];
|
||||
const nextTokens = [].concat(balance.tokens);
|
||||
|
||||
tokens.forEach((t) => {
|
||||
const { token, value } = t;
|
||||
const { tag } = token;
|
||||
|
||||
const tokenIndex = nextTokens.findIndex((tok) => tok.token.tag === tag);
|
||||
|
||||
if (tokenIndex === -1) {
|
||||
nextTokens.push({
|
||||
token,
|
||||
value
|
||||
});
|
||||
} else {
|
||||
const oldValue = nextTokens[tokenIndex].value;
|
||||
|
||||
// If received a token/eth (old value < new value), notify
|
||||
if (oldValue.lt(value) && accounts[address]) {
|
||||
const account = accounts[address];
|
||||
const txValue = value.minus(oldValue);
|
||||
|
||||
const redirectToAccount = () => {
|
||||
const route = `/account/${account.address}`;
|
||||
dispatch(push(route));
|
||||
};
|
||||
|
||||
notifyTransaction(account, token, txValue, redirectToAccount);
|
||||
}
|
||||
|
||||
nextTokens[tokenIndex] = { token, value };
|
||||
}
|
||||
});
|
||||
|
||||
balances[address] = { txCount: txCount || new BigNumber(0), tokens: nextTokens };
|
||||
});
|
||||
|
||||
dispatch(_setBalances(balances));
|
||||
};
|
||||
}
|
||||
|
||||
function _setBalances (balances) {
|
||||
return {
|
||||
type: 'setBalances',
|
||||
balances
|
||||
@@ -123,14 +183,14 @@ export function fetchBalances (_addresses) {
|
||||
|
||||
const fullFetch = addresses.length === 1;
|
||||
|
||||
const fetchedAddresses = uniq(addresses.concat(Object.keys(accounts)));
|
||||
const addressesToFetch = uniq(addresses.concat(Object.keys(accounts)));
|
||||
|
||||
return Promise
|
||||
.all(fetchedAddresses.map((addr) => fetchAccount(addr, api, fullFetch)))
|
||||
.all(addressesToFetch.map((addr) => fetchAccount(addr, api, fullFetch)))
|
||||
.then((accountsBalances) => {
|
||||
const balances = {};
|
||||
|
||||
fetchedAddresses.forEach((addr, idx) => {
|
||||
addressesToFetch.forEach((addr, idx) => {
|
||||
balances[addr] = accountsBalances[idx];
|
||||
});
|
||||
|
||||
@@ -146,10 +206,12 @@ export function fetchBalances (_addresses) {
|
||||
export function updateTokensFilter (_addresses, _tokens) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, balances, personal } = getState();
|
||||
const { visibleAccounts } = personal;
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
const { tokensFilter } = balances;
|
||||
|
||||
const addresses = uniq(_addresses || visibleAccounts || []).sort();
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const addresses = uniq(_addresses || addressesToFetch || []).sort();
|
||||
|
||||
const tokens = _tokens || Object.values(balances.tokens) || [];
|
||||
const tokenAddresses = tokens.map((t) => t.address).sort();
|
||||
|
||||
@@ -221,8 +283,10 @@ export function updateTokensFilter (_addresses, _tokens) {
|
||||
export function queryTokensFilter (tokensFilter) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, personal, balances } = getState();
|
||||
const { visibleAccounts } = personal;
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const visibleAddresses = visibleAccounts.map((a) => a.toLowerCase());
|
||||
const addressesToFetch = uniq(visibleAddresses.concat(Object.keys(accounts)));
|
||||
|
||||
Promise
|
||||
.all([
|
||||
@@ -237,18 +301,16 @@ export function queryTokensFilter (tokensFilter) {
|
||||
.concat(logsTo)
|
||||
.forEach((log) => {
|
||||
const tokenAddress = log.address;
|
||||
|
||||
const fromAddress = '0x' + log.topics[1].slice(-40);
|
||||
const toAddress = '0x' + log.topics[2].slice(-40);
|
||||
|
||||
const fromIdx = visibleAddresses.indexOf(fromAddress);
|
||||
const toIdx = visibleAddresses.indexOf(toAddress);
|
||||
|
||||
if (fromIdx > -1) {
|
||||
addresses.push(visibleAccounts[fromIdx]);
|
||||
if (addressesToFetch.includes(fromAddress)) {
|
||||
addresses.push(fromAddress);
|
||||
}
|
||||
|
||||
if (toIdx > -1) {
|
||||
addresses.push(visibleAccounts[toIdx]);
|
||||
if (addressesToFetch.includes(toAddress)) {
|
||||
addresses.push(toAddress);
|
||||
}
|
||||
|
||||
tokenAddresses.push(tokenAddress);
|
||||
@@ -269,9 +331,10 @@ export function queryTokensFilter (tokensFilter) {
|
||||
export function fetchTokensBalances (_addresses = null, _tokens = null) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, personal, balances } = getState();
|
||||
const { visibleAccounts } = personal;
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const addresses = _addresses || visibleAccounts;
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const addresses = _addresses || addressesToFetch;
|
||||
const tokens = _tokens || Object.values(balances.tokens);
|
||||
|
||||
if (addresses.length === 0) {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { handleActions } from 'redux-actions';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
const initialState = {
|
||||
balances: {},
|
||||
@@ -26,39 +25,7 @@ const initialState = {
|
||||
|
||||
export default handleActions({
|
||||
setBalances (state, action) {
|
||||
const nextBalances = action.balances;
|
||||
const prevBalances = state.balances;
|
||||
const balances = { ...prevBalances };
|
||||
|
||||
Object.keys(nextBalances).forEach((address) => {
|
||||
if (!balances[address]) {
|
||||
balances[address] = Object.assign({}, nextBalances[address]);
|
||||
return;
|
||||
}
|
||||
|
||||
const balance = Object.assign({}, balances[address]);
|
||||
const { tokens, txCount = balance.txCount } = nextBalances[address];
|
||||
const nextTokens = [].concat(balance.tokens);
|
||||
|
||||
tokens.forEach((t) => {
|
||||
const { token, value } = t;
|
||||
const { tag } = token;
|
||||
|
||||
const tokenIndex = nextTokens.findIndex((tok) => tok.token && tok.token.tag === tag);
|
||||
|
||||
if (tokenIndex === -1) {
|
||||
nextTokens.push({
|
||||
token,
|
||||
value
|
||||
});
|
||||
} else {
|
||||
nextTokens[tokenIndex] = { token, value };
|
||||
}
|
||||
});
|
||||
|
||||
balances[address] = Object.assign({}, { txCount: txCount || new BigNumber(0), tokens: nextTokens });
|
||||
});
|
||||
|
||||
const { balances } = action;
|
||||
return Object.assign({}, state, { balances });
|
||||
},
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ export Status from './status';
|
||||
|
||||
export apiReducer from './apiReducer';
|
||||
export balancesReducer from './balancesReducer';
|
||||
export blockchainReducer from './blockchainReducer';
|
||||
export compilerReducer from './compilerReducer';
|
||||
export imagesReducer from './imagesReducer';
|
||||
export personalReducer from './personalReducer';
|
||||
export signerReducer from './signerReducer';
|
||||
export statusReducer from './statusReducer';
|
||||
export blockchainReducer from './blockchainReducer';
|
||||
export compilerReducer from './compilerReducer';
|
||||
export snackbarReducer from './snackbarReducer';
|
||||
export statusReducer from './statusReducer';
|
||||
export walletReducer from './walletReducer';
|
||||
|
||||
@@ -54,7 +54,10 @@ export default class Status {
|
||||
this._api.eth
|
||||
.getBlockByNumber(blockNumber)
|
||||
.then((block) => {
|
||||
this._store.dispatch(statusCollection({ gasLimit: block.gasLimit }));
|
||||
this._store.dispatch(statusCollection({
|
||||
blockTimestamp: block.timestamp,
|
||||
gasLimit: block.gasLimit
|
||||
}));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('status._subscribeBlockNumber', 'getBlockByNumber', error);
|
||||
|
||||
@@ -19,6 +19,7 @@ import { handleActions } from 'redux-actions';
|
||||
|
||||
const initialState = {
|
||||
blockNumber: new BigNumber(0),
|
||||
blockTimestamp: new Date(),
|
||||
devLogs: [],
|
||||
devLogsLevels: null,
|
||||
devLogsEnabled: false,
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import { routerReducer } from 'react-router-redux';
|
||||
|
||||
import { apiReducer, balancesReducer, blockchainReducer, compilerReducer, imagesReducer, personalReducer, signerReducer, statusReducer as nodeStatusReducer, snackbarReducer, walletReducer } from './providers';
|
||||
import {
|
||||
apiReducer, balancesReducer, blockchainReducer,
|
||||
compilerReducer, imagesReducer, personalReducer,
|
||||
signerReducer, statusReducer as nodeStatusReducer,
|
||||
snackbarReducer, walletReducer
|
||||
} from './providers';
|
||||
import certificationsReducer from './providers/certifications/reducer';
|
||||
|
||||
import errorReducer from '~/ui/Errors/reducers';
|
||||
|
||||
@@ -32,9 +32,9 @@ const storeCreation = window.devToolsExtension
|
||||
? window.devToolsExtension()(createStore)
|
||||
: createStore;
|
||||
|
||||
export default function (api) {
|
||||
export default function (api, browserHistory) {
|
||||
const reducers = initReducers();
|
||||
const middleware = initMiddleware(api);
|
||||
const middleware = initMiddleware(api, browserHistory);
|
||||
const store = applyMiddleware(...middleware)(storeCreation)(reducers);
|
||||
|
||||
new BalancesProvider(store, api).start();
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
|
||||
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import styles from './actionbar.css';
|
||||
|
||||
export default class Actionbar extends Component {
|
||||
static propTypes = {
|
||||
title: PropTypes.string,
|
||||
title: nodeOrStringProptype(),
|
||||
buttons: PropTypes.array,
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
.layout {
|
||||
padding: 0.25em;
|
||||
|
||||
> * {
|
||||
&>div {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,21 +16,38 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import Actionbar from '../Actionbar';
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import styles from './page.css';
|
||||
|
||||
export default class Page extends Component {
|
||||
static propTypes = {
|
||||
buttons: PropTypes.array,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
children: PropTypes.node,
|
||||
title: nodeOrStringProptype()
|
||||
};
|
||||
|
||||
render () {
|
||||
const { className, children } = this.props;
|
||||
const { buttons, className, children, title } = this.props;
|
||||
const classes = `${styles.layout} ${className}`;
|
||||
let actionbar = null;
|
||||
|
||||
if (title || buttons) {
|
||||
actionbar = (
|
||||
<Actionbar
|
||||
buttons={ buttons }
|
||||
title={ title } />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ classes }>
|
||||
{ children }
|
||||
<div>
|
||||
{ actionbar }
|
||||
<div className={ classes }>
|
||||
{ children }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
45
js/src/util/notifications.js
Normal file
45
js/src/util/notifications.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 Push from 'push.js';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { fromWei } from '~/api/util/wei';
|
||||
|
||||
import ethereumIcon from '~/../assets/images/contracts/ethereum-black-64x64.png';
|
||||
import unkownIcon from '~/../assets/images/contracts/unknown-64x64.png';
|
||||
|
||||
export function notifyTransaction (account, token, _value, onClick) {
|
||||
const name = account.name || account.address;
|
||||
const value = token.tag.toLowerCase() === 'eth'
|
||||
? fromWei(_value)
|
||||
: _value.div(new BigNumber(token.format || 1));
|
||||
|
||||
const icon = token.tag.toLowerCase() === 'eth'
|
||||
? ethereumIcon
|
||||
: (token.image || unkownIcon);
|
||||
|
||||
Push.create(`${name}`, {
|
||||
body: `You just received ${value.toFormat()} ${token.tag.toUpperCase()}`,
|
||||
icon: {
|
||||
x16: icon,
|
||||
x32: icon
|
||||
},
|
||||
timeout: 20000,
|
||||
onClick: onClick || noop
|
||||
});
|
||||
}
|
||||
@@ -51,9 +51,16 @@ export default class Dapp extends Component {
|
||||
src = `${dappsUrl}/${app.contentHash}/`;
|
||||
break;
|
||||
default:
|
||||
const dapphost = process.env.NODE_ENV === 'production' && !app.secure
|
||||
? `${dappsUrl}/ui`
|
||||
: '';
|
||||
let dapphost = process.env.DAPPS_URL || (
|
||||
process.env.NODE_ENV === 'production' && !app.secure
|
||||
? `${dappsUrl}/ui`
|
||||
: ''
|
||||
);
|
||||
|
||||
if (dapphost === '/') {
|
||||
dapphost = '';
|
||||
}
|
||||
|
||||
src = `${dapphost}/${app.url}.html`;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@ export default class Signer extends Component {
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<Actionbar
|
||||
title='Trusted Signer' />
|
||||
<Actionbar title='Trusted Signer' />
|
||||
<RequestsPage />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -30,12 +30,6 @@ export default class Store {
|
||||
}
|
||||
}
|
||||
|
||||
@action unsubscribe () {
|
||||
if (this._timeoutId) {
|
||||
clearTimeout(this._timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
@action setBalance = (address, balance) => {
|
||||
this.setBalances({ [address]: balance });
|
||||
}
|
||||
@@ -50,6 +44,12 @@ export default class Store {
|
||||
}
|
||||
}
|
||||
|
||||
@action unsubscribe () {
|
||||
if (this._timeoutId) {
|
||||
clearTimeout(this._timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
fetchBalance (address) {
|
||||
this._api.eth
|
||||
.getBalance(address)
|
||||
|
||||
@@ -22,7 +22,7 @@ import ReorderIcon from 'material-ui/svg-icons/action/reorder';
|
||||
|
||||
import { Container } from '~/ui';
|
||||
|
||||
import styles from './Debug.css';
|
||||
import styles from './debug.css';
|
||||
|
||||
export default class Debug extends Component {
|
||||
static propTypes = {
|
||||
@@ -14,4 +14,4 @@
|
||||
// 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 './Debug';
|
||||
export default from './debug';
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
// 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 './MiningSettings';
|
||||
export default from './miningSettings';
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
// 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';
|
||||
export default from './status';
|
||||
|
||||
@@ -28,10 +28,19 @@
|
||||
content: '';
|
||||
}
|
||||
|
||||
.blockinfo {
|
||||
font-size: 24px;
|
||||
.blockInfo {
|
||||
color: #aaa;
|
||||
line-height: 24px;
|
||||
font-size: 1.5em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.blockByline {
|
||||
color: #aaa;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.padBottom {
|
||||
padding-bottom: 1.25em !important;
|
||||
}
|
||||
|
||||
.col,
|
||||
@@ -14,14 +14,16 @@
|
||||
// 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 bytes from 'bytes';
|
||||
import moment from 'moment';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { Container, ContainerTitle, Input } from '~/ui';
|
||||
|
||||
import styles from './Status.css';
|
||||
import MiningSettings from '../MiningSettings';
|
||||
|
||||
import styles from './status.css';
|
||||
|
||||
export default class Status extends Component {
|
||||
static propTypes = {
|
||||
nodeStatus: PropTypes.object.isRequired,
|
||||
@@ -44,23 +46,26 @@ export default class Status extends Component {
|
||||
<div className={ styles.container }>
|
||||
<div className={ styles.row }>
|
||||
<div className={ styles.col3 }>
|
||||
<div className={ styles.col12 }>
|
||||
<div className={ `${styles.col12} ${styles.padBottom}` }>
|
||||
<ContainerTitle title='best block' />
|
||||
<h2 { ...this._test('best-block') } className={ styles.blockinfo }>
|
||||
<div { ...this._test('best-block') } className={ styles.blockInfo }>
|
||||
#{ nodeStatus.blockNumber.toFormat() }
|
||||
</h2>
|
||||
</div>
|
||||
<div className={ styles.blockByline }>
|
||||
{ moment().calendar(nodeStatus.blockTimestamp) }
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.col12 }>
|
||||
<div className={ `${styles.col12} ${styles.padBottom}` }>
|
||||
<ContainerTitle title='peers' />
|
||||
<h2 { ...this._test('peers') } className={ styles.blockinfo }>
|
||||
<div { ...this._test('peers') } className={ styles.blockInfo }>
|
||||
{ peers }
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.col12 }>
|
||||
<div className={ `${styles.col12} ${styles.padBottom}` }>
|
||||
<ContainerTitle title='hash rate' />
|
||||
<h2 { ...this._test('hashrate') } className={ styles.blockinfo }>
|
||||
<div { ...this._test('hashrate') } className={ styles.blockInfo }>
|
||||
{ `${hashrate} H/s` }
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={ styles.col5 }>
|
||||
@@ -14,4 +14,4 @@
|
||||
// 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 './StatusPage';
|
||||
export default from './statusPage';
|
||||
|
||||
@@ -14,5 +14,9 @@
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
|
||||
.body {
|
||||
&>div {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import { clearStatusLogs, toggleStatusLogs, toggleStatusRefresh } from '~/redux/
|
||||
import Debug from '../../components/Debug';
|
||||
import Status from '../../components/Status';
|
||||
|
||||
import styles from './statusPage.css';
|
||||
|
||||
class StatusPage extends Component {
|
||||
static propTypes = {
|
||||
nodeStatus: PropTypes.object.isRequired,
|
||||
@@ -39,7 +41,7 @@ class StatusPage extends Component {
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<div className={ styles.body }>
|
||||
<Status { ...this.props } />
|
||||
<Debug { ...this.props } />
|
||||
</div>
|
||||
@@ -16,22 +16,16 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Actionbar, Page } from '~/ui';
|
||||
import { Page } from '~/ui';
|
||||
|
||||
import StatusPage from './containers/StatusPage';
|
||||
|
||||
import styles from './status.css';
|
||||
|
||||
export default class Status extends Component {
|
||||
render () {
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
<Actionbar
|
||||
title='status' />
|
||||
<Page>
|
||||
<StatusPage />
|
||||
</Page>
|
||||
</div>
|
||||
<Page title='status'>
|
||||
<StatusPage />
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ const path = require('path');
|
||||
const WebpackErrorNotificationPlugin = require('webpack-error-notification');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
|
||||
const Shared = require('./shared');
|
||||
const DAPPS = require('../src/dapps');
|
||||
@@ -41,7 +42,7 @@ module.exports = {
|
||||
output: {
|
||||
publicPath: '/',
|
||||
path: path.join(__dirname, '../', DEST),
|
||||
filename: '[name].[hash].js'
|
||||
filename: '[name].[hash:10].js'
|
||||
},
|
||||
|
||||
module: {
|
||||
@@ -85,13 +86,20 @@ module.exports = {
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: [ /src/ ],
|
||||
// exclude: [ /src\/dapps/ ],
|
||||
loader: isProd ? ExtractTextPlugin.extract([
|
||||
// 'style-loader',
|
||||
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
|
||||
'postcss-loader'
|
||||
]) : undefined,
|
||||
// use: [ 'happypack/loader?id=css' ]
|
||||
use: [
|
||||
use: isProd ? undefined : [
|
||||
'style-loader',
|
||||
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
|
||||
'postcss-loader'
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [ /src/ ],
|
||||
@@ -99,11 +107,15 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
use: [ 'file-loader?name=[name].[hash].[ext]' ]
|
||||
use: [ 'file-loader?&name=assets/[name].[hash:10].[ext]' ]
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)|ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
use: [ 'file-loader' ]
|
||||
test: /\.(woff(2)|ttf|eot|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
use: [ 'file-loader?name=fonts/[name][hash:10].[ext]' ]
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
use: [ 'file-loader?name=assets/[name].[hash:10].[ext]' ]
|
||||
}
|
||||
],
|
||||
noParse: [
|
||||
@@ -153,13 +165,20 @@ module.exports = {
|
||||
if (!isProd) {
|
||||
plugins.push(
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
filename: 'commons.[hash].js',
|
||||
filename: 'commons.[hash:10].js',
|
||||
name: 'commons',
|
||||
minChunks: Infinity
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (isProd) {
|
||||
plugins.push(new ExtractTextPlugin({
|
||||
filename: 'styles/[name].[hash:10].css',
|
||||
allChunks: true
|
||||
}));
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}())
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user