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 a9d48871e..ffc087ae2 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
@@ -7,6 +7,8 @@ import { selectSelectedConversation } from "../../redux/messaging/messaging.sele
import { TimeAgoFormatter } from "../../utils/DateFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
+import { List as VirtualizedList, AutoSizer } from "react-virtualized";
+
import "./chat-conversation-list.styles.scss";
const mapStateToProps = createStructuredSelector({
@@ -18,73 +20,87 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(setSelectedConversation(conversationId)),
});
-const ChatConversationListComponent = React.forwardRef(
- function ChatConversationListComponent(
- {
- conversationList,
- selectedConversation,
- setSelectedConversation,
- subscribeToMoreConversations,
- },
- ref
- ) {
- useEffect(
- () => subscribeToMoreConversations(),
- // eslint-disable-next-line react-hooks/exhaustive-deps
- []
- );
+function ChatConversationListComponent({
+ conversationList,
+ selectedConversation,
+ setSelectedConversation,
+ subscribeToMoreConversations,
+ loadMoreConversations,
+}) {
+ useEffect(
+ () => subscribeToMoreConversations(),
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ []
+ );
+
+ const rowRenderer = ({ index, key, style }) => {
+ const item = conversationList[index];
return (
-
-
(
- setSelectedConversation(item.id)}
- className={`chat-list-item ${
- item.id === selectedConversation
- ? "chat-list-selected-conversation"
- : null
- }`}
- >
-
- {item.label &&
{item.label}
}
- {item.job_conversations.length > 0 ? (
-
- {item.job_conversations.map((j, idx) => (
-
-
-
- ))}
-
- ) : (
-
{item.phone_num}
- )}
-
-
-
- {item.job_conversations.length > 0
- ? item.job_conversations.map((j, idx) => (
-
- {j.job.ro_number}
-
- ))
- : null}
+
setSelectedConversation(item.id)}
+ className={`chat-list-item ${
+ item.id === selectedConversation
+ ? "chat-list-selected-conversation"
+ : null
+ }`}
+ style={style}
+ >
+
+ {item.label &&
{item.label}
}
+ {item.job_conversations.length > 0 ? (
+
+ {item.job_conversations.map((j, idx) => (
+
+
-
{item.updated_at}
-
-
-
+ ))}
+
+ ) : (
+ {item.phone_num}
)}
- footer={}
- />
-
+
+
+
+ {item.job_conversations.length > 0
+ ? item.job_conversations.map((j, idx) => (
+
+ {j.job.ro_number}
+
+ ))
+ : null}
+
+
{item.updated_at}
+
+
+
);
- }
-);
+ };
-export default connect(mapStateToProps, mapDispatchToProps, null, {
- forwardRef: true,
-})(ChatConversationListComponent);
+ return (
+
+
+ {({ height, width }) => (
+ {
+ if (scrollTop + clientHeight === scrollHeight) {
+ loadMoreConversations();
+ }
+ }}
+ />
+ )}
+
+
+ );
+}
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ChatConversationListComponent);
diff --git a/client/src/components/chat-conversation-list/chat-conversation-list.styles.scss b/client/src/components/chat-conversation-list/chat-conversation-list.styles.scss
index bfc83d947..20cf8f4ef 100644
--- a/client/src/components/chat-conversation-list/chat-conversation-list.styles.scss
+++ b/client/src/components/chat-conversation-list/chat-conversation-list.styles.scss
@@ -3,8 +3,9 @@
}
.chat-list-container {
flex: 1;
- overflow: auto;
+ overflow: hidden;
height: 100%;
+ border: 1px solid gainsboro;
}
.chat-list-item {
@@ -21,4 +22,6 @@
.ro-number-tag {
align-self: baseline;
}
+ padding: 12px 24px;
+ border-bottom: 1px solid gainsboro;
}
diff --git a/client/src/components/chat-popup/chat-popup.component.jsx b/client/src/components/chat-popup/chat-popup.component.jsx
index a3fda4843..5ac4baec1 100644
--- a/client/src/components/chat-popup/chat-popup.component.jsx
+++ b/client/src/components/chat-popup/chat-popup.component.jsx
@@ -4,9 +4,9 @@ import {
ShrinkOutlined,
SyncOutlined,
} from "@ant-design/icons";
-import { useQuery, useSubscription } from "@apollo/client";
+import { useLazyQuery, useQuery, useSubscription } from "@apollo/client";
import { Badge, Card, Col, Row, Space, Tag, Tooltip, Typography } from "antd";
-import React, { useEffect, useState } from "react";
+import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -25,7 +25,6 @@ import ChatConversationContainer from "../chat-conversation/chat-conversation.co
import ChatNewConversation from "../chat-new-conversation/chat-new-conversation.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import "./chat-popup.styles.scss";
-import { useInView } from "react-intersection-observer";
const mapStateToProps = createStructuredSelector({
selectedConversation: selectSelectedConversation,
@@ -42,7 +41,6 @@ export function ChatPopupComponent({
}) {
const { t } = useTranslation();
const [pollInterval, setpollInterval] = useState(0);
- const { ref, inView } = useInView({});
const { data: unreadData } = useSubscription(
UNREAD_CONVERSATION_COUNT_SUBSCRIPTION
@@ -56,15 +54,14 @@ export function ChatPopupComponent({
// }
// );
- const { loading, data, called, refetch, fetchMore, subscribeToMore } =
- useQuery(CONVERSATION_LIST_QUERY, {
- variables: {
- offset: 0,
- },
- fetchPolicy: "cache-and-network",
- nextFetchPolicy: "cache-first",
- skip: !chatVisible,
- });
+ const [
+ getConversations,
+ { loading, data, called, fetchMore, subscribeToMore },
+ ] = useLazyQuery(CONVERSATION_LIST_QUERY, {
+ fetchPolicy: "cache-and-network",
+ nextFetchPolicy: "cache-first",
+ skip: !chatVisible,
+ });
const fcmToken = sessionStorage.getItem("fcmtoken");
@@ -77,18 +74,60 @@ export function ChatPopupComponent({
}, [fcmToken]);
useEffect(() => {
- if (called && chatVisible) refetch();
- }, [chatVisible, called, refetch]);
+ if (called && chatVisible)
+ getConversations({
+ variables: {
+ offset: 0,
+ },
+ });
+ }, [chatVisible, called, getConversations]);
- useEffect(() => {
- if (inView && data && data.conversations) {
+ const loadMoreConversations = useCallback(() => {
+ if (data)
fetchMore({
variables: {
offset: data.conversations.length,
},
});
- }
- }, [inView, data, fetchMore]);
+ }, [data, fetchMore]);
+
+ const subscribeToMoreConversations = useCallback(
+ () =>
+ subscribeToMore({
+ document: CONVERSATION_LIST_SUBSCRIPTION,
+ variables: { offset: 0 },
+ updateQuery: (prev, { subscriptionData }) => {
+ console.log("Hello");
+ if (
+ !subscriptionData.data ||
+ subscriptionData.data.conversations.length === 0
+ )
+ return prev;
+
+ let conversations = prev.conversations;
+ const newConversations = subscriptionData.data.conversations;
+
+ for (const conversation of newConversations) {
+ const index = conversations.findIndex(
+ (prevConversation) => prevConversation.id === conversation.id
+ );
+
+ if (index !== -1) {
+ conversations.splice(index, 1);
+ conversations.unshift(conversation);
+ continue;
+ }
+
+ conversation.unshift(conversation);
+ }
+
+ return Object.assign({}, prev, {
+ conversations: conversations,
+ });
+ },
+ }),
+ [subscribeToMore]
+ );
const unreadCount = unreadData?.messages_aggregate.aggregate.count || 0;
@@ -105,10 +144,10 @@ export function ChatPopupComponent({
- refetch()}
- />
+ /> */}
{pollInterval > 0 && (
{t("messaging.labels.nopush")}
)}
@@ -125,7 +164,8 @@ export function ChatPopupComponent({
) : (
{
+ loadMoreConversations={loadMoreConversations}
+ subscribeToMoreConversations={() =>
subscribeToMore({
document: CONVERSATION_LIST_SUBSCRIPTION,
variables: { offset: 0 },
@@ -135,16 +175,33 @@ export function ChatPopupComponent({
subscriptionData.data.conversations.length === 0
)
return prev;
+
+ let conversations = [...prev.conversations];
const newConversations =
subscriptionData.data.conversations;
+ for (const conversation of newConversations) {
+ const index = conversations.findIndex(
+ (prevConversation) =>
+ prevConversation.id === conversation.id
+ );
+
+ if (index !== -1) {
+ conversations.splice(index, 1);
+ conversations.unshift(conversation);
+
+ continue;
+ }
+
+ conversations.unshift(conversation);
+ }
+
return Object.assign({}, prev, {
- conversations: [...newConversations],
+ conversations: conversations,
});
},
- });
- }}
- ref={ref}
+ })
+ }
/>
)}