openethereum/js/src/dapps/gavcoin/Application/application.js
Jaco Greeff 65c985bef3 Gavcoin event display updates (#2956)
* Mapp all known addresses

* Display timestamp in event log

* Shorten addresses

* Display "Pending" timestamps as well

* Pending/Loading with empty timestamp
2016-10-29 13:04:47 +02:00

250 lines
6.5 KiB
JavaScript

// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
const muiTheme = getMuiTheme(lightBaseTheme);
import { api } from '../parity';
import * as abis from '../../../contracts/abi';
import Accounts from '../Accounts';
import Actions, { ActionBuyIn, ActionRefund, ActionTransfer } from '../Actions';
import Events from '../Events';
import Loading from '../Loading';
import Status from '../Status';
import styles from './application.css';
import bgimage from '../../../../assets/images/dapps/gavcoin-bg.jpg';
const bgstyle = {
backgroundImage: `url(${bgimage})`
};
const DIVISOR = 10 ** 6;
export default class Application extends Component {
static childContextTypes = {
api: PropTypes.object,
contract: PropTypes.object,
instance: PropTypes.object,
muiTheme: PropTypes.object
};
state = {
action: null,
address: null,
accounts: [],
accountsInfo: {},
blockNumber: new BigNumber(-1),
ethBalance: new BigNumber(0),
gavBalance: new BigNumber(0),
instance: null,
loading: true,
price: null,
remaining: null,
totalSupply: null
}
componentDidMount () {
this.attachInterface();
}
render () {
const { accounts, accountsInfo, address, blockNumber, gavBalance, loading, price, remaining, totalSupply } = this.state;
if (loading) {
return (
<Loading />
);
}
return (
<div className={ styles.body } style={ bgstyle }>
{ this.renderModals() }
<Status
address={ address }
blockNumber={ blockNumber }
gavBalance={ gavBalance }
price={ price }
remaining={ remaining }
totalSupply={ totalSupply }>
<Accounts
accounts={ accounts } />
</Status>
<Actions
gavBalance={ gavBalance }
onAction={ this.onAction } />
<Events
accountsInfo={ accountsInfo } />
</div>
);
}
renderModals () {
const { action, accounts, price } = this.state;
switch (action) {
case 'BuyIn':
return (
<ActionBuyIn
accounts={ accounts }
price={ price }
onClose={ this.onActionClose } />
);
case 'Refund':
return (
<ActionRefund
accounts={ accounts }
price={ price }
onClose={ this.onActionClose } />
);
case 'Transfer':
return (
<ActionTransfer
accounts={ accounts }
onClose={ this.onActionClose } />
);
default:
return null;
}
}
getChildContext () {
const { contract, instance } = this.state;
return {
api,
contract,
instance,
muiTheme
};
}
onAction = (action) => {
this.setState({
action
});
}
onActionClose = () => {
this.setState({
action: null
});
}
onNewBlockNumber = (_error, blockNumber) => {
const { instance, accounts } = this.state;
if (_error) {
console.error('onNewBlockNumber', _error);
return;
}
Promise
.all([
instance.totalSupply.call(),
instance.remaining.call(),
instance.price.call()
])
.then(([totalSupply, remaining, price]) => {
this.setState({
blockNumber,
totalSupply,
remaining,
price
});
const gavQueries = accounts.map((account) => instance.balanceOf.call({}, [account.address]));
const ethQueries = accounts.map((account) => api.eth.getBalance(account.address));
return Promise.all([
Promise.all(gavQueries),
Promise.all(ethQueries)
]);
})
.then(([gavBalances, ethBalances]) => {
this.setState({
ethBalance: ethBalances.reduce((total, balance) => total.add(balance), new BigNumber(0)),
gavBalance: gavBalances.reduce((total, balance) => total.add(balance), new BigNumber(0)),
accounts: accounts.map((account, idx) => {
const ethBalance = ethBalances[idx];
const gavBalance = gavBalances[idx];
account.ethBalance = api.util.fromWei(ethBalance).toFormat(3);
account.gavBalance = gavBalance.div(DIVISOR).toFormat(6);
account.hasGav = gavBalance.gt(0);
return account;
})
});
})
.catch((error) => {
console.error('onNewBlockNumber', error);
});
}
attachInterface = () => {
api.ethcore
.registryAddress()
.then((registryAddress) => {
console.log(`the registry was found at ${registryAddress}`);
const registry = api.newContract(abis.registry, registryAddress).instance;
return Promise
.all([
registry.getAddress.call({}, [api.util.sha3('gavcoin'), 'A']),
api.eth.accounts(),
api.personal.accountsInfo()
]);
})
.then(([address, addresses, accountsInfo]) => {
accountsInfo = accountsInfo || {};
console.log(`gavcoin was found at ${address}`);
const contract = api.newContract(abis.gavcoin, address);
this.setState({
loading: false,
address,
contract,
accountsInfo,
instance: contract.instance,
accounts: addresses.map((address) => {
const info = accountsInfo[address] || {};
return {
address,
name: info.name,
uuid: info.uuid
};
})
});
api.subscribe('eth_blockNumber', this.onNewBlockNumber);
})
.catch((error) => {
console.error('attachInterface', error);
});
}
}