Sort by ETH balance and contract by date (#3107)
* Added timestamps to contract creation // Sort by date (#3070) * Added sort by ETH balance (#3070) * Added timestamp meta to accounts / addresses entry creations (#3107)
This commit is contained in:
parent
6098f008ce
commit
391f408653
@ -136,6 +136,7 @@ export default class AddAddress extends Component {
|
|||||||
api.personal.setAccountName(address, name),
|
api.personal.setAccountName(address, name),
|
||||||
api.personal.setAccountMeta(address, {
|
api.personal.setAccountMeta(address, {
|
||||||
description,
|
description,
|
||||||
|
timestamp: Date.now(),
|
||||||
deleted: false
|
deleted: false
|
||||||
})
|
})
|
||||||
]).catch((error) => {
|
]).catch((error) => {
|
||||||
|
@ -145,6 +145,7 @@ export default class AddContract extends Component {
|
|||||||
api.personal.setAccountMeta(address, {
|
api.personal.setAccountMeta(address, {
|
||||||
contract: true,
|
contract: true,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
|
timestamp: Date.now(),
|
||||||
abi: abiParsed,
|
abi: abiParsed,
|
||||||
description
|
description
|
||||||
})
|
})
|
||||||
|
@ -214,7 +214,10 @@ export default class CreateAccount extends Component {
|
|||||||
this.setState({ address });
|
this.setState({ address });
|
||||||
return api.personal
|
return api.personal
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, { passwordHint: this.state.passwordHint }));
|
.then(() => api.personal.setAccountMeta(address, {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
passwordHint: this.state.passwordHint
|
||||||
|
}));
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.onNext();
|
this.onNext();
|
||||||
@ -236,7 +239,10 @@ export default class CreateAccount extends Component {
|
|||||||
this.setState({ address });
|
this.setState({ address });
|
||||||
return api.personal
|
return api.personal
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, { passwordHint: this.state.passwordHint }));
|
.then(() => api.personal.setAccountMeta(address, {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
passwordHint: this.state.passwordHint
|
||||||
|
}));
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.onNext();
|
this.onNext();
|
||||||
@ -285,7 +291,10 @@ export default class CreateAccount extends Component {
|
|||||||
|
|
||||||
return api.personal
|
return api.personal
|
||||||
.setAccountName(address, this.state.name)
|
.setAccountName(address, this.state.name)
|
||||||
.then(() => api.personal.setAccountMeta(address, { passwordHint: this.state.passwordHint }));
|
.then(() => api.personal.setAccountMeta(address, {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
passwordHint: this.state.passwordHint
|
||||||
|
}));
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.onNext();
|
this.onNext();
|
||||||
|
@ -216,6 +216,7 @@ export default class DeployContract extends Component {
|
|||||||
api.personal.setAccountMeta(address, {
|
api.personal.setAccountMeta(address, {
|
||||||
abi: abiParsed,
|
abi: abiParsed,
|
||||||
contract: true,
|
contract: true,
|
||||||
|
timestamp: Date.now(),
|
||||||
deleted: false,
|
deleted: false,
|
||||||
description
|
description
|
||||||
})
|
})
|
||||||
|
@ -27,14 +27,23 @@ import styles from './sort.css';
|
|||||||
export default class ActionbarSort extends Component {
|
export default class ActionbarSort extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
order: PropTypes.string
|
order: PropTypes.string,
|
||||||
|
showDefault: PropTypes.bool,
|
||||||
|
metas: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
metas: [],
|
||||||
|
showDefault: true
|
||||||
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
menuOpen: false
|
menuOpen: false
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { showDefault } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconMenu
|
<IconMenu
|
||||||
iconButtonElement={
|
iconButtonElement={
|
||||||
@ -50,14 +59,56 @@ export default class ActionbarSort extends Component {
|
|||||||
onItemTouchTap={ this.handleSortChange }
|
onItemTouchTap={ this.handleSortChange }
|
||||||
targetOrigin={ { horizontal: 'right', vertical: 'top' } }
|
targetOrigin={ { horizontal: 'right', vertical: 'top' } }
|
||||||
anchorOrigin={ { horizontal: 'right', vertical: 'top' } }
|
anchorOrigin={ { horizontal: 'right', vertical: 'top' } }
|
||||||
>
|
touchTapCloseDelay={ 0 }
|
||||||
<MenuItem value='' primaryText='Default' />
|
>
|
||||||
<MenuItem value='tags' primaryText='Sort by tags' />
|
{
|
||||||
<MenuItem value='name' primaryText='Sort by name' />
|
showDefault
|
||||||
|
? this.renderMenuItem('', 'Default')
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{ this.renderMenuItem('tags', 'Sort by tags') }
|
||||||
|
{ this.renderMenuItem('name', 'Sort by name') }
|
||||||
|
{ this.renderMenuItem('eth', 'Sort by ETH') }
|
||||||
|
|
||||||
|
{ this.renderSortByMetas() }
|
||||||
</IconMenu>
|
</IconMenu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderSortByMetas () {
|
||||||
|
const { metas } = this.props;
|
||||||
|
|
||||||
|
return metas
|
||||||
|
.map((meta, index) => {
|
||||||
|
return this
|
||||||
|
.renderMenuItem(meta.key, `Sort by ${meta.label}`, index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMenuItem (value, label, key = null) {
|
||||||
|
const { order } = this.props;
|
||||||
|
|
||||||
|
const props = {};
|
||||||
|
|
||||||
|
if (key !== null) {
|
||||||
|
props.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checked = order === value;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
checked={ checked }
|
||||||
|
value={ value }
|
||||||
|
primaryText={ label }
|
||||||
|
innerDivStyle={ {
|
||||||
|
paddingLeft: checked ? 50 : 16
|
||||||
|
} }
|
||||||
|
{ ...props }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
handleSortChange = (event, child) => {
|
handleSortChange = (event, child) => {
|
||||||
const order = child.props.value;
|
const order = child.props.value;
|
||||||
this.props.onChange(order);
|
this.props.onChange(order);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 0em;
|
padding: 0em;
|
||||||
background: rgba(0, 0, 0, 0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact,
|
.compact,
|
||||||
|
@ -29,6 +29,7 @@ export default class List extends Component {
|
|||||||
search: PropTypes.array,
|
search: PropTypes.array,
|
||||||
empty: PropTypes.bool,
|
empty: PropTypes.bool,
|
||||||
order: PropTypes.string,
|
order: PropTypes.string,
|
||||||
|
orderFallback: PropTypes.string,
|
||||||
handleAddSearchToken: PropTypes.func
|
handleAddSearchToken: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,9 +80,9 @@ export default class List extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sortAddresses (addresses) {
|
sortAddresses (addresses) {
|
||||||
const { order } = this.props;
|
const { order, orderFallback } = this.props;
|
||||||
|
|
||||||
if (!order || ['tags', 'name'].indexOf(order) === -1) {
|
if (!order) {
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,26 +92,77 @@ export default class List extends Component {
|
|||||||
const accountA = accounts[addressA];
|
const accountA = accounts[addressA];
|
||||||
const accountB = accounts[addressB];
|
const accountB = accounts[addressB];
|
||||||
|
|
||||||
if (order === 'name') {
|
const sort = this.compareAccounts(accountA, accountB, order);
|
||||||
return accountA.name.localeCompare(accountB.name);
|
|
||||||
|
if (sort === 0 && orderFallback) {
|
||||||
|
return this.compareAccounts(accountA, accountB, orderFallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order === 'tags') {
|
return sort;
|
||||||
const tagsA = [].concat(accountA.meta.tags)
|
|
||||||
.filter(t => t)
|
|
||||||
.sort();
|
|
||||||
const tagsB = [].concat(accountB.meta.tags)
|
|
||||||
.filter(t => t)
|
|
||||||
.sort();
|
|
||||||
|
|
||||||
if (tagsA.length === 0) return 1;
|
|
||||||
if (tagsB.length === 0) return -1;
|
|
||||||
|
|
||||||
return tagsA.join('').localeCompare(tagsB.join(''));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compareAccounts (accountA, accountB, key) {
|
||||||
|
if (key === 'name') {
|
||||||
|
return accountA.name.localeCompare(accountB.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'eth') {
|
||||||
|
const { balances } = this.props;
|
||||||
|
|
||||||
|
const balanceA = balances[accountA.address];
|
||||||
|
const balanceB = balances[accountB.address];
|
||||||
|
|
||||||
|
if (!balanceA && !balanceB) return 0;
|
||||||
|
if (balanceA && !balanceB) return -1;
|
||||||
|
if (!balanceA && balanceB) return 1;
|
||||||
|
|
||||||
|
const ethA = balanceA.tokens
|
||||||
|
.find(token => token.token.tag.toLowerCase() === 'eth')
|
||||||
|
.value;
|
||||||
|
const ethB = balanceB.tokens
|
||||||
|
.find(token => token.token.tag.toLowerCase() === 'eth')
|
||||||
|
.value;
|
||||||
|
|
||||||
|
return -1 * ethA.comparedTo(ethB);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'tags') {
|
||||||
|
const tagsA = [].concat(accountA.meta.tags)
|
||||||
|
.filter(t => t)
|
||||||
|
.sort()
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
const tagsB = [].concat(accountB.meta.tags)
|
||||||
|
.filter(t => t)
|
||||||
|
.sort()
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
if (!tagsA && !tagsB) return 0;
|
||||||
|
if (tagsA && !tagsB) return -1;
|
||||||
|
if (!tagsA && tagsB) return 1;
|
||||||
|
|
||||||
|
return tagsA.localeCompare(tagsB);
|
||||||
|
}
|
||||||
|
|
||||||
|
const metaA = accountA.meta[key];
|
||||||
|
const metaB = accountB.meta[key];
|
||||||
|
|
||||||
|
if (!metaA && !metaB) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((metaA && !metaB) || (metaA < metaB)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!metaA && metaB) || (metaA > metaB)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
getFilteredAddresses () {
|
getFilteredAddresses () {
|
||||||
const { accounts, search } = this.props;
|
const { accounts, search } = this.props;
|
||||||
const searchValues = (search || []).map(v => v.toLowerCase());
|
const searchValues = (search || []).map(v => v.toLowerCase());
|
||||||
|
@ -42,7 +42,7 @@ class Contracts extends Component {
|
|||||||
state = {
|
state = {
|
||||||
addContract: false,
|
addContract: false,
|
||||||
deployContract: false,
|
deployContract: false,
|
||||||
sortOrder: '',
|
sortOrder: 'timestamp',
|
||||||
searchValues: [],
|
searchValues: [],
|
||||||
searchTokens: []
|
searchTokens: []
|
||||||
}
|
}
|
||||||
@ -65,6 +65,7 @@ class Contracts extends Component {
|
|||||||
balances={ balances }
|
balances={ balances }
|
||||||
empty={ !hasContracts }
|
empty={ !hasContracts }
|
||||||
order={ sortOrder }
|
order={ sortOrder }
|
||||||
|
orderFallback='name'
|
||||||
handleAddSearchToken={ this.onAddSearchToken } />
|
handleAddSearchToken={ this.onAddSearchToken } />
|
||||||
</Page>
|
</Page>
|
||||||
</div>
|
</div>
|
||||||
@ -80,6 +81,10 @@ class Contracts extends Component {
|
|||||||
<ActionbarSort
|
<ActionbarSort
|
||||||
key='sortAccounts'
|
key='sortAccounts'
|
||||||
order={ this.state.sortOrder }
|
order={ this.state.sortOrder }
|
||||||
|
metas={ [
|
||||||
|
{ key: 'timestamp', label: 'date' }
|
||||||
|
] }
|
||||||
|
showDefault={ false }
|
||||||
onChange={ onChange } />
|
onChange={ onChange } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user