Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elaine/keyimport #143

Merged
merged 7 commits into from
Jun 16, 2017
Merged
11 changes: 9 additions & 2 deletions src/components/accounts/add/importjson.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { required } from 'lib/validators';
import { translate } from 'react-i18next';
import AccountShow from '../show';

import { green300, red300 } from 'material-ui/styles/colors';


class ImportRender extends React.Component {
constructor(props) {
super(props);
Expand All @@ -40,7 +43,7 @@ class ImportRender extends React.Component {
const { t, accounts } = this.props;
const { submitSucceeded, invalid, pristine, submitting, cancel } = this.props;

const p = this.state.accountId && accounts.findKey(this.state.accountId);
const p = this.state.accountId && accounts.findKey((acc) => acc.get('id') === this.state.accountId);
const account = p && (p >= 0) && accounts.get(p);

return (
Expand Down Expand Up @@ -69,14 +72,17 @@ class ImportRender extends React.Component {
disabled={pristine || submitting || invalid } />
</form>
</CardText>
{account && <CardText color={green100}>
Account Successfully Imported.
</CardText>}
{account && <CardText>
<AccountShow key={(account === undefined) ? undefined : account.get('id')} account={account}/>
<FlatButton label={t("common:done")}
onClick={cancel}
icon={<FontIcon className="fa fa-home" />}/>
</CardText>}
{this.state.fileError}
{this.state.fileError && <CardText>
{this.state.fileError && <CardText color={red300}>
{this.state.fileError}
</CardText>}
<CardActions>
Expand All @@ -91,6 +97,7 @@ class ImportRender extends React.Component {

ImportRender.propTypes = {
account: PropTypes.object.isRequired,
accounts: PropTypes.array.isRequired,
submitSucceeded: PropTypes.bool.isRequired,
handleSubmit: PropTypes.func.isRequired,
invalid: PropTypes.bool.isRequired,
Expand Down
23 changes: 23 additions & 0 deletions src/components/accounts/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { connect } from 'react-redux';
import { AddressForm } from '../addressbook/form';

const AccountEdit = connect(
(state, ownProps) => ({
blockAddress: true,
initialValues: {
name: ownProps.address.get('name'),
address: ownProps.address.get('id'),
description: ownProps.address.get('description'),
},
}),
(dispatch, ownProps) => ({
onSubmit: (data) => {
ownProps.submit(data);
},
cancel: () => {
ownProps.cancel();
},
})
)(AddressForm);

export default AccountEdit;
154 changes: 102 additions & 52 deletions src/components/accounts/show.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Card, CardActions, CardHeader, CardText } from 'material-ui/Card';
import { Card, CardActions, CardText } from 'material-ui/Card';
import { AddressAvatar } from 'elements/dl';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import FontIcon from 'material-ui/FontIcon';
import { Row, Col } from 'react-flexbox-grid/lib/index';
import { DescriptionList, DescriptionTitle, DescriptionData } from 'elements/dl';
import QRCode from 'qrcode.react';
import log from 'loglevel';
import { translate } from 'react-i18next';
import { cardSpace } from 'lib/styles';
import { gotoScreen } from 'store/screenActions';
import { updateAccount } from 'store/accountActions';
import AccountEdit from './edit';

const TokenRow = ({ token }) => {
const balance = token.get('balance') ? token.get('balance').getDecimalized() : '0';
Expand All @@ -23,77 +26,111 @@ TokenRow.propTypes = {
token: PropTypes.object.isRequired,
};

const Render = translate('accounts')(({ t, account, fiat, createTx }) => {
const value = t('show.value', {value: account.get('balance') ? account.get('balance').getEther() : '?'});
const pending = account.get('balancePending') ? `(${account.get('balancePending').getEther()} pending)` : null;
class AccountRender extends React.Component {
constructor(props) {
super(props);
this.state = {
edit: false,
showModal: false,
};
}

return (
<Card style={cardSpace}>
<CardHeader
title={t('show.header', {account: account.get('name') || account.get('id')})}
subtitle={value}
actAsExpander={true}
showExpandableButton={true}
/>
<CardActions>
<FlatButton label={t('show.send')}
onClick={createTx}
icon={<FontIcon className="fa fa-arrow-circle-o-right" />}/>
</CardActions>
<CardText expandable={true}>
<Row>
<Col xs={8}>
<DescriptionList>
{account.get('description') && <div>
<DescriptionTitle>{t('show.description.title')}</DescriptionTitle>
<DescriptionData>{account.get('description')}</DescriptionData>
</div>}
handleEdit = () => {
this.setState({ edit: true });
}

handleSave = (data) => {
this.props.editAccount(data)
.then((result) => {
this.setState({ edit: false });
log.debug(result);
})
}

<DescriptionTitle>{t('show.description.address')}</DescriptionTitle>
<DescriptionData>{account.get('id')}</DescriptionData>
cancelEdit = () => {
this.setState({ edit: false });
}

<DescriptionTitle>{t('show.description.sentTransactions')}</DescriptionTitle>
<DescriptionData>{account.get('txcount') || '0'}</DescriptionData>
showModal = () => {
this.setState({ showModal: true });
}

<DescriptionTitle>{t('show.description.etherBalance')}</DescriptionTitle>
<DescriptionData>{value}</DescriptionData>
<DescriptionData>{value} {pending}</DescriptionData>
closeModal = () => {
this.setState({ showModal: false });
}

<DescriptionTitle>{t('show.description.tokenBalance')}</DescriptionTitle>
<DescriptionData>
{account
.get('tokens')
.map((tok) =>
<TokenRow token={tok} key={tok.get('address')}/>
)}
</DescriptionData>
render() {
const { account, rates, createTx, goBack } = this.props;
const value = account.get('balance') ? account.get('balance').getEther() : '?';
const pending = account.get('balancePending') ? `(${account.get('balancePending').getEther()} pending)` : null;

<DescriptionTitle>Equivalent Values</DescriptionTitle>
<DescriptionData>
<div><span>BTC {fiat.btc}</span></div>
<div><span>USD {fiat.usd}</span></div>
<div><span>CNY {fiat.cny}</span></div>
</DescriptionData>

return (
<Card style={cardSpace}>
<CardActions>
<FlatButton label="DASHBOARD"
primary={true}
onClick={goBack}
icon={<FontIcon className="fa fa-arrow-left" />}/>
</CardActions>
<CardText>
<Row>
<Col xs={8}>
<h2>
{value}
{pending && <FlatButton label={pending} primary={true} />}
</h2>
{account.get('balance') ? `$${account.get('balance').getFiat(rates.get('usd'))}` : ''}

</DescriptionList>
{!this.state.edit && <AddressAvatar
secondary={account.get('id')}
tertiary={account.get('description')}
primary={account.get('name')}
onClick={this.handleEdit}
/>}
{this.state.edit && <AccountEdit
address={account}
submit={this.handleSave}
cancel={this.cancelEdit}
/>}
</Col>
<Col xs={4} md={2} mdOffset={2}>
<QRCode value={account.get('id')} />
</Col>
</Row>
</CardText>
<CardActions>
<FlatButton label="ADD ETHER"
onClick={this.showModal}
icon={<FontIcon className="fa fa-qrcode" />}/>
<FlatButton label="SEND"
onClick={createTx}
icon={<FontIcon className="fa fa-arrow-circle-o-right" />}/>
</CardActions>
{/*
TODO: Replace with @whilei's ADD ETHER modal
*/}
<Dialog
title="ADD ETHER!!"
modal={false}
open={this.state.showModal}
onRequestClose={this.closeModal}
/>
</Card>
);
});
);
}
}

Render.propTypes = {
AccountRender.propTypes = {
account: PropTypes.object.isRequired,
createTx: PropTypes.func.isRequired,
goBack: PropTypes.func.isRequired,
};

const AccountShow = connect(
(state, ownProps) => {
const accounts = state.accounts.get('accounts');
const pos = accounts.findKey((acc) => acc.get('id') === ownProps.account.get('id'));
const rates = state.accounts.get('rates');
const balance = ownProps.account.get('balance');
let fiat = {};
Expand All @@ -107,6 +144,8 @@ const AccountShow = connect(
}
return {
fiat,
rates,
account: (accounts.get(pos) || Immutable.Map({})),
};
},
(dispatch, ownProps) => ({
Expand All @@ -115,7 +154,18 @@ const AccountShow = connect(
log.debug('create tx from', account.get('id'));
dispatch(gotoScreen('create-tx', account));
},
goBack: () => {
dispatch(gotoScreen('home'));
},
editAccount: (data) => {
return new Promise((resolve, reject) => {
dispatch(updateAccount(data.address, data.name, data.description))
.then((response) => {
resolve(response);
});
});
}
})
)(Render);
)(AccountRender);

export default AccountShow;
17 changes: 17 additions & 0 deletions src/store/accountActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ export function createAccount(password, name, description) {
});
}

export function updateAccount(address, name, description) {
return (dispatch) =>
rpc.call('emerald_updateAccounts', [{
name,
description,
address
}]).then((result) => {
dispatch({
type: 'ACCOUNT/UPDATE_ACCOUNT',
address,
name,
description,
});
});
}

export function sendTransaction(accountId, password, to, gas, gasPrice, value) {
return (dispatch) =>
rpc.call('eth_sendTransaction', [{
Expand Down Expand Up @@ -141,6 +157,7 @@ export function importWallet(wallet, name, description) {
name,
description,
});
dispatch(loadAccountBalance(result));
resolve(result);
} else {
reject({error: result});
Expand Down
11 changes: 11 additions & 0 deletions src/store/accountReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ function onSetAccountsList(state, action) {
}
}

function onUpdateAccount(state, action) {
if (action.type === 'ACCOUNT/UPDATE_ACCOUNT') {
return updateAccount(state, action.address, (acc) =>
acc.set('name', action.name)
.set('description', action.description)
);
}
return state;
}

function onSetBalance(state, action) {
if (action.type === 'ACCOUNT/SET_BALANCE') {
return updateAccount(state, action.accountId, (acc) =>
Expand Down Expand Up @@ -213,6 +223,7 @@ export default function accountsReducers(state, action) {
state = onLoading(state, action);
state = onSetAccountsList(state, action);
state = onAddAccount(state, action);
state = onUpdateAccount(state, action);
state = onSetBalance(state, action);
state = onSetTxCount(state, action);
state = onSetTokenBalance(state, action);
Expand Down