Load messages until message is found or 30 days (#56)

This commit is contained in:
Szymon Szlachtowicz 2021-10-08 10:21:59 +02:00 committed by GitHub
parent 5ffd8a537d
commit c52a7963d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 39 deletions

View File

@ -1,12 +1,14 @@
// import { StoreCodec } from "js-waku"; // import { StoreCodec } from "js-waku";
import { getBootstrapNodes, 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 { Identity, Messenger } from "status-communities/dist/cjs";
import { ApplicationMetadataMessage } from "status-communities/dist/cjs"; import { ApplicationMetadataMessage } from "status-communities/dist/cjs";
import { uintToImgUrl } from "../helpers/uintToImgUrl"; import { uintToImgUrl } from "../helpers/uintToImgUrl";
import { ChatMessage } from "../models/ChatMessage"; import { ChatMessage } from "../models/ChatMessage";
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
function binarySetInsert<T>( function binarySetInsert<T>(
arr: T[], arr: T[],
val: T, val: T,
@ -31,16 +33,25 @@ function binarySetInsert<T>(
export function useMessenger(chatId: string, chatIdList: string[]) { export function useMessenger(chatId: string, chatIdList: string[]) {
const [messenger, setMessenger] = useState<Messenger | undefined>(undefined); const [messenger, setMessenger] = useState<Messenger | undefined>(undefined);
const [activeMessages, setActiveMessages] = useState<ChatMessage[]>([]);
const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>( const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>(
{} {}
); );
const [notifications, setNotifications] = useState<{ const [notifications, setNotifications] = useState<{
[chatId: string]: number; [chatId: string]: number;
}>({}); }>({});
const [lastLoadTime, setLastLoadTime] = useState<{ const loadingPreviousMessages = useRef<{
[chatId: string]: boolean;
}>({});
const lastLoadTime = useRef<{
[chatId: string]: Date; [chatId: string]: Date;
}>({}); }>({});
const [lastMessage, setLastMessage] = useState(new Date());
useEffect(() => {
if (lastLoadTime.current?.[chatId]) {
setLastMessage(lastLoadTime.current?.[chatId]);
}
}, [chatId]);
const clearNotifications = useCallback((id: string) => { const clearNotifications = useCallback((id: string) => {
setNotifications((prevNotifications) => { setNotifications((prevNotifications) => {
@ -101,28 +112,34 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
); );
const loadNextDay = useCallback( const loadNextDay = useCallback(
(id: string) => { async (id: string) => {
if (messenger) { if (messenger) {
const endTime = lastLoadTime[id]; const endTime = lastLoadTime.current[id];
const startTime = new Date(); const startTime = new Date(endTime.getTime() - _MS_PER_DAY);
startTime.setDate(endTime.getDate() - 1); const timeDiff = Math.floor(
startTime.setHours(0, 0, 0, 0); (new Date().getTime() - endTime.getTime()) / _MS_PER_DAY
messenger.retrievePreviousMessages(
id,
startTime,
endTime,
() => undefined
); );
setLastLoadTime((prev) => { if (timeDiff < 30) {
return { if (!loadingPreviousMessages.current[id]) {
...prev, loadingPreviousMessages.current[id] = true;
[id]: startTime, 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(() => { useEffect(() => {
@ -150,12 +167,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
await Promise.all( await Promise.all(
chatIdList.map(async (id) => { chatIdList.map(async (id) => {
await messenger.joinChatById(id); await messenger.joinChatById(id);
setLastLoadTime((prev) => { lastLoadTime.current[id] = new Date();
return {
...prev,
[id]: new Date(),
};
});
messenger.addObserver( messenger.addObserver(
(msg, date) => addNewMessage(msg, id, date), (msg, date) => addNewMessage(msg, id, date),
id id
@ -199,9 +211,10 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
[chatId, messenger] [chatId, messenger]
); );
useEffect(() => { const activeMessages = useMemo(
setActiveMessages(messages?.[chatId] ?? []); () => messages?.[chatId] ?? [],
}, [messages, chatId]); [messages, chatId]
);
return { return {
messenger, messenger,
@ -210,6 +223,6 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
notifications, notifications,
clearNotifications, clearNotifications,
loadNextDay, loadNextDay,
lastMessage: lastLoadTime[chatId], lastMessage,
}; };
} }

View File

@ -157,8 +157,8 @@ export class Messenger {
chatId: string, chatId: string,
startTime: Date, startTime: Date,
endTime: Date, endTime: Date,
callback: (messages: ApplicationMetadataMessage[]) => void callback?: (messages: ApplicationMetadataMessage[]) => void
): Promise<void> { ): Promise<number> {
const chat = this.chatsById.get(chatId); const chat = this.chatsById.get(chatId);
if (!chat) if (!chat)
throw `Failed to retrieve messages, chat is not joined: ${chatId}`; throw `Failed to retrieve messages, chat is not joined: ${chatId}`;
@ -184,14 +184,19 @@ export class Messenger {
return; return;
} }
}); });
if (callback) {
callback(messages.filter(isDefined)); callback(messages.filter(isDefined));
}
}; };
await this.waku.store.queryHistory([chat.contentTopic], { const allMessages = await this.waku.store.queryHistory(
timeFilter: { startTime, endTime }, [chat.contentTopic],
callback: _callback, {
}); timeFilter: { startTime, endTime },
callback: _callback,
}
);
return allMessages.length;
} }
private _handleNewChatMessage( private _handleNewChatMessage(