From befcc9cc1a432b3ec7563418c0dcbe4ec9f83320 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 9 Dec 2016 13:44:10 +0100 Subject: [PATCH 1/5] Cleanups (#3742) * Remove unused file * Combine tx checks into single file * Move UI components into UI * DRY links * Unused rollup config * Cleanup util paths * Revert "Move UI components into UI" This reverts commit 3379e61246cde635c296d31322b71e63395a5cd4. * Re-apply ~/util/tx move * Cleanup unused styles --- js/src/3rdparty/etherscan/links.js | 8 ++- js/src/jsonrpc/rollup.config.js | 12 ----- js/src/modals/AddAddress/addAddress.js | 2 +- js/src/modals/AddContract/addContract.js | 2 +- .../modals/CreateWallet/createWalletStore.js | 5 +- .../DeployContract/DetailsStep/detailsStep.js | 4 +- .../ParametersStep/parametersStep.js | 2 +- .../modals/DeployContract/deployContract.js | 2 +- js/src/modals/EditMeta/editMeta.js | 2 +- .../modals/ExecuteContract/executeContract.js | 4 +- js/src/modals/SMSVerification/store.js | 5 +- js/src/modals/SaveContract/saveContract.js | 2 +- js/src/modals/Shapeshift/shapeshift.js | 2 +- js/src/redux/providers/walletActions.js | 6 +-- js/src/ui/Form/TypedInput/typedInput.js | 3 +- js/src/ui/TxHash/txHash.js | 2 +- js/src/ui/TxList/txList.js | 2 +- js/src/util/check-if-tx-failed.js | 28 ---------- js/src/util/is-testnet.js | 19 ------- ...{wait-for-block-confirmations.js => tx.js} | 17 ++++-- .../Account/Transactions/transactions.css | 3 -- .../Account/Transactions/transactions.js | 2 +- js/src/views/Account/account.css | 2 - js/src/views/Account/account.js | 2 +- js/src/views/Accounts/accounts.css | 2 - js/src/views/Accounts/accounts.js | 2 +- js/src/views/Address/address.css | 52 +++++++++---------- js/src/views/Address/address.js | 4 +- js/src/views/Addresses/addresses.css | 20 ++++--- js/src/views/Addresses/addresses.js | 2 +- js/src/views/Connection/connection.js | 1 - js/src/views/Contract/Events/Event/event.js | 2 +- js/src/views/Contract/contract.css | 26 ++++------ js/src/views/Contract/contract.js | 2 +- js/src/views/Contracts/contracts.css | 18 ------- js/src/views/Contracts/contracts.js | 5 +- js/src/views/Settings/settings.css | 44 +++++++--------- js/src/views/Settings/settings.js | 2 +- .../Account/AccountLink/AccountLink.js | 2 +- .../components/TxHashLink/TxHashLink.js | 2 +- .../Signer/containers/Embedded/embedded.css | 3 -- .../Signer/containers/Embedded/embedded.js | 2 +- .../containers/RequestsPage/RequestsPage.css | 6 --- .../containers/RequestsPage/RequestsPage.js | 5 +- js/src/views/Signer/signer.css | 24 --------- js/src/views/Signer/signer.js | 4 +- .../containers/StatusPage/StatusPage.js | 4 +- .../containers/StatusPage/statusPage.css | 18 ------- 48 files changed, 118 insertions(+), 272 deletions(-) delete mode 100644 js/src/jsonrpc/rollup.config.js delete mode 100644 js/src/util/check-if-tx-failed.js delete mode 100644 js/src/util/is-testnet.js rename js/src/util/{wait-for-block-confirmations.js => tx.js} (73%) delete mode 100644 js/src/views/Contracts/contracts.css delete mode 100644 js/src/views/Signer/signer.css delete mode 100644 js/src/views/Status/containers/StatusPage/statusPage.css diff --git a/js/src/3rdparty/etherscan/links.js b/js/src/3rdparty/etherscan/links.js index 2745873fc..e85572850 100644 --- a/js/src/3rdparty/etherscan/links.js +++ b/js/src/3rdparty/etherscan/links.js @@ -14,10 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +export const url = (isTestnet = false) => { + return `https://${isTestnet ? 'testnet.' : ''}etherscan.io`; +}; + export const txLink = (hash, isTestnet = false) => { - return `https://${isTestnet ? 'testnet.' : ''}etherscan.io/tx/${hash}`; + return `${url(isTestnet)}/tx/${hash}`; }; export const addressLink = (address, isTestnet = false) => { - return `https://${isTestnet ? 'testnet.' : ''}etherscan.io/address/${address}`; + return `${url(isTestnet)}/address/${address}`; }; diff --git a/js/src/jsonrpc/rollup.config.js b/js/src/jsonrpc/rollup.config.js deleted file mode 100644 index cc4f8c931..000000000 --- a/js/src/jsonrpc/rollup.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import babel from 'rollup-plugin-babel'; - -export default { - entry: 'src/index.js', - dest: 'release/index.js', - format: 'cjs', - plugins: [babel({ - babelrc: false, - presets: ['es2015-rollup', 'stage-0'], - runtimeHelpers: true - })] -}; diff --git a/js/src/modals/AddAddress/addAddress.js b/js/src/modals/AddAddress/addAddress.js index 590287e73..e44cb0b3c 100644 --- a/js/src/modals/AddAddress/addAddress.js +++ b/js/src/modals/AddAddress/addAddress.js @@ -19,7 +19,7 @@ import ContentAdd from 'material-ui/svg-icons/content/add'; import ContentClear from 'material-ui/svg-icons/content/clear'; import { Button, Modal, Form, Input, InputAddress } from '~/ui'; -import { ERRORS, validateAddress, validateName } from '../../util/validation'; +import { ERRORS, validateAddress, validateName } from '~/util/validation'; export default class AddAddress extends Component { static contextTypes = { diff --git a/js/src/modals/AddContract/addContract.js b/js/src/modals/AddContract/addContract.js index 71f8a911d..b19398001 100644 --- a/js/src/modals/AddContract/addContract.js +++ b/js/src/modals/AddContract/addContract.js @@ -21,7 +21,7 @@ import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forwa import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back'; import { Button, Modal, Form, Input, InputAddress, RadioButtons } from '~/ui'; -import { ERRORS, validateAbi, validateAddress, validateName } from '../../util/validation'; +import { ERRORS, validateAbi, validateAddress, validateName } from '~/util/validation'; import { eip20, wallet } from '~/contracts/abi'; diff --git a/js/src/modals/CreateWallet/createWalletStore.js b/js/src/modals/CreateWallet/createWalletStore.js index d8c308a12..1d3aa6ee2 100644 --- a/js/src/modals/CreateWallet/createWalletStore.js +++ b/js/src/modals/CreateWallet/createWalletStore.js @@ -16,13 +16,12 @@ import { observable, computed, action, transaction } from 'mobx'; -import { validateUint, validateAddress, validateName } from '~/util/validation'; -import { ERROR_CODES } from '~/api/transport/error'; - import Contract from '~/api/contract'; +import { ERROR_CODES } from '~/api/transport/error'; import { wallet as walletAbi } from '~/contracts/abi'; import { wallet as walletCode } from '~/contracts/code'; +import { validateUint, validateAddress, validateName } from '~/util/validation'; import WalletsUtils from '~/util/wallets'; const STEPS = { diff --git a/js/src/modals/DeployContract/DetailsStep/detailsStep.js b/js/src/modals/DeployContract/DetailsStep/detailsStep.js index 54ef8f850..aa0a30e55 100644 --- a/js/src/modals/DeployContract/DetailsStep/detailsStep.js +++ b/js/src/modals/DeployContract/DetailsStep/detailsStep.js @@ -18,8 +18,8 @@ import React, { Component, PropTypes } from 'react'; import { MenuItem } from 'material-ui'; import { AddressSelect, Form, Input, Select } from '~/ui'; -import { validateAbi } from '../../../util/validation'; -import { parseAbiType } from '../../../util/abi'; +import { validateAbi } from '~/util/validation'; +import { parseAbiType } from '~/util/abi'; export default class DetailsStep extends Component { static contextTypes = { diff --git a/js/src/modals/DeployContract/ParametersStep/parametersStep.js b/js/src/modals/DeployContract/ParametersStep/parametersStep.js index 4c7228b67..4ab5df693 100644 --- a/js/src/modals/DeployContract/ParametersStep/parametersStep.js +++ b/js/src/modals/DeployContract/ParametersStep/parametersStep.js @@ -32,7 +32,7 @@ import React, { Component, PropTypes } from 'react'; import { Form, TypedInput } from '~/ui'; -import { parseAbiType } from '../../../util/abi'; +import { parseAbiType } from '~/util/abi'; import styles from '../deployContract.css'; diff --git a/js/src/modals/DeployContract/deployContract.js b/js/src/modals/DeployContract/deployContract.js index ae5578e40..5bf4fc389 100644 --- a/js/src/modals/DeployContract/deployContract.js +++ b/js/src/modals/DeployContract/deployContract.js @@ -19,7 +19,7 @@ import ActionDoneAll from 'material-ui/svg-icons/action/done-all'; import ContentClear from 'material-ui/svg-icons/content/clear'; import { BusyStep, CompletedStep, CopyToClipboard, Button, IdentityIcon, Modal, TxHash } from '~/ui'; -import { ERRORS, validateAbi, validateCode, validateName } from '../../util/validation'; +import { ERRORS, validateAbi, validateCode, validateName } from '~/util/validation'; import DetailsStep from './DetailsStep'; import ParametersStep from './ParametersStep'; diff --git a/js/src/modals/EditMeta/editMeta.js b/js/src/modals/EditMeta/editMeta.js index ad26c19fe..8ab9233f1 100644 --- a/js/src/modals/EditMeta/editMeta.js +++ b/js/src/modals/EditMeta/editMeta.js @@ -19,7 +19,7 @@ import ContentClear from 'material-ui/svg-icons/content/clear'; import ContentSave from 'material-ui/svg-icons/content/save'; import { Button, Form, Input, InputChip, Modal } from '~/ui'; -import { validateName } from '../../util/validation'; +import { validateName } from '~/util/validation'; export default class EditMeta extends Component { static contextTypes = { diff --git a/js/src/modals/ExecuteContract/executeContract.js b/js/src/modals/ExecuteContract/executeContract.js index 4a708d17a..2db5e2b04 100644 --- a/js/src/modals/ExecuteContract/executeContract.js +++ b/js/src/modals/ExecuteContract/executeContract.js @@ -21,8 +21,8 @@ import ActionDoneAll from 'material-ui/svg-icons/action/done-all'; import ContentClear from 'material-ui/svg-icons/content/clear'; import { BusyStep, CompletedStep, Button, IdentityIcon, Modal, TxHash } from '~/ui'; -import { MAX_GAS_ESTIMATION } from '../../util/constants'; -import { validateAddress, validateUint } from '../../util/validation'; +import { MAX_GAS_ESTIMATION } from '~/util/constants'; +import { validateAddress, validateUint } from '~/util/validation'; import { parseAbiType } from '~/util/abi'; import DetailsStep from './DetailsStep'; diff --git a/js/src/modals/SMSVerification/store.js b/js/src/modals/SMSVerification/store.js index 49b91fa70..7a132aaf7 100644 --- a/js/src/modals/SMSVerification/store.js +++ b/js/src/modals/SMSVerification/store.js @@ -21,9 +21,8 @@ import { sha3 } from '~/api/util/sha3'; import Contracts from '~/contracts'; import { checkIfVerified, checkIfRequested, awaitPuzzle } from '~/contracts/sms-verification'; -import { postToServer } from '../../3rdparty/sms-verification'; -import checkIfTxFailed from '../../util/check-if-tx-failed'; -import waitForConfirmations from '../../util/wait-for-block-confirmations'; +import { postToServer } from '~/3rdparty/sms-verification'; +import { checkIfTxFailed, waitForConfirmations } from '~/util/tx'; export const LOADING = 'fetching-contract'; export const QUERY_DATA = 'query-data'; diff --git a/js/src/modals/SaveContract/saveContract.js b/js/src/modals/SaveContract/saveContract.js index c73fd8a21..5d7863632 100644 --- a/js/src/modals/SaveContract/saveContract.js +++ b/js/src/modals/SaveContract/saveContract.js @@ -20,7 +20,7 @@ import SaveIcon from 'material-ui/svg-icons/content/save'; import ContentClear from 'material-ui/svg-icons/content/clear'; import { Button, Modal, Editor, Form, Input } from '~/ui'; -import { ERRORS, validateName } from '../../util/validation'; +import { ERRORS, validateName } from '~/util/validation'; import styles from './saveContract.css'; diff --git a/js/src/modals/Shapeshift/shapeshift.js b/js/src/modals/Shapeshift/shapeshift.js index 562c8cbf3..9c5d696b0 100644 --- a/js/src/modals/Shapeshift/shapeshift.js +++ b/js/src/modals/Shapeshift/shapeshift.js @@ -19,7 +19,7 @@ import ActionDoneAll from 'material-ui/svg-icons/action/done-all'; import ContentClear from 'material-ui/svg-icons/content/clear'; import { Button, IdentityIcon, Modal } from '~/ui'; -import initShapeshift from '../../3rdparty/shapeshift'; +import initShapeshift from '~/3rdparty/shapeshift'; import shapeshiftLogo from '../../../assets/images/shapeshift-logo.png'; import AwaitingDepositStep from './AwaitingDepositStep'; diff --git a/js/src/redux/providers/walletActions.js b/js/src/redux/providers/walletActions.js index 8e13ac1a0..4a8a3f82a 100644 --- a/js/src/redux/providers/walletActions.js +++ b/js/src/redux/providers/walletActions.js @@ -17,12 +17,10 @@ import { isEqual, uniq } from 'lodash'; import Contract from '~/api/contract'; -import { wallet as WALLET_ABI } from '~/contracts/abi'; import { bytesToHex, toHex } from '~/api/util/format'; - import { ERROR_CODES } from '~/api/transport/error'; -import { MAX_GAS_ESTIMATION } from '../../util/constants'; - +import { wallet as WALLET_ABI } from '~/contracts/abi'; +import { MAX_GAS_ESTIMATION } from '~/util/constants'; import WalletsUtils from '~/util/wallets'; import { newError } from '~/ui/Errors/actions'; diff --git a/js/src/ui/Form/TypedInput/typedInput.js b/js/src/ui/Form/TypedInput/typedInput.js index 9162348e0..a81ec7b79 100644 --- a/js/src/ui/Form/TypedInput/typedInput.js +++ b/js/src/ui/Form/TypedInput/typedInput.js @@ -22,12 +22,11 @@ import IconButton from 'material-ui/IconButton'; import AddIcon from 'material-ui/svg-icons/content/add'; import RemoveIcon from 'material-ui/svg-icons/content/remove'; +import { fromWei, toWei } from '~/api/util/wei'; import Input from '~/ui/Form/Input'; import InputAddressSelect from '~/ui/Form/InputAddressSelect'; import Select from '~/ui/Form/Select'; - import { ABI_TYPES } from '~/util/abi'; -import { fromWei, toWei } from '~/api/util/wei'; import styles from './typedInput.css'; diff --git a/js/src/ui/TxHash/txHash.js b/js/src/ui/TxHash/txHash.js index 81c4e0bf5..715568fd9 100644 --- a/js/src/ui/TxHash/txHash.js +++ b/js/src/ui/TxHash/txHash.js @@ -20,7 +20,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { LinearProgress } from 'material-ui'; -import { txLink } from '../../3rdparty/etherscan/links'; +import { txLink } from '~/3rdparty/etherscan/links'; import ShortenedHash from '../ShortenedHash'; import styles from './txHash.css'; diff --git a/js/src/ui/TxList/txList.js b/js/src/ui/TxList/txList.js index b8c53c1d9..3f5dab264 100644 --- a/js/src/ui/TxList/txList.js +++ b/js/src/ui/TxList/txList.js @@ -20,7 +20,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { observer } from 'mobx-react'; -import { txLink, addressLink } from '../../3rdparty/etherscan/links'; +import { txLink, addressLink } from '~/3rdparty/etherscan/links'; import IdentityIcon from '../IdentityIcon'; import IdentityName from '../IdentityName'; diff --git a/js/src/util/check-if-tx-failed.js b/js/src/util/check-if-tx-failed.js deleted file mode 100644 index 39689bedd..000000000 --- a/js/src/util/check-if-tx-failed.js +++ /dev/null @@ -1,28 +0,0 @@ -// 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 . - -const checkIfTxFailed = (api, tx, gasSent) => { - return api.pollMethod('eth_getTransactionReceipt', tx) - .then((receipt) => { - // TODO: Right now, there's no way to tell wether the EVM code crashed. - // Because you usually send a bit more gas than estimated (to make sure - // it gets mined quickly), we transaction probably failed if all the gas - // has been used up. - return receipt.gasUsed.eq(gasSent); - }); -}; - -export default checkIfTxFailed; diff --git a/js/src/util/is-testnet.js b/js/src/util/is-testnet.js deleted file mode 100644 index c2bf2c450..000000000 --- a/js/src/util/is-testnet.js +++ /dev/null @@ -1,19 +0,0 @@ -// 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 . - -export default (chain) => { - return chain === 'morden' || chain === 'ropsten' || chain === 'testnet'; -}; diff --git a/js/src/util/wait-for-block-confirmations.js b/js/src/util/tx.js similarity index 73% rename from js/src/util/wait-for-block-confirmations.js rename to js/src/util/tx.js index 79ba2be25..b688d06fe 100644 --- a/js/src/util/wait-for-block-confirmations.js +++ b/js/src/util/tx.js @@ -18,7 +18,18 @@ const isValidReceipt = (receipt) => { return receipt && receipt.blockNumber && receipt.blockNumber.gt(0); }; -const waitForConfirmations = (api, tx, confirmations) => { +export function checkIfTxFailed (api, tx, gasSent) { + return api.pollMethod('eth_getTransactionReceipt', tx) + .then((receipt) => { + // TODO: Right now, there's no way to tell wether the EVM code crashed. + // Because you usually send a bit more gas than estimated (to make sure + // it gets mined quickly), we transaction probably failed if all the gas + // has been used up. + return receipt.gasUsed.eq(gasSent); + }); +} + +export function waitForConfirmations (api, tx, confirmations) { return new Promise((resolve, reject) => { api.pollMethod('eth_getTransactionReceipt', tx, isValidReceipt) .then((receipt) => { @@ -39,6 +50,4 @@ const waitForConfirmations = (api, tx, confirmations) => { .catch(reject); }); }); -}; - -export default waitForConfirmations; +} diff --git a/js/src/views/Account/Transactions/transactions.css b/js/src/views/Account/Transactions/transactions.css index 13d727deb..6b44d298f 100644 --- a/js/src/views/Account/Transactions/transactions.css +++ b/js/src/views/Account/Transactions/transactions.css @@ -15,9 +15,6 @@ /* along with Parity. If not, see . */ -.transactions { -} - .infonone { opacity: 0.25; } diff --git a/js/src/views/Account/Transactions/transactions.js b/js/src/views/Account/Transactions/transactions.js index e71781adf..2e98208b6 100644 --- a/js/src/views/Account/Transactions/transactions.js +++ b/js/src/views/Account/Transactions/transactions.js @@ -18,7 +18,7 @@ import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; -import etherscan from '../../../3rdparty/etherscan'; +import etherscan from '~/3rdparty/etherscan'; import { Container, TxList } from '~/ui'; import styles from './transactions.css'; diff --git a/js/src/views/Account/account.css b/js/src/views/Account/account.css index b1410f23a..a9a039c83 100644 --- a/js/src/views/Account/account.css +++ b/js/src/views/Account/account.css @@ -14,8 +14,6 @@ /* You should have received a copy of the GNU General Public License /* along with Parity. If not, see . */ -.account { -} .btnicon { width: 24px; diff --git a/js/src/views/Account/account.js b/js/src/views/Account/account.js index 98b0a5e97..cbacd5280 100644 --- a/js/src/views/Account/account.js +++ b/js/src/views/Account/account.js @@ -105,7 +105,7 @@ class Account extends Component { } return ( -
+
{ this.renderDeleteDialog(account) } { this.renderEditDialog(account) } { this.renderFundDialog() } diff --git a/js/src/views/Accounts/accounts.css b/js/src/views/Accounts/accounts.css index 469f33ddc..317905fd5 100644 --- a/js/src/views/Accounts/accounts.css +++ b/js/src/views/Accounts/accounts.css @@ -14,8 +14,6 @@ /* You should have received a copy of the GNU General Public License /* along with Parity. If not, see . */ -.accounts { -} .accountTooltip { top: 13.3em; diff --git a/js/src/views/Accounts/accounts.js b/js/src/views/Accounts/accounts.js index a8a29945f..4383b7662 100644 --- a/js/src/views/Accounts/accounts.js +++ b/js/src/views/Accounts/accounts.js @@ -82,7 +82,7 @@ class Accounts extends Component { render () { return ( -
+
{ this.renderNewDialog() } { this.renderNewWalletDialog() } { this.renderActionbar() } diff --git a/js/src/views/Address/address.css b/js/src/views/Address/address.css index d93b88b59..cd44688bb 100644 --- a/js/src/views/Address/address.css +++ b/js/src/views/Address/address.css @@ -14,37 +14,37 @@ /* You should have received a copy of the GNU General Public License /* along with Parity. If not, see . */ -.address { -} -.delete .hero { - padding-bottom: 1em; -} +.delete { + .hero { + padding-bottom: 1em; + } -.delete .info { - display: inline-block; -} + .info { + display: inline-block; + } -.delete .icon { - display: inline-block; -} + .icon { + display: inline-block; + } -.delete .nameinfo { - display: inline-block; - text-align: left; -} + .nameinfo { + display: inline-block; + text-align: left; + } -.delete .header { - text-transform: uppercase; - font-size: 1.25em; - padding-bottom: 0.25em; -} + .header { + text-transform: uppercase; + font-size: 1.25em; + padding-bottom: 0.25em; + } -.delete .address { -} + .address { + } -.delete .description { - padding-top: 1em; - font-size: 0.75em; - color: #aaa; + .description { + padding-top: 1em; + font-size: 0.75em; + color: #aaa; + } } diff --git a/js/src/views/Address/address.js b/js/src/views/Address/address.js index 0fae3cb1f..c1427b2be 100644 --- a/js/src/views/Address/address.js +++ b/js/src/views/Address/address.js @@ -28,8 +28,6 @@ import Transactions from '../Account/Transactions'; import Delete from './Delete'; import { setVisibleAccounts } from '~/redux/providers/personalActions'; -import styles from './address.css'; - class Address extends Component { static contextTypes = { api: PropTypes.object.isRequired, @@ -85,7 +83,7 @@ class Address extends Component { } return ( -
+
{ this.renderEditDialog(contact) } { this.renderActionbar(contact) } . */ -.addresses { -} .list { display: flex; @@ -26,21 +24,21 @@ flex: 0 1 50%; width: 50%; position: relative; -} -.address:nth-child(odd)>div { - padding-right: 0.5em !important; -} + &:nth-child(odd)>div { + padding-right: 0.5em !important; + } -.address:nth-child(even)>div { - padding-left: 0.5em !important; + &:nth-child(even)>div { + padding-left: 0.5em !important; + } } .empty { width: 100%; display: block; -} -.empty div { - color: #aaa; + div { + color: #aaa; + } } diff --git a/js/src/views/Addresses/addresses.js b/js/src/views/Addresses/addresses.js index 4edfb0e6e..5e0ed4e18 100644 --- a/js/src/views/Addresses/addresses.js +++ b/js/src/views/Addresses/addresses.js @@ -76,7 +76,7 @@ class Addresses extends Component { const { searchValues, sortOrder } = this.state; return ( -
+
{ this.renderActionbar() } { this.renderAddAddress() } diff --git a/js/src/views/Connection/connection.js b/js/src/views/Connection/connection.js index 451624a2b..ad0e0c140 100644 --- a/js/src/views/Connection/connection.js +++ b/js/src/views/Connection/connection.js @@ -19,7 +19,6 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import ActionCompareArrows from 'material-ui/svg-icons/action/compare-arrows'; import ActionDashboard from 'material-ui/svg-icons/action/dashboard'; -// import CommunicationVpnKey from 'material-ui/svg-icons/communication/vpn-key'; import HardwareDesktopMac from 'material-ui/svg-icons/hardware/desktop-mac'; import NotificationVpnLock from 'material-ui/svg-icons/notification/vpn-lock'; diff --git a/js/src/views/Contract/Events/Event/event.js b/js/src/views/Contract/Events/Event/event.js index b42295198..1ed114d07 100644 --- a/js/src/views/Contract/Events/Event/event.js +++ b/js/src/views/Contract/Events/Event/event.js @@ -20,7 +20,7 @@ import React, { Component, PropTypes } from 'react'; import { IdentityIcon, IdentityName, Input, InputAddress } from '~/ui'; import ShortenedHash from '~/ui/ShortenedHash'; -import { txLink } from '../../../../3rdparty/etherscan/links'; +import { txLink } from '~/3rdparty/etherscan/links'; import styles from '../../contract.css'; diff --git a/js/src/views/Contract/contract.css b/js/src/views/Contract/contract.css index eb6cabfa2..f49da0831 100644 --- a/js/src/views/Contract/contract.css +++ b/js/src/views/Contract/contract.css @@ -15,26 +15,26 @@ /* along with Parity. If not, see . */ -.contract { -} - .events { width: 100%; border: none; border-spacing: 0; -} -.events tr { - line-height: 32px; - vertical-align: top; + tr { + line-height: 32px; + vertical-align: top; + } } .event { -} + td { + vertical-align: top; + padding: 1em 0.5em; -.event td { - vertical-align: top; - padding: 1em 0.5em; + div { + white-space: nowrap; + } + } } .txhash { @@ -47,10 +47,6 @@ color: #aaa; } -.event td div { - white-space: nowrap; -} - .mined { } diff --git a/js/src/views/Contract/contract.js b/js/src/views/Contract/contract.js index 2aa37f847..35ad95fe2 100644 --- a/js/src/views/Contract/contract.js +++ b/js/src/views/Contract/contract.js @@ -124,7 +124,7 @@ class Contract extends Component { } return ( -
+
{ this.renderActionbar(account) } { this.renderDeleteDialog(account) } { this.renderEditDialog(account) } diff --git a/js/src/views/Contracts/contracts.css b/js/src/views/Contracts/contracts.css deleted file mode 100644 index eab0858e7..000000000 --- a/js/src/views/Contracts/contracts.css +++ /dev/null @@ -1,18 +0,0 @@ -/* 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 . -*/ -.contracts { -} diff --git a/js/src/views/Contracts/contracts.js b/js/src/views/Contracts/contracts.js index d97d88b09..b84705b32 100644 --- a/js/src/views/Contracts/contracts.js +++ b/js/src/views/Contracts/contracts.js @@ -28,8 +28,6 @@ import { setVisibleAccounts } from '~/redux/providers/personalActions'; import List from '../Accounts/List'; -import styles from './contracts.css'; - class Contracts extends Component { static contextTypes = { api: PropTypes.object.isRequired @@ -80,7 +78,7 @@ class Contracts extends Component { const { searchValues, sortOrder } = this.state; return ( -
+
{ this.renderActionbar() } { this.renderAddContract() } { this.renderAddContract() } @@ -159,7 +157,6 @@ class Contracts extends Component { return ( ); diff --git a/js/src/views/Settings/settings.css b/js/src/views/Settings/settings.css index 91138db68..1eab3aac3 100644 --- a/js/src/views/Settings/settings.css +++ b/js/src/views/Settings/settings.css @@ -15,9 +15,6 @@ /* along with Parity. If not, see . */ -.layout { -} - .menu { display: inline-block; } @@ -35,31 +32,24 @@ padding: 16px 2em !important; line-height: 24px !important; width: auto !important; -} -.tabactive { -} + &>div { + height: 24px !important; -.tab>div, -.tabactive>div { - height: 24px !important; -} + &>div { + display: inline-block !important; + } + } -.tab>div>div, -.tabactive>div>div { - display: inline-block !important; -} + svg { + margin-right: 0.5em; + margin-bottom: 0 !important; + } -.tab svg, -.tabactive svg { - margin-right: 0.5em; - margin-bottom: 0 !important; -} - -.tab .menu, -.tabactive .menu { - vertical-align: top; - display: inline-block; + .menu { + vertical-align: top; + display: inline-block; + } } .imageIcon { @@ -68,6 +58,8 @@ opacity: 0.5; } -.tabactive .imageIcon { - opacity: 1; +.tabactive { + .imageIcon { + opacity: 1; + } } diff --git a/js/src/views/Settings/settings.js b/js/src/views/Settings/settings.js index 54b4fa6dd..a6c455dad 100644 --- a/js/src/views/Settings/settings.js +++ b/js/src/views/Settings/settings.js @@ -45,7 +45,7 @@ export default class Settings extends Component { } return ( -
+
{ this.renderTab(hash, 'views', ) } diff --git a/js/src/views/Signer/components/Account/AccountLink/AccountLink.js b/js/src/views/Signer/components/Account/AccountLink/AccountLink.js index 97ff35ce9..f42675474 100644 --- a/js/src/views/Signer/components/Account/AccountLink/AccountLink.js +++ b/js/src/views/Signer/components/Account/AccountLink/AccountLink.js @@ -16,7 +16,7 @@ import React, { Component, PropTypes } from 'react'; -import { addressLink } from '../../../../../3rdparty/etherscan/links'; +import { addressLink } from '~/3rdparty/etherscan/links'; import styles from './AccountLink.css'; export default class AccountLink extends Component { diff --git a/js/src/views/Signer/components/TxHashLink/TxHashLink.js b/js/src/views/Signer/components/TxHashLink/TxHashLink.js index 5fbd5695e..bce30eded 100644 --- a/js/src/views/Signer/components/TxHashLink/TxHashLink.js +++ b/js/src/views/Signer/components/TxHashLink/TxHashLink.js @@ -16,7 +16,7 @@ import React, { Component, PropTypes } from 'react'; -import { txLink } from '../../../../3rdparty/etherscan/links'; +import { txLink } from '~/3rdparty/etherscan/links'; export default class TxHashLink extends Component { diff --git a/js/src/views/Signer/containers/Embedded/embedded.css b/js/src/views/Signer/containers/Embedded/embedded.css index 94e0f3933..ffc6a209f 100644 --- a/js/src/views/Signer/containers/Embedded/embedded.css +++ b/js/src/views/Signer/containers/Embedded/embedded.css @@ -23,9 +23,6 @@ width: $embedWidth; } -.pending { -} - .none { color: #aaa; } diff --git a/js/src/views/Signer/containers/Embedded/embedded.js b/js/src/views/Signer/containers/Embedded/embedded.js index 57639ea11..4629a6522 100644 --- a/js/src/views/Signer/containers/Embedded/embedded.js +++ b/js/src/views/Signer/containers/Embedded/embedded.js @@ -71,7 +71,7 @@ class Embedded extends Component { const items = pending.sort(this._sortRequests).map(this.renderPending); return ( -
+
{ items }
); diff --git a/js/src/views/Signer/containers/RequestsPage/RequestsPage.css b/js/src/views/Signer/containers/RequestsPage/RequestsPage.css index 3701c3097..662c45817 100644 --- a/js/src/views/Signer/containers/RequestsPage/RequestsPage.css +++ b/js/src/views/Signer/containers/RequestsPage/RequestsPage.css @@ -15,12 +15,6 @@ /* along with Parity. If not, see . */ -.request { -} - .noRequestsMsg { color: #aaa; } - -.items { -} diff --git a/js/src/views/Signer/containers/RequestsPage/RequestsPage.js b/js/src/views/Signer/containers/RequestsPage/RequestsPage.js index ecb2ccd43..f3cd5a267 100644 --- a/js/src/views/Signer/containers/RequestsPage/RequestsPage.js +++ b/js/src/views/Signer/containers/RequestsPage/RequestsPage.js @@ -98,9 +98,7 @@ class RequestsPage extends Component { return ( -
- { items } -
+ { items }
); } @@ -111,7 +109,6 @@ class RequestsPage extends Component { return ( . -*/ -.signer { -} - -.container { -} - -.mainContainer { -} diff --git a/js/src/views/Signer/signer.js b/js/src/views/Signer/signer.js index 536cf1d37..6d68c1dc0 100644 --- a/js/src/views/Signer/signer.js +++ b/js/src/views/Signer/signer.js @@ -19,12 +19,10 @@ import React, { Component } from 'react'; import { Actionbar } from '~/ui'; import RequestsPage from './containers/RequestsPage'; -import styles from './signer.css'; - export default class Signer extends Component { render () { return ( -
+
diff --git a/js/src/views/Status/containers/StatusPage/StatusPage.js b/js/src/views/Status/containers/StatusPage/StatusPage.js index 286e2c20e..c7ab56c5e 100644 --- a/js/src/views/Status/containers/StatusPage/StatusPage.js +++ b/js/src/views/Status/containers/StatusPage/StatusPage.js @@ -23,8 +23,6 @@ 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, @@ -41,7 +39,7 @@ class StatusPage extends Component { render () { return ( -
+
diff --git a/js/src/views/Status/containers/StatusPage/statusPage.css b/js/src/views/Status/containers/StatusPage/statusPage.css deleted file mode 100644 index 850ee0856..000000000 --- a/js/src/views/Status/containers/StatusPage/statusPage.css +++ /dev/null @@ -1,18 +0,0 @@ -/* 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 . -*/ -.body { -} From 2582514b5875be42e74a5de541937ebbc7b40a04 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 9 Dec 2016 13:44:35 +0100 Subject: [PATCH 2/5] GasEditor component (#3750) * Initial split of component (WIP) * GasPriceEditor externalised * Fix lint --- js/src/modals/Transfer/Extras/extras.js | 97 ++------- js/src/modals/Transfer/store.js | 85 ++------ js/src/modals/Transfer/transfer.css | 9 - js/src/modals/Transfer/transfer.js | 23 +-- .../GasPriceSelector/gasPriceSelector.css | 10 + .../GasPriceSelector/gasPriceSelector.js | 194 +++++++++--------- .../GasPriceEditor}/GasPriceSelector/index.js | 0 js/src/ui/GasPriceEditor/gasPriceEditor.css | 49 +++++ js/src/ui/GasPriceEditor/gasPriceEditor.js | 98 +++++++++ js/src/ui/GasPriceEditor/index.js | 17 ++ js/src/ui/GasPriceEditor/store.js | 105 ++++++++++ js/src/ui/index.js | 6 +- js/src/util/validation.js | 24 ++- 13 files changed, 440 insertions(+), 277 deletions(-) rename js/src/{modals/Transfer => ui/GasPriceEditor}/GasPriceSelector/gasPriceSelector.css (85%) rename js/src/{modals/Transfer => ui/GasPriceEditor}/GasPriceSelector/gasPriceSelector.js (77%) rename js/src/{modals/Transfer => ui/GasPriceEditor}/GasPriceSelector/index.js (100%) create mode 100644 js/src/ui/GasPriceEditor/gasPriceEditor.css create mode 100644 js/src/ui/GasPriceEditor/gasPriceEditor.js create mode 100644 js/src/ui/GasPriceEditor/index.js create mode 100644 js/src/ui/GasPriceEditor/store.js diff --git a/js/src/modals/Transfer/Extras/extras.js b/js/src/modals/Transfer/Extras/extras.js index f7ff4612b..6d2bfc821 100644 --- a/js/src/modals/Transfer/Extras/extras.js +++ b/js/src/modals/Transfer/Extras/extras.js @@ -16,96 +16,35 @@ import React, { Component, PropTypes } from 'react'; -import Form, { Input } from '~/ui/Form'; -import GasPriceSelector from '../GasPriceSelector'; - -import styles from '../transfer.css'; +import { GasPriceEditor, Form, Input } from '~/ui'; export default class Extras extends Component { static propTypes = { isEth: PropTypes.bool, data: PropTypes.string, dataError: PropTypes.string, - gas: PropTypes.string, - gasEst: PropTypes.string, - gasError: PropTypes.string, - gasPrice: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object - ]), - gasPriceDefault: PropTypes.string, - gasPriceError: PropTypes.string, - gasPriceHistogram: PropTypes.object, total: PropTypes.string, totalError: PropTypes.string, - onChange: PropTypes.func.isRequired + onChange: PropTypes.func.isRequired, + gasStore: PropTypes.object.isRequired } render () { - const { gas, gasPrice, gasError, gasEst, gasPriceDefault, gasPriceError, gasPriceHistogram, total, totalError } = this.props; - - const gasLabel = `gas amount (estimated: ${gasEst})`; - const priceLabel = `gas price (current: ${gasPriceDefault})`; + const { gasStore, onChange, total, totalError } = this.props; return (
- { this.renderData() } - -
-
- -
- -
-
- - - -
- -
- -
-
-
- -
-

- You can choose the gas price based on the - distribution of recent included transactions' gas prices. - The lower the gas price is, the cheaper the transaction will - be. The higher the gas price is, the faster it should - get mined by the network. -

-
- + + +
); } @@ -129,14 +68,6 @@ export default class Extras extends Component { ); } - onEditGas = (event) => { - this.props.onChange('gas', event.target.value); - } - - onEditGasPrice = (event, value) => { - this.props.onChange('gasPrice', value); - } - onEditData = (event) => { this.props.onChange('data', event.target.value); } diff --git a/js/src/modals/Transfer/store.js b/js/src/modals/Transfer/store.js index 8f8baf55f..a43057c86 100644 --- a/js/src/modals/Transfer/store.js +++ b/js/src/modals/Transfer/store.js @@ -23,7 +23,8 @@ import { bytesToHex } from '~/api/util/format'; import Contract from '~/api/contract'; import ERRORS from './errors'; import { ERROR_CODES } from '~/api/transport/error'; -import { DEFAULT_GAS, DEFAULT_GASPRICE, MAX_GAS_ESTIMATION } from '~/util/constants'; +import { DEFAULT_GAS, MAX_GAS_ESTIMATION } from '~/util/constants'; +import GasPriceStore from '~/ui/GasPriceEditor/store'; const TITLES = { transfer: 'transfer details', @@ -48,14 +49,6 @@ export default class TransferStore { @observable data = ''; @observable dataError = null; - @observable gas = DEFAULT_GAS; - @observable gasError = null; - - @observable gasEst = '0'; - @observable gasLimitError = null; - @observable gasPrice = DEFAULT_GASPRICE; - @observable gasPriceError = null; - @observable recipient = ''; @observable recipientError = ERRORS.requireRecipient; @@ -68,11 +61,8 @@ export default class TransferStore { @observable value = '0.0'; @observable valueError = null; - gasPriceHistogram = {}; - account = null; balance = null; - gasLimit = null; onClose = null; senders = null; @@ -81,6 +71,8 @@ export default class TransferStore { isWallet = false; wallet = null; + gasStore = null; + @computed get steps () { const steps = [].concat(this.extras ? STAGES_EXTRA : STAGES_BASIC); @@ -93,7 +85,7 @@ export default class TransferStore { @computed get isValid () { const detailsValid = !this.recipientError && !this.valueError && !this.totalError && !this.senderError; - const extrasValid = !this.gasError && !this.gasPriceError && !this.totalError; + const extrasValid = !this.gasStore.errorGas && !this.gasStore.errorPrice && !this.totalError; const verifyValid = !this.passwordError; switch (this.stage) { @@ -118,11 +110,12 @@ export default class TransferStore { const { account, balance, gasLimit, senders, onClose, newError, sendersBalances } = props; this.account = account; this.balance = balance; - this.gasLimit = gasLimit; this.onClose = onClose; this.isWallet = account && account.wallet; this.newError = newError; + this.gasStore = new GasPriceStore(api, gasLimit); + if (this.isWallet) { this.wallet = props.wallet; this.walletContract = new Contract(this.api, walletAbi); @@ -179,26 +172,6 @@ export default class TransferStore { } } - @action getDefaults = () => { - Promise - .all([ - this.api.parity.gasPriceHistogram(), - this.api.eth.gasPrice() - ]) - .then(([gasPriceHistogram, gasPrice]) => { - transaction(() => { - this.gasPrice = gasPrice.toString(); - this.gasPriceDefault = gasPrice.toFormat(); - this.gasPriceHistogram = gasPriceHistogram; - - this.recalculate(); - }); - }) - .catch((error) => { - console.warn('getDefaults', error); - }); - } - @action onSend = () => { this.onNext(); this.sending = true; @@ -281,25 +254,11 @@ export default class TransferStore { } @action _onUpdateGas = (gas) => { - const gasError = this._validatePositiveNumber(gas); - - transaction(() => { - this.gas = gas; - this.gasError = gasError; - - this.recalculate(); - }); + this.recalculate(); } @action _onUpdateGasPrice = (gasPrice) => { - const gasPriceError = this._validatePositiveNumber(gasPrice); - - transaction(() => { - this.gasPrice = gasPrice; - this.gasPriceError = gasPriceError; - - this.recalculate(); - }); + this.recalculate(); } @action _onUpdateRecipient = (recipient) => { @@ -362,7 +321,7 @@ export default class TransferStore { @action recalculateGas = () => { if (!this.isValid) { - this.gas = 0; + this.gasStore.setGas('0'); return this.recalculate(); } @@ -370,28 +329,20 @@ export default class TransferStore { .estimateGas() .then((gasEst) => { let gas = gasEst; - let gasLimitError = null; if (gas.gt(DEFAULT_GAS)) { gas = gas.mul(1.2); } - if (gas.gte(MAX_GAS_ESTIMATION)) { - gasLimitError = ERRORS.gasException; - } else if (gas.gt(this.gasLimit)) { - gasLimitError = ERRORS.gasBlockLimit; - } - transaction(() => { - this.gas = gas.toFixed(0); - this.gasEst = gasEst.toFormat(); - this.gasLimitError = gasLimitError; + this.gasStore.setEstimated(gasEst.toFixed(0)); + this.gasStore.setGas(gas.toFixed(0)); this.recalculate(); }); }) .catch((error) => { - console.error('etimateGas', error); + console.warn('etimateGas', error); this.recalculate(); }); } @@ -411,9 +362,9 @@ export default class TransferStore { return; } - const { gas, gasPrice, tag, valueAll, isEth, isWallet } = this; + const { tag, valueAll, isEth, isWallet } = this; - const gasTotal = new BigNumber(gasPrice || 0).mul(new BigNumber(gas || 0)); + const gasTotal = new BigNumber(this.gasStore.price || 0).mul(new BigNumber(this.gasStore.gas || 0)); const availableEth = new BigNumber(balance.tokens[0].value); @@ -453,7 +404,7 @@ export default class TransferStore { } transaction(() => { - this.total = this.api.util.fromWei(totalEth).toString(); + this.total = this.api.util.fromWei(totalEth).toFixed(); this.totalError = totalError; this.value = value; this.valueError = valueError; @@ -522,8 +473,8 @@ export default class TransferStore { }; if (!gas) { - options.gas = this.gas; - options.gasPrice = this.gasPrice; + options.gas = this.gasStore.gas; + options.gasPrice = this.gasStore.price; } else { options.gas = MAX_GAS_ESTIMATION; } diff --git a/js/src/modals/Transfer/transfer.css b/js/src/modals/Transfer/transfer.css index 3bd17ba96..28612f299 100644 --- a/js/src/modals/Transfer/transfer.css +++ b/js/src/modals/Transfer/transfer.css @@ -144,15 +144,6 @@ font-size: 1.2rem; } -.chart { - position: absolute; - width: 100%; -} - -.gasPriceDesc { - font-size: 0.9em; -} - .warning { border-radius: 0.5em; background: #f80; diff --git a/js/src/modals/Transfer/transfer.js b/js/src/modals/Transfer/transfer.js index e1e2a0951..00e84adaf 100644 --- a/js/src/modals/Transfer/transfer.js +++ b/js/src/modals/Transfer/transfer.js @@ -56,10 +56,6 @@ class Transfer extends Component { store = new TransferStore(this.context.api, this.props); - componentDidMount () { - this.store.getDefaults(); - } - render () { const { stage, extras, steps } = this.store; @@ -186,27 +182,20 @@ class Transfer extends Component { } renderExtrasPage () { - if (!this.store.gasPriceHistogram) { + if (!this.store.gasStore.histogram) { return null; } - const { isEth, data, dataError, gas, gasEst, gasError, gasPrice } = this.store; - const { gasPriceDefault, gasPriceError, gasPriceHistogram, total, totalError } = this.store; + const { isEth, data, dataError, total, totalError } = this.store; return ( ); } @@ -263,15 +252,15 @@ class Transfer extends Component { } renderWarning () { - const { gasLimitError } = this.store; + const { errorEstimated } = this.store.gasStore; - if (!gasLimitError) { + if (!errorEstimated) { return null; } return (
- { gasLimitError } + { errorEstimated }
); } diff --git a/js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.css b/js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.css similarity index 85% rename from js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.css rename to js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.css index 445174c59..247211c50 100644 --- a/js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.css +++ b/js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.css @@ -15,3 +15,13 @@ /* along with Parity. If not, see . */ +.chart { + position: absolute; + width: 100%; +} + +.columns { + display: flex; + flex-wrap: wrap; + position: relative; +} diff --git a/js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.js b/js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.js similarity index 77% rename from js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.js rename to js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.js index adf644c4e..893a50188 100644 --- a/js/src/modals/Transfer/GasPriceSelector/gasPriceSelector.js +++ b/js/src/ui/GasPriceEditor/GasPriceSelector/gasPriceSelector.js @@ -29,10 +29,7 @@ import { import Slider from 'material-ui/Slider'; import BigNumber from 'bignumber.js'; -import componentStyles from './gasPriceSelector.css'; -import mainStyles from '../transfer.css'; - -const styles = Object.assign({}, mainStyles, componentStyles); +import styles from './gasPriceSelector.css'; const COLORS = { default: 'rgba(255, 99, 132, 0.2)', @@ -194,10 +191,7 @@ class CustomizedShape extends Component { class CustomTooltip extends Component { static propTypes = { - gasPriceHistogram: PropTypes.shape({ - bucketBounds: PropTypes.array.isRequired, - counts: PropTypes.array.isRequired - }).isRequired, + gasPriceHistogram: PropTypes.object.isRequired, type: PropTypes.string, payload: PropTypes.array, label: PropTypes.number, @@ -231,12 +225,16 @@ class CustomTooltip extends Component { } } +const TOOL_STYLE = { + color: 'rgba(255,255,255,0.5)', + backgroundColor: 'rgba(0, 0, 0, 0.75)', + padding: '0 0.5em', + fontSize: '0.75em' +}; + export default class GasPriceSelector extends Component { static propTypes = { - gasPriceHistogram: PropTypes.shape({ - bucketBounds: PropTypes.array.isRequired, - counts: PropTypes.array.isRequired - }).isRequired, + gasPriceHistogram: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired, gasPrice: PropTypes.oneOfType([ @@ -287,21 +285,23 @@ export default class GasPriceSelector extends Component { renderSlider () { const { sliderValue } = this.state; - return (
- -
); + return ( +
+ +
+ ); } renderChart () { @@ -316,85 +316,83 @@ export default class GasPriceSelector extends Component { const countIndex = Math.max(0, Math.min(selectedIndex, gasPriceHistogram.counts.length - 1)); const selectedCount = countModifier(gasPriceHistogram.counts[countIndex]); - return (
-
-
- - +
+
+ - } - line - isAnimationActive={ false } - /> + + } + line + isAnimationActive={ false } + /> - - - - -
+ + + + +
-
- - + - } - /> + + } + /> - } - /> + } + /> - - - - + + + + +
-
); + ); } renderCustomCursor = () => { diff --git a/js/src/modals/Transfer/GasPriceSelector/index.js b/js/src/ui/GasPriceEditor/GasPriceSelector/index.js similarity index 100% rename from js/src/modals/Transfer/GasPriceSelector/index.js rename to js/src/ui/GasPriceEditor/GasPriceSelector/index.js diff --git a/js/src/ui/GasPriceEditor/gasPriceEditor.css b/js/src/ui/GasPriceEditor/gasPriceEditor.css new file mode 100644 index 000000000..cf1fff81c --- /dev/null +++ b/js/src/ui/GasPriceEditor/gasPriceEditor.css @@ -0,0 +1,49 @@ +/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* This file is part of Parity. +/* +/* Parity is free software: you can redistribute it and/or modify +/* it under the terms of the GNU General Public License as published by +/* the Free Software Foundation, either version 3 of the License, or +/* (at your option) any later version. +/* +/* Parity is distributed in the hope that it will be useful, +/* but WITHOUT ANY WARRANTY; without even the implied warranty of +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/* GNU General Public License for more details. +/* +/* You should have received a copy of the GNU General Public License +/* along with Parity. If not, see . +*/ + +.columns { + display: flex; + flex-wrap: wrap; + position: relative; +} + +.graphColumn { + flex: 65; +} + +.editColumn { + flex: 35; + padding-left: 1em; + justify-ontent: space-around; + padding-bottom: 12; + display: flex; + flex-wrap: wrap; + position: relative; + flex-direction: column; +} + +.gasPriceDesc { + font-size: 0.75em; + opacity: 0.5; +} + +.row { + display: flex; + flex-wrap: wrap; + position: relative; + flex-direction: column; +} diff --git a/js/src/ui/GasPriceEditor/gasPriceEditor.js b/js/src/ui/GasPriceEditor/gasPriceEditor.js new file mode 100644 index 000000000..c6759ddf1 --- /dev/null +++ b/js/src/ui/GasPriceEditor/gasPriceEditor.js @@ -0,0 +1,98 @@ +// 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 . + +import BigNumber from 'bignumber.js'; +import React, { Component, PropTypes } from 'react'; +import { observer } from 'mobx-react'; + +import Input from '../Form/Input'; +import GasPriceSelector from './GasPriceSelector'; +import Store from './store'; + +import styles from './gasPriceEditor.css'; + +@observer +export default class GasPriceEditor extends Component { + static propTypes = { + children: PropTypes.node, + store: PropTypes.object.isRequired, + onChange: PropTypes.func + } + + static Store = Store; + + render () { + const { children, store } = this.props; + const { estimated, priceDefault, price, gas, histogram, errorGas, errorPrice } = store; + + const gasLabel = `gas (estimated: ${new BigNumber(estimated).toFormat()})`; + const priceLabel = `price (current: ${new BigNumber(priceDefault).toFormat()})`; + + return ( +
+
+ +
+ You can choose the gas price based on the + distribution of recent included transaction gas prices. + The lower the gas price is, the cheaper the transaction will + be. The higher the gas price is, the faster it should + get mined by the network. +
+
+ +
+
+ + + +
+ +
+ { children } +
+
+
+ ); + } + + onEditGas = (event, gas) => { + const { store, onChange } = this.props; + + store.setGas(gas); + onChange && onChange('gas', gas); + } + + onEditGasPrice = (event, price) => { + const { store, onChange } = this.props; + + store.setPrice(price); + onChange && onChange('gasPrice', price); + } +} diff --git a/js/src/ui/GasPriceEditor/index.js b/js/src/ui/GasPriceEditor/index.js new file mode 100644 index 000000000..956f6ffd2 --- /dev/null +++ b/js/src/ui/GasPriceEditor/index.js @@ -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 . + +export default from './gasPriceEditor'; diff --git a/js/src/ui/GasPriceEditor/store.js b/js/src/ui/GasPriceEditor/store.js new file mode 100644 index 000000000..3f3e50430 --- /dev/null +++ b/js/src/ui/GasPriceEditor/store.js @@ -0,0 +1,105 @@ +// 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 . + +import BigNumber from 'bignumber.js'; +import { action, observable, transaction } from 'mobx'; + +import { ERRORS, validatePositiveNumber } from '~/util/validation'; +import { DEFAULT_GAS, DEFAULT_GASPRICE, MAX_GAS_ESTIMATION } from '~/util/constants'; + +export default class GasPriceEditor { + @observable errorEstimated = null; + @observable errorGas = null; + @observable errorPrice = null; + @observable estimated = DEFAULT_GAS; + @observable histogram = null; + @observable price = DEFAULT_GASPRICE; + @observable priceDefault = DEFAULT_GASPRICE; + @observable gas = DEFAULT_GAS; + @observable gasLimit = 0; + + constructor (api, gasLimit, loadDefaults = true) { + this._api = api; + this.gasLimit = gasLimit; + + if (loadDefaults) { + this.loadDefaults(); + } + } + + @action setEstimated = (estimated) => { + transaction(() => { + const bn = new BigNumber(estimated); + + this.estimated = estimated; + + if (bn.gte(MAX_GAS_ESTIMATION)) { + this.errorEstimated = ERRORS.gasException; + } else if (bn.gte(this.gasLimit)) { + this.errorEstimated = ERRORS.gasBlockLimit; + } else { + this.errorEstimated = null; + } + }); + } + + @action setHistogram = (gasHistogram) => { + this.histogram = gasHistogram; + } + + @action setPrice = (price) => { + transaction(() => { + this.errorPrice = validatePositiveNumber(price).numberError; + this.price = price; + }); + } + + @action setGas = (gas) => { + transaction(() => { + const { numberError } = validatePositiveNumber(gas); + const bn = new BigNumber(gas); + + this.gas = gas; + + if (numberError) { + this.errorGas = numberError; + } else if (bn.gte(this.gasLimit)) { + this.errorGas = ERRORS.gasBlockLimit; + } else { + this.errorGas = null; + } + }); + } + + @action loadDefaults () { + Promise + .all([ + this._api.parity.gasPriceHistogram(), + this._api.eth.gasPrice() + ]) + .then(([gasPriceHistogram, gasPrice]) => { + transaction(() => { + this.setPrice(gasPrice.toFixed(0)); + this.setHistogram(gasPriceHistogram); + + this.priceDefault = gasPrice.toFixed(); + }); + }) + .catch((error) => { + console.warn('getDefaults', error); + }); + } +} diff --git a/js/src/ui/index.js b/js/src/ui/index.js index 6c763f0f3..c5a965458 100644 --- a/js/src/ui/index.js +++ b/js/src/ui/index.js @@ -31,6 +31,7 @@ import CopyToClipboard from './CopyToClipboard'; import Editor from './Editor'; import Errors from './Errors'; import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select, RadioButtons } from './Form'; +import GasPriceEditor from './GasPriceEditor'; import IdentityIcon from './IdentityIcon'; import IdentityName from './IdentityName'; import Loading from './Loading'; @@ -67,7 +68,7 @@ export { Errors, Form, FormWrap, - TypedInput, + GasPriceEditor, Input, InputAddress, InputAddressSelect, @@ -91,5 +92,6 @@ export { Tooltip, Tooltips, TxHash, - TxList + TxList, + TypedInput }; diff --git a/js/src/util/validation.js b/js/src/util/validation.js index 2b64141db..3d312a2f4 100644 --- a/js/src/util/validation.js +++ b/js/src/util/validation.js @@ -20,6 +20,7 @@ import util from '~/api/util'; export const ERRORS = { invalidAddress: 'address is an invalid network address', + invalidAmount: 'the supplied amount should be a valid positive number', duplicateAddress: 'the address is already in your address book', invalidChecksum: 'address has failed the checksum formatting', invalidName: 'name should not be blank and longer than 2', @@ -27,7 +28,9 @@ export const ERRORS = { invalidCode: 'code should be the compiled hex string', invalidNumber: 'invalid number format', negativeNumber: 'input number should be positive', - decimalNumber: 'input number should not contain decimals' + decimalNumber: 'input number should not contain decimals', + gasException: 'the transaction will throw an exception with the current values', + gasBlockLimit: 'the transaction execution will exceed the block gas limit' }; export function validateAbi (abi, api) { @@ -133,6 +136,25 @@ export function validateName (name) { }; } +export function validatePositiveNumber (number) { + let numberError = null; + + try { + const v = new BigNumber(number); + + if (v.lt(0)) { + numberError = ERRORS.invalidAmount; + } + } catch (e) { + numberError = ERRORS.invalidAmount; + } + + return { + number, + numberError + }; +} + export function validateUint (value) { let valueError = null; From 1213ada59ce2d48b1aed4b91c67d1dd11f5267aa Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Fri, 9 Dec 2016 12:52:50 +0000 Subject: [PATCH 3/5] [ci skip] js-precompiled 20161209-125036 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5795de427..d0664d801 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1271,7 +1271,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#1bf7160f6c8f25353d790dbd0935560d3d395727" +source = "git+https://github.com/ethcore/js-precompiled.git#8e8e515f958d2d4a5abec07253a51a052f2b744d" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 4be14d531..ab501f6a7 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.102", + "version": "0.2.103", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From ffd8314a115b49c9dc7eeff582bd480fbaec0a8e Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 9 Dec 2016 17:52:25 +0100 Subject: [PATCH 4/5] Be lenient around invalid owners map (#3764) * Be lenient around invalid owners map * Filter invalid owners before render --- js/src/views/Accounts/Summary/summary.js | 6 ++++-- js/src/views/Accounts/accounts.js | 18 +++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/js/src/views/Accounts/Summary/summary.js b/js/src/views/Accounts/Summary/summary.js index 764f24edf..aeff8a2e5 100644 --- a/js/src/views/Accounts/Summary/summary.js +++ b/js/src/views/Accounts/Summary/summary.js @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import BigNumber from 'bignumber.js'; import React, { Component, PropTypes } from 'react'; import { Link } from 'react-router'; import { isEqual } from 'lodash'; @@ -113,15 +114,16 @@ export default class Summary extends Component { renderOwners () { const { owners } = this.props; + const ownersValid = (owners || []).filter((owner) => owner.address && new BigNumber(owner.address).gt(0)); - if (!owners || owners.length === 0) { + if (!ownersValid || ownersValid.length === 0) { return null; } return (
{ - owners.map((owner) => ( + ownersValid.map((owner) => (
({ - owners: walletsInfo[wallet].owners.map((owner) => ({ - address: owner, - name: accountsInfo[owner] && accountsInfo[owner].name || owner - })), - address: wallet - })) + .map((wallet) => { + const owners = walletsInfo[wallet].owners || []; + + return { + owners: owners.map((owner) => ({ + address: owner, + name: accountsInfo[owner] && accountsInfo[owner].name || owner + })), + address: wallet + }; + }) .reduce((walletsOwners, wallet) => { walletsOwners[wallet.address] = wallet.owners; return walletsOwners; From fd23a2972c08455c61fc83e6af80407ee4429a88 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Fri, 9 Dec 2016 17:00:59 +0000 Subject: [PATCH 5/5] [ci skip] js-precompiled 20161209-165845 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0664d801..675d94ec4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1271,7 +1271,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#8e8e515f958d2d4a5abec07253a51a052f2b744d" +source = "git+https://github.com/ethcore/js-precompiled.git#b8e8e9a8482a51b9a86bb841674f71aca1e57934" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index ab501f6a7..77c9686a5 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.103", + "version": "0.2.104", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ",