Use retrieve previous messages (#39)

This commit is contained in:
Szymon Szlachtowicz 2021-10-05 14:47:18 +02:00 committed by GitHub
parent aad475a435
commit ea49955412
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 84 deletions

View File

@ -20,7 +20,7 @@ export function ChatMessages({ messages, theme }: ChatMessagesProps) {
if (ref && ref.current) { if (ref && ref.current) {
ref.current.scrollTop = ref.current.scrollHeight; ref.current.scrollTop = ref.current.scrollHeight;
} }
}, [messages]); }, [messages, messages.length]);
return ( return (
<MessagesWrapper ref={ref}> <MessagesWrapper ref={ref}>
{messages.map((message, idx) => { {messages.map((message, idx) => {

View File

@ -1,15 +1,33 @@
// 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, useState } from "react";
import { import { Identity, Messenger } from "status-communities/dist/cjs";
ChatMessage as ApiChatMessage, import { ApplicationMetadataMessage } from "status-communities/dist/cjs/application_metadata_message";
ApplicationMetadataMessage,
Identity,
Messenger,
} from "status-communities/dist/cjs";
import { ChatMessage } from "../models/ChatMessage"; import { ChatMessage } from "../models/ChatMessage";
function binarySetInsert<T>(
arr: T[],
val: T,
compFunc: (a: T, b: T) => boolean,
eqFunc: (a: T, b: T) => boolean
) {
let low = 0;
let high = arr.length;
while (low < high) {
const mid = (low + high) >> 1;
if (compFunc(arr[mid], val)) {
low = mid + 1;
} else {
high = mid;
}
}
if (arr.length === low || !eqFunc(arr[low], val)) {
arr.splice(low, 0, val);
}
return arr;
}
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 [activeMessages, setActiveMessages] = useState<ChatMessage[]>([]);
@ -29,40 +47,42 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
}); });
}, []); }, []);
const addNewMessage = useCallback( const addNewMessageRaw = useCallback(
(sender: Uint8Array, content: string, date: Date, id: string) => { (signer: Uint8Array, content: string, date: Date, id: string) => {
let signer = "0x"; const sender = signer.reduce((p, c) => p + c.toString(16), "0x");
sender.forEach((e) => { const newMessage = { sender, content, date };
signer = signer + e.toString(16); setMessages((prev) => {
});
setMessages((prevMessages) => {
const newMessage = {
sender: signer,
content: content,
date: date,
};
if (prevMessages?.[id]) {
return {
...prevMessages,
[id]: [...prevMessages[id], newMessage],
};
} else {
return {
...prevMessages,
[id]: [newMessage],
};
}
});
setNotifications((prevNotifications) => {
return { return {
...prevNotifications, ...prev,
[id]: prevNotifications[id] + 1, [id]: binarySetInsert(
prev?.[id] ?? [],
newMessage,
(a, b) => a.date < b.date,
(a, b) => a.date.getTime() === b.date.getTime()
),
};
});
setNotifications((prev) => {
return {
...prev,
[id]: prev[id] + 1,
}; };
}); });
}, },
[] []
); );
const addNewMessage = useCallback(
(msg: ApplicationMetadataMessage, id: string) => {
if (msg.signer && msg.chatMessage?.text) {
const content = msg.chatMessage.text;
const date = new Date(msg.chatMessage.clock);
addNewMessageRaw(msg.signer, content, date, id);
}
},
[addNewMessageRaw]
);
useEffect(() => { useEffect(() => {
const createMessenger = async () => { const createMessenger = async () => {
const identity = Identity.generate(); const identity = Identity.generate();
@ -86,54 +106,19 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
}); });
await Promise.all( await Promise.all(
chatIdList.map(async (id) => await messenger.joinChat(id))
);
Promise.all(
chatIdList.map(async (id) => { chatIdList.map(async (id) => {
await messenger.joinChat(id); await messenger.retrievePreviousMessages(
const chat = messenger.chatsById.get(id); id,
if (chat) { new Date(0),
const messages = await messenger.waku.store.queryHistory( new Date(),
[chat.contentTopic], (messages) => messages.forEach((msg) => addNewMessage(msg, id))
{ );
decryptionKeys: [chat.symKey],
}
);
messages.sort((a, b) =>
(a?.timestamp?.getTime() ?? 0) > (b?.timestamp?.getTime() ?? 0)
? 1
: -1
);
messages.forEach((message) => {
if (message.payload) {
const metadata = ApplicationMetadataMessage.decode(
message.payload
);
if (metadata.payload) {
const chatMessage = ApiChatMessage.decode(metadata.payload);
if (
metadata.signer &&
chatMessage.text &&
chatMessage.proto.timestamp
) {
addNewMessage(
metadata.signer,
chatMessage.text,
new Date(chatMessage.proto.timestamp ?? 0),
id
);
}
}
}
return undefined;
});
}
clearNotifications(id); clearNotifications(id);
messenger.addObserver((message) => { messenger.addObserver((msg) => addNewMessage(msg, id), id);
addNewMessage(
message.signer ?? new Uint8Array(),
message.chatMessage?.text ?? "",
new Date(message.chatMessage?.proto.timestamp ?? 0),
id
);
}, id);
}) })
); );
setMessenger(messenger); setMessenger(messenger);
@ -144,7 +129,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
const sendMessage = useCallback( const sendMessage = useCallback(
async (messageText: string) => { async (messageText: string) => {
await messenger?.sendMessage(messageText, chatId); await messenger?.sendMessage(messageText, chatId);
addNewMessage( addNewMessageRaw(
messenger?.identity.publicKey ?? new Uint8Array(), messenger?.identity.publicKey ?? new Uint8Array(),
messageText, messageText,
new Date(), new Date(),

View File

@ -1,5 +1,3 @@
import { ApplicationMetadataMessage } from "./application_metadata_message";
import { ChatMessage } from "./chat_message";
import { Identity } from "./identity"; import { Identity } from "./identity";
import { Messenger } from "./messenger"; import { Messenger } from "./messenger";
export { Messenger, Identity, ApplicationMetadataMessage, ChatMessage }; export { Messenger, Identity };