Skip to content
Merged

Beta #28

Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@qte/react-native-firebase-chat",
"private": false,
"version": "0.5.9",
"version": "0.5.10",
"description": "test",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
102 changes: 97 additions & 5 deletions src/CuteChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import {
arrayUnion,
collection,
doc,
endAt,
FirebaseFirestoreTypes,
getDoc,
getFirestore,
limit,
onSnapshot,
Expand All @@ -13,6 +15,7 @@ import {
import React, {
useCallback,
useEffect,
useImperativeHandle,
useLayoutEffect,
useMemo,
useRef,
Expand All @@ -25,6 +28,7 @@ import {
StyleProp,
ViewStyle,
ScrollViewProps,
FlatListProps,
} from 'react-native';
import type { IMessage } from 'react-native-gifted-chat';
import { GiftedChat, GiftedChatProps } from 'react-native-gifted-chat';
Expand All @@ -42,6 +46,7 @@ interface CustomCuteChatProps {
newMessagesBannerComponent?: () => React.ReactNode;
newMessagesBannerStyles?: StyleProp<ViewStyle>;
maintainVisibleContentPosition?: ScrollViewProps['maintainVisibleContentPosition'];
getItemLayout?: FlatListProps<IMessage>['getItemLayout'];
}

interface User {
Expand All @@ -54,9 +59,16 @@ interface User {
type CuteChatProps = Omit<GiftedChatProps, 'messages' | 'user' | 'onSend'> &
CustomCuteChatProps;

type CuteChatRef = {
scrollToMessage: (messageId: string) => Promise<void>;
};

const messageBatch = 20;

export function CuteChat(props: CuteChatProps) {
export const CuteChat = React.forwardRef<CuteChatRef, CuteChatProps>(function (
props,
ref
) {
const { chatId, user, setIsLoading } = props;

const [closeToTop, setCloseToTop] = useState(true);
Expand Down Expand Up @@ -287,6 +299,75 @@ export function CuteChat(props: CuteChatProps) {
}
}, [chatId, lastMessageDoc, setIsLoadingBool, initializing, loading]);

const scrollToMessage = useCallback(
async (messageId: string) => {
console.log('Scrolling to message:', messageId);

const messageIndex = messages.findIndex(
(message) => message._id === messageId
);

if (messageIndex !== -1) {
console.log('Message found at index:', messageIndex);
chatListRef.current?.scrollToIndex({
index: messageIndex,
animated: true,
});

return;
}

console.warn(
`Message with ID ${messageId} not found in messages. Fetching message`
);

const messageRef = doc(
getFirestore(),
`chats/${chatId}/messages/${messageId}`
);

const messageSnapshot = await getDoc(messageRef);
const messageData = messageSnapshot.data();

const scrollToMessageQuery = query(
collection(getFirestore(), `chats/${chatId}/messages`),
orderBy('createdAt', 'desc'),
startAfter(lastMessageDoc),
endAt(messageData?.createdAt)
);

onSnapshot(scrollToMessageQuery, async (snapshot) => {
if (!snapshot.empty) {
const snapshotChanges = await prepareSnapshot(snapshot, chatId);
let newMessageIndex = -1;
setMessages((old) => {
const newMessages = appendSnapshot(old, snapshotChanges);
newMessageIndex = newMessages.findIndex(
(message) => message._id === messageId
);
console.log('Message index after fetching:', newMessageIndex);
return newMessages;
});

if (newMessageIndex !== -1) {
console.log('New message found at index:', newMessageIndex);
chatListRef.current?.scrollToIndex({
index: newMessageIndex,
animated: true,
});
} else {
console.warn(
`New message with ID ${messageId} not found in messages after fetching`
);
}
} else {
console.warn('No messages found after fetching');
}
});
},
[lastMessageDoc, messages, chatId]
);

// Keep `lastMessageDoc` up to date based on `messages`
useEffect(() => {
if (!messages.length) {
Expand Down Expand Up @@ -319,9 +400,11 @@ export function CuteChat(props: CuteChatProps) {
}
}, [messages, chatId]);

console.log('Amount of msgs:', messages.length);

console.log('Close to top:', closeToTop);
useImperativeHandle(ref, () => {
return {
scrollToMessage,
};
});

return (
<GiftedChat
Expand Down Expand Up @@ -355,7 +438,16 @@ export function CuteChat(props: CuteChatProps) {
},
scrollEventThrottle: 500,
maintainVisibleContentPosition: props.maintainVisibleContentPosition,
getItemLayout: props.getItemLayout,
onScrollToIndexFailed: (info: { index: number }) => {
setTimeout(() => {
chatListRef.current?.scrollToIndex({
index: info.index,
animated: true,
});
}, 100); // Delay to allow the list to render
},
}}
/>
);
}
});