Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions src/MessagesContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import {
View,
LayoutChangeEvent,
Expand Down Expand Up @@ -56,6 +56,7 @@

const daysPositions = useSharedValue<DaysPositions>({})
const listHeight = useSharedValue(0)
const contentHeight = useSharedValue(0)
const scrolledY = useSharedValue(0)

const renderTypingIndicator = useCallback(() => {
Expand Down Expand Up @@ -125,6 +126,7 @@
(!isInverted && lastScrolledY.value < contentOffsetY)

lastScrolledY.value = contentOffsetY
contentHeight.value = contentSizeHeight

if (isInverted)
if (contentOffsetY > scrollToBottomOffset!)
Expand All @@ -138,7 +140,39 @@
changeScrollToBottomVisibility(false)
else
changeScrollToBottomVisibility(false)
}, [isInverted, scrollToBottomOffset, changeScrollToBottomVisibility, isScrollingDown, lastScrolledY, listPropsOnScrollProp])
}, [isInverted, scrollToBottomOffset, changeScrollToBottomVisibility, isScrollingDown, lastScrolledY, contentHeight, listPropsOnScrollProp])

// Auto-scroll to the newest message when it arrives in a non-inverted list.
// Inverted lists keep the newest message visible on their own, but a
// non-inverted list appends new messages off-screen at the end (#2612).
// Only scroll when the user is already near the bottom so we don't yank
// them away while they are reading earlier messages.
const latestMessageId = !isInverted && messages.length > 0
? messages[messages.length - 1]._id
: undefined
const previousLatestMessageId = useRef(latestMessageId)
useEffect(() => {
if (isInverted) {
previousLatestMessageId.current = latestMessageId
return
}

if (
latestMessageId != null &&
latestMessageId !== previousLatestMessageId.current &&
// skip the very first render; initial positioning is handled on layout
previousLatestMessageId.current !== undefined
) {
const isNearBottom =
contentHeight.value === 0 ||
lastScrolledY.value + listHeight.value >= contentHeight.value - scrollToBottomOffset!

if (isNearBottom)
doScrollToBottom(true)
}

previousLatestMessageId.current = latestMessageId
}, [latestMessageId, isInverted, doScrollToBottom, contentHeight, lastScrolledY, listHeight, scrollToBottomOffset])

const restProps = useMemo(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down Expand Up @@ -348,7 +382,7 @@
)
}, [daysPositions, isInverted, isDayAnimationEnabled])

const scrollHandler = useAnimatedScrollHandler({

Check warning on line 385 in src/MessagesContainer/index.tsx

View workflow job for this annotation

GitHub Actions / checks (24)

React Hook useAnimatedScrollHandler received a function whose dependencies are unknown. Pass an inline function instead

Check warning on line 385 in src/MessagesContainer/index.tsx

View workflow job for this annotation

GitHub Actions / checks (22)

React Hook useAnimatedScrollHandler received a function whose dependencies are unknown. Pass an inline function instead
onScroll: event => {
scrolledY.value = event.contentOffset.y

Expand Down
Loading