Properly close emoji picker when picking emoji

This commit is contained in:
Fedor Indutny 2022-07-07 14:39:22 -07:00 committed by GitHub
parent fcf75fdd1c
commit 4a15df5904
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 9 deletions

View file

@ -15,7 +15,10 @@ import type { ErrorDialogAudioRecorderType } from '../state/ducks/audioRecorder'
import { RecordingState } from '../state/ducks/audioRecorder'; import { RecordingState } from '../state/ducks/audioRecorder';
import type { HandleAttachmentsProcessingArgsType } from '../util/handleAttachmentsProcessing'; import type { HandleAttachmentsProcessingArgsType } from '../util/handleAttachmentsProcessing';
import { Spinner } from './Spinner'; import { Spinner } from './Spinner';
import type { Props as EmojiButtonProps } from './emoji/EmojiButton'; import type {
Props as EmojiButtonProps,
EmojiButtonAPI,
} from './emoji/EmojiButton';
import { EmojiButton } from './emoji/EmojiButton'; import { EmojiButton } from './emoji/EmojiButton';
import type { Props as StickerButtonProps } from './stickers/StickerButton'; import type { Props as StickerButtonProps } from './stickers/StickerButton';
import { StickerButton } from './stickers/StickerButton'; import { StickerButton } from './stickers/StickerButton';
@ -259,6 +262,7 @@ export const CompositionArea = ({
AttachmentDraftType | undefined AttachmentDraftType | undefined
>(); >();
const inputApiRef = useRef<InputApi | undefined>(); const inputApiRef = useRef<InputApi | undefined>();
const emojiButtonRef = useRef<EmojiButtonAPI | undefined>();
const fileInputRef = useRef<null | HTMLInputElement>(null); const fileInputRef = useRef<null | HTMLInputElement>(null);
const handleForceSend = useCallback(() => { const handleForceSend = useCallback(() => {
@ -270,6 +274,7 @@ export const CompositionArea = ({
const handleSubmit = useCallback( const handleSubmit = useCallback(
(message: string, mentions: Array<BodyRangeType>, timestamp: number) => { (message: string, mentions: Array<BodyRangeType>, timestamp: number) => {
emojiButtonRef.current?.close();
onSendMessage({ onSendMessage({
draftAttachments, draftAttachments,
mentions, mentions,
@ -358,8 +363,8 @@ export const CompositionArea = ({
<> <>
<div className="CompositionArea__button-cell"> <div className="CompositionArea__button-cell">
<EmojiButton <EmojiButton
emojiButtonApi={emojiButtonRef}
i18n={i18n} i18n={i18n}
closeOnPick
doSend={handleForceSend} doSend={handleForceSend}
onPickEmoji={insertEmoji} onPickEmoji={insertEmoji}
onClose={focusInput} onClose={focusInput}
@ -394,6 +399,7 @@ export const CompositionArea = ({
onSendAudioRecording={( onSendAudioRecording={(
voiceNoteAttachment: InMemoryAttachmentDraftType voiceNoteAttachment: InMemoryAttachmentDraftType
) => { ) => {
emojiButtonRef.current?.close();
onSendMessage({ voiceNoteAttachment }); onSendMessage({ voiceNoteAttachment });
}} }}
startRecording={startRecording} startRecording={startRecording}

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react'; import * as React from 'react';
import type { MutableRefObject } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { get, noop } from 'lodash'; import { get, noop } from 'lodash';
import { Manager, Popper, Reference } from 'react-popper'; import { Manager, Popper, Reference } from 'react-popper';
@ -13,13 +14,14 @@ import type { LocalizerType } from '../../types/Util';
import { useRefMerger } from '../../hooks/useRefMerger'; import { useRefMerger } from '../../hooks/useRefMerger';
import * as KeyboardLayout from '../../services/keyboardLayout'; import * as KeyboardLayout from '../../services/keyboardLayout';
export type OwnProps = { export type OwnProps = Readonly<{
readonly className?: string; className?: string;
readonly closeOnPick?: boolean; closeOnPick?: boolean;
readonly emoji?: string; emoji?: string;
readonly i18n: LocalizerType; i18n: LocalizerType;
readonly onClose?: () => unknown; onClose?: () => unknown;
}; emojiButtonApi?: MutableRefObject<EmojiButtonAPI | undefined>;
}>;
export type Props = OwnProps & export type Props = OwnProps &
Pick< Pick<
@ -27,11 +29,16 @@ export type Props = OwnProps &
'doSend' | 'onPickEmoji' | 'onSetSkinTone' | 'recentEmojis' | 'skinTone' 'doSend' | 'onPickEmoji' | 'onSetSkinTone' | 'recentEmojis' | 'skinTone'
>; >;
export type EmojiButtonAPI = Readonly<{
close: () => void;
}>;
export const EmojiButton = React.memo( export const EmojiButton = React.memo(
({ ({
className, className,
closeOnPick, closeOnPick,
emoji, emoji,
emojiButtonApi,
i18n, i18n,
doSend, doSend,
onClose, onClose,
@ -62,6 +69,19 @@ export const EmojiButton = React.memo(
} }
}, [setOpen, onClose]); }, [setOpen, onClose]);
const api = React.useMemo(
() => ({
close: () => setOpen(false),
}),
[setOpen]
);
if (emojiButtonApi) {
// Using a React.MutableRefObject, so we need to reassign this prop.
// eslint-disable-next-line no-param-reassign
emojiButtonApi.current = api;
}
// Create popper root and handle outside clicks // Create popper root and handle outside clicks
React.useEffect(() => { React.useEffect(() => {
if (open) { if (open) {

View file

@ -8964,6 +8964,13 @@
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2021-09-23T00:07:11.885Z" "updated": "2021-09-23T00:07:11.885Z"
}, },
{
"rule": "React-useRef",
"path": "ts/components/CompositionArea.tsx",
"line": " const emojiButtonRef = useRef<EmojiButtonAPI | undefined>();",
"reasonCategory": "usageTrusted",
"updated": "2022-07-07T20:51:44.602Z"
},
{ {
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/CompositionInput.tsx", "path": "ts/components/CompositionInput.tsx",