From 1436cb69087f9221f1920dd39f9fa0325ac79bee Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 11 May 2021 02:57:05 +0300 Subject: [PATCH] Emoji Tooltip: Update recent emojis (#1066) --- src/components/middle/composer/Composer.tsx | 1 + .../middle/composer/EmojiTooltip.tsx | 13 +++++++-- .../middle/composer/hooks/useEmojiTooltip.ts | 29 +++++++++++-------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index 43cbdf44a..f0b34d220 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -811,6 +811,7 @@ const Composer: FC = ({ emojis={filteredEmojis} onClose={closeEmojiTooltip} onEmojiSelect={insertEmoji} + addRecentEmoji={addRecentEmoji} /> void; onClose: NoneToVoidFunction; + addRecentEmoji: AnyToVoidFunction; emojis: Emoji[]; }; +const CLOSE_DURATION = 350; + const EmojiTooltip: FC = ({ isOpen, emojis, onClose, onEmojiSelect, + addRecentEmoji, }) => { // eslint-disable-next-line no-null/no-null const containerRef = useRef(null); const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false); + const listEmojis: Emoji[] = usePrevDuringAnimation(emojis.length ? emojis : undefined, CLOSE_DURATION) || []; const [selectedIndex, setSelectedIndex] = useState(-1); @@ -95,9 +101,10 @@ const EmojiTooltip: FC = ({ if (emoji) { e.preventDefault(); onEmojiSelect(emoji.native); + addRecentEmoji({ emoji: emoji.id }); } } - }, [emojis, onEmojiSelect, selectedIndex]); + }, [addRecentEmoji, emojis, onEmojiSelect, selectedIndex]); useEffect(() => (isOpen ? captureKeyboardListeners({ onEsc: onClose, @@ -126,8 +133,8 @@ const EmojiTooltip: FC = ({ onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined} onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined} > - {shouldRender && emojis ? ( - emojis.map((emoji, index) => ( + {shouldRender && listEmojis ? ( + listEmojis.map((emoji, index) => ( void, ) { const [isOpen, markIsOpen, unmarkIsOpen] = useFlag(); - const [emojis, setEmojis] = useState([]); + const [emojiIds, setEmojiIds] = useState([]); const [filteredEmojis, setFilteredEmojis] = useState([]); const recentEmojis = useMemo( () => { - if (!emojis && !recentEmojiIds.length) { + if (!emojiIds.length || !recentEmojiIds.length) { return []; } - return emojis.filter((emoji) => recentEmojiIds.includes(emoji.id)) as Emoji[]; + return recentEmojiIds + .map((emojiId) => emojiData.emojis[emojiId]) + .filter(Boolean as any); }, - [emojis, recentEmojiIds], + [emojiIds, recentEmojiIds], ); // Initialize data on first render. useEffect(() => { const exec = () => { - setEmojis(Object.values(emojiData.emojis)); + setEmojiIds(Object.keys(emojiData.emojis)); }; if (emojiData) { @@ -54,7 +56,7 @@ export default function useEmojiTooltip( }, []); useEffect(() => { - if (!html || !emojis) { + if (!html || !emojiIds.length) { unmarkIsOpen(); return; } @@ -67,17 +69,20 @@ export default function useEmojiTooltip( } const filter = code.substr(1); - const matched = filter === '' ? recentEmojis : emojis.filter((emoji) => { - return 'names' in emoji && (!filter || emoji.names.find((name) => name.includes(filter))); - }) as Emoji[]; + const matched = filter === '' + ? recentEmojis + : emojiIds + .filter((emojiId) => emojiData.emojis[emojiId].names.find((name) => name.includes(filter))) + .slice(0, EMOJIS_LIMIT) + .map((emojiId) => emojiData.emojis[emojiId]); if (matched.length) { markIsOpen(); - setFilteredEmojis(matched.slice(0, EMOJIS_LIMIT)); + setFilteredEmojis(matched); } else { unmarkIsOpen(); } - }, [emojis, html, markIsOpen, recentEmojis, unmarkIsOpen]); + }, [emojiIds, html, markIsOpen, recentEmojis, unmarkIsOpen]); const insertEmoji = useCallback((textEmoji: string) => { const atIndex = html.lastIndexOf(':');