diff --git a/client/src/components/chat-affix/registerMessagingSocketHandlers.js b/client/src/components/chat-affix/registerMessagingSocketHandlers.js
index 09b405861..895fa9db1 100644
--- a/client/src/components/chat-affix/registerMessagingSocketHandlers.js
+++ b/client/src/components/chat-affix/registerMessagingSocketHandlers.js
@@ -2,39 +2,65 @@ import { CONVERSATION_LIST_QUERY, GET_CONVERSATION_DETAILS } from "../../graphql
import { gql } from "@apollo/client";
const logLocal = (message, ...args) => {
- if (import.meta.env.PROD) {
- return;
+ if (import.meta.env.VITE_APP_IS_TEST || !import.meta.env.PROD) {
+ console.log(`==================== ${message} ====================`);
+ console.dir({ ...args });
}
- console.log(`==================== ${message} ====================`);
- console.dir({ ...args });
};
+// Utility function to enrich conversation data
+const enrichConversation = (conversation, isOutbound) => ({
+ ...conversation,
+ updated_at: conversation.updated_at || new Date().toISOString(),
+ unreadcnt: conversation.unreadcnt || 0,
+ archived: conversation.archived || false,
+ label: conversation.label || null,
+ job_conversations: conversation.job_conversations || [],
+ messages_aggregate: conversation.messages_aggregate || {
+ __typename: "messages_aggregate",
+ aggregate: {
+ __typename: "messages_aggregate_fields",
+ count: isOutbound ? 0 : 1
+ }
+ },
+ __typename: "conversations"
+});
+
export const registerMessagingHandlers = ({ socket, client }) => {
if (!(socket && client)) return;
const handleNewMessageSummary = async (message) => {
const { conversationId, newConversation, existingConversation, isoutbound } = message;
+
logLocal("handleNewMessageSummary - Start", { message, isNew: !existingConversation });
const queryVariables = { offset: 0 };
- // Utility function to enrich conversation data
- const enrichConversation = (conversation, isOutbound) => ({
- ...conversation,
- updated_at: conversation.updated_at || new Date().toISOString(),
- unreadcnt: conversation.unreadcnt || 0,
- archived: conversation.archived || false,
- label: conversation.label || null,
- job_conversations: conversation.job_conversations || [],
- messages_aggregate: conversation.messages_aggregate || {
- __typename: "messages_aggregate",
- aggregate: {
- __typename: "messages_aggregate_fields",
- count: isOutbound ? 0 : 1
+ if (!existingConversation && conversationId) {
+ // Attempt to read from the cache to determine if this is actually a new conversation
+ try {
+ const cachedConversation = client.cache.readFragment({
+ id: client.cache.identify({ __typename: "conversations", id: conversationId }),
+ fragment: gql`
+ fragment ExistingConversationCheck on conversations {
+ id
+ }
+ `
+ });
+
+ if (cachedConversation) {
+ logLocal("handleNewMessageSummary - Existing Conversation inferred from cache", {
+ conversationId
+ });
+ return handleNewMessageSummary({
+ ...message,
+ existingConversation: true
+ });
}
- },
- __typename: "conversations"
- });
+ } catch (error) {
+ logLocal("handleNewMessageSummary - Cache miss", { conversationId });
+ }
+ }
// Handle new conversation
if (!existingConversation && newConversation?.phone_num) {
@@ -49,7 +75,6 @@ export const registerMessagingHandlers = ({ socket, client }) => {
const existingConversations = queryResults?.conversations || [];
const enrichedConversation = enrichConversation(newConversation, isoutbound);
- // Avoid adding duplicate conversations
if (!existingConversations.some((conv) => conv.id === enrichedConversation.id)) {
client.cache.modify({
id: "ROOT_QUERY",
@@ -68,81 +93,7 @@ export const registerMessagingHandlers = ({ socket, client }) => {
// Handle existing conversation
if (existingConversation) {
- let conversationDetails;
-
- // Attempt to read existing conversation details from cache
try {
- conversationDetails = client.cache.readFragment({
- id: client.cache.identify({ __typename: "conversations", id: conversationId }),
- fragment: gql`
- fragment ExistingConversation on conversations {
- id
- phone_num
- updated_at
- archived
- label
- unreadcnt
- job_conversations {
- jobid
- conversationid
- }
- messages_aggregate {
- aggregate {
- count
- }
- }
- __typename
- }
- `
- });
- } catch (error) {
- logLocal("handleNewMessageSummary - Cache miss for conversation, fetching from server", { conversationId });
- }
-
- // Fetch conversation details from server if not in cache
- if (!conversationDetails) {
- try {
- const { data } = await client.query({
- query: GET_CONVERSATION_DETAILS,
- variables: { conversationId },
- fetchPolicy: "network-only"
- });
- conversationDetails = data?.conversations_by_pk;
- } catch (error) {
- console.error("Failed to fetch conversation details from server:", error);
- return;
- }
- }
-
- // Validate that conversation details were retrieved
- if (!conversationDetails) {
- console.error("Unable to retrieve conversation details. Skipping cache update.");
- return;
- }
-
- try {
- // Check if the conversation is already in the cache
- const queryResults = client.cache.readQuery({
- query: CONVERSATION_LIST_QUERY,
- variables: queryVariables
- });
-
- const isAlreadyInCache = queryResults?.conversations.some((conv) => conv.id === conversationId);
-
- if (!isAlreadyInCache) {
- const enrichedConversation = enrichConversation(conversationDetails, isoutbound);
-
- client.cache.modify({
- id: "ROOT_QUERY",
- fields: {
- conversations(existingConversations = []) {
- return [enrichedConversation, ...existingConversations];
- }
- }
- });
- }
-
- // Update fields for the existing conversation in the cache
client.cache.modify({
id: client.cache.identify({ __typename: "conversations", id: conversationId }),
fields: {
@@ -166,7 +117,11 @@ export const registerMessagingHandlers = ({ socket, client }) => {
} catch (error) {
console.error("Error updating cache for existing conversation:", error);
}
+
+ return;
}
+
+ logLocal("New Conversation Summary finished without work", { message });
};
const handleNewMessageDetailed = (message) => {
diff --git a/client/src/components/chat-conversation-list/chat-conversation-list.component.jsx b/client/src/components/chat-conversation-list/chat-conversation-list.component.jsx
index fe71ee46e..16d4c0bf1 100644
--- a/client/src/components/chat-conversation-list/chat-conversation-list.component.jsx
+++ b/client/src/components/chat-conversation-list/chat-conversation-list.component.jsx
@@ -1,5 +1,5 @@
import { Badge, Card, List, Space, Tag } from "antd";
-import React from "react";
+import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Virtuoso } from "react-virtuoso";
import { createStructuredSelector } from "reselect";
@@ -20,8 +20,25 @@ const mapDispatchToProps = (dispatch) => ({
});
function ChatConversationListComponent({ conversationList, selectedConversation, setSelectedConversation }) {
+ // That comma is there for a reason, do not remove it
+ const [, forceUpdate] = useState(false);
+
+ // Re-render every minute
+ useEffect(() => {
+ const interval = setInterval(() => {
+ forceUpdate((prev) => !prev); // Toggle state to trigger re-render
+ }, 60000); // 1 minute in milliseconds
+
+ return () => clearInterval(interval); // Cleanup on unmount
+ }, []);
+
+ // Memoize the sorted conversation list
+ const sortedConversationList = React.useMemo(() => {
+ return _.orderBy(conversationList, ["updated_at"], ["desc"]);
+ }, [conversationList]);
+
const renderConversation = (index) => {
- const item = conversationList[index];
+ const item = sortedConversationList[index];
const cardContentRight =