|
@@ -10,8 +10,9 @@ import {
|
|
|
Alert,
|
|
|
ScrollView,
|
|
|
Linking,
|
|
|
- Platform,
|
|
|
- ActivityIndicator
|
|
|
+ ActivityIndicator,
|
|
|
+ AppState,
|
|
|
+ AppStateStatus
|
|
|
} from 'react-native';
|
|
|
import {
|
|
|
GiftedChat,
|
|
@@ -75,7 +76,11 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
const [messages, setMessages] = useState<CustomMessage[] | null>();
|
|
|
const navigation = useNavigation();
|
|
|
const [prevThenMessageId, setPrevThenMessageId] = useState<number>(-1);
|
|
|
- const { data: chatData } = usePostGetChatWithQuery(token, id, 50, prevThenMessageId, true); // to do cache
|
|
|
+ const {
|
|
|
+ data: chatData,
|
|
|
+ refetch,
|
|
|
+ isFetching
|
|
|
+ } = usePostGetChatWithQuery(token, id, 50, prevThenMessageId, true);
|
|
|
const { mutateAsync: sendMessage } = usePostSendMessageMutation();
|
|
|
|
|
|
const swipeableRowRef = useRef<Swipeable | null>(null);
|
|
@@ -117,6 +122,8 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
const [isLoadingEarlier, setIsLoadingEarlier] = useState(false);
|
|
|
const [hasMoreMessages, setHasMoreMessages] = useState(true);
|
|
|
|
|
|
+ const appState = useRef(AppState.currentState);
|
|
|
+
|
|
|
const socket = useRef<WebSocket | null>(null);
|
|
|
|
|
|
const closeModal = () => {
|
|
@@ -161,6 +168,35 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
};
|
|
|
}, [token]);
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
+ const handleAppStateChange = async (nextAppState: AppStateStatus) => {
|
|
|
+ if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
|
|
|
+ if (!socket.current || socket.current.readyState === WebSocket.CLOSED) {
|
|
|
+ socket.current = new WebSocket(WEBSOCKET_URL);
|
|
|
+ socket.current.onopen = () => {
|
|
|
+ socket.current?.send(JSON.stringify({ token }));
|
|
|
+ };
|
|
|
+ socket.current.onmessage = (event) => {
|
|
|
+ const data = JSON.parse(event.data);
|
|
|
+ handleWebSocketMessage(data);
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ await dismissChatNotifications(id, isSubscribed, setModalInfo, navigation);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const subscription = AppState.addEventListener('change', handleAppStateChange);
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ subscription.remove();
|
|
|
+ if (socket.current) {
|
|
|
+ socket.current.close();
|
|
|
+ socket.current = null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }, [token]);
|
|
|
+
|
|
|
const handleWebSocketMessage = (data: any) => {
|
|
|
switch (data.action) {
|
|
|
case 'new_message':
|
|
@@ -282,6 +318,22 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
const pingInterval = setInterval(() => {
|
|
|
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
|
|
|
socket.current.send(JSON.stringify({ action: 'ping', conversation_with: id }));
|
|
|
+ } else {
|
|
|
+ socket.current = new WebSocket(WEBSOCKET_URL);
|
|
|
+ socket.current.onopen = () => {
|
|
|
+ socket.current?.send(JSON.stringify({ token }));
|
|
|
+ };
|
|
|
+ socket.current.onmessage = (event) => {
|
|
|
+ const data = JSON.parse(event.data);
|
|
|
+ handleWebSocketMessage(data);
|
|
|
+ };
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ if (socket.current) {
|
|
|
+ socket.current.close();
|
|
|
+ socket.current = null;
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
}, 50000);
|
|
|
|
|
@@ -373,12 +425,18 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
};
|
|
|
};
|
|
|
|
|
|
+ useFocusEffect(
|
|
|
+ useCallback(() => {
|
|
|
+ refetch();
|
|
|
+ }, [])
|
|
|
+ );
|
|
|
+
|
|
|
useFocusEffect(
|
|
|
useCallback(() => {
|
|
|
if (chatData?.messages) {
|
|
|
const mappedMessages = chatData.messages.map(mapApiMessageToGiftedMessage);
|
|
|
|
|
|
- if (unreadMessageIndex === null && Platform.OS === 'ios') {
|
|
|
+ if (unreadMessageIndex === null && !isFetching) {
|
|
|
const firstUnreadIndex = mappedMessages.findLastIndex(
|
|
|
(msg) => !msg.received && !msg?.deleted && msg.user._id === id
|
|
|
);
|
|
@@ -393,6 +451,15 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
};
|
|
|
|
|
|
mappedMessages.splice(firstUnreadIndex + 1, 0, unreadMarker);
|
|
|
+ setTimeout(() => {
|
|
|
+ if (flatList.current) {
|
|
|
+ flatList.current.scrollToIndex({
|
|
|
+ index: firstUnreadIndex,
|
|
|
+ animated: true,
|
|
|
+ viewPosition: 0.5
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, 500);
|
|
|
} else {
|
|
|
setUnreadMessageIndex(0);
|
|
|
}
|
|
@@ -1111,7 +1178,6 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
initialNumToRender: 30,
|
|
|
onViewableItemsChanged: handleViewableItemsChanged,
|
|
|
viewabilityConfig: { itemVisiblePercentThreshold: 50 },
|
|
|
- initialScrollIndex: unreadMessageIndex ?? 0,
|
|
|
onScrollToIndexFailed: (info: any) => {
|
|
|
const wait = new Promise((resolve) => setTimeout(resolve, 300));
|
|
|
wait.then(() => {
|