// Copyright 2017-2018 @polkadot/app-example authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. import { ApiProps } from '@polkadot/ui-react-rx/types'; import BN from 'bn.js'; import React from 'react'; import storage from '@polkadot/storage'; import IdentityIcon from '@polkadot/ui-react/IdentityIcon'; import withApi from '@polkadot/ui-react-rx/with/api'; type StorageProposal = [BN, any, string]; type StorageIntentions = Array; type StorageValidators = Array; type StateBalances = { [index: string]: BN }; type StateProposals = { [index: string]: number[] }; type State = { balances: StateBalances, intentions: Array, proposals: StateProposals, subscriptions: Array, validators: Array }; const ZERO = new BN(0); class Comp extends React.PureComponent { constructor (props: ApiProps) { super(props); this.state = { balances: {}, intentions: [], proposals: {}, subscriptions: [], validators: [] }; } componentDidMount () { this.setState({ subscriptions: [ this.subscribeIntentions(), this.subscribeProposals(), this.subscribeValidators() ] }); } subscribeIntentions () { const { api } = this.props; return api.state .getStorage(storage.staking.public.intentions) .subscribe((intentions: StorageIntentions) => { this.setState({ intentions }, () => { this.subscribeBalances(intentions); }); }); } subscribeProposals () { const { api } = this.props; return api.state .getStorage(storage.democracy.public.proposals) .subscribe((value: Array) => { this.setState({ proposals: value.reduce((proposals: StateProposals, [propIdx, proposal, accountId]) => { if (!proposals[accountId]) { proposals[accountId] = [propIdx.toNumber()]; } else { proposals[accountId].push(propIdx.toNumber()); } return proposals; }, {} as StateProposals) }); }); } subscribeValidators () { const { api } = this.props; return api.state .getStorage(storage.session.public.validators) .subscribe((validators: StorageValidators) => { this.setState({ validators }); }); } subscribeBalances (accounts: string[]) { const { api } = this.props; const { balances, subscriptions } = this.state; const newBalances = { ...balances }; accounts.forEach((account) => { if (newBalances[account]) { return; } else { newBalances[account] = ZERO; } subscriptions.push( api.state // Here we pass a parameter to the key generator, so it points to the correct storage entry .getStorage(storage.staking.public.freeBalanceOf, account) .subscribe((balance: BN) => { this.setState(({ balances }: State) => { const newBalances = { ...balances }; newBalances[account] = balance; return { balances: newBalances }; }); }) ); }); this.setState({ balances: newBalances, subscriptions }); } componentWillUnmount () { const { subscriptions } = this.state; subscriptions.forEach((sub) => sub.unsubscribe()); } render () { const { balances, intentions, proposals, validators } = this.state; const sortedIntentions = intentions.sort((a, b) => (balances[b] || ZERO).cmp(balances[a] || ZERO) ); return ( {sortedIntentions.map((address) => ( this.renderAccount(address, balances[address], proposals[address], validators.includes(address)) ))}
Address Balance Proposals
); } renderAccount = (address: string, balance: BN = ZERO, proposals: number[] = [], isValidator: boolean = false) => { return ( {address} {balance.toString(10)} {proposals.length} ); } } export default withApi(Comp);