Refactor groupChats and add images to group chats msgs (#145)

This commit is contained in:
Szymon Szlachtowicz 2021-12-03 14:36:06 +01:00 committed by GitHub
parent ff733a15fc
commit 3d48c1fe98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 135 additions and 92 deletions

View File

@ -10,6 +10,7 @@ import {
import { ChannelData, ChannelsData } from "../../models/ChannelData"; import { ChannelData, ChannelsData } from "../../models/ChannelData";
import { ChatMessage } from "../../models/ChatMessage"; import { ChatMessage } from "../../models/ChatMessage";
import { Contact } from "../../models/Contact"; import { Contact } from "../../models/Contact";
import { uintToImgUrl } from "../../utils";
export function useGroupChats( export function useGroupChats(
messenger: Messenger | undefined, messenger: Messenger | undefined,
@ -54,11 +55,21 @@ export function useGroupChats(
type: "channel", type: "channel",
} as ChannelData); } as ChannelData);
}; };
const handleMessage = (msg: StatusChatMessage, sender: string) => const handleMessage = (msg: StatusChatMessage, sender: string) => {
let image: string | undefined = undefined;
if (msg.image) {
image = uintToImgUrl(msg.image.payload);
}
addChatMessage( addChatMessage(
new ChatMessage(msg.text ?? "", new Date(msg.clock ?? 0), sender), new ChatMessage(
msg.text ?? "",
new Date(msg.clock ?? 0),
sender,
image
),
msg.chatId msg.chatId
); );
};
return new GroupChats( return new GroupChats(
identity, identity,
messenger.waku, messenger.waku,

View File

@ -200,21 +200,25 @@ export function useMessenger(
const sendMessage = useCallback( const sendMessage = useCallback(
async (messageText?: string, image?: Uint8Array) => { async (messageText?: string, image?: Uint8Array) => {
if (activeChannel.type === "group") { let content;
groupChat?.sendMessage(activeChannel.id, messageText ?? "");
} else {
if (messageText) { if (messageText) {
await messenger?.sendMessage(activeChannel.id, { content = {
text: messageText, text: messageText,
contentType: 0, contentType: 0,
}); };
} }
if (image) { if (image) {
await messenger?.sendMessage(activeChannel.id, { content = {
image, image,
imageType: 1, imageType: 1,
contentType: 2, contentType: 2,
}); };
}
if (content) {
if (activeChannel.type === "group") {
await groupChat?.sendMessage(activeChannel.id, content);
} else {
await messenger?.sendMessage(activeChannel.id, content);
} }
} }
}, },

View File

@ -4,9 +4,12 @@ import { Identity } from "./identity";
import { MembershipUpdateEvent_EventType } from "./proto/communities/v1/membership_update_message"; import { MembershipUpdateEvent_EventType } from "./proto/communities/v1/membership_update_message";
import { getNegotiatedTopic, getPartitionedTopic } from "./topics"; import { getNegotiatedTopic, getPartitionedTopic } from "./topics";
import { bufToHex } from "./utils"; import { bufToHex } from "./utils";
import { MembershipUpdateMessage } from "./wire/membership_update_message"; import {
MembershipSignedEvent,
MembershipUpdateMessage,
} from "./wire/membership_update_message";
import { ChatMessage, ContentType } from "."; import { ChatMessage, Content } from ".";
export type GroupChat = { export type GroupChat = {
chatId: string; chatId: string;
@ -65,16 +68,18 @@ export class GroupChats {
* *
* @param text text message to send * @param text text message to send
*/ */
public async sendMessage(chatId: string, text: string): Promise<void> { public async sendMessage(chatId: string, content: Content): Promise<void> {
const now = Date.now(); const now = Date.now();
const chat = this.chats[chatId]; const chat = this.chats[chatId];
if (chat) { if (chat) {
await Promise.all( await Promise.all(
chat.members.map(async (member) => { chat.members.map(async (member) => {
const chatMessage = ChatMessage.createMessage(now, now, chatId, { const chatMessage = ChatMessage.createMessage(
text, now,
contentType: ContentType.Text, now,
}); chatId,
content
);
const wakuMessage = await WakuMessage.fromBytes( const wakuMessage = await WakuMessage.fromBytes(
chatMessage.encode(), chatMessage.encode(),
await getNegotiatedTopic(this.identity, member) await getNegotiatedTopic(this.identity, member)
@ -85,22 +90,14 @@ export class GroupChats {
} }
} }
private async decodeUpdateMessage( private async handleUpdateEvent(
message: WakuMessage, chatId: string,
event: MembershipSignedEvent,
useCallback: boolean useCallback: boolean
): Promise<void> { ): Promise<void> {
try {
if (message.payload) {
const membershipUpdate = MembershipUpdateMessage.decode(
message?.payload
);
await Promise.all(
membershipUpdate.events.map(async (event) => {
const signer = event.signer ? bufToHex(event.signer) : ""; const signer = event.signer ? bufToHex(event.signer) : "";
const thisUser = bufToHex(this.identity.publicKey); const thisUser = bufToHex(this.identity.publicKey);
const chatId = membershipUpdate.chatId;
const chat: GroupChat | undefined = this.chats[chatId]; const chat: GroupChat | undefined = this.chats[chatId];
if (signer) { if (signer) {
switch (event.event.type) { switch (event.event.type) {
case MembershipUpdateEvent_EventType.CHAT_CREATED: { case MembershipUpdateEvent_EventType.CHAT_CREATED: {
@ -137,12 +134,9 @@ export class GroupChats {
break; break;
} }
case MembershipUpdateEvent_EventType.MEMBERS_ADDED: { case MembershipUpdateEvent_EventType.MEMBERS_ADDED: {
if (chat) { if (chat && chat.admins?.includes(signer)) {
chat.members.push(...event.event.members); chat.members.push(...event.event.members);
if ( if (chat.members.includes(thisUser)) {
chat.members.includes(thisUser) &&
chat.admins?.includes(signer)
) {
chat.removed = false; chat.removed = false;
await this.addChat(chat, useCallback); await this.addChat(chat, useCallback);
} }
@ -160,7 +154,26 @@ export class GroupChats {
} }
} }
} }
}) }
private async decodeUpdateMessage(
message: WakuMessage,
useCallback: boolean
): Promise<void> {
try {
if (message?.payload) {
const membershipUpdate = MembershipUpdateMessage.decode(
message.payload
);
await Promise.all(
membershipUpdate.events.map(
async (event) =>
await this.handleUpdateEvent(
membershipUpdate.chatId,
event,
useCallback
)
)
); );
} }
} catch { } catch {
@ -224,6 +237,7 @@ export class GroupChats {
): Promise<void> { ): Promise<void> {
this.chats[chat.chatId] = chat; this.chats[chat.chatId] = chat;
if (useCallback) { if (useCallback) {
await this.handleChatObserver(chat, true);
this.removeCallback(chat); this.removeCallback(chat);
} }
} }
@ -268,6 +282,13 @@ export class GroupChats {
wakuMessages.forEach((msg) => this.waku.relay.send(msg)); wakuMessages.forEach((msg) => this.waku.relay.send(msg));
} }
/**
* Sends a change chat name chat membership update message
*
* @param chatId a chat id to which message is to be sent
*
* @param name a name which chat should be changed to
*/
public async changeChatName(chatId: string, name: string): Promise<void> { public async changeChatName(chatId: string, name: string): Promise<void> {
const payload = MembershipUpdateMessage.create(chatId, this.identity); const payload = MembershipUpdateMessage.create(chatId, this.identity);
const chat = this.chats[chatId]; const chat = this.chats[chatId];
@ -277,6 +298,13 @@ export class GroupChats {
} }
} }
/**
* Sends a add members group chat membership update message with given members
*
* @param chatId a chat id to which message is to be sent
*
* @param members a list of members to be added
*/
public async addMembers(chatId: string, members: string[]): Promise<void> { public async addMembers(chatId: string, members: string[]): Promise<void> {
const payload = MembershipUpdateMessage.create(chatId, this.identity); const payload = MembershipUpdateMessage.create(chatId, this.identity);
const chat = this.chats[chatId]; const chat = this.chats[chatId];