Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Use "frequently used emojis" for autocompletion in composer #8998

Merged
merged 8 commits into from
Jul 21, 2022
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions src/autocomplete/EmojiProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ import QueryMatcher from './QueryMatcher';
import { PillCompletion } from './Components';
import { ICompletion, ISelectionRange } from './Autocompleter';
import SettingsStore from "../settings/SettingsStore";
import { EMOJI, IEmoji } from '../emoji';
import { EMOJI, IEmoji, getEmojiFromUnicode } from '../emoji';
import { TimelineRenderingType } from '../contexts/RoomContext';
import * as recent from '../emojipicker/recent';

const LIMIT = 20;

Expand Down Expand Up @@ -73,6 +74,7 @@ function colonsTrimmed(str: string): string {
export default class EmojiProvider extends AutocompleteProvider {
matcher: QueryMatcher<ISortedEmoji>;
nameMatcher: QueryMatcher<ISortedEmoji>;
private readonly recentlyUsed: IEmoji[];

constructor(room: Room, renderingType?: TimelineRenderingType) {
super({ commandRegex: EMOJI_REGEX, renderingType });
Expand All @@ -87,6 +89,8 @@ export default class EmojiProvider extends AutocompleteProvider {
// For removing punctuation
shouldMatchWordsOnly: true,
});

this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean)));
}

async getCompletions(
Expand All @@ -109,7 +113,7 @@ export default class EmojiProvider extends AutocompleteProvider {
// Do second match with shouldMatchWordsOnly in order to match against 'name'
completions = completions.concat(this.nameMatcher.match(matchedString));

const sorters = [];
let sorters = [];
// make sure that emoticons come first
sorters.push(c => score(matchedString, c.emoji.emoticon || ""));

Expand All @@ -130,6 +134,15 @@ export default class EmojiProvider extends AutocompleteProvider {
sorters.push(c => c._orderBy);
completions = sortBy(uniq(completions), sorters);

completions = completions.slice(0, LIMIT);

// Do a second sort to place emoji matching with frequently used one on top
sorters = [];
this.recentlyUsed.forEach(emoji => {
sorters.push(c => score(emoji.shortcodes[0], c.emoji.shortcodes[0]));
});
completions = sortBy(uniq(completions), sorters);

completions = completions.map(c => ({
completion: c.emoji.unicode,
component: (
Expand All @@ -138,7 +151,7 @@ export default class EmojiProvider extends AutocompleteProvider {
</PillCompletion>
),
range,
})).slice(0, LIMIT);
}));
}
return completions;
}
Expand Down