mirror of https://github.com/vector-im/riot-web
Apply code review suggestions
including filling in gaps in emoji shortcode coverage. Signed-off-by: Robin Townsend <robin@robin.town>pull/21833/head
parent
c1ed023e17
commit
f8a922eaa1
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
19
src/emoji.ts
19
src/emoji.ts
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue