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 ContextMenuContainer from './message/ContextMenuContainer.async';
|
||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
|
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
message: ApiMessage;
|
message: ApiMessage;
|
||||||
@ -96,6 +97,11 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
} = useContextMenuHandlers(ref);
|
} = useContextMenuHandlers(ref);
|
||||||
const isContextMenuShown = contextMenuPosition !== undefined;
|
const isContextMenuShown = contextMenuPosition !== undefined;
|
||||||
|
|
||||||
|
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||||
|
preventMessageInputBlur(e);
|
||||||
|
handleBeforeContextMenu(e);
|
||||||
|
};
|
||||||
|
|
||||||
if (isEmbedded) {
|
if (isEmbedded) {
|
||||||
return <span className="embedded-action-message">{renderText(content as string)}</span>;
|
return <span className="embedded-action-message">{renderText(content as string)}</span>;
|
||||||
}
|
}
|
||||||
@ -114,7 +120,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
id={`message${message.id}`}
|
id={`message${message.id}`}
|
||||||
className={className}
|
className={className}
|
||||||
data-message-id={message.id}
|
data-message-id={message.id}
|
||||||
onMouseDown={handleBeforeContextMenu}
|
onMouseDown={handleMouseDown}
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
>
|
>
|
||||||
<span>{content}</span>
|
<span>{content}</span>
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import { formatHumanDate } from '../../util/dateFormat';
|
|||||||
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { groupMessages, MessageDateGroup, isAlbum } from './helpers/groupMessages';
|
import { groupMessages, MessageDateGroup, isAlbum } from './helpers/groupMessages';
|
||||||
|
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
|
||||||
import { ObserveFn, useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
import { ObserveFn, useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
||||||
import useOnChange from '../../hooks/useOnChange';
|
import useOnChange from '../../hooks/useOnChange';
|
||||||
import useStickyDates from './hooks/useStickyDates';
|
import useStickyDates from './hooks/useStickyDates';
|
||||||
@ -521,7 +522,12 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className={className} onScroll={handleScroll}>
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className={className}
|
||||||
|
onScroll={handleScroll}
|
||||||
|
onMouseDown={preventMessageInputBlur}
|
||||||
|
>
|
||||||
{isRestricted ? (
|
{isRestricted ? (
|
||||||
<div className="empty">
|
<div className="empty">
|
||||||
<span>
|
<span>
|
||||||
@ -704,11 +710,13 @@ function renderMessages(
|
|||||||
<div
|
<div
|
||||||
className="message-date-group"
|
className="message-date-group"
|
||||||
key={dateGroup.datetime}
|
key={dateGroup.datetime}
|
||||||
|
onMouseDown={preventMessageInputBlur}
|
||||||
teactFastList
|
teactFastList
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={buildClassName('sticky-date', !isSchedule && 'interactive')}
|
className={buildClassName('sticky-date', !isSchedule && 'interactive')}
|
||||||
key="date-header"
|
key="date-header"
|
||||||
|
onMouseDown={preventMessageInputBlur}
|
||||||
onClick={!isSchedule ? () => openHistoryCalendar({ selectedAt: dateGroup.datetime }) : undefined}
|
onClick={!isSchedule ? () => openHistoryCalendar({ selectedAt: dateGroup.datetime }) : undefined}
|
||||||
>
|
>
|
||||||
<span dir="auto">
|
<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, {
|
import React, {
|
||||||
FC,
|
FC,
|
||||||
memo,
|
memo,
|
||||||
@ -67,6 +66,7 @@ import { ROUND_VIDEO_DIMENSIONS } from '../../common/helpers/mediaDimensions';
|
|||||||
import { buildContentClassName, isEmojiOnlyMessage } from './helpers/buildContentClassName';
|
import { buildContentClassName, isEmojiOnlyMessage } from './helpers/buildContentClassName';
|
||||||
import { getMinMediaWidth, calculateMediaDimensions } from './helpers/mediaDimensions';
|
import { getMinMediaWidth, calculateMediaDimensions } from './helpers/mediaDimensions';
|
||||||
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
|
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
|
||||||
|
import { preventMessageInputBlur } from '../helpers/preventMessageInputBlur';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import calculateAuthorWidth from './helpers/calculateAuthorWidth';
|
import calculateAuthorWidth from './helpers/calculateAuthorWidth';
|
||||||
import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
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;
|
appendixRef.current.innerHTML = isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN;
|
||||||
}, [isOwn, withAppendix]);
|
}, [isOwn, withAppendix]);
|
||||||
|
|
||||||
const handleGroupDocumentMessagesSelect = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
const handleGroupDocumentMessagesSelect = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
toggleMessageSelection({
|
toggleMessageSelection({
|
||||||
@ -351,7 +351,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
});
|
});
|
||||||
}, [messageId, message.groupedId, toggleMessageSelection]);
|
}, [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
|
const params = isAlbum && album && album.messages
|
||||||
? {
|
? {
|
||||||
messageId,
|
messageId,
|
||||||
@ -366,10 +366,15 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
setReplyingToId({ messageId });
|
setReplyingToId({ messageId });
|
||||||
}, [setReplyingToId, messageId]);
|
}, [setReplyingToId, messageId]);
|
||||||
|
|
||||||
const handleContentDoubleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
const handleContentDoubleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||||
|
preventMessageInputBlur(e);
|
||||||
|
handleBeforeContextMenu(e);
|
||||||
|
};
|
||||||
|
|
||||||
const handleAvatarClick = useCallback(() => {
|
const handleAvatarClick = useCallback(() => {
|
||||||
if (!avatarPeer) {
|
if (!avatarPeer) {
|
||||||
return;
|
return;
|
||||||
@ -425,7 +430,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
});
|
});
|
||||||
}, [chatId, threadId, openMediaViewer, isScheduled]);
|
}, [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;
|
const target = e.target as HTMLDivElement;
|
||||||
if (!target.classList.contains('text-content') && !target.classList.contains('Message')) {
|
if (!target.classList.contains('text-content') && !target.classList.contains('Message')) {
|
||||||
return;
|
return;
|
||||||
@ -754,7 +759,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
data-message-id={messageId}
|
data-message-id={messageId}
|
||||||
onClick={isInSelectMode ? handleMessageSelect : IS_ANDROID ? handleClick : undefined}
|
onClick={isInSelectMode ? handleMessageSelect : IS_ANDROID ? handleClick : undefined}
|
||||||
onDoubleClick={!isInSelectMode ? handleContainerDoubleClick : undefined}
|
onDoubleClick={!isInSelectMode ? handleContainerDoubleClick : undefined}
|
||||||
onMouseDown={!isInSelectMode ? handleBeforeContextMenu : undefined}
|
onMouseDown={!isInSelectMode ? handleMouseDown : undefined}
|
||||||
onContextMenu={!isInSelectMode ? handleContextMenu : undefined}
|
onContextMenu={!isInSelectMode ? handleContextMenu : undefined}
|
||||||
onMouseEnter={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseEnter : undefined}
|
onMouseEnter={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseEnter : undefined}
|
||||||
onMouseLeave={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseLeave : undefined}
|
onMouseLeave={isInDocumentGroup && !isLastInDocumentGroup ? handleDocumentGroupMouseLeave : undefined}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user