Commit 1e58e447 authored by Ethan Reesor's avatar Ethan Reesor

Use fuzzy matching for issuable awards

parent 9e72553a
...@@ -572,7 +572,7 @@ export class AwardsHandler { ...@@ -572,7 +572,7 @@ export class AwardsHandler {
} }
findMatchingEmojiElements(query) { findMatchingEmojiElements(query) {
const emojiMatches = this.emoji.filterEmojiNamesByAlias(query); const emojiMatches = this.emoji.queryEmojiNames(query);
const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]'); const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');
const $matchingElements = $emojiElements.filter( const $matchingElements = $emojiElements.filter(
(i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0, (i, elm) => emojiMatches.indexOf(elm.dataset.name) >= 0,
......
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import emojiAliases from 'emojis/aliases.json'; import emojiAliases from 'emojis/aliases.json';
import axios from '../lib/utils/axios_utils'; import axios from '../lib/utils/axios_utils';
...@@ -62,13 +63,18 @@ export function isEmojiNameValid(name) { ...@@ -62,13 +63,18 @@ export function isEmojiNameValid(name) {
return validEmojiNames.indexOf(name) >= 0; return validEmojiNames.indexOf(name) >= 0;
} }
export function filterEmojiNames(filter) { /**
const match = filter.toLowerCase(); * Search emoji by name or alias. Returns a normalized, deduplicated list of
return validEmojiNames.filter(name => name.indexOf(match) >= 0); * names.
} *
* Calling with an empty filter returns an empty array.
export function filterEmojiNamesByAlias(filter) { *
return uniq(filterEmojiNames(filter).map(name => normalizeEmojiName(name))); * @param {String}
* @returns {Array}
*/
export function queryEmojiNames(filter) {
const matches = fuzzaldrinPlus.filter(validEmojiNames, filter);
return uniq(matches.map(name => normalizeEmojiName(name)));
} }
let emojiCategoryMap; let emojiCategoryMap;
......
---
title: Use fuzzy matching for issuable awards
merge_request: 42674
author: Ethan Reesor (@firelizzard)
type: added
...@@ -309,6 +309,16 @@ describe('AwardsHandler', () => { ...@@ -309,6 +309,16 @@ describe('AwardsHandler', () => {
expect($('[data-name=alien]').is(':visible')).toBe(true); expect($('[data-name=alien]').is(':visible')).toBe(true);
expect($('.js-emoji-menu-search').val()).toBe(''); expect($('.js-emoji-menu-search').val()).toBe('');
}); });
it('should fuzzy filter the emoji', async () => {
await openAndWaitForEmojiMenu();
awardsHandler.searchEmojis('sgls');
expect($('[data-name=angel]').is(':visible')).toBe(false);
expect($('[data-name=anger]').is(':visible')).toBe(false);
expect($('[data-name=sunglasses]').is(':visible')).toBe(true);
});
}); });
describe('emoji menu', () => { describe('emoji menu', () => {
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { initEmojiMap, glEmojiTag, EMOJI_VERSION } from '~/emoji'; import { initEmojiMap, glEmojiTag, queryEmojiNames, EMOJI_VERSION } from '~/emoji';
import isEmojiUnicodeSupported, { import isEmojiUnicodeSupported, {
isFlagEmoji, isFlagEmoji,
isRainbowFlagEmoji, isRainbowFlagEmoji,
...@@ -57,8 +57,15 @@ describe('gl_emoji', () => { ...@@ -57,8 +57,15 @@ describe('gl_emoji', () => {
let mock; let mock;
beforeEach(() => { beforeEach(() => {
const emojiData = Object.fromEntries(
Object.values(emojiFixtureMap).map(m => {
const { name: n, moji: e, unicodeVersion: u, category: c, description: d } = m;
return [n, { c, e, d, u }];
}),
);
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
mock.onGet(`/-/emojis/${EMOJI_VERSION}/emojis.json`).reply(200); mock.onGet(`/-/emojis/${EMOJI_VERSION}/emojis.json`).reply(200, JSON.stringify(emojiData));
return initEmojiMap().catch(() => {}); return initEmojiMap().catch(() => {});
}); });
...@@ -378,4 +385,15 @@ describe('gl_emoji', () => { ...@@ -378,4 +385,15 @@ describe('gl_emoji', () => {
expect(isSupported).toBeFalsy(); expect(isSupported).toBeFalsy();
}); });
}); });
describe('queryEmojiNames', () => {
const contains = (e, term) => {
const names = queryEmojiNames(term);
expect(names.indexOf(e.name) >= 0).toBe(true);
};
it('should match by name', () => contains(emojiFixtureMap.grey_question, 'grey_question'));
it('should match by partial name', () => contains(emojiFixtureMap.grey_question, 'question'));
it('should fuzzy match by name', () => contains(emojiFixtureMap.grey_question, 'grqtn'));
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment