From cf044474a411e3b7400f6b4b7631d7e5adf2701d Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Sun, 9 May 2021 03:42:58 +0300 Subject: [PATCH] Emoji Picker: Update recent emojis after picker is closed --- src/components/middle/composer/Composer.tsx | 5 ++- .../middle/composer/EmojiPicker.tsx | 15 ++++---- src/components/middle/composer/SymbolMenu.tsx | 34 ++++++++++++++++--- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index 697991c31..43cbdf44a 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -124,7 +124,7 @@ type DispatchProps = Pick; enum MainButtonState { @@ -189,6 +189,7 @@ const Composer: FC = ({ closePaymentModal, openChat, clearReceipt, + addRecentEmoji, }) => { // eslint-disable-next-line no-null/no-null const appendixRef = useRef(null); @@ -835,6 +836,7 @@ const Composer: FC = ({ onGifSelect={handleGifSelect} onRemoveSymbol={removeSymbol} onSearchOpen={handleSearchOpen} + addRecentEmoji={addRecentEmoji} /> @@ -948,5 +950,6 @@ export default memo(withGlobal( 'clearReceipt', 'loadScheduledHistory', 'openChat', + 'addRecentEmoji', ]), )(Composer)); diff --git a/src/components/middle/composer/EmojiPicker.tsx b/src/components/middle/composer/EmojiPicker.tsx index ceb177e72..93497e6af 100644 --- a/src/components/middle/composer/EmojiPicker.tsx +++ b/src/components/middle/composer/EmojiPicker.tsx @@ -3,7 +3,7 @@ import React, { } from '../../../lib/teact/teact'; import { withGlobal } from '../../../lib/teact/teactn'; -import { GlobalState, GlobalActions } from '../../../global/types'; +import { GlobalState } from '../../../global/types'; import { MENU_TRANSITION_DURATION } from '../../../config'; import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; @@ -31,11 +31,10 @@ import './EmojiPicker.scss'; type OwnProps = { className?: string; - onEmojiSelect: (emoji: string) => void; + onEmojiSelect: (emoji: string, name: string) => void; }; type StateProps = Pick; -type DispatchProps = Pick; type EmojiCategoryData = { id: string; name: string; emojis: string[] }; const ICONS_BY_CATEGORY: Record = { @@ -63,8 +62,8 @@ let emojiDataPromise: Promise; let emojiRawData: EmojiRawData; let emojiData: EmojiData; -const EmojiPicker: FC = ({ - className, onEmojiSelect, recentEmojis, addRecentEmoji, +const EmojiPicker: FC = ({ + className, onEmojiSelect, recentEmojis, }) => { // eslint-disable-next-line no-null/no-null const containerRef = useRef(null); @@ -161,9 +160,8 @@ const EmojiPicker: FC = ({ }, []); const handleEmojiSelect = useCallback((emoji: string, name: string) => { - onEmojiSelect(emoji); - addRecentEmoji({ emoji: name }); - }, [addRecentEmoji, onEmojiSelect]); + onEmojiSelect(emoji, name); + }, [onEmojiSelect]); const canRenderContents = useAsyncRendering([], MENU_TRANSITION_DURATION); @@ -228,5 +226,4 @@ async function ensureEmojiData() { export default memo(withGlobal( (global): StateProps => pick(global, ['recentEmojis']), - (setGlobal, actions): DispatchProps => pick(actions, ['addRecentEmoji']), )(EmojiPicker)); diff --git a/src/components/middle/composer/SymbolMenu.tsx b/src/components/middle/composer/SymbolMenu.tsx index ee1aeccdd..91be71bd1 100644 --- a/src/components/middle/composer/SymbolMenu.tsx +++ b/src/components/middle/composer/SymbolMenu.tsx @@ -1,11 +1,11 @@ import React, { - FC, memo, useState, useCallback, useEffect, useLayoutEffect, + FC, memo, useCallback, useEffect, useLayoutEffect, useRef, useState, } from '../../../lib/teact/teact'; import { ApiSticker, ApiVideo } from '../../../api/types'; import { IAllowedAttachmentOptions } from '../../../modules/helpers'; -import { IS_TOUCH_ENV, IS_MOBILE_SCREEN } from '../../../util/environment'; +import { IS_MOBILE_SCREEN, IS_TOUCH_ENV } from '../../../util/environment'; import { fastRaf } from '../../../util/schedulers'; import buildClassName from '../../../util/buildClassName'; import useShowTransition from '../../../hooks/useShowTransition'; @@ -18,7 +18,7 @@ import Transition from '../../ui/Transition'; import EmojiPicker from './EmojiPicker'; import StickerPicker from './StickerPicker'; import GifPicker from './GifPicker'; -import SymbolMenuFooter, { SymbolMenuTabs, SYMBOL_MENU_TAB_TITLES } from './SymbolMenuFooter'; +import SymbolMenuFooter, { SYMBOL_MENU_TAB_TITLES, SymbolMenuTabs } from './SymbolMenuFooter'; import Portal from '../../ui/Portal'; import './SymbolMenu.scss'; @@ -35,6 +35,7 @@ export type OwnProps = { onGifSelect: (gif: ApiVideo) => void; onRemoveSymbol: () => void; onSearchOpen: (type: 'stickers' | 'gifs') => void; + addRecentEmoji: AnyToVoidFunction; }; let isActivated = false; @@ -43,9 +44,10 @@ const SymbolMenu: FC = ({ isOpen, allowedAttachmentOptions, onLoad, onClose, onEmojiSelect, onStickerSelect, onGifSelect, - onRemoveSymbol, onSearchOpen, + onRemoveSymbol, onSearchOpen, addRecentEmoji, }) => { const [activeTab, setActiveTab] = useState(0); + const [recentEmojis, setRecentEmojis] = useState([]); const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose); const { shouldRender, transitionClassNames } = useShowTransition(isOpen, onClose, false, false); @@ -80,6 +82,28 @@ const SymbolMenu: FC = ({ }; }, [isOpen]); + const recentEmojisRef = useRef(recentEmojis); + recentEmojisRef.current = recentEmojis; + useEffect(() => { + if (!recentEmojisRef.current.length) { + return; + } + + recentEmojisRef.current.forEach((name) => { + addRecentEmoji({ emoji: name }); + }); + + setRecentEmojis([]); + }, [isOpen, activeTab, addRecentEmoji]); + + const handleEmojiSelect = useCallback((emoji: string, name: string) => { + setRecentEmojis((emojis) => { + return [...emojis, name]; + }); + + onEmojiSelect(emoji); + }, [onEmojiSelect]); + const handleSearch = useCallback((type: 'stickers' | 'gifs') => { onClose(); onSearchOpen(type); @@ -95,7 +119,7 @@ const SymbolMenu: FC = ({ return ( ); case SymbolMenuTabs.Stickers: