Skip to content

Commit

Permalink
Maybe fix scroll-to-end on conversation screens (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
duogenesis authored May 7, 2024
1 parent 4eb22e4 commit 7e77b31
Showing 1 changed file with 39 additions and 28 deletions.
67 changes: 39 additions & 28 deletions components/conversation-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { api } from '../api/api';
import { TopNavBarButton } from './top-nav-bar-button';
import { RotateCcw, Flag, X } from "react-native-feather";
import { setSkipped } from '../hide-and-block/hide-and-block';
import { isMobile } from '../util/util';
import { delay, isMobile } from '../util/util';
import { ReportModalInitialData } from './report-modal';
import { listen, notify } from '../events/events';

Expand Down Expand Up @@ -271,13 +271,6 @@ const ConversationScreen = ({navigation, route}) => {
return mamId;
})();

const scrollToEnd = useCallback(() => {
if (listRef.current && !hasScrolled.current) {
listRef.current.scrollToEnd({animated: true});
hasScrolled.current = true;
}
}, [listRef.current]);

const onPressSend = useCallback(async (text: string): Promise<MessageStatus> => {
const isFirstMessage = messages === null || messages.length === 0;

Expand Down Expand Up @@ -352,33 +345,20 @@ const ConversationScreen = ({navigation, route}) => {
}, []);

const isCloseToTop = ({contentOffset}) => contentOffset.y === 0;
const isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}) => {
const paddingToBottom = 20;
return layoutMeasurement.height + contentOffset.y >=
contentSize.height - paddingToBottom;
};

const isAtBottom = ({layoutMeasurement, contentOffset, contentSize}) =>
layoutMeasurement.height + contentOffset.y >= contentSize.height;

const onScroll = useCallback(({nativeEvent}) => {
if (isCloseToTop(nativeEvent) && hasFinishedFirstLoad.current) {
maybeLoadNextPage();
}
if (isCloseToBottom(nativeEvent)) {

if (messages !== null && isAtBottom(nativeEvent)) {
hasFinishedFirstLoad.current = true;
}
}, [maybeLoadNextPage]);

useEffect(() => {
maybeLoadNextPage();

return onReceiveMessage(_onReceiveMessage, personId, isFocused);
}, [
maybeLoadNextPage,
onReceiveMessage,
_onReceiveMessage,
personId,
isFocused,
]);

const toggleMenu = useCallback(() => {
setShowMenu(x => !x);
}, []);
Expand All @@ -397,6 +377,39 @@ const ConversationScreen = ({navigation, route}) => {
});
}, [navigation, personId]);

// Fetch the first page of messages when the conversation first loads
useEffect(() => {
fetchConversation(personId, lastMamId)
.then((fetchedMessages) => {
if (fetchedMessages === 'timeout') {
setMessageFetchTimeout(true);
} else {
setMessages(fetchedMessages ?? []);
}
});
}, []);

// Scroll to end when last message changes
useEffect(() => {
(async () => {
await delay(500);
if (listRef.current) {
listRef.current.scrollToEnd({animated: true});
}
})();
}, [lastMessage?.id]);


// Listen for new messages
useEffect(() => {
return onReceiveMessage(_onReceiveMessage, personId, isFocused);
}, [
onReceiveMessage,
_onReceiveMessage,
personId,
isFocused,
]);

if (Platform.OS === 'web') {
useEffect(() => {
const handleFocus = () => {
Expand Down Expand Up @@ -489,8 +502,6 @@ const ConversationScreen = ({navigation, route}) => {
{messages !== null &&
<ScrollView
ref={listRef}
onLayout={scrollToEnd}
onContentSizeChange={scrollToEnd}
onScroll={onScroll}
scrollEventThrottle={0}
maintainVisibleContentPosition={{
Expand Down

0 comments on commit 7e77b31

Please sign in to comment.