Reactions: Raise service messages after adding a reaction (#5431)
This commit is contained in:
parent
a7ebaf3aa8
commit
d0633cb419
@ -40,6 +40,7 @@ import useFlag from '../../hooks/useFlag';
|
|||||||
import { useIsIntersecting, useOnIntersect } from '../../hooks/useIntersectionObserver';
|
import { useIsIntersecting, useOnIntersect } from '../../hooks/useIntersectionObserver';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
import useOldLang from '../../hooks/useOldLang';
|
||||||
|
import useMessageResizeObserver from '../../hooks/useResizeMessageObserver';
|
||||||
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
|
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
|
||||||
import useFocusMessage from './message/hooks/useFocusMessage';
|
import useFocusMessage from './message/hooks/useFocusMessage';
|
||||||
|
|
||||||
@ -171,6 +172,8 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const withServiceReactions = Boolean(message.areReactionsPossible && message?.reactions);
|
const withServiceReactions = Boolean(message.areReactionsPossible && message?.reactions);
|
||||||
|
|
||||||
|
useMessageResizeObserver(ref, isLastInList);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (noAppearanceAnimation) {
|
if (noAppearanceAnimation) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
import React, {
|
import React, {
|
||||||
beginHeavyAnimation,
|
|
||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
@ -111,17 +110,12 @@ import {
|
|||||||
selectUploadProgress,
|
selectUploadProgress,
|
||||||
selectUser,
|
selectUser,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import { isAnimatingScroll } from '../../../util/animateScroll';
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { isElementInViewport } from '../../../util/isElementInViewport';
|
import { isElementInViewport } from '../../../util/isElementInViewport';
|
||||||
import { getMessageKey } from '../../../util/keys/messageKey';
|
import { getMessageKey } from '../../../util/keys/messageKey';
|
||||||
import stopEvent from '../../../util/stopEvent';
|
import stopEvent from '../../../util/stopEvent';
|
||||||
import { IS_ANDROID, IS_ELECTRON, IS_TRANSLATION_SUPPORTED } from '../../../util/windowEnvironment';
|
import { IS_ANDROID, IS_ELECTRON, IS_TRANSLATION_SUPPORTED } from '../../../util/windowEnvironment';
|
||||||
import {
|
import { calculateDimensionsForMessageMedia, getStickerDimensions, REM } from '../../common/helpers/mediaDimensions';
|
||||||
calculateDimensionsForMessageMedia,
|
|
||||||
getStickerDimensions,
|
|
||||||
REM,
|
|
||||||
} from '../../common/helpers/mediaDimensions';
|
|
||||||
import { getPeerColorClass } from '../../common/helpers/peerColor';
|
import { getPeerColorClass } from '../../common/helpers/peerColor';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import { getCustomEmojiSize } from '../composer/helpers/customEmoji';
|
import { getCustomEmojiSize } from '../composer/helpers/customEmoji';
|
||||||
@ -139,10 +133,9 @@ import { useOnIntersect } from '../../../hooks/useIntersectionObserver';
|
|||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
|
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
|
||||||
import useResizeObserver from '../../../hooks/useResizeObserver';
|
import useMessageResizeObserver from '../../../hooks/useResizeMessageObserver';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import useTextLanguage from '../../../hooks/useTextLanguage';
|
import useTextLanguage from '../../../hooks/useTextLanguage';
|
||||||
import useThrottledCallback from '../../../hooks/useThrottledCallback';
|
|
||||||
import useDetectChatLanguage from './hooks/useDetectChatLanguage';
|
import useDetectChatLanguage from './hooks/useDetectChatLanguage';
|
||||||
import useFocusMessage from './hooks/useFocusMessage';
|
import useFocusMessage from './hooks/useFocusMessage';
|
||||||
import useInnerHandlers from './hooks/useInnerHandlers';
|
import useInnerHandlers from './hooks/useInnerHandlers';
|
||||||
@ -322,9 +315,6 @@ const APPEARANCE_DELAY = 10;
|
|||||||
const NO_MEDIA_CORNERS_THRESHOLD = 18;
|
const NO_MEDIA_CORNERS_THRESHOLD = 18;
|
||||||
const QUICK_REACTION_SIZE = 1.75 * REM;
|
const QUICK_REACTION_SIZE = 1.75 * REM;
|
||||||
const EXTRA_SPACE_FOR_REACTIONS = 2.25 * REM;
|
const EXTRA_SPACE_FOR_REACTIONS = 2.25 * REM;
|
||||||
const BOTTOM_FOCUS_SCROLL_THRESHOLD = 5;
|
|
||||||
const THROTTLE_MS = 300;
|
|
||||||
const RESIZE_ANIMATION_DURATION = 400;
|
|
||||||
|
|
||||||
const Message: FC<OwnProps & StateProps> = ({
|
const Message: FC<OwnProps & StateProps> = ({
|
||||||
message,
|
message,
|
||||||
@ -442,8 +432,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const quickReactionRef = useRef<HTMLDivElement>(null);
|
const quickReactionRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const messageHeightRef = useRef(0);
|
|
||||||
|
|
||||||
const lang = useOldLang();
|
const lang = useOldLang();
|
||||||
|
|
||||||
const [isTranscriptionHidden, setTranscriptionHidden] = useState(false);
|
const [isTranscriptionHidden, setTranscriptionHidden] = useState(false);
|
||||||
@ -850,34 +838,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
|| ((asForwarded || isChatWithSelf) && forwardInfo?.postAuthorTitle)
|
|| ((asForwarded || isChatWithSelf) && forwardInfo?.postAuthorTitle)
|
||||||
|| undefined;
|
|| undefined;
|
||||||
|
|
||||||
const shouldFocusOnResize = isLastInList;
|
useMessageResizeObserver(ref, isLastInList);
|
||||||
|
|
||||||
const handleResize = useLastCallback((entry: ResizeObserverEntry) => {
|
|
||||||
const lastHeight = messageHeightRef.current;
|
|
||||||
|
|
||||||
const newHeight = entry.contentRect.height;
|
|
||||||
messageHeightRef.current = newHeight;
|
|
||||||
|
|
||||||
if (isAnimatingScroll() || !lastHeight || newHeight <= lastHeight) return;
|
|
||||||
|
|
||||||
const container = entry.target.closest<HTMLDivElement>('.MessageList');
|
|
||||||
if (!container) return;
|
|
||||||
|
|
||||||
beginHeavyAnimation(RESIZE_ANIMATION_DURATION);
|
|
||||||
|
|
||||||
const resizeDiff = newHeight - lastHeight;
|
|
||||||
const { offsetHeight, scrollHeight, scrollTop } = container;
|
|
||||||
const currentScrollBottom = Math.round(scrollHeight - scrollTop - offsetHeight);
|
|
||||||
const previousScrollBottom = currentScrollBottom - resizeDiff;
|
|
||||||
|
|
||||||
if (previousScrollBottom <= BOTTOM_FOCUS_SCROLL_THRESHOLD) {
|
|
||||||
focusLastMessage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const throttledResize = useThrottledCallback(handleResize, [handleResize], THROTTLE_MS, false);
|
|
||||||
|
|
||||||
useResizeObserver(ref, throttledResize, !shouldFocusOnResize);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const bottomMarker = bottomMarkerRef.current;
|
const bottomMarker = bottomMarkerRef.current;
|
||||||
|
|||||||
52
src/hooks/useResizeMessageObserver.ts
Normal file
52
src/hooks/useResizeMessageObserver.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { beginHeavyAnimation, useRef } from '../lib/teact/teact';
|
||||||
|
import { getActions } from '../global';
|
||||||
|
|
||||||
|
import { isAnimatingScroll } from '../util/animateScroll';
|
||||||
|
import useLastCallback from './useLastCallback';
|
||||||
|
import useResizeObserver from './useResizeObserver';
|
||||||
|
import useThrottledCallback from './useThrottledCallback';
|
||||||
|
|
||||||
|
const BOTTOM_FOCUS_SCROLL_THRESHOLD = 5;
|
||||||
|
const THROTTLE_MS = 300;
|
||||||
|
const RESIZE_ANIMATION_DURATION = 400;
|
||||||
|
|
||||||
|
function useMessageResizeObserver(
|
||||||
|
ref: React.RefObject<HTMLElement> | undefined,
|
||||||
|
shouldFocusOnResize = false,
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
focusLastMessage,
|
||||||
|
} = getActions();
|
||||||
|
const messageHeightRef = useRef(0);
|
||||||
|
|
||||||
|
const handleResize = useLastCallback(
|
||||||
|
(entry) => {
|
||||||
|
const lastHeight = messageHeightRef.current;
|
||||||
|
|
||||||
|
const newHeight = entry.contentRect.height;
|
||||||
|
messageHeightRef.current = newHeight;
|
||||||
|
|
||||||
|
if (isAnimatingScroll() || !lastHeight || newHeight <= lastHeight) return;
|
||||||
|
|
||||||
|
const container = entry.target.closest('.MessageList');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
beginHeavyAnimation(RESIZE_ANIMATION_DURATION);
|
||||||
|
|
||||||
|
const resizeDiff = newHeight - lastHeight;
|
||||||
|
const { offsetHeight, scrollHeight, scrollTop } = container;
|
||||||
|
const currentScrollBottom = Math.round(scrollHeight - scrollTop - offsetHeight);
|
||||||
|
const previousScrollBottom = currentScrollBottom - resizeDiff;
|
||||||
|
|
||||||
|
if (previousScrollBottom <= BOTTOM_FOCUS_SCROLL_THRESHOLD) {
|
||||||
|
focusLastMessage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const throttledResize = useThrottledCallback(handleResize, [handleResize], THROTTLE_MS, false);
|
||||||
|
|
||||||
|
useResizeObserver(ref, throttledResize, !shouldFocusOnResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useMessageResizeObserver;
|
||||||
Loading…
x
Reference in New Issue
Block a user