diff --git a/src/components/middle/MessageList.tsx b/src/components/middle/MessageList.tsx index dc5e06cb1..44316b12b 100644 --- a/src/components/middle/MessageList.tsx +++ b/src/components/middle/MessageList.tsx @@ -50,6 +50,7 @@ import { isChatWithRepliesBot, isChatGroup, isLocalMessageId, + getMessageHtmlId, } from '../../global/helpers'; import { orderBy } from '../../util/iteratees'; import { debounce, onTickEnd } from '../../util/schedulers'; @@ -393,6 +394,9 @@ const MessageList: FC = ({ const container = containerRef.current!; listItemElementsRef.current = Array.from(container.querySelectorAll('.message-list-item')); const lastItemElement = listItemElementsRef.current[listItemElementsRef.current.length - 1]; + const firstUnreadElement = memoFirstUnreadIdRef.current + ? container.querySelector(`#${getMessageHtmlId(memoFirstUnreadIdRef.current)}`) + : undefined; const hasLastMessageChanged = ( messageIds && prevMessageIds && messageIds[messageIds.length - 1] !== prevMessageIds[prevMessageIds.length - 1] @@ -437,14 +441,16 @@ const MessageList: FC = ({ const isAtBottom = isViewportNewest && prevIsViewportNewest && bottomOffset <= BOTTOM_THRESHOLD; const isAlreadyFocusing = messageIds && memoFocusingIdRef.current === messageIds[messageIds.length - 1]; - // Animate incoming message - if (wasMessageAdded && isAtBottom && !isAlreadyFocusing && !isBackgroundModeActive()) { + // Animate incoming message, but if app is in background mode, scroll to the first unread + if (wasMessageAdded && isAtBottom && !isAlreadyFocusing) { // Break out of `forceLayout` requestMeasure(() => { + const shouldScrollToBottom = !isBackgroundModeActive() || !firstUnreadElement; + animateScroll( container, - lastItemElement!, - 'end', + shouldScrollToBottom ? lastItemElement! : firstUnreadElement!, + shouldScrollToBottom ? 'end' : 'start', BOTTOM_FOCUS_MARGIN, undefined, undefined, diff --git a/src/components/middle/hooks/useMessageObservers.ts b/src/components/middle/hooks/useMessageObservers.ts index a0f93563c..35851e722 100644 --- a/src/components/middle/hooks/useMessageObservers.ts +++ b/src/components/middle/hooks/useMessageObservers.ts @@ -6,7 +6,7 @@ import type { PinnedIntersectionChangedCallback } from './usePinnedMessage'; import { IS_ANDROID } from '../../../util/windowEnvironment'; import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; -import useBackgroundMode from '../../../hooks/useBackgroundMode'; +import useBackgroundMode, { isBackgroundModeActive } from '../../../hooks/useBackgroundMode'; import useAppLayout from '../../../hooks/useAppLayout'; const INTERSECTION_THROTTLE_FOR_READING = 150; @@ -33,7 +33,7 @@ export default function useMessageObservers( rootRef: containerRef, throttleMs: INTERSECTION_THROTTLE_FOR_READING, }, (entries) => { - if (type !== 'thread') { + if (type !== 'thread' || isBackgroundModeActive()) { return; }