diff --git a/js/src/dapps/registry/Application/application.js b/js/src/dapps/registry/Application/application.js index 1ebb7594aea..3d3d8d582d8 100644 --- a/js/src/dapps/registry/Application/application.js +++ b/js/src/dapps/registry/Application/application.js @@ -22,10 +22,11 @@ const muiTheme = getMuiTheme(lightBaseTheme); import CircularProgress from 'material-ui/CircularProgress'; import styles from './application.css'; -import Accounts from '../accounts'; +import Accounts from '../Accounts'; +import Events from '../Events'; import Lookup from '../Lookup'; -import Names from '../names'; -import Events from '../events'; +import Names from '../Names'; +import Records from '../Records'; const nullable = (type) => React.PropTypes.oneOfType([ React.PropTypes.oneOf([ null ]), type ]); @@ -46,7 +47,8 @@ export default class Application extends Component { fee: nullable(PropTypes.object.isRequired), lookup: PropTypes.object.isRequired, events: PropTypes.object.isRequired, - names: PropTypes.object.isRequired + names: PropTypes.object.isRequired, + records: PropTypes.object.isRequired }; render () { @@ -56,7 +58,8 @@ export default class Application extends Component { contract, fee, lookup, events, - names + names, + records } = this.props; return ( @@ -69,6 +72,7 @@ export default class Application extends Component {
+

The Registry is provided by the contract at { contract.address }. diff --git a/js/src/dapps/registry/Container.js b/js/src/dapps/registry/Container.js index 9651488cd28..1464320e63c 100644 --- a/js/src/dapps/registry/Container.js +++ b/js/src/dapps/registry/Container.js @@ -60,6 +60,7 @@ export default connect( bound.lookup = bindActionCreators(actions.lookup, dispatch); bound.events = bindActionCreators(actions.events, dispatch); bound.names = bindActionCreators(actions.names, dispatch); + bound.records = bindActionCreators(actions.records, dispatch); return { actions: bound }; } )(Container); diff --git a/js/src/dapps/registry/IdentityIcon/identityIcon.css b/js/src/dapps/registry/IdentityIcon/identityIcon.css new file mode 100644 index 00000000000..3fa1df99e4d --- /dev/null +++ b/js/src/dapps/registry/IdentityIcon/identityIcon.css @@ -0,0 +1,23 @@ +/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* This file is part of Parity. +/* +/* Parity is free software: you can redistribute it and/or modify +/* it under the terms of the GNU General Public License as published by +/* the Free Software Foundation, either version 3 of the License, or +/* (at your option) any later version. +/* +/* Parity is distributed in the hope that it will be useful, +/* but WITHOUT ANY WARRANTY; without even the implied warranty of +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/* GNU General Public License for more details. +/* +/* You should have received a copy of the GNU General Public License +/* along with Parity. If not, see . +*/ + +.icon { + width: 24px; + height: 24px; + border-radius: 50%; + margin-right: 0.5em; +} diff --git a/js/src/dapps/registry/IdentityIcon/identityIcon.js b/js/src/dapps/registry/IdentityIcon/identityIcon.js new file mode 100644 index 00000000000..e4baf27057d --- /dev/null +++ b/js/src/dapps/registry/IdentityIcon/identityIcon.js @@ -0,0 +1,39 @@ +// 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 React, { Component, PropTypes } from 'react'; + +import { api } from '../parity'; +import styles from './identityIcon.css'; + +export default class IdentityIcon extends Component { + static propTypes = { + address: PropTypes.string.isRequired, + className: PropTypes.string, + style: PropTypes.object + } + + render () { + const { address, className, style } = this.props; + + return ( + + ); + } +} diff --git a/js/src/dapps/registry/IdentityIcon/index.js b/js/src/dapps/registry/IdentityIcon/index.js new file mode 100644 index 00000000000..76c107bfb75 --- /dev/null +++ b/js/src/dapps/registry/IdentityIcon/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 './identityIcon'; diff --git a/js/src/dapps/registry/Records/reducers.js b/js/src/dapps/registry/Records/reducers.js new file mode 100644 index 00000000000..a9a3ae37158 --- /dev/null +++ b/js/src/dapps/registry/Records/reducers.js @@ -0,0 +1,29 @@ +const initialState = { + hasAccount: false, + pending: false, + name: '', type: '', value: '' +}; + +export default (state = initialState, action) => { + if (action.type === 'accounts select') { + return { ...state, hasAccount: !!action.address }; + } + + if (action.type === 'records update start') { + return { + ...state, + pending: true, + name: action.name, type: action.entry, value: action.value + }; + } + + if (action.type === 'records update error' && action.type === 'records update success') { + return { + ...state, + pending: false, + name: initialState.name, type: initialState.type, value: initialState.value + }; + } + + return state; +}; diff --git a/js/src/dapps/registry/accounts/accounts.css b/js/src/dapps/registry/accounts/accounts.css index b9612358a4c..344a92867e2 100644 --- a/js/src/dapps/registry/accounts/accounts.css +++ b/js/src/dapps/registry/accounts/accounts.css @@ -33,6 +33,6 @@ } .menuText { display: inline-block; - line-height: 20px; - vertical-align: middle; + line-height: 24px; + vertical-align: top; } diff --git a/js/src/dapps/registry/accounts/accounts.js b/js/src/dapps/registry/accounts/accounts.js index 9774136b7c0..fe262a84ffc 100644 --- a/js/src/dapps/registry/accounts/accounts.js +++ b/js/src/dapps/registry/accounts/accounts.js @@ -19,22 +19,11 @@ import IconMenu from 'material-ui/IconMenu'; import IconButton from 'material-ui/IconButton/IconButton'; import AccountIcon from 'material-ui/svg-icons/action/account-circle'; import MenuItem from 'material-ui/MenuItem'; -import IdentityIcon from '../../../ui/IdentityIcon'; -import styles from './accounts.css'; +import IdentityIcon from '../IdentityIcon'; +import renderAddress from '../ui/address'; -const renderAccount = (active) => (account) => { - const selected = active && active.address === account.address; - return ( - - - { account.name } - - ); -}; +import styles from './accounts.css'; export default class Accounts extends Component { @@ -50,23 +39,37 @@ export default class Accounts extends Component { const accountsButton = ( { selected - ? () + ? () : () } ); return ( - { Object.values(all).map(renderAccount(selected)) } + { Object.values(all).map(this.renderAccount) } ); } + renderAccount = (account) => { + const { all, selected } = this.props; + const isSelected = selected && selected.address === account.address; + + return ( + + { renderAddress(account.address, all, {}) } + + ); + }; + onAccountSelect = (e, address) => { this.props.actions.select(address); }; diff --git a/js/src/dapps/registry/actions.js b/js/src/dapps/registry/actions.js index 90b261045bb..882af036036 100644 --- a/js/src/dapps/registry/actions.js +++ b/js/src/dapps/registry/actions.js @@ -16,21 +16,22 @@ import { registry as registryAbi } from '../../contracts/abi'; -import { newContract, ethcore } from './parity.js'; +import { api } from './parity.js'; import * as addresses from './addresses/actions.js'; -import * as accounts from './accounts/actions.js'; +import * as accounts from './Accounts/actions.js'; import * as lookup from './Lookup/actions.js'; -import * as events from './events/actions.js'; -import * as names from './names/actions.js'; +import * as events from './Events/actions.js'; +import * as names from './Names/actions.js'; +import * as records from './Records/actions.js'; -export { addresses, accounts, lookup, events, names }; +export { addresses, accounts, lookup, events, names, records }; export const setContract = (contract) => ({ type: 'set contract', contract }); export const fetchContract = () => (dispatch) => - ethcore.registryAddress() + api.ethcore.registryAddress() .then((address) => { - const contract = newContract(registryAbi, address); + const contract = api.newContract(registryAbi, address); dispatch(setContract(contract)); dispatch(fetchFee()); dispatch(fetchOwner()); diff --git a/js/src/dapps/registry/addresses/actions.js b/js/src/dapps/registry/addresses/actions.js index 6a9ae826afe..b6091acb57f 100644 --- a/js/src/dapps/registry/addresses/actions.js +++ b/js/src/dapps/registry/addresses/actions.js @@ -14,23 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { personal } from '../parity.js'; +import { api } from '../parity'; export const set = (addresses) => ({ type: 'addresses set', addresses }); export const fetch = () => (dispatch) => { - return Promise.all([ personal.listAccounts(), personal.accountsInfo() ]) - .then(([ accounts, data ]) => { - const addresses = Object.keys(data) - .filter((address) => data[address] && !data[address].meta.deleted) - .map((address) => ({ - ...data[address], address, - isAccount: accounts.includes(address) - })); - dispatch(set(addresses)); - }) - .catch((err) => { - console.error('could not fetch addresses'); - if (err) console.error(err.stack); - }); + return Promise + .all([ + api.personal.listAccounts(), + api.personal.accountsInfo() + ]) + .then(([ accounts, data ]) => { + const addresses = Object.keys(data) + .filter((address) => data[address] && !data[address].meta.deleted) + .map((address) => ({ + ...data[address], address, + isAccount: accounts.includes(address) + })); + dispatch(set(addresses)); + }) + .catch((error) => { + console.error('could not fetch addresses', error); + }); }; diff --git a/js/src/dapps/registry/events/actions.js b/js/src/dapps/registry/events/actions.js index df33a531243..e12c98c4f67 100644 --- a/js/src/dapps/registry/events/actions.js +++ b/js/src/dapps/registry/events/actions.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { getBlockByNumber } from '../parity.js'; +import { api } from '../parity.js'; export const start = (name, from, to) => ({ type: 'events subscribe start', name, from, to }); export const fail = (name) => ({ type: 'events subscribe fail', name }); @@ -38,7 +38,7 @@ export const subscribe = (name, from = 0, to = 'pending') => } events.forEach((e) => { - getBlockByNumber(e.blockNumber) + api.eth.getBlockByNumber(e.blockNumber) .then((block) => { const data = { type: name, diff --git a/js/src/dapps/registry/events/events.css b/js/src/dapps/registry/events/events.css index 2e3ec53bab4..66277dae3d5 100644 --- a/js/src/dapps/registry/events/events.css +++ b/js/src/dapps/registry/events/events.css @@ -24,11 +24,6 @@ } .reserved, .dropped, .dataChanged { - margin: .5em 0; - display: flex; - justify-content: space-between; - flex-wrap: wrap; - align-items: center; } .reserved abbr, .dropped abbr { @@ -45,3 +40,12 @@ line-height: 32px; word-wrap: break-word; } + +.eventsList { + width: 100%; + boder: none; +} + +.eventsList td { + padding: 0.25em 0.5em; +} diff --git a/js/src/dapps/registry/events/events.js b/js/src/dapps/registry/events/events.js index 28d32f59a71..ffb1fc9190a 100644 --- a/js/src/dapps/registry/events/events.js +++ b/js/src/dapps/registry/events/events.js @@ -19,9 +19,9 @@ import { Card, CardHeader, CardActions, CardText } from 'material-ui/Card'; import Toggle from 'material-ui/Toggle'; import moment from 'moment'; -import { bytesToHex } from '../parity.js'; -import renderHash from '../ui/hash.js'; -import renderAddress from '../ui/address.js'; +import { bytesToHex } from '../parity'; +import renderHash from '../ui/hash'; +import renderAddress from '../ui/address'; import styles from './events.css'; const inlineButton = { @@ -47,12 +47,12 @@ const renderEvent = (classNames, verb) => (e, accounts, contacts) => { ? classNames + ' ' + styles.pending : classNames; return ( -

- { renderAddress(e.parameters.owner, accounts, contacts) } - { ' ' }{ verb } - { ' ' }{ renderHash(bytesToHex(e.parameters.name)) } - { ' ' }{ renderStatus(e.timestamp, e.state === 'pending') } -
+ + { renderAddress(e.parameters.owner, accounts, contacts) } + { verb } + { renderHash(bytesToHex(e.parameters.name)) } + { renderStatus(e.timestamp, e.state === 'pending') } + ); }; @@ -63,13 +63,14 @@ const renderDataChanged = (e, accounts, contacts) => { } return ( -
- { renderAddress(e.parameters.owner, accounts, contacts) } - { ' ' }updated - key { new Buffer(e.parameters.plainKey).toString('utf8') } - of { renderHash(bytesToHex(e.parameters.name)) } - { ' ' }{ renderStatus(e.timestamp, e.state === 'pending') } -
+ + { renderAddress(e.parameters.owner, accounts, contacts) } + updated + + key { new Buffer(e.parameters.plainKey).toString('utf8') } of { renderHash(bytesToHex(e.parameters.name)) } + + { renderStatus(e.timestamp, e.state === 'pending') } + ); }; @@ -118,11 +119,17 @@ export default class Events extends Component { style={ inlineButton } /> - { - this.props.events - .filter((e) => eventTypes[e.type]) - .map((e) => eventTypes[e.type](e, accounts, contacts)) - } + + + + { + this.props.events + .filter((e) => eventTypes[e.type]) + .map((e) => eventTypes[e.type](e, accounts, contacts)) + } + +
+
); } diff --git a/js/src/dapps/registry/names/actions.js b/js/src/dapps/registry/names/actions.js index 255a63e12fd..ee73ad78e52 100644 --- a/js/src/dapps/registry/names/actions.js +++ b/js/src/dapps/registry/names/actions.js @@ -17,7 +17,7 @@ import { sha3, toWei } from '../parity.js'; const alreadyQueued = (queue, action, name) => - !!queue.find((entry) => entry.action === action && entry.name === name) + !!queue.find((entry) => entry.action === action && entry.name === name); export const reserveStart = (name) => ({ type: 'names reserve start', name }); diff --git a/js/src/dapps/registry/names/names.js b/js/src/dapps/registry/names/names.js index ffcc951cb30..330eb413971 100644 --- a/js/src/dapps/registry/names/names.js +++ b/js/src/dapps/registry/names/names.js @@ -26,16 +26,16 @@ import { fromWei } from '../parity.js'; import styles from './names.css'; -const useSignerText = (

Use the Signer to authenticate the following changes.

) +const useSignerText = (

Use the Signer to authenticate the following changes.

); const renderNames = (names) => { - const out = [] + const out = []; for (let name of names) { - out.push(({ name }), ', ') + out.push(({ name }), ', '); } - out.pop() - return out -} + out.pop(); + return out; +}; const renderQueue = (queue) => { if (queue.length === 0) { @@ -43,18 +43,18 @@ const renderQueue = (queue) => { } const grouped = queue.reduce((grouped, change) => { - const last = grouped[grouped.length - 1] + const last = grouped[grouped.length - 1]; if (last && last.action === change.action) { - last.names.push(change.name) + last.names.push(change.name); } else { - grouped.push({action: change.action, names: [change.name]}) + grouped.push({ action: change.action, names: [change.name] }); } - return grouped + return grouped; }, []); return (
    - { grouped.map(({action, names}) => ( + { grouped.map(({ action, names }) => (
  • { renderNames(names) } { ' will be ' } @@ -63,7 +63,7 @@ const renderQueue = (queue) => { )) }
); -} +}; export default class Names extends Component { @@ -92,8 +92,8 @@ export default class Names extends Component { ? (

Please select an account first.

) : (action === 'reserve' ? (

- The fee to reserve a name is { fromWei(fee).toFixed(3) }ΞTH. -

) + The fee to reserve a name is { fromWei(fee).toFixed(3) }ΞTH. +

) : (

To drop a name, you have to be the owner.

) ) } diff --git a/js/src/dapps/registry/names/reducers.js b/js/src/dapps/registry/names/reducers.js index eb5e7c69043..1fcee57d8b2 100644 --- a/js/src/dapps/registry/names/reducers.js +++ b/js/src/dapps/registry/names/reducers.js @@ -31,7 +31,7 @@ export default (state = initialState, action) => { if (action.type === 'names reserve success') { return { ...state, pending: false, - queue: state.queue.concat({action: 'reserve', name: action.name}) + queue: state.queue.concat({ action: 'reserve', name: action.name }) }; } if (action.type === 'names reserve fail') { @@ -44,7 +44,7 @@ export default (state = initialState, action) => { if (action.type === 'names drop success') { return { ...state, pending: false, - queue: state.queue.concat({action: 'drop', name: action.name}) + queue: state.queue.concat({ action: 'drop', name: action.name }) }; } if (action.type === 'names drop fail') { diff --git a/js/src/dapps/registry/parity.js b/js/src/dapps/registry/parity.js index 77c8e9e7083..cf9819b60eb 100644 --- a/js/src/dapps/registry/parity.js +++ b/js/src/dapps/registry/parity.js @@ -14,15 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -const { IdentityIcon } = window.parity.react; -const newContract = window.parity.api.newContract.bind(window.parity.api); -const { personal, ethcore } = window.parity.api; +const api = window.parity.api; const { bytesToHex, sha3, toWei, fromWei } = window.parity.api.util; -const getBlockByNumber = window.parity.api.eth.getBlockByNumber.bind(window.parity.api.eth); export { - IdentityIcon, - personal, ethcore, newContract, - bytesToHex, sha3, toWei, fromWei, - getBlockByNumber + api, + bytesToHex, sha3, toWei, fromWei }; diff --git a/js/src/dapps/registry/records/actions.js b/js/src/dapps/registry/records/actions.js new file mode 100644 index 00000000000..b93a85fcf5a --- /dev/null +++ b/js/src/dapps/registry/records/actions.js @@ -0,0 +1,33 @@ +import { sha3 } from '../parity.js'; + +export const start = (name, key, value) => ({ type: 'records update start', name, key, value }); + +export const success = () => ({ type: 'records update success' }); + +export const fail = () => ({ type: 'records update error' }); + +export const update = (name, key, value) => (dispatch, getState) => { + const state = getState(); + const account = state.accounts.selected; + const contract = state.contract; + if (!contract || !account) return; + const fn = contract.functions.find((f) => f.name === 'set'); + + name = name.toLowerCase(); + const options = { from: account.address }; + const values = [ sha3(name), key, value ]; + + dispatch(start(name, key, value)); + fn.estimateGas(options, values) + .then((gas) => { + options.gas = gas.mul(1.2).toFixed(0); + return fn.postTransaction(options, values); + }) + .then((data) => { + dispatch(success()); + }).catch((err) => { + console.error(`could not update ${key} record of ${name}`); + if (err) console.error(err.stack); + dispatch(fail()); + }); +}; diff --git a/js/src/dapps/registry/records/index.js b/js/src/dapps/registry/records/index.js new file mode 100644 index 00000000000..e2528968e5e --- /dev/null +++ b/js/src/dapps/registry/records/index.js @@ -0,0 +1 @@ +export default from './records.js'; diff --git a/js/src/dapps/registry/records/records.css b/js/src/dapps/registry/records/records.css new file mode 100644 index 00000000000..72b62595d0f --- /dev/null +++ b/js/src/dapps/registry/records/records.css @@ -0,0 +1,28 @@ +/* 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 . +*/ + +.records { + margin: 1em; +} + +.noSpacing { + margin-top: 0; +} + +.spacing { + margin-left: 1em; +} diff --git a/js/src/dapps/registry/records/records.js b/js/src/dapps/registry/records/records.js new file mode 100644 index 00000000000..355522e6054 --- /dev/null +++ b/js/src/dapps/registry/records/records.js @@ -0,0 +1,76 @@ +import React, { Component, PropTypes } from 'react'; +import { Card, CardHeader, CardText } from 'material-ui/Card'; +import TextField from 'material-ui/TextField'; +import RaisedButton from 'material-ui/RaisedButton'; +import SaveIcon from 'material-ui/svg-icons/content/save'; + +import recordTypeSelect from '../ui/record-type-select.js'; +import styles from './records.css'; + +export default class Records extends Component { + + static propTypes = { + actions: PropTypes.object.isRequired, + hasAccount: PropTypes.bool.isRequired, + pending: PropTypes.bool.isRequired, + name: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, + value: PropTypes.string.isRequired + } + + state = { name: '', type: 'A', value: '' }; + + render () { + const { hasAccount, pending } = this.props; + const name = this.state.name || this.props.name; + const type = this.state.type || this.props.type; + const value = this.state.value || this.props.value; + + return ( + + + + { !hasAccount + ? (

Please select an account first.

) + : (

You can only modify entries of names that you previously registered.

) + } + + { recordTypeSelect(type, this.onTypeChange, styles.spacing) } + + } + onClick={ this.onSaveClick } + /> +
+
+ ); + } + + onNameChange = (e) => { + this.setState({ name: e.target.value }); + }; + onTypeChange = (e, i, type) => { + this.setState({ type }); + }; + onValueChange = (e) => { + this.setState({ value: e.target.value }); + }; + onSaveClick = () => { + const { name, type, value } = this.state; + this.props.actions.update(name, type, value); + }; +} diff --git a/js/src/dapps/registry/reducers.js b/js/src/dapps/registry/reducers.js index 0183d53eecd..e0f620b7084 100644 --- a/js/src/dapps/registry/reducers.js +++ b/js/src/dapps/registry/reducers.js @@ -17,8 +17,9 @@ import accountsReducer from './addresses/accounts-reducer.js'; import contactsReducer from './addresses/contacts-reducer.js'; import lookupReducer from './Lookup/reducers.js'; -import eventsReducer from './events/reducers.js'; -import namesReducer from './names/reducers.js'; +import eventsReducer from './Events/reducers.js'; +import namesReducer from './Names/reducers.js'; +import recordsReducer from './Records/reducers.js'; const contractReducer = (state = null, action) => action.type === 'set contract' ? action.contract : state; @@ -37,7 +38,8 @@ const initialState = { owner: ownerReducer(undefined, { type: '' }), lookup: lookupReducer(undefined, { type: '' }), events: eventsReducer(undefined, { type: '' }), - names: namesReducer(undefined, { type: '' }) + names: namesReducer(undefined, { type: '' }), + records: recordsReducer(undefined, { type: '' }) }; export default (state = initialState, action) => ({ @@ -48,5 +50,6 @@ export default (state = initialState, action) => ({ owner: ownerReducer(state.owner, action), lookup: lookupReducer(state.lookup, action), events: eventsReducer(state.events, action), - names: namesReducer(state.names, action) + names: namesReducer(state.names, action), + records: recordsReducer(state.records, action) }); diff --git a/js/src/dapps/registry/ui/address.js b/js/src/dapps/registry/ui/address.js index 327212eaee7..e4a5a953e5d 100644 --- a/js/src/dapps/registry/ui/address.js +++ b/js/src/dapps/registry/ui/address.js @@ -15,16 +15,18 @@ // along with Parity. If not, see . import React from 'react'; -import renderHash from './hash.js'; -import { IdentityIcon } from '../parity.js'; +import renderHash from './hash'; +import IdentityIcon from '../IdentityIcon'; const container = { - display: 'inline-block' + display: 'inline-block', + verticalAlign: 'middle', + height: '24px' }; const align = { display: 'inline-block', verticalAlign: 'top', - lineHeight: '32px' + lineHeight: '24px' }; export default (address, accounts, contacts, shortenHash = true) => { @@ -38,7 +40,7 @@ export default (address, accounts, contacts, shortenHash = true) => { } return (
- + { caption }
); diff --git a/js/src/jsonrpc/interfaces/ethcore.js b/js/src/jsonrpc/interfaces/ethcore.js index 7cea0473d83..5b291061852 100644 --- a/js/src/jsonrpc/interfaces/ethcore.js +++ b/js/src/jsonrpc/interfaces/ethcore.js @@ -113,7 +113,7 @@ export default { } ], returns: { - types: Hash, + type: Hash, desc: 'The hash of the content' } }, diff --git a/js/src/parity.js b/js/src/parity.js index 664757adeb0..1fe788b5a23 100644 --- a/js/src/parity.js +++ b/js/src/parity.js @@ -21,14 +21,10 @@ import es6Promise from 'es6-promise'; es6Promise.polyfill(); import Api from './api'; -import { IdentityIcon } from './ui'; const api = new Api(new Api.Transport.Http('/rpc/')); window.parity = { Api, - api, - react: { - IdentityIcon - } + api }; diff --git a/parity/main.rs b/parity/main.rs index b74af7b3d87..e0d6dfe3671 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -196,6 +196,9 @@ fn sync_main() -> bool { } fn main() { + // Always print backtrace on panic. + ::std::env::set_var("RUST_BACKTRACE", "1"); + if sync_main() { return; }