Composer: Prevent losing input focus when sending various media

This commit is contained in:
Alexander Zinchuk 2021-08-25 16:29:22 +03:00
parent c64e309495
commit 6cc4a94407
6 changed files with 22 additions and 10 deletions

View File

@ -11,6 +11,7 @@ import useTransitionForMedia from '../../hooks/useTransitionForMedia';
import useVideoCleanup from '../../hooks/useVideoCleanup'; import useVideoCleanup from '../../hooks/useVideoCleanup';
import useBuffering from '../../hooks/useBuffering'; import useBuffering from '../../hooks/useBuffering';
import useCanvasBlur from '../../hooks/useCanvasBlur'; import useCanvasBlur from '../../hooks/useCanvasBlur';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import Spinner from '../ui/Spinner'; import Spinner from '../ui/Spinner';
@ -66,6 +67,7 @@ const GifButton: FC<OwnProps> = ({
<div <div
ref={ref} ref={ref}
className={fullClassName} className={fullClassName}
onMouseDown={preventMessageInputBlurWithBubbling}
onClick={handleClick} onClick={handleClick}
> >
{hasThumbnail && ( {hasThumbnail && (

View File

@ -10,6 +10,7 @@ import useMedia from '../../hooks/useMedia';
import useTransitionForMedia from '../../hooks/useTransitionForMedia'; import useTransitionForMedia from '../../hooks/useTransitionForMedia';
import useFlag from '../../hooks/useFlag'; import useFlag from '../../hooks/useFlag';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import AnimatedSticker from './AnimatedSticker'; import AnimatedSticker from './AnimatedSticker';
import Button from '../ui/Button'; import Button from '../ui/Button';
@ -90,6 +91,7 @@ const StickerButton: FC<OwnProps> = ({
// @ts-ignore // @ts-ignore
style={style} style={style}
data-sticker-id={sticker.id} data-sticker-id={sticker.id}
onMouseDown={preventMessageInputBlurWithBubbling}
onClick={handleClick} onClick={handleClick}
> >
{shouldRenderPreview && !canAnimatedPlay && ( {shouldRenderPreview && !canAnimatedPlay && (

View File

@ -9,6 +9,7 @@ import useMedia from '../../../../hooks/useMedia';
import ListItem from '../../../ui/ListItem'; import ListItem from '../../../ui/ListItem';
import './BaseResult.scss'; import './BaseResult.scss';
import { preventMessageInputBlurWithBubbling } from '../../helpers/preventMessageInputBlur';
export type OwnProps = { export type OwnProps = {
focus?: boolean; focus?: boolean;
@ -46,6 +47,7 @@ const BaseResult: FC<OwnProps> = ({
<ListItem <ListItem
focus={focus} focus={focus}
className="BaseResult chat-item-clickable" className="BaseResult chat-item-clickable"
onMouseDown={preventMessageInputBlurWithBubbling}
onClick={onClick} onClick={onClick}
> >
<span className="thumb"> <span className="thumb">

View File

@ -3,15 +3,19 @@ import React from '../../../lib/teact/teact';
import { EDITABLE_INPUT_ID } from '../../../config'; import { EDITABLE_INPUT_ID } from '../../../config';
import { IS_IOS } from '../../../util/environment'; import { IS_IOS } from '../../../util/environment';
export function preventMessageInputBlur(e: React.MouseEvent<HTMLElement>) { export function preventMessageInputBlur(e: React.MouseEvent<HTMLElement>, withBubbling = false) {
if ( if (
IS_IOS IS_IOS
|| !document.activeElement || !document.activeElement
|| document.activeElement.id !== EDITABLE_INPUT_ID || document.activeElement.id !== EDITABLE_INPUT_ID
|| e.target !== e.currentTarget || (!withBubbling && e.target !== e.currentTarget)
) { ) {
return; return;
} }
e.preventDefault(); e.preventDefault();
} }
export function preventMessageInputBlurWithBubbling(e: React.MouseEvent<HTMLElement>) {
preventMessageInputBlur(e, true);
}

View File

@ -15,16 +15,14 @@ import MenuItem from './MenuItem';
import './ListItem.scss'; import './ListItem.scss';
type OnClickHandler = (e: React.MouseEvent<HTMLDivElement>) => void; interface MenuItemContextAction {
type MenuItemContextAction = {
title: string; title: string;
icon: string; icon: string;
destructive?: boolean; destructive?: boolean;
handler?: () => void; handler?: () => void;
}; }
type OwnProps = { interface OwnProps {
ref?: RefObject<HTMLDivElement>; ref?: RefObject<HTMLDivElement>;
buttonRef?: RefObject<HTMLDivElement>; buttonRef?: RefObject<HTMLDivElement>;
icon?: string; icon?: string;
@ -40,8 +38,9 @@ type OwnProps = {
multiline?: boolean; multiline?: boolean;
isStatic?: boolean; isStatic?: boolean;
contextActions?: MenuItemContextAction[]; contextActions?: MenuItemContextAction[];
onClick?: OnClickHandler; onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;
}; onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
}
const ListItem: FC<OwnProps> = (props) => { const ListItem: FC<OwnProps> = (props) => {
const { const {
@ -60,6 +59,7 @@ const ListItem: FC<OwnProps> = (props) => {
multiline, multiline,
isStatic, isStatic,
contextActions, contextActions,
onMouseDown,
onClick, onClick,
} = props; } = props;
@ -147,6 +147,7 @@ const ListItem: FC<OwnProps> = (props) => {
dir={lang.isRtl ? 'rtl' : undefined} dir={lang.isRtl ? 'rtl' : undefined}
// @ts-ignore // @ts-ignore
style={style} style={style}
onMouseDown={onMouseDown}
> >
<div <div
className={buildClassName('ListItem-button', isTouched && 'active')} className={buildClassName('ListItem-button', isTouched && 'active')}

View File

@ -9,6 +9,7 @@ import captureEscKeyListener from '../../util/captureEscKeyListener';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'; import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import './Menu.scss'; import './Menu.scss';
@ -109,7 +110,7 @@ const Menu: FC<OwnProps> = ({
> >
{isOpen && ( {isOpen && (
// This only prevents click events triggering on underlying elements // This only prevents click events triggering on underlying elements
<div className="backdrop" /> <div className="backdrop" onMouseDown={preventMessageInputBlurWithBubbling} />
)} )}
<div <div
ref={menuRef} ref={menuRef}