Composer: Prevent losing focus when clicking on the message list (#1238)
This commit is contained in:
parent
fc975f87cc
commit
50d25947fe
@ -25,6 +25,7 @@ import useLang from '../../hooks/useLang';
|
||||
import ContextMenuContainer from './message/ContextMenuContainer.async';
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||
|
||||
type OwnProps = {
|
||||
message: ApiMessage;
|
||||
@ -96,6 +97,11 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
} = useContextMenuHandlers(ref);
|
||||
const isContextMenuShown = contextMenuPosition !== undefined;
|
||||
|
||||
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
preventMessageInputBlur(e);
|
||||
handleBeforeContextMenu(e);
|
||||
};
|
||||
|
||||
if (isEmbedded) {
|
||||
return <span className="embedded-action-message">{renderText(content as string)}</span>;
|
||||
}
|
||||
@ -114,7 +120,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
||||
id={`message${message.id}`}
|
||||
className={className}
|
||||
data-message-id={message.id}
|
||||
onMouseDown={handleBeforeContextMenu}
|
||||
onMouseDown={handleMouseDown}
|
||||
onContextMenu={handleContextMenu}
|
||||
>
|
||||
<span>{content}</span>
|
||||
|
||||
@ -45,6 +45,7 @@ import { formatHumanDate } from '../../util/dateFormat';
|
||||
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { groupMessages, MessageDateGroup, isAlbum } from './helpers/groupMessages';
|
||||
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||
import { ObserveFn, useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
||||
import useOnChange from '../../hooks/useOnChange';
|
||||
import useStickyDates from './hooks/useStickyDates';
|
||||
@ -521,7 +522,12 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className={className} onScroll={handleScroll}>
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={className}
|
||||
onScroll={handleScroll}
|
||||
onMouseDown={preventMessageInputBlur}
|
||||
>
|
||||
{isRestricted ? (
|
||||
<div className="empty">
|
||||
<span>
|
||||
@ -704,11 +710,13 @@ function renderMessages(
|
||||
<div
|
||||
className="message-date-group"
|
||||
key={dateGroup.datetime}
|
||||
onMouseDown={preventMessageInputBlur}
|
||||
teactFastList
|
||||
>
|
||||
<div
|
||||
className={buildClassName('sticky-date', !isSchedule && 'interactive')}
|
||||
key="date-header"
|
||||
onMouseDown={preventMessageInputBlur}
|
||||
onClick={!isSchedule ? () => openHistoryCalendar({ selectedAt: dateGroup.datetime }) : undefined}
|
||||
>
|
||||
<span dir="auto">
|
||||
|
||||
17
src/components/middle/helpers/preventMessageInputBlur.ts
Normal file
17
src/components/middle/helpers/preventMessageInputBlur.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import React from '../../../lib/teact/teact';
|
||||
|
||||
import { EDITABLE_INPUT_ID } from '../../../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||
|
||||
export function preventMessageInputBlur(e: React.MouseEvent<HTMLElement>) {
|
||||
if (
|
||||
IS_SINGLE_COLUMN_LAYOUT
|
||||
|| !document.activeElement
|
||||
|| document.activeElement.id !== EDITABLE_INPUT_ID
|
||||
|| e.target !== e.currentTarget
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||
import React, {
|
||||
FC,
|
||||
memo,
|
||||
@ -67,6 +66,7 @@ import { ROUND_VIDEO_DIMENSIONS } from '../../common/helpers/mediaDimensions';
|
||||
import { buildContentClassName, isEmojiOnlyMessage } from './helpers/buildContentClassName';
|
||||
import { getMinMediaWidth, calculateMediaDimensions } from './helpers/mediaDimensions';
|
||||
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
|
||||
import { preventMessageInputBlur } from '../helpers/preventMessageInputBlur';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
import calculateAuthorWidth from './helpers/calculateAuthorWidth';
|
||||
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
||||
@ -342,7 +342,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
appendixRef.current.innerHTML = isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN;
|
||||
}, [isOwn, withAppendix]);
|
||||
|
||||
const handleGroupDocumentMessagesSelect = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const handleGroupDocumentMessagesSelect = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
|
||||
toggleMessageSelection({
|
||||
@ -351,7 +351,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
});
|
||||
}, [messageId, message.groupedId, toggleMessageSelection]);
|
||||
|
||||
const handleMessageSelect = useCallback((e?: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const handleMessageSelect = useCallback((e?: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const params = isAlbum && album && album.messages
|
||||
? {
|
||||
messageId,
|
||||
@ -366,10 +366,15 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
setReplyingToId({ messageId });
|
||||
}, [setReplyingToId, messageId]);
|
||||
|
||||
const handleContentDoubleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const handleContentDoubleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
preventMessageInputBlur(e);
|
||||
handleBeforeContextMenu(e);
|
||||
};
|
||||
|
||||
const handleAvatarClick = useCallback(() => {
|
||||
if (!avatarPeer) {
|
||||
return;
|
||||
@ -425,7 +430,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
});
|
||||
}, [chatId, threadId, openMediaViewer, isScheduled]);
|
||||
|
||||
const handleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
const target = e.target as HTMLDivElement;
|
||||
if (!target.classList.contains('text-content') && !target.classList.contains('Message')) {
|
||||
return;
|
||||
@ -754,7 +759,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
data-message-id={messageId}
|
||||
onClick={isInSelectMode ? handleMessageSelect : IS_ANDROID ? handleClick : undefined}
|
||||
onDoubleClick={!isInSelectMode ? handleContainerDoubleClick : undefined}
|
||||
onMouseDown={!isInSelectMode ? handleBeforeContextMenu : undefined}
|
||||
onMouseDown={!isInSelectMode ? handleMouseDown : undefined}
|
||||
onContextMenu={!isInSelectMode ? handleContextMenu : undefined}
|
||||
onMouseEnter={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseEnter : undefined}
|
||||
onMouseLeave={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseLeave : undefined}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user