Apply code review suggestions

including filling in gaps in emoji shortcode coverage.

Signed-off-by: Robin Townsend <robin@robin.town>
pull/21833/head
Robin Townsend 2021-07-19 15:09:15 -04:00
parent c1ed023e17
commit f8a922eaa1
5 changed files with 21 additions and 21 deletions

View File

@ -49,7 +49,7 @@ const EMOJI_SHORTCODES: IEmojiShort[] = EMOJI.sort((a, b) => {
emoji,
// Include the index so that we can preserve the original order
_orderBy: index,
})).filter(o => o.emoji.shortcodes[0]);
}));
function score(query, space) {
const index = space.indexOf(query);
@ -68,7 +68,7 @@ export default class EmojiProvider extends AutocompleteProvider {
super(EMOJI_REGEX);
this.matcher = new QueryMatcher<IEmojiShort>(EMOJI_SHORTCODES, {
keys: ['emoji.emoticon'],
funcs: [o => o.emoji.shortcodes.map(s => `:${s}:`).join(" ")],
funcs: [o => o.emoji.shortcodes.map(s => `:${s}:`)],
// For matching against ascii equivalents
shouldMatchWordsOnly: false,
});

View File

@ -32,6 +32,8 @@ export const CATEGORY_HEADER_HEIGHT = 22;
export const EMOJI_HEIGHT = 37;
export const EMOJIS_PER_ROW = 8;
const ZERO_WIDTH_JOINER = "\u200D";
interface IProps {
selectedEmojis?: Set<string>;
showQuickReactions?: boolean;
@ -180,7 +182,7 @@ class EmojiPicker extends React.Component<IProps, IState> {
} else {
emojis = cat.id === "recent" ? this.recentlyUsed : DATA_BY_CATEGORY[cat.id];
}
emojis = emojis.filter(emoji => emoji.filterString.includes(filter));
emojis = emojis.filter(emoji => this.emojiMatchesFilter(emoji, filter));
this.memoizedDataByCategory[cat.id] = emojis;
cat.enabled = emojis.length > 0;
// The setState below doesn't re-render the header and we already have the refs for updateVisibility, so...
@ -192,6 +194,10 @@ class EmojiPicker extends React.Component<IProps, IState> {
setTimeout(this.updateVisibility, 0);
};
private emojiMatchesFilter = (emoji: IEmoji, filter: string): boolean =>
[emoji.annotation, ...emoji.shortcodes, emoji.emoticon, ...emoji.unicode.split(ZERO_WIDTH_JOINER)]
.some(x => x?.includes(filter));
private onEnterFilter = () => {
const btn = this.bodyRef.current.querySelector<HTMLButtonElement>(".mx_EmojiPicker_item");
if (btn) {

View File

@ -38,9 +38,9 @@ class Preview extends React.PureComponent<IProps> {
<div className="mx_EmojiPicker_name mx_EmojiPicker_preview_name">
{annotation}
</div>
{ shortcode ?
<div className="mx_EmojiPicker_shortcode">{shortcode}</div> :
null }
<div className="mx_EmojiPicker_shortcode">
{shortcode}
</div>
</div>
</div>
);

View File

@ -62,7 +62,6 @@ class QuickReactions extends React.Component<IProps, IState> {
};
render() {
const shortcode = this.state.hover?.shortcodes?.[0];
return (
<section className="mx_EmojiPicker_footer mx_EmojiPicker_quick mx_EmojiPicker_category">
<h2 className="mx_EmojiPicker_quick_header mx_EmojiPicker_category_label">
@ -70,9 +69,7 @@ class QuickReactions extends React.Component<IProps, IState> {
? _t("Quick Reactions")
: <React.Fragment>
<span className="mx_EmojiPicker_name">{this.state.hover.annotation}</span>
{ shortcode ?
<span className="mx_EmojiPicker_shortcode">{shortcode}</span> :
null }
<span className="mx_EmojiPicker_shortcode">{this.state.hover.shortcodes[0]}</span>
</React.Fragment>
}
</h2>

View File

@ -25,8 +25,8 @@ export interface IEmoji {
shortcodes: string[];
tags?: string[];
unicode: string;
skins?: any[]; // Currently unused
emoticon?: string;
filterString: string;
}
// The unicode is stored without the variant selector
@ -59,20 +59,17 @@ export const DATA_BY_CATEGORY = {
"flags": [],
};
const ZERO_WIDTH_JOINER = "\u200D";
// Store various mappings from unicode/emoticon/shortcode to the Emoji objects
export const EMOJI: IEmoji[] = EMOJIBASE.map(emojiData => {
export const EMOJI: IEmoji[] = EMOJIBASE.map((emojiData: Omit<IEmoji, "shortcodes">) => {
const shortcodeData = SHORTCODES[emojiData.hexcode];
// Homogenize shortcodes by ensuring that everything is an array
const shortcodes = typeof shortcodeData === "string" ? [shortcodeData] : (shortcodeData ?? []);
const emoji: IEmoji = {
...emojiData,
shortcodes,
// This is used as the string to match the query against when filtering emojis
filterString: (`${emojiData.annotation}\n${shortcodes.join('\n')}}\n${emojiData.emoticon || ''}\n` +
`${emojiData.unicode.split(ZERO_WIDTH_JOINER).join("\n")}`).toLowerCase(),
// Homogenize shortcodes by ensuring that everything is an array
shortcodes: typeof shortcodeData === "string" ?
[shortcodeData] :
// If there's ever a gap in shortcode coverage, we fudge it by
// filling it in with the emoji's CLDR annotation
(shortcodeData ?? [emojiData.annotation.toLowerCase().replace(/ /g, "_")]),
};
const categoryId = EMOJIBASE_GROUP_ID_TO_CATEGORY[emoji.group];