Attachment Modal: Support Emoji Tooltip, fix layout and pasting from clipboard (#1093)

This commit is contained in:
Alexander Zinchuk 2021-05-13 12:00:43 +03:00
parent 73e32621a5
commit f7972c87f3
5 changed files with 38 additions and 10 deletions

View File

@ -9,6 +9,7 @@ import { getFileExtension } from '../../common/helpers/documentInfo';
import captureEscKeyListener from '../../../util/captureEscKeyListener';
import usePrevious from '../../../hooks/usePrevious';
import useMentionTooltip from './hooks/useMentionTooltip';
import useEmojiTooltip from './hooks/useEmojiTooltip';
import useLang from '../../../hooks/useLang';
import Button from '../../ui/Button';
@ -16,6 +17,7 @@ import Modal from '../../ui/Modal';
import File from '../../common/File';
import MessageInput from './MessageInput';
import MentionTooltip from './MentionTooltip';
import EmojiTooltip from './EmojiTooltip.async';
import './AttachmentModal.scss';
@ -23,9 +25,12 @@ export type OwnProps = {
attachments: ApiAttachment[];
caption: string;
canSuggestMembers?: boolean;
canSuggestEmoji?: boolean;
currentUserId?: number;
groupChatMembers?: ApiChatMember[];
usersById?: Record<number, ApiUser>;
recentEmojis: string[];
addRecentEmoji: AnyToVoidFunction;
onCaptionUpdate: (html: string) => void;
onSend: () => void;
onClear: () => void;
@ -38,7 +43,9 @@ const AttachmentModal: FC<OwnProps> = ({
groupChatMembers,
currentUserId,
usersById,
recentEmojis,
onCaptionUpdate,
addRecentEmoji,
onSend,
onClear,
}) => {
@ -59,6 +66,15 @@ const AttachmentModal: FC<OwnProps> = ({
currentUserId,
usersById,
);
const {
isEmojiTooltipOpen, closeEmojiTooltip, filteredEmojis, insertEmoji,
} = useEmojiTooltip(
isOpen,
caption,
recentEmojis,
EDITABLE_INPUT_MODAL_ID,
onCaptionUpdate,
);
useEffect(() => (isOpen ? captureEscKeyListener(onClear) : undefined), [isOpen, onClear]);
@ -144,6 +160,13 @@ const AttachmentModal: FC<OwnProps> = ({
filteredChatMembers={mentionFilteredMembers}
usersById={usersById}
/>
<EmojiTooltip
isOpen={isEmojiTooltipOpen}
emojis={filteredEmojis}
onClose={closeEmojiTooltip}
onEmojiSelect={insertEmoji}
addRecentEmoji={addRecentEmoji}
/>
<MessageInput
id="caption-input-text"
html={caption}

View File

@ -256,7 +256,7 @@
padding-top: calc(1rem - var(--border-width));
padding-bottom: calc(1rem - var(--border-width));
overflow: hidden;
line-height: 1.5rem;
line-height: 1.375rem;
&.overflown {
overflow-y: auto;
@ -276,7 +276,7 @@
.placeholder-text {
position: absolute;
bottom: 1rem;
bottom: .9375rem;
color: var(--color-placeholders);
pointer-events: none;
@ -318,6 +318,8 @@
min-height: 3.5rem;
max-height: 26rem;
line-height: 1.3125;
padding-top: calc(1.15625rem - var(--border-width));
padding-bottom: calc(1.15625rem - var(--border-width));
@media (max-width: 600px) {
height: 2.875rem;
@ -359,13 +361,14 @@
#caption-input-text {
.form-control {
height: 3.25rem;
min-height: 3.25rem;
max-height: 15rem;
}
.placeholder-text {
bottom: 1rem;
left: 1rem;
bottom: .8125rem;
left: .90625rem;
}
}

View File

@ -301,9 +301,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
setHtml,
);
const insertTextAndUpdateCursor = useCallback((text: string) => {
const insertTextAndUpdateCursor = useCallback((text: string, inputId: string = EDITABLE_INPUT_ID) => {
const selection = window.getSelection()!;
const messageInput = document.getElementById(EDITABLE_INPUT_ID)!;
const messageInput = document.getElementById(inputId)!;
const newHtml = renderText(text, ['escape_html', 'emoji_html', 'br_html'])
.join('')
.replace(/\u200b+/g, '\u200b');
@ -679,7 +679,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
groupChatMembers={groupChatMembers}
currentUserId={currentUserId}
usersById={usersById}
recentEmojis={recentEmojis}
onCaptionUpdate={setHtml}
addRecentEmoji={addRecentEmoji}
onSend={shouldSchedule ? openCalendar : handleSend}
onClear={handleClearAttachment}
/>

View File

@ -8,7 +8,7 @@ const CLIPBOARD_ACCEPTED_TYPES = ['image/png', 'image/jpeg', 'image/gif'];
const MAX_MESSAGE_LENGTH = 4096;
export default (
insertTextAndUpdateCursor: (text: string) => void,
insertTextAndUpdateCursor: (text: string, inputId?: string) => void,
setAttachments: StateHookSetter<ApiAttachment[]>,
editedMessage: ApiMessage | undefined,
) => {
@ -43,7 +43,7 @@ export default (
}
if (pastedText) {
insertTextAndUpdateCursor(pastedText);
insertTextAndUpdateCursor(pastedText, input ? input.id : undefined);
}
}

View File

@ -56,7 +56,7 @@ export default function useEmojiTooltip(
}, []);
useEffect(() => {
if (!html || !emojiIds.length) {
if (!isAllowed || !html || !emojiIds.length) {
unmarkIsOpen();
return;
}
@ -82,7 +82,7 @@ export default function useEmojiTooltip(
} else {
unmarkIsOpen();
}
}, [emojiIds, html, markIsOpen, recentEmojis, unmarkIsOpen]);
}, [emojiIds, html, isAllowed, markIsOpen, recentEmojis, unmarkIsOpen]);
const insertEmoji = useCallback((textEmoji: string) => {
const atIndex = html.lastIndexOf(':');