Message: Fix quick reaction position (#2969)
This commit is contained in:
parent
180599f5d4
commit
a27ec8243b
@ -80,6 +80,7 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: transform 0.2s ease-out, opacity 0.2s ease-out;
|
transition: transform 0.2s ease-out, opacity 0.2s ease-out;
|
||||||
transition-delay: 0.2s;
|
transition-delay: 0.2s;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
|
|||||||
@ -263,6 +263,9 @@ type ReactionsPosition =
|
|||||||
'inside'
|
'inside'
|
||||||
| 'outside'
|
| 'outside'
|
||||||
| 'none';
|
| 'none';
|
||||||
|
type QuickReactionPosition =
|
||||||
|
'in-content'
|
||||||
|
| 'in-meta';
|
||||||
|
|
||||||
const NBSP = '\u00A0';
|
const NBSP = '\u00A0';
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
@ -371,7 +374,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const bottomMarkerRef = useRef<HTMLDivElement>(null);
|
const bottomMarkerRef = useRef<HTMLDivElement>(null);
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const contentRef = useRef<HTMLDivElement>(null);
|
const quickReactionRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const messageHeightRef = useRef(0);
|
const messageHeightRef = useRef(0);
|
||||||
|
|
||||||
@ -492,7 +495,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
handleBeforeContextMenu,
|
handleBeforeContextMenu,
|
||||||
chatId,
|
chatId,
|
||||||
isContextMenuShown,
|
isContextMenuShown,
|
||||||
contentRef,
|
quickReactionRef,
|
||||||
isOwn,
|
isOwn,
|
||||||
isInDocumentGroupNotLast,
|
isInDocumentGroupNotLast,
|
||||||
);
|
);
|
||||||
@ -641,6 +644,8 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
reactionsPosition = 'none';
|
reactionsPosition = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const quickReactionPosition: QuickReactionPosition = isCustomShape ? 'in-meta' : 'in-content';
|
||||||
|
|
||||||
useEnsureMessage(
|
useEnsureMessage(
|
||||||
isRepliesChat && message.replyToChatId ? message.replyToChatId : chatId,
|
isRepliesChat && message.replyToChatId ? message.replyToChatId : chatId,
|
||||||
hasReply ? message.replyToMessageId : undefined,
|
hasReply ? message.replyToMessageId : undefined,
|
||||||
@ -788,6 +793,25 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderQuickReactionButton() {
|
||||||
|
if (!defaultReaction) return undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={buildClassName('quick-reaction', isQuickReactionVisible && !activeReactions && 'visible')}
|
||||||
|
onClick={handleSendQuickReaction}
|
||||||
|
ref={quickReactionRef}
|
||||||
|
>
|
||||||
|
<ReactionStaticEmoji
|
||||||
|
reaction={defaultReaction}
|
||||||
|
size={QUICK_REACTION_SIZE}
|
||||||
|
availableReactions={availableReactions}
|
||||||
|
observeIntersection={observeIntersectionForPlaying}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function renderReactionsAndMeta() {
|
function renderReactionsAndMeta() {
|
||||||
const meta = (
|
const meta = (
|
||||||
<MessageMeta
|
<MessageMeta
|
||||||
@ -798,6 +822,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
outgoingStatus={outgoingStatus}
|
outgoingStatus={outgoingStatus}
|
||||||
signature={signature}
|
signature={signature}
|
||||||
withReactionOffset={reactionsPosition === 'inside'}
|
withReactionOffset={reactionsPosition === 'inside'}
|
||||||
|
renderQuickReactionButton={
|
||||||
|
withQuickReactionButton && quickReactionPosition === 'in-meta' ? renderQuickReactionButton : undefined
|
||||||
|
}
|
||||||
availableReactions={availableReactions}
|
availableReactions={availableReactions}
|
||||||
isTranslated={Boolean(requestedTranslationLanguage ? currentTranslatedText : undefined)}
|
isTranslated={Boolean(requestedTranslationLanguage ? currentTranslatedText : undefined)}
|
||||||
onClick={handleMetaClick}
|
onClick={handleMetaClick}
|
||||||
@ -1216,7 +1243,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
className={buildClassName('message-content-wrapper', contentClassName.includes('text') && 'can-select-text')}
|
className={buildClassName('message-content-wrapper', contentClassName.includes('text') && 'can-select-text')}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
ref={contentRef}
|
|
||||||
className={contentClassName}
|
className={contentClassName}
|
||||||
style={style}
|
style={style}
|
||||||
dir="auto"
|
dir="auto"
|
||||||
@ -1256,19 +1282,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
{withAppendix && (
|
{withAppendix && (
|
||||||
<div className="svg-appendix" dangerouslySetInnerHTML={isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN} />
|
<div className="svg-appendix" dangerouslySetInnerHTML={isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN} />
|
||||||
)}
|
)}
|
||||||
{withQuickReactionButton && (
|
{withQuickReactionButton && quickReactionPosition === 'in-content' && renderQuickReactionButton()}
|
||||||
<div
|
|
||||||
className={buildClassName('quick-reaction', isQuickReactionVisible && !activeReactions && 'visible')}
|
|
||||||
onClick={handleSendQuickReaction}
|
|
||||||
>
|
|
||||||
<ReactionStaticEmoji
|
|
||||||
reaction={defaultReaction}
|
|
||||||
size={QUICK_REACTION_SIZE}
|
|
||||||
availableReactions={availableReactions}
|
|
||||||
observeIntersection={observeIntersectionForPlaying}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{message.inlineButtons && (
|
{message.inlineButtons && (
|
||||||
<InlineButtons message={message} onClick={clickBotInlineButton} />
|
<InlineButtons message={message} onClick={clickBotInlineButton} />
|
||||||
|
|||||||
@ -168,8 +168,6 @@
|
|||||||
|
|
||||||
.Message:not(.own) {
|
.Message:not(.own) {
|
||||||
.custom-shape .with-subheader + .MessageMeta {
|
.custom-shape .with-subheader + .MessageMeta {
|
||||||
right: auto;
|
|
||||||
left: 13.25rem;
|
|
||||||
bottom: 0.25rem;
|
bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC, TeactNode } from '../../../lib/teact/teact';
|
||||||
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
||||||
import { getActions } from '../../../global';
|
import { getActions } from '../../../global';
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ type OwnProps = {
|
|||||||
isPinned?: boolean;
|
isPinned?: boolean;
|
||||||
onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
onTranslationClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
onTranslationClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
|
renderQuickReactionButton?: () => TeactNode | undefined;
|
||||||
onOpenThread: NoneToVoidFunction;
|
onOpenThread: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
signature,
|
signature,
|
||||||
withReactionOffset,
|
withReactionOffset,
|
||||||
repliesThreadInfo,
|
repliesThreadInfo,
|
||||||
|
renderQuickReactionButton,
|
||||||
noReplies,
|
noReplies,
|
||||||
isTranslated,
|
isTranslated,
|
||||||
isPinned,
|
isPinned,
|
||||||
@ -140,6 +142,7 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
{outgoingStatus && (
|
{outgoingStatus && (
|
||||||
<MessageOutgoingStatus status={outgoingStatus} />
|
<MessageOutgoingStatus status={outgoingStatus} />
|
||||||
)}
|
)}
|
||||||
|
{renderQuickReactionButton && renderQuickReactionButton()}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export default function useOuterHandlers(
|
|||||||
handleBeforeContextMenu: (e: React.MouseEvent) => void,
|
handleBeforeContextMenu: (e: React.MouseEvent) => void,
|
||||||
chatId: string,
|
chatId: string,
|
||||||
isContextMenuShown: boolean,
|
isContextMenuShown: boolean,
|
||||||
contentRef: RefObject<HTMLDivElement>,
|
quickReactionRef: RefObject<HTMLDivElement>,
|
||||||
isOwn: boolean,
|
isOwn: boolean,
|
||||||
shouldHandleMouseLeave: boolean,
|
shouldHandleMouseLeave: boolean,
|
||||||
) {
|
) {
|
||||||
@ -46,16 +46,18 @@ export default function useOuterHandlers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleMouseMove(e: React.MouseEvent) {
|
function handleMouseMove(e: React.MouseEvent) {
|
||||||
const container = contentRef.current;
|
const quickReactionContainer = quickReactionRef.current;
|
||||||
if (!container) return;
|
if (!quickReactionContainer) return;
|
||||||
|
|
||||||
const { clientX, clientY } = e;
|
const { clientX, clientY } = e;
|
||||||
const {
|
const {
|
||||||
x, width, y, height,
|
x: quickReactionX, width: quickReactionWidth, y: quickReactionY, height: quickReactionHeight,
|
||||||
} = container.getBoundingClientRect();
|
} = quickReactionContainer.getBoundingClientRect();
|
||||||
|
const x = quickReactionX + quickReactionWidth / 2;
|
||||||
|
const y = quickReactionY + quickReactionHeight / 2;
|
||||||
|
|
||||||
const isVisibleX = Math.abs((isOwn ? (clientX - x) : (x + width - clientX))) < QUICK_REACTION_AREA_WIDTH;
|
const isVisibleX = Math.abs(x - clientX) < QUICK_REACTION_AREA_WIDTH;
|
||||||
const isVisibleY = Math.abs(y + height - clientY) < QUICK_REACTION_AREA_HEIGHT;
|
const isVisibleY = Math.abs(y - clientY) < QUICK_REACTION_AREA_HEIGHT;
|
||||||
if (isVisibleX && isVisibleY) {
|
if (isVisibleX && isVisibleY) {
|
||||||
markQuickReactionVisible();
|
markQuickReactionVisible();
|
||||||
} else {
|
} else {
|
||||||
@ -63,7 +65,8 @@ export default function useOuterHandlers(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSendQuickReaction() {
|
function handleSendQuickReaction(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
||||||
|
e.stopPropagation();
|
||||||
sendDefaultReaction({
|
sendDefaultReaction({
|
||||||
chatId,
|
chatId,
|
||||||
messageId,
|
messageId,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user