Attachment Modal: Send attachments on enter when input not focused (#6397)
This commit is contained in:
parent
c9f9b27332
commit
28a41a6764
@ -14,7 +14,7 @@ import type {
|
||||
} from '../../../types';
|
||||
import type { Signal } from '../../../util/signals';
|
||||
|
||||
import { EDITABLE_INPUT_ID } from '../../../config';
|
||||
import { EDITABLE_INPUT_ID, EDITABLE_INPUT_MODAL_ID } from '../../../config';
|
||||
import { requestForcedReflow, requestMutation } from '../../../lib/fasterdom/fasterdom';
|
||||
import { selectCanPlayAnimatedEmojis, selectDraft, selectIsInSelectMode } from '../../../global/selectors';
|
||||
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
||||
@ -23,7 +23,7 @@ import {
|
||||
IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_TOUCH_ENV,
|
||||
} from '../../../util/browser/windowEnvironment';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import captureKeyboardListeners from '../../../util/captureKeyboardListeners';
|
||||
import captureKeyboardListeners, { hasActiveHandler } from '../../../util/captureKeyboardListeners';
|
||||
import { getIsDirectTextInputDisabled } from '../../../util/directInputManager';
|
||||
import parseEmojiOnlyString from '../../../util/emoji/parseEmojiOnlyString';
|
||||
import focusEditableElement from '../../../util/focusEditableElement';
|
||||
@ -379,6 +379,22 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
document.addEventListener('keydown', handleCloseContextMenu);
|
||||
}
|
||||
|
||||
const isSendShortcut = useLastCallback((e: KeyboardEvent | React.KeyboardEvent<HTMLDivElement>) => {
|
||||
return e.key === 'Enter'
|
||||
&& !e.shiftKey
|
||||
&& !isMobileDevice
|
||||
&& (
|
||||
(messageSendKeyCombo === 'enter' && !e.shiftKey)
|
||||
|| (messageSendKeyCombo === 'ctrl-enter' && (e.ctrlKey || e.metaKey))
|
||||
);
|
||||
});
|
||||
|
||||
const handleSendShortcut = useLastCallback((e: KeyboardEvent | React.KeyboardEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
closeTextFormatter();
|
||||
onSend();
|
||||
});
|
||||
|
||||
function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {
|
||||
// https://levelup.gitconnected.com/javascript-events-handlers-keyboard-and-load-events-1b3e46a6b0c3#1960
|
||||
const { isComposing } = e;
|
||||
@ -394,19 +410,8 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (!isComposing && e.key === 'Enter' && !e.shiftKey) {
|
||||
if (
|
||||
!isMobileDevice
|
||||
&& (
|
||||
(messageSendKeyCombo === 'enter' && !e.shiftKey)
|
||||
|| (messageSendKeyCombo === 'ctrl-enter' && (e.ctrlKey || e.metaKey))
|
||||
)
|
||||
) {
|
||||
e.preventDefault();
|
||||
|
||||
closeTextFormatter();
|
||||
onSend();
|
||||
}
|
||||
if (!isComposing && isSendShortcut(e)) {
|
||||
handleSendShortcut(e);
|
||||
} else if (!isComposing && e.key === 'ArrowUp' && !html && !e.metaKey && !e.ctrlKey && !e.altKey) {
|
||||
e.preventDefault();
|
||||
editLastMessage();
|
||||
@ -474,8 +479,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
useEffect(() => {
|
||||
if (
|
||||
!chatId
|
||||
|| editableInputId !== EDITABLE_INPUT_ID
|
||||
|| noFocusInterception
|
||||
|| (editableInputId !== EDITABLE_INPUT_ID && editableInputId !== EDITABLE_INPUT_MODAL_ID)
|
||||
|| isMobileDevice
|
||||
|| isSelectModeActive
|
||||
) {
|
||||
@ -483,18 +487,29 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
|
||||
const handleDocumentKeyDown = (e: KeyboardEvent) => {
|
||||
if (getIsDirectTextInputDisabled()) {
|
||||
const target = e.target as HTMLElement | undefined;
|
||||
const input = inputRef.current!;
|
||||
|
||||
const shouldHandleDocumentKeyDown =
|
||||
isActive && input && target
|
||||
&& target !== input
|
||||
&& target.tagName !== 'INPUT'
|
||||
&& target.tagName !== 'TEXTAREA'
|
||||
&& !target.isContentEditable
|
||||
&& !hasActiveHandler('Enter');
|
||||
|
||||
if (!shouldHandleDocumentKeyDown) return;
|
||||
|
||||
if (isSendShortcut(e)) {
|
||||
handleSendShortcut(e);
|
||||
return;
|
||||
}
|
||||
|
||||
const { key } = e;
|
||||
const target = e.target as HTMLElement | undefined;
|
||||
|
||||
if (!target || IGNORE_KEYS.includes(key)) {
|
||||
if (noFocusInterception || getIsDirectTextInputDisabled() || IGNORE_KEYS.includes(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const input = inputRef.current!;
|
||||
const isSelectionCollapsed = document.getSelection()?.isCollapsed;
|
||||
|
||||
if (
|
||||
@ -504,18 +519,10 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
input
|
||||
&& target !== input
|
||||
&& target.tagName !== 'INPUT'
|
||||
&& target.tagName !== 'TEXTAREA'
|
||||
&& !target.isContentEditable
|
||||
) {
|
||||
focusEditableElement(input, true, true);
|
||||
focusEditableElement(input, true, true);
|
||||
|
||||
const newEvent = new KeyboardEvent(e.type, e as any);
|
||||
input.dispatchEvent(newEvent);
|
||||
}
|
||||
const newEvent = new KeyboardEvent(e.type, e as any);
|
||||
input.dispatchEvent(newEvent);
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleDocumentKeyDown, true);
|
||||
@ -523,7 +530,8 @@ const MessageInput: FC<OwnProps & StateProps> = ({
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleDocumentKeyDown, true);
|
||||
};
|
||||
}, [chatId, editableInputId, isMobileDevice, isSelectModeActive, noFocusInterception]);
|
||||
}, [chatId, editableInputId, isMobileDevice,
|
||||
isActive, isSelectModeActive, noFocusInterception]);
|
||||
|
||||
useEffect(() => {
|
||||
const captureFirstTab = debounce((e: KeyboardEvent) => {
|
||||
|
||||
@ -62,6 +62,11 @@ function hasActiveHandlers() {
|
||||
return Object.values(handlers).some((keyHandlers) => Boolean(keyHandlers.length));
|
||||
}
|
||||
|
||||
export function hasActiveHandler(key: string) {
|
||||
const handlerName = keyToHandlerName[key];
|
||||
return handlerName ? Boolean(handlers[handlerName].length) : false;
|
||||
}
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
const handlerName = keyToHandlerName[e.key];
|
||||
if (!handlerName) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user