1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-24 11:01:41 +01:00
metamask-extension/ui/components/app/contact-list/contact-list.component.js
Elliot Winkler 49e1abc374
Sort contacts alphabetically (#11982)
* Sort contacts alphabetically

Contacts are grouped together by letter, and the groups are listed
alphabetically, but the contacts in each group are not sorted
alphabetically themselves.

Fixes #10318.

* Improve tests to be less brittle

* Remove this matcher

* Revert this file

* Also don't need this change anymore

* Don't need this data attribute either
2021-09-03 12:31:12 -07:00

116 lines
3.1 KiB
JavaScript

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { sortBy } from 'lodash';
import Button from '../../ui/button';
import RecipientGroup from './recipient-group/recipient-group.component';
export default class ContactList extends PureComponent {
static propTypes = {
searchForContacts: PropTypes.func,
searchForRecents: PropTypes.func,
searchForMyAccounts: PropTypes.func,
selectRecipient: PropTypes.func,
children: PropTypes.node,
selectedAddress: PropTypes.string,
};
static contextTypes = {
t: PropTypes.func,
};
state = {
isShowingAllRecent: false,
};
renderRecents() {
const { t } = this.context;
const { isShowingAllRecent } = this.state;
const nonContacts = this.props.searchForRecents();
const showLoadMore = !isShowingAllRecent && nonContacts.length > 2;
return (
<div className="send__select-recipient-wrapper__recent-group-wrapper">
<RecipientGroup
label={t('recents')}
items={showLoadMore ? nonContacts.slice(0, 2) : nonContacts}
onSelect={this.props.selectRecipient}
selectedAddress={this.props.selectedAddress}
/>
{showLoadMore && (
<Button
type="link"
className="send__select-recipient-wrapper__recent-group-wrapper__load-more"
onClick={() => this.setState({ isShowingAllRecent: true })}
>
{t('loadMore')}
</Button>
)}
</div>
);
}
renderAddressBook() {
const unsortedContactsByLetter = this.props
.searchForContacts()
.reduce((obj, contact) => {
const firstLetter = contact.name[0].toUpperCase();
return {
...obj,
[firstLetter]: [...(obj[firstLetter] || []), contact],
};
}, {});
const letters = Object.keys(unsortedContactsByLetter).sort();
const sortedContactGroups = letters.map((letter) => {
return [
letter,
sortBy(unsortedContactsByLetter[letter], (contact) => {
return contact.name.toLowerCase();
}),
];
});
return sortedContactGroups.map(([letter, groupItems]) => (
<RecipientGroup
key={`${letter}-contact-group`}
label={letter}
items={groupItems}
onSelect={this.props.selectRecipient}
selectedAddress={this.props.selectedAddress}
/>
));
}
renderMyAccounts() {
const myAccounts = this.props.searchForMyAccounts();
return (
<RecipientGroup
items={myAccounts}
onSelect={this.props.selectRecipient}
selectedAddress={this.props.selectedAddress}
/>
);
}
render() {
const {
children,
searchForRecents,
searchForContacts,
searchForMyAccounts,
} = this.props;
return (
<div className="send__select-recipient-wrapper__list">
{children || null}
{searchForRecents && this.renderRecents()}
{searchForContacts && this.renderAddressBook()}
{searchForMyAccounts && this.renderMyAccounts()}
</div>
);
}
}