From ae7626ce6ed08059c161345046b6037313fc2505 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 6 May 2024 08:48:08 -0700 Subject: [PATCH] =?UTF-8?q?[=F0=9F=90=B4]=20Finalize=20web=20message=20scr?= =?UTF-8?q?een=20(#3868)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add `onStartReached` to web list * fix `rootMargin` * Add `contain`, handle scroll events * improve types, fix typo * simplify * adjust `scrollToTop` and `scrollToOffset` to support `contain`, add `scrollToEnd` * rename `handleWindowScroll` to `handleScroll` * support basic `maintainVisibleContentPosition` * rename `contain` to `containWeb` * remove unnecessary `flex: 1` * add missing props * add root prop to `Visibility` * add root prop to `Visibility` * revert adding `maintainVisibleContentPosition` * remove unnecessary wrapper * add style * oops * maintain position for web * always apply `flex: 1` to styles when contained * add a contained list to storybook * make `onScroll` a worklet in storybook * revert test code * remove unnecessary `flex: 1` --- .../Messages/Conversation/MessagesList.tsx | 81 +++++++++++-------- src/view/com/util/List.web.tsx | 1 + 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index e00cf11cd8..7068097fcf 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -94,6 +94,9 @@ export function MessagesList() { // the bottom. const isAtBottom = useSharedValue(true) + // This will be used on web to assist in determing if we need to maintain the content offset + const isAtTop = useSharedValue(true) + // Used to keep track of the current content height. We'll need this in `onScroll` so we know when to start allowing // onStartReached to fire. const contentHeight = useSharedValue(0) @@ -116,6 +119,15 @@ export function MessagesList() { // we will not scroll whenever new items get prepended to the top. const onContentSizeChange = useCallback( (_: number, height: number) => { + // Because web does not have `maintainVisibleContentPosition` support, we will need to manually scroll to the + // previous offset whenever we add new content to the previous offset whenever we add new content to the list. + if (isWeb && isAtTop.value && hasInitiallyScrolled) { + flatListRef.current?.scrollToOffset({ + animated: false, + offset: height - contentHeight.value, + }) + } + contentHeight.value = height // This number _must_ be the height of the MaybeLoader component @@ -133,6 +145,7 @@ export function MessagesList() { contentHeight, hasInitiallyScrolled, isAtBottom.value, + isAtTop.value, isMomentumScrolling, ], ) @@ -164,6 +177,7 @@ export function MessagesList() { // Most apps have a little bit of space the user can scroll past while still automatically scrolling ot the bottom // when a new message is added, hence the 100 pixel offset isAtBottom.value = e.contentSize.height - 100 < bottomOffset + isAtTop.value = e.contentOffset.y <= 1 // This number _must_ be the height of the MaybeLoader component. // We don't check for zero, because the `MaybeLoader` component is always present, even when not visible, which @@ -172,7 +186,7 @@ export function MessagesList() { runOnJS(setHasInitiallyScrolled)(true) } }, - [contentHeight.value, hasInitiallyScrolled, isAtBottom], + [contentHeight.value, hasInitiallyScrolled, isAtBottom, isAtTop], ) const onMomentumEnd = React.useCallback(() => { @@ -211,40 +225,37 @@ export function MessagesList() { keyboardVerticalOffset={isIOS ? topInset : 0} behavior="padding" contentContainerStyle={a.flex_1}> - {/* This view keeps the scroll bar and content within the CenterView on web, otherwise the entire window would scroll */} - {/* @ts-expect-error web only */} - - {/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */} - - - } - /> - - + {/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */} + + + } + /> + ) diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index e5c427f136..73000d95f1 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -143,6 +143,7 @@ function ListImpl( scrollToTop() { getScrollableNode()?.scrollTo({top: 0}) }, + scrollToOffset({ animated, offset,