diff --git a/src/components/middle/ScrollDownButton.scss b/src/components/middle/ScrollDownButton.scss index 3cc4fc9b3..8f22ded08 100644 --- a/src/components/middle/ScrollDownButton.scss +++ b/src/components/middle/ScrollDownButton.scss @@ -7,7 +7,7 @@ opacity: 0; transform: translateY(4.5rem); transition: transform .25s cubic-bezier(0.34, 1.56, 0.64, 1), opacity .2s ease; - z-index: 10; + z-index: var(--z-scroll-down-button); pointer-events: none; body.animation-level-0 & { diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index 998f41dc3..7d7242291 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -106,20 +106,22 @@ type MessagePositionProperties = { isLastInList: boolean; }; -type OwnProps = { - message: ApiMessage; - observeIntersectionForBottom: ObserveFn; - observeIntersectionForMedia: ObserveFn; - observeIntersectionForAnimatedStickers: ObserveFn; - album?: IAlbum; - noAvatars?: boolean; - withAvatar?: boolean; - withSenderName?: boolean; - threadId: number; - messageListType: MessageListType; - noComments: boolean; - appearanceOrder: number; -} & MessagePositionProperties; +type OwnProps = + { + message: ApiMessage; + observeIntersectionForBottom: ObserveFn; + observeIntersectionForMedia: ObserveFn; + observeIntersectionForAnimatedStickers: ObserveFn; + album?: IAlbum; + noAvatars?: boolean; + withAvatar?: boolean; + withSenderName?: boolean; + threadId: number; + messageListType: MessageListType; + noComments: boolean; + appearanceOrder: number; + } + & MessagePositionProperties; type StateProps = { theme: ISettings['theme']; @@ -137,6 +139,7 @@ type StateProps = { isFocused?: boolean; focusDirection?: FocusDirection; noFocusHighlight?: boolean; + isResizingContainer?: boolean; isForwarding?: boolean; isChatWithSelf?: boolean; isChannel?: boolean; @@ -203,6 +206,7 @@ const Message: FC = ({ isFocused, focusDirection, noFocusHighlight, + isResizingContainer, isForwarding, isChatWithSelf, isChannel, @@ -338,7 +342,7 @@ const Message: FC = ({ const withAppendix = contentClassName.includes('has-appendix'); useEnsureMessage(chatId, hasReply ? message.replyToMessageId : undefined, replyMessage, message.id); - useFocusMessage(ref, chatId, isFocused, focusDirection, noFocusHighlight); + useFocusMessage(ref, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer); useLayoutEffect(() => { if (!appendixRef.current) { return; @@ -454,7 +458,9 @@ const Message: FC = ({ if (IS_ANDROID) { if (windowSize.getIsKeyboardVisible()) { - setTimeout(() => { onContextMenu(e); }, ANDROID_KEYBOARD_HIDE_DELAY_MS); + setTimeout(() => { + onContextMenu(e); + }, ANDROID_KEYBOARD_HIDE_DELAY_MS); } else { onContextMenu(e); } @@ -941,7 +947,9 @@ export default memo(withGlobal( : selectIsMessageFocused(global, message) ); - const { direction: focusDirection, noHighlight: noFocusHighlight } = (isFocused && focusedMessage) || {}; + const { + direction: focusDirection, noHighlight: noFocusHighlight, isResizingContainer, + } = (isFocused && focusedMessage) || {}; const isForwarding = forwardMessages.messageIds && forwardMessages.messageIds.includes(id); @@ -987,7 +995,7 @@ export default memo(withGlobal( shouldLoopStickers: selectShouldLoopStickers(global), ...(isOutgoing && { outgoingStatus: selectOutgoingStatus(global, message, messageListType === 'scheduled') }), ...(typeof uploadProgress === 'number' && { uploadProgress }), - ...(isFocused && { focusDirection, noFocusHighlight }), + ...(isFocused && { focusDirection, noFocusHighlight, isResizingContainer }), }; }, (setGlobal, actions): DispatchProps => pick(actions, [ diff --git a/src/components/middle/message/hooks/useFocusMessage.ts b/src/components/middle/message/hooks/useFocusMessage.ts index 348bc7b10..8ce337872 100644 --- a/src/components/middle/message/hooks/useFocusMessage.ts +++ b/src/components/middle/message/hooks/useFocusMessage.ts @@ -13,6 +13,7 @@ export default function useFocusMessage( isFocused?: boolean, focusDirection?: FocusDirection, noFocusHighlight?: boolean, + isResizingContainer?: boolean, ) { useLayoutEffect(() => { if (isFocused && elementRef.current) { @@ -26,7 +27,9 @@ export default function useFocusMessage( FOCUS_MARGIN, focusDirection !== undefined ? RELOCATED_FOCUS_OFFSET : undefined, focusDirection, + undefined, + isResizingContainer, ); } - }, [elementRef, chatId, isFocused, focusDirection, noFocusHighlight]); + }, [elementRef, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer]); } diff --git a/src/global/types.ts b/src/global/types.ts index 84c11bb4c..95acf0691 100644 --- a/src/global/types.ts +++ b/src/global/types.ts @@ -170,6 +170,7 @@ export type GlobalState = { messageId?: number; direction?: FocusDirection; noHighlight?: boolean; + isResizingContainer?: boolean; }; selectedMessages?: { diff --git a/src/modules/actions/apiUpdaters/messages.ts b/src/modules/actions/apiUpdaters/messages.ts index c31e3653a..6b076f486 100644 --- a/src/modules/actions/apiUpdaters/messages.ts +++ b/src/modules/actions/apiUpdaters/messages.ts @@ -71,6 +71,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => { threadId: currentMessageList.threadId, messageId: message.id, noHighlight: true, + isResizingContainer: true, }); } } diff --git a/src/modules/actions/ui/messages.ts b/src/modules/actions/ui/messages.ts index fa3f10954..bbdb20c59 100644 --- a/src/modules/actions/ui/messages.ts +++ b/src/modules/actions/ui/messages.ts @@ -276,7 +276,7 @@ addReducer('focusNextReply', (global, actions) => { addReducer('focusMessage', (global, actions, payload) => { const { chatId, threadId = MAIN_THREAD_ID, messageListType = 'thread', noHighlight, groupedId, groupedChatId, - replyMessageId, + replyMessageId, isResizingContainer, } = payload!; let { messageId } = payload!; @@ -306,7 +306,7 @@ addReducer('focusMessage', (global, actions, payload) => { setGlobal(newGlobal); }, noHighlight ? FOCUS_NO_HIGHLIGHT_DURATION : FOCUS_DURATION); - global = updateFocusedMessage(global, chatId, messageId, noHighlight); + global = updateFocusedMessage(global, chatId, messageId, noHighlight, isResizingContainer); global = updateFocusDirection(global, undefined); if (replyMessageId) { diff --git a/src/modules/reducers/messages.ts b/src/modules/reducers/messages.ts index 2193f9e55..109ce1249 100644 --- a/src/modules/reducers/messages.ts +++ b/src/modules/reducers/messages.ts @@ -431,7 +431,7 @@ function updateScheduledMessages( } export function updateFocusedMessage( - global: GlobalState, chatId?: number, messageId?: number, noHighlight = false, + global: GlobalState, chatId?: number, messageId?: number, noHighlight = false, isResizingContainer = false, ): GlobalState { return { ...global, @@ -440,6 +440,7 @@ export function updateFocusedMessage( chatId, messageId, noHighlight, + isResizingContainer, }, }; } diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index af15af65f..844067a35 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -188,6 +188,7 @@ $color-user-8: #faa774; --z-menu-backdrop: 20; --z-message-highlighted: 14; --z-message-context-menu: 13; + --z-scroll-down-button: 12; --z-mobile-search: 12; --z-middle-header: 11; --z-middle-footer: 11; diff --git a/src/util/fastSmoothScroll.ts b/src/util/fastSmoothScroll.ts index 94663ea2e..4106ccab5 100644 --- a/src/util/fastSmoothScroll.ts +++ b/src/util/fastSmoothScroll.ts @@ -20,7 +20,7 @@ export default function fastSmoothScroll( maxDistance = FAST_SMOOTH_MAX_DISTANCE, forceDirection?: FocusDirection, forceDuration?: number, - forceCurrentContainerHeight?: boolean, + forceNormalContainerHeight?: boolean, ) { const scrollFrom = calculateScrollFrom(container, element, maxDistance, forceDirection); @@ -33,7 +33,7 @@ export default function fastSmoothScroll( forceDuration = 0; } - scrollWithJs(container, element, scrollFrom, position, margin, forceDuration, forceCurrentContainerHeight); + scrollWithJs(container, element, scrollFrom, position, margin, forceDuration, forceNormalContainerHeight); } export function isAnimatingScroll() { @@ -73,11 +73,11 @@ function scrollWithJs( position: ScrollLogicalPosition | 'centerOrTop', margin = 0, forceDuration?: number, - forceCurrentContainerHeight?: boolean, + forceNormalContainerHeight?: boolean, ) { const { offsetTop: elementTop, offsetHeight: elementHeight } = element; const { scrollTop: currentScrollTop, offsetHeight: containerHeight, scrollHeight } = container; - const targetContainerHeight = !forceCurrentContainerHeight && container.dataset.normalHeight + const targetContainerHeight = forceNormalContainerHeight && container.dataset.normalHeight ? Number(container.dataset.normalHeight) : containerHeight;