Emoji Tooltip: Update recent emojis (#1066)
This commit is contained in:
parent
0cf1bbb72c
commit
1436cb6908
@ -811,6 +811,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
emojis={filteredEmojis}
|
||||
onClose={closeEmojiTooltip}
|
||||
onEmojiSelect={insertEmoji}
|
||||
addRecentEmoji={addRecentEmoji}
|
||||
/>
|
||||
<AttachMenu
|
||||
isOpen={isAttachMenuOpen}
|
||||
|
||||
@ -10,6 +10,7 @@ import findInViewport from '../../../util/findInViewport';
|
||||
import isFullyVisible from '../../../util/isFullyVisible';
|
||||
import fastSmoothScrollHorizontal from '../../../util/fastSmoothScrollHorizontal';
|
||||
import useShowTransition from '../../../hooks/useShowTransition';
|
||||
import usePrevDuringAnimation from '../../../hooks/usePrevDuringAnimation';
|
||||
|
||||
import Loading from '../../ui/Loading';
|
||||
import EmojiButton from './EmojiButton';
|
||||
@ -51,18 +52,23 @@ export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
onEmojiSelect: (text: string) => void;
|
||||
onClose: NoneToVoidFunction;
|
||||
addRecentEmoji: AnyToVoidFunction;
|
||||
emojis: Emoji[];
|
||||
};
|
||||
|
||||
const CLOSE_DURATION = 350;
|
||||
|
||||
const EmojiTooltip: FC<OwnProps> = ({
|
||||
isOpen,
|
||||
emojis,
|
||||
onClose,
|
||||
onEmojiSelect,
|
||||
addRecentEmoji,
|
||||
}) => {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const containerRef = useRef<HTMLDivElement>(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<OwnProps> = ({
|
||||
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<OwnProps> = ({
|
||||
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
|
||||
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
|
||||
>
|
||||
{shouldRender && emojis ? (
|
||||
emojis.map((emoji, index) => (
|
||||
{shouldRender && listEmojis ? (
|
||||
listEmojis.map((emoji, index) => (
|
||||
<EmojiButton
|
||||
key={emoji.id}
|
||||
emoji={emoji}
|
||||
|
||||
@ -15,7 +15,7 @@ let emojiRawData: EmojiRawData;
|
||||
let emojiData: EmojiData;
|
||||
|
||||
const RE_NOT_EMOJI_SEARCH = /[^-:_a-z\d]+/i;
|
||||
const EMOJIS_LIMIT = 50;
|
||||
const EMOJIS_LIMIT = 36;
|
||||
|
||||
export default function useEmojiTooltip(
|
||||
isAllowed: boolean,
|
||||
@ -25,24 +25,26 @@ export default function useEmojiTooltip(
|
||||
onUpdateHtml: (html: string) => void,
|
||||
) {
|
||||
const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();
|
||||
const [emojis, setEmojis] = useState<Emoji[]>([]);
|
||||
const [emojiIds, setEmojiIds] = useState<string[]>([]);
|
||||
const [filteredEmojis, setFilteredEmojis] = useState<Emoji[]>([]);
|
||||
|
||||
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<Emoji>(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(':');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user