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:
Dave Richer
2024-11-21 22:14:39 -08:00
parent 141deff41e
commit 6504b27eca
5 changed files with 376 additions and 249 deletions

View File

@@ -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);
}
}
};