Apply code review suggestions

including filling in gaps in emoji shortcode coverage.

Signed-off-by: Robin Townsend <robin@robin.town>
This commit is contained in:
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, emoji,
// Include the index so that we can preserve the original order // Include the index so that we can preserve the original order
_orderBy: index, _orderBy: index,
})).filter(o => o.emoji.shortcodes[0]); }));
function score(query, space) { function score(query, space) {
const index = space.indexOf(query); const index = space.indexOf(query);
@ -68,7 +68,7 @@ export default class EmojiProvider extends AutocompleteProvider {
super(EMOJI_REGEX); super(EMOJI_REGEX);
this.matcher = new QueryMatcher<IEmojiShort>(EMOJI_SHORTCODES, { this.matcher = new QueryMatcher<IEmojiShort>(EMOJI_SHORTCODES, {
keys: ['emoji.emoticon'], 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 // For matching against ascii equivalents
shouldMatchWordsOnly: false, shouldMatchWordsOnly: false,
}); });

View file

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

View file

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

View file

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

View file

@ -25,8 +25,8 @@ export interface IEmoji {
shortcodes: string[]; shortcodes: string[];
tags?: string[]; tags?: string[];
unicode: string; unicode: string;
skins?: any[]; // Currently unused
emoticon?: string; emoticon?: string;
filterString: string;
} }
// The unicode is stored without the variant selector // The unicode is stored without the variant selector
@ -59,20 +59,17 @@ export const DATA_BY_CATEGORY = {
"flags": [], "flags": [],
}; };
const ZERO_WIDTH_JOINER = "\u200D";
// Store various mappings from unicode/emoticon/shortcode to the Emoji objects // 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]; const shortcodeData = SHORTCODES[emojiData.hexcode];
// Homogenize shortcodes by ensuring that everything is an array
const shortcodes = typeof shortcodeData === "string" ? [shortcodeData] : (shortcodeData ?? []);
const emoji: IEmoji = { const emoji: IEmoji = {
...emojiData, ...emojiData,
shortcodes, // Homogenize shortcodes by ensuring that everything is an array
// This is used as the string to match the query against when filtering emojis shortcodes: typeof shortcodeData === "string" ?
filterString: (`${emojiData.annotation}\n${shortcodes.join('\n')}}\n${emojiData.emoticon || ''}\n` + [shortcodeData] :
`${emojiData.unicode.split(ZERO_WIDTH_JOINER).join("\n")}`).toLowerCase(), // 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]; const categoryId = EMOJIBASE_GROUP_ID_TO_CATEGORY[emoji.group];