feature/IO-3000-messaging-sockets-migrations2 -
- A lot of a lot of testing.... Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { useApolloClient, useQuery } from "@apollo/client";
|
||||
import axios from "axios";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
@@ -17,19 +17,73 @@ const mapStateToProps = createStructuredSelector({
|
||||
export default connect(mapStateToProps, null)(ChatConversationContainer);
|
||||
|
||||
export function ChatConversationContainer({ bodyshop, selectedConversation }) {
|
||||
const client = useApolloClient();
|
||||
const { socket } = useContext(SocketContext);
|
||||
const [markingAsReadInProgress, setMarkingAsReadInProgress] = useState(false);
|
||||
|
||||
const {
|
||||
loading: convoLoading,
|
||||
error: convoError,
|
||||
data: convoData
|
||||
} = useQuery(GET_CONVERSATION_DETAILS, {
|
||||
variables: { conversationId: selectedConversation },
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only"
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
const { socket } = useContext(SocketContext);
|
||||
|
||||
// Utility to update Apollo cache
|
||||
const updateCacheWithReadMessages = (conversationId, messageIds) => {
|
||||
if (!conversationId || !messageIds || messageIds.length === 0) return;
|
||||
|
||||
messageIds.forEach((messageId) => {
|
||||
client.cache.modify({
|
||||
id: client.cache.identify({ __typename: "messages", id: messageId }),
|
||||
fields: {
|
||||
read() {
|
||||
return true; // Mark message as read
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Optionally update aggregate unread count
|
||||
client.cache.modify({
|
||||
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
|
||||
fields: {
|
||||
messages_aggregate(existingAggregate) {
|
||||
const updatedAggregate = {
|
||||
...existingAggregate,
|
||||
aggregate: {
|
||||
...existingAggregate.aggregate,
|
||||
count: 0 // No unread messages remaining
|
||||
}
|
||||
};
|
||||
return updatedAggregate;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Handle WebSocket events
|
||||
useEffect(() => {
|
||||
if (!socket || !socket.connected) return;
|
||||
|
||||
const handleConversationChange = (data) => {
|
||||
if (data.type === "conversation-marked-read") {
|
||||
const { conversationId, messageIds } = data;
|
||||
console.log("Conversation change received:", data);
|
||||
updateCacheWithReadMessages(conversationId, messageIds);
|
||||
}
|
||||
};
|
||||
|
||||
socket.on("conversation-changed", handleConversationChange);
|
||||
|
||||
return () => {
|
||||
socket.off("conversation-changed", handleConversationChange);
|
||||
};
|
||||
}, [socket, client]);
|
||||
|
||||
// Handle joining/leaving conversation
|
||||
useEffect(() => {
|
||||
// Early gate, we have no socket, bail.
|
||||
if (!socket || !socket.connected) return;
|
||||
|
||||
socket.emit("join-bodyshop-conversation", {
|
||||
@@ -45,25 +99,41 @@ export function ChatConversationContainer({ bodyshop, selectedConversation }) {
|
||||
};
|
||||
}, [selectedConversation, bodyshop, socket]);
|
||||
|
||||
const [markingAsReadInProgress, setMarkingAsReadInProgress] = useState(false);
|
||||
|
||||
const unreadCount =
|
||||
convoData &&
|
||||
convoData.conversations_by_pk &&
|
||||
convoData.conversations_by_pk.messages &&
|
||||
convoData.conversations_by_pk.messages.reduce((acc, val) => {
|
||||
return !val.read && !val.isoutbound ? acc + 1 : acc;
|
||||
}, 0);
|
||||
|
||||
// Handle marking conversation as read
|
||||
const handleMarkConversationAsRead = async () => {
|
||||
if (unreadCount > 0 && !!selectedConversation && !markingAsReadInProgress) {
|
||||
if (!convoData || !selectedConversation || markingAsReadInProgress) return;
|
||||
|
||||
const conversation = convoData.conversations_by_pk;
|
||||
if (!conversation) {
|
||||
console.warn(`No data found for conversation ID: ${selectedConversation}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const unreadMessageIds = conversation.messages
|
||||
?.filter((message) => !message.read && !message.isoutbound)
|
||||
.map((message) => message.id);
|
||||
|
||||
if (unreadMessageIds?.length > 0) {
|
||||
setMarkingAsReadInProgress(true);
|
||||
await axios.post("/sms/markConversationRead", {
|
||||
conversationid: selectedConversation,
|
||||
imexshopid: bodyshop.imexshopid,
|
||||
bodyshopid: bodyshop.id
|
||||
});
|
||||
setMarkingAsReadInProgress(false);
|
||||
|
||||
try {
|
||||
const payload = {
|
||||
conversation,
|
||||
imexshopid: bodyshop?.imexshopid,
|
||||
bodyshopid: bodyshop?.id
|
||||
};
|
||||
|
||||
console.log("Marking conversation as read:", payload);
|
||||
|
||||
await axios.post("/sms/markConversationRead", payload);
|
||||
|
||||
// Update local cache
|
||||
updateCacheWithReadMessages(selectedConversation, unreadMessageIds);
|
||||
} catch (error) {
|
||||
console.error("Error marking conversation as read:", error.response?.data || error.message);
|
||||
} finally {
|
||||
setMarkingAsReadInProgress(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user