[MM-22078] [MM-22083] Sort emojis in EmojiPicker (#3865)

* Sort emojis in EmojiPicker

* Pass search term to compareEmojis

* Sort emojis that include search term first

* Fix sorting

* Handle compareEmojis without search term

* Return doDefaultComparison

* Check includes only if needed

* Make linter happy

* Use doDefaultComparison
This commit is contained in:
Miguel Alatzar 2020-01-28 15:04:59 -07:00 committed by GitHub
parent ee25cf49eb
commit a8f0314067
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 12 deletions

View file

@ -94,13 +94,18 @@ export default class EmojiSuggestion extends PureComponent {
const results = await fuse.search(matchTerm.toLowerCase());
const data = results.map((index) => emojis[index]);
this.setEmojiData(data);
this.setEmojiData(data, matchTerm);
};
setEmojiData = (data) => {
setEmojiData = (data, matchTerm = null) => {
let sorter = compareEmojis;
if (matchTerm) {
sorter = (a, b) => compareEmojis(a, b, matchTerm);
}
this.setState({
active: data.length > 0,
dataSource: data.sort(compareEmojis),
dataSource: data.sort(sorter),
});
this.props.onResultCountChange(data.length);

View file

@ -24,6 +24,7 @@ import {
makeStyleSheetFromTheme,
changeOpacity,
} from 'app/utils/theme';
import {compareEmojis} from 'app/utils/emoji_utils';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import EmojiPickerRow from './emoji_picker_row';
@ -211,7 +212,9 @@ export default class EmojiPicker extends PureComponent {
}
const results = fuse.search(searchTermLowerCase);
const data = results.map((index) => emojis[index]);
const sorter = (a, b) => compareEmojis(a, b, searchTerm);
const data = results.map((index) => emojis[index]).sort(sorter);
return data;
};

View file

@ -132,23 +132,45 @@ const customComparisonRules = {
'+1': thumbsUpComparisonRule,
};
function doDefaultComparison(aName, bName) {
if (customComparisonRules[aName]) {
return customComparisonRules[aName](bName) || defaultComparisonRule(aName, bName);
}
return defaultComparisonRule(aName, bName);
}
export function compareEmojis(emojiA, emojiB, searchedName) {
const aName = emojiA.name || (emojiA.aliases ? emojiA.aliases[0] : emojiA);
const bName = emojiB.name || (emojiB.aliases ? emojiB.aliases[0] : emojiB);
// Have the emojis that contain the search appear first
if (!searchedName) {
return doDefaultComparison(aName, bName);
}
// Have the emojis that start with the search appear first
const aPrefix = aName.startsWith(searchedName);
const bPrefix = bName.startsWith(searchedName);
if (aPrefix === bPrefix) {
if (customComparisonRules[aName]) {
return customComparisonRules[aName](bName) || defaultComparisonRule(aName, bName);
}
return defaultComparisonRule(aName, bName, searchedName);
if (aPrefix && bPrefix) {
return doDefaultComparison(aName, bName);
} else if (aPrefix) {
return -1;
} else if (bPrefix) {
return 1;
}
return 1;
// Have the emojis that contain the search appear next
const aIncludes = aName.includes(searchedName);
const bIncludes = bName.includes(searchedName);
if (aIncludes && bIncludes) {
return doDefaultComparison(aName, bName);
} else if (aIncludes) {
return -1;
} else if (bIncludes) {
return 1;
}
return doDefaultComparison(aName, bName);
}

View file

@ -411,4 +411,18 @@ describe('compareEmojis', () => {
expect(emojiArray).toEqual([thumbsUpEmoji, thumbsDownEmoji, smileEmoji]);
});
test('it sorts emojis that start with search term first, then includes search term, then alphabetically', () => {
const printerEmoji = 'printer';
const pointDownEmoji = 'point_down';
const paintBrushEmoji = 'paintbrush';
const footPrintsEmoji = 'footprints';
const disappointedEmoji = 'disappointed';
const sixPointedStarEmoji = 'six_pointed_star';
const emojiArray = [printerEmoji, pointDownEmoji, paintBrushEmoji, footPrintsEmoji, disappointedEmoji, sixPointedStarEmoji];
emojiArray.sort((a, b) => compareEmojis(a, b, 'point'));
expect(emojiArray).toEqual([pointDownEmoji, disappointedEmoji, sixPointedStarEmoji, footPrintsEmoji, paintBrushEmoji, printerEmoji]);
});
});