Use retrieve previous messages (#39)
This commit is contained in:
parent
aad475a435
commit
ea49955412
|
@ -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) => {
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
Loading…
Reference in New Issue