diff --git a/packages/react-chat/src/hooks/useMessenger.ts b/packages/react-chat/src/hooks/useMessenger.ts index 6d069c9..a29c9a8 100644 --- a/packages/react-chat/src/hooks/useMessenger.ts +++ b/packages/react-chat/src/hooks/useMessenger.ts @@ -1,12 +1,14 @@ // import { StoreCodec } from "js-waku"; import { getBootstrapNodes, StoreCodec } from "js-waku"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Identity, Messenger } from "status-communities/dist/cjs"; import { ApplicationMetadataMessage } from "status-communities/dist/cjs"; import { uintToImgUrl } from "../helpers/uintToImgUrl"; import { ChatMessage } from "../models/ChatMessage"; +const _MS_PER_DAY = 1000 * 60 * 60 * 24; + function binarySetInsert( arr: T[], val: T, @@ -31,16 +33,25 @@ function binarySetInsert( export function useMessenger(chatId: string, chatIdList: string[]) { const [messenger, setMessenger] = useState(undefined); - const [activeMessages, setActiveMessages] = useState([]); const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>( {} ); const [notifications, setNotifications] = useState<{ [chatId: string]: number; }>({}); - const [lastLoadTime, setLastLoadTime] = useState<{ + const loadingPreviousMessages = useRef<{ + [chatId: string]: boolean; + }>({}); + const lastLoadTime = useRef<{ [chatId: string]: Date; }>({}); + const [lastMessage, setLastMessage] = useState(new Date()); + + useEffect(() => { + if (lastLoadTime.current?.[chatId]) { + setLastMessage(lastLoadTime.current?.[chatId]); + } + }, [chatId]); const clearNotifications = useCallback((id: string) => { setNotifications((prevNotifications) => { @@ -101,28 +112,34 @@ export function useMessenger(chatId: string, chatIdList: string[]) { ); const loadNextDay = useCallback( - (id: string) => { + async (id: string) => { if (messenger) { - const endTime = lastLoadTime[id]; - const startTime = new Date(); - startTime.setDate(endTime.getDate() - 1); - startTime.setHours(0, 0, 0, 0); - - messenger.retrievePreviousMessages( - id, - startTime, - endTime, - () => undefined + const endTime = lastLoadTime.current[id]; + const startTime = new Date(endTime.getTime() - _MS_PER_DAY); + const timeDiff = Math.floor( + (new Date().getTime() - endTime.getTime()) / _MS_PER_DAY ); - setLastLoadTime((prev) => { - return { - ...prev, - [id]: startTime, - }; - }); + if (timeDiff < 30) { + if (!loadingPreviousMessages.current[id]) { + loadingPreviousMessages.current[id] = true; + const amountOfMessages = await messenger.retrievePreviousMessages( + id, + startTime, + endTime + ); + lastLoadTime.current[id] = startTime; + if (id === chatId) { + setLastMessage(startTime); + } + loadingPreviousMessages.current[id] = false; + if (amountOfMessages === 0) { + loadNextDay(id); + } + } + } } }, - [lastLoadTime, messenger] + [lastLoadTime, messenger, chatId] ); useEffect(() => { @@ -150,12 +167,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) { await Promise.all( chatIdList.map(async (id) => { await messenger.joinChatById(id); - setLastLoadTime((prev) => { - return { - ...prev, - [id]: new Date(), - }; - }); + lastLoadTime.current[id] = new Date(); messenger.addObserver( (msg, date) => addNewMessage(msg, id, date), id @@ -199,9 +211,10 @@ export function useMessenger(chatId: string, chatIdList: string[]) { [chatId, messenger] ); - useEffect(() => { - setActiveMessages(messages?.[chatId] ?? []); - }, [messages, chatId]); + const activeMessages = useMemo( + () => messages?.[chatId] ?? [], + [messages, chatId] + ); return { messenger, @@ -210,6 +223,6 @@ export function useMessenger(chatId: string, chatIdList: string[]) { notifications, clearNotifications, loadNextDay, - lastMessage: lastLoadTime[chatId], + lastMessage, }; } diff --git a/packages/status-communities/src/messenger.ts b/packages/status-communities/src/messenger.ts index 375c49c..69d175d 100644 --- a/packages/status-communities/src/messenger.ts +++ b/packages/status-communities/src/messenger.ts @@ -157,8 +157,8 @@ export class Messenger { chatId: string, startTime: Date, endTime: Date, - callback: (messages: ApplicationMetadataMessage[]) => void - ): Promise { + callback?: (messages: ApplicationMetadataMessage[]) => void + ): Promise { const chat = this.chatsById.get(chatId); if (!chat) throw `Failed to retrieve messages, chat is not joined: ${chatId}`; @@ -184,14 +184,19 @@ export class Messenger { return; } }); - - callback(messages.filter(isDefined)); + if (callback) { + callback(messages.filter(isDefined)); + } }; - await this.waku.store.queryHistory([chat.contentTopic], { - timeFilter: { startTime, endTime }, - callback: _callback, - }); + const allMessages = await this.waku.store.queryHistory( + [chat.contentTopic], + { + timeFilter: { startTime, endTime }, + callback: _callback, + } + ); + return allMessages.length; } private _handleNewChatMessage(