Skip to content

Commit

Permalink
Merge pull request #1068 from dm3-org/contact-pagination-fe
Browse files Browse the repository at this point in the history
Contact pagination fe
  • Loading branch information
AlexNi245 authored Jul 1, 2024
2 parents e5c5be6 + c76258a commit 404c224
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export const getMessages =
ownerId: account.id,
encryptedContactName,
},
orderBy: {
createdAt: 'desc',
},
});
if (messageRecord.length === 0) {
return [];
Expand Down
3 changes: 3 additions & 0 deletions packages/lib/storage/src/new/cloudStorage/getCloudStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,11 @@ export const getCloudStorage = (
await encryption.encryptAsync(
JSON.stringify(storageEnvelopContainer),
);
//The client defines the createdAt timestamp for the message so it can be used to sort the messages
const createdAt = Date.now();
return {
encryptedEnvelopContainer,
createdAt,
messageId:
storageEnvelopContainer.envelop.metadata
?.encryptedMessageHash! ??
Expand Down
3 changes: 3 additions & 0 deletions packages/messenger-widget/src/components/Chat/Chat.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
flex-direction: column;
}

.infinite-scroll-component__outerdiv{
height: auto;
}

/* =================== Mobile Responsive CSS =================== */

Expand Down
40 changes: 30 additions & 10 deletions packages/messenger-widget/src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ export function Chat() {
useState<boolean>(false);
const [showShimEffect, setShowShimEffect] = useState(false);

// state which tracks old msgs loading is active or not
const [loadingOldMsgs, setLoadingOldMsgs] = useState(false);

// state to track more old msgs exists or not
const [hasMoreOldMsgs, setHasMoreOldMsgs] = useState(true);

const fetchOldMessages = async () => {
setLoadingOldMsgs(true);
const newMsgCount = await loadMoreMessages(
selectedContact?.contactDetails.account.ensName!,
);
// if no old msgs are found, sets state to no more old msgs exists
if (!newMsgCount) {
setHasMoreOldMsgs(false);
}
};

useEffect(() => {
if (!selectedContact) {
return;
Expand All @@ -50,15 +67,23 @@ export function Chat() {
const isLoading = contactIsLoading(
selectedContact?.contactDetails.account.ensName!,
);
setShowShimEffect(isLoading);
// shim effect must be visible only if the messages are loaded first time
if (!messages.length) {
setShowShimEffect(isLoading);
}
}, [contactIsLoading]);

// scrolls to bottom of chat when messages are loaded
useEffect(() => {
if (messages.length && lastMessageAction === MessageActionType.NONE) {
// scrolls to bottom only when old msgs are not fetched
if (
messages.length &&
lastMessageAction === MessageActionType.NONE &&
!loadingOldMsgs
) {
scrollToBottomOfChat();
}
console.log(messages);
setLoadingOldMsgs(false);
}, [messages]);

/**
Expand Down Expand Up @@ -153,18 +178,13 @@ export function Chat() {
>
<InfiniteScroll
dataLength={messages.length}
next={() =>
loadMoreMessages(
selectedContact?.contactDetails.account
.ensName!,
)
}
next={fetchOldMessages}
style={{
display: 'flex',
flexDirection: 'column-reverse',
}} //To put endMessage and loader to the top.
inverse={true}
hasMore={true}
hasMore={hasMoreOldMsgs}
loader={
<h4
style={{
Expand Down
97 changes: 59 additions & 38 deletions packages/messenger-widget/src/components/Contacts/Contacts.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import './Contacts.css';
import { useCallback, useContext, useEffect, useState } from 'react';
import { useContext, useEffect, useState } from 'react';
import loader from '../../assets/images/loader.svg';
import threeDotsIcon from '../../assets/images/three-dots.svg';
import { ConversationContext } from '../../context/ConversationContext';
Expand All @@ -22,7 +22,7 @@ import InfiniteScroll from 'react-infinite-scroll-component';

export function Contacts() {
const { dm3Configuration } = useContext(DM3ConfigurationContext);
const { getMessages, getUnreadMessageCount, contactIsLoading } =
const { messages, getMessages, getUnreadMessageCount, contactIsLoading } =
useContext(MessageContext);
const { selectedRightView, setSelectedRightView, setSelectedLeftView } =
useContext(UiViewContext);
Expand All @@ -38,6 +38,9 @@ export function Contacts() {
boolean | null
>(null);

/* Hidden content for highlighting css */
const [hiddenData, setHiddenData] = useState<number[]>([]);

const [hasMoreContact, setHasMoreContact] = useState<boolean>(true);

const getMoreContacts = async () => {
Expand Down Expand Up @@ -130,13 +133,41 @@ export function Contacts() {
return contactIsSelected && contactIsLoading(contactName);
};

// updates hidden contacts data for highlighted border
const setHiddenContentForHighlightedBorder = () => {
const element: HTMLElement = document.getElementById(
'chat-scroller',
) as HTMLElement;
if (element) {
// fetch height of chat window
const height = element.clientHeight;
// divide it by each contact height to show in UI
const minimumContactCount = height / 64;
// get count of hidden contacts to add
const hiddenContacts = minimumContactCount - contacts.length + 10;
if (hiddenData.length !== hiddenContacts) {
setHiddenData(
Array.from({ length: hiddenContacts }, (_, i) => i + 1),
);
}
}
};

// handles change in screen size
window.addEventListener('resize', setHiddenContentForHighlightedBorder);

// sets hidden content styles for higlighted border
useEffect(() => {
setHiddenContentForHighlightedBorder();
}, [contacts]);

return (
<div
id="chat-scroller"
className={'contacts-scroller width-fill scroller-active'}
>
<InfiniteScroll
dataLength={contacts.length}
dataLength={contacts.length + hiddenData.length}
next={getMoreContacts}
style={{
display: 'flex',
Expand All @@ -145,18 +176,7 @@ export function Contacts() {
}}
inverse={false}
hasMore={hasMoreContact}
loader={
<h4
style={{
marginTop: '1rem',
fontSize: '14px',
textAlign: 'center',
color: 'white',
}}
>
Loading ...
</h4>
}
loader={<></>}
scrollableTarget="chat-scroller"
>
{contacts.length > 0 &&
Expand Down Expand Up @@ -254,7 +274,16 @@ export function Contacts() {
)}
{/* //TODO add loading state for message */}
{isContactSelected(id) ? (
!isContactLoading(id) ? (
isContactLoading(id) &&
!messages[id].length ? (
<div className="pe-2">
<img
className="rotating"
src={loader}
alt="loader"
/>
</div>
) : (
<div>
<div className="action-container">
<img
Expand Down Expand Up @@ -284,14 +313,6 @@ export function Contacts() {
}
</div>
</div>
) : (
<div className="pe-2">
<img
className="rotating"
src={loader}
alt="loader"
/>
</div>
)
) : (
<></>
Expand All @@ -309,21 +330,21 @@ export function Contacts() {
)
);
})}
</InfiniteScroll>

{/* Hidden content for highlighting css */}
{/* {hiddenData.map((data) => (
<div
key={data}
className={
selectedContact
? 'highlight-right-border'
: 'highlight-right-border-none'
}
>
<div className="hidden-data"></div>
</div>
))} */}
{/* Hidden content for highlighting css */}
{hiddenData.map((data) => (
<div
key={data}
className={
selectedContact
? 'highlight-right-border'
: 'highlight-right-border-none'
}
>
<div className="hidden-data"></div>
</div>
))}
</InfiniteScroll>
</div>
);
}
7 changes: 5 additions & 2 deletions packages/messenger-widget/src/context/MessageContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type MessageContextType = {
getMessages: GetMessages;
getUnreadMessageCount: (contact: string) => number;
addMessage: AddMessage;
loadMoreMessages: (contact: string) => void;
loadMoreMessages: (contact: string) => Promise<number>;
contactIsLoading: (contact: string) => boolean;
messages: MessageStorage;
};
Expand All @@ -23,7 +23,10 @@ export const MessageContext = React.createContext<MessageContextType>({
new Promise(() => {
isSuccess: true;
}),
loadMoreMessages: (contact: string) => {},
loadMoreMessages: (contact: string) =>
new Promise(() => {
return 0;
}),
contactIsLoading: (contact: string) => false,
messages: {},
});
Expand Down
18 changes: 15 additions & 3 deletions packages/messenger-widget/src/hooks/messages/useMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,17 +374,26 @@ export const useMessage = () => {
await _addMessages(contactName, flatten);
};

const loadMoreMessages = async (_contactName: string) => {
const loadMoreMessages = async (_contactName: string): Promise<number> => {
const contactName = normalizeEnsName(_contactName);

const messagesFromContact = messages[contactName] ?? [];
//For the messageCount we only consider emssages from the MessageSource storage
//For the messageCount we only consider messages from the MessageSource storage
const messageCount = messagesFromContact.filter(
(message) => message.source === MessageSource.Storage,
).length;

//We dont need to fetch more messages if the previously fetched page is smaller than the default pagesize
const isLastPage = messageCount % DEFAULT_MESSAGE_PAGESIZE !== 0;
if (isLastPage) {
console.log('all messages loaded for ', messagesFromContact);
//No more messages have been added
return 0;
}

//We calculate the offset based on the messageCount
const offset = Math.floor(messageCount / DEFAULT_MESSAGE_PAGESIZE);
console.log('load more ', messageCount, offset);

const messagesFromStorage = await handleMessagesFromStorage(
setContactsLoading,
Expand All @@ -393,7 +402,7 @@ export const useMessage = () => {
DEFAULT_MESSAGE_PAGESIZE,
offset,
);
await _addMessages(contactName, messagesFromStorage);
return await _addMessages(contactName, messagesFromStorage);
};

const _addMessages = async (
Expand Down Expand Up @@ -433,6 +442,9 @@ export const useMessage = () => {
setContactsLoading((prev) => {
return prev.filter((contact) => contact !== contactName);
});

// the count of new messages added
return withResolvedAliasNames.length;
};

/**
Expand Down

0 comments on commit 404c224

Please sign in to comment.