Refactor groupChats and add images to group chats msgs (#145)
This commit is contained in:
parent
ff733a15fc
commit
3d48c1fe98
|
@ -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,
|
||||||
|
|
|
@ -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 ?? "");
|
if (messageText) {
|
||||||
} else {
|
content = {
|
||||||
if (messageText) {
|
text: messageText,
|
||||||
await messenger?.sendMessage(activeChannel.id, {
|
contentType: 0,
|
||||||
text: messageText,
|
};
|
||||||
contentType: 0,
|
}
|
||||||
});
|
if (image) {
|
||||||
}
|
content = {
|
||||||
if (image) {
|
image,
|
||||||
await messenger?.sendMessage(activeChannel.id, {
|
imageType: 1,
|
||||||
image,
|
contentType: 2,
|
||||||
imageType: 1,
|
};
|
||||||
contentType: 2,
|
}
|
||||||
});
|
if (content) {
|
||||||
|
if (activeChannel.type === "group") {
|
||||||
|
await groupChat?.sendMessage(activeChannel.id, content);
|
||||||
|
} else {
|
||||||
|
await messenger?.sendMessage(activeChannel.id, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,82 +90,90 @@ export class GroupChats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleUpdateEvent(
|
||||||
|
chatId: string,
|
||||||
|
event: MembershipSignedEvent,
|
||||||
|
useCallback: boolean
|
||||||
|
): Promise<void> {
|
||||||
|
const signer = event.signer ? bufToHex(event.signer) : "";
|
||||||
|
const thisUser = bufToHex(this.identity.publicKey);
|
||||||
|
const chat: GroupChat | undefined = this.chats[chatId];
|
||||||
|
if (signer) {
|
||||||
|
switch (event.event.type) {
|
||||||
|
case MembershipUpdateEvent_EventType.CHAT_CREATED: {
|
||||||
|
await this.addChat(
|
||||||
|
{
|
||||||
|
chatId: chatId,
|
||||||
|
members: event.event.members,
|
||||||
|
admins: [signer],
|
||||||
|
removed: false,
|
||||||
|
},
|
||||||
|
useCallback
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MembershipUpdateEvent_EventType.MEMBER_REMOVED: {
|
||||||
|
if (chat) {
|
||||||
|
chat.members = chat.members.filter(
|
||||||
|
(member) => !event.event.members.includes(member)
|
||||||
|
);
|
||||||
|
if (event.event.members.includes(thisUser)) {
|
||||||
|
await this.removeChat(
|
||||||
|
{
|
||||||
|
...chat,
|
||||||
|
removed: true,
|
||||||
|
},
|
||||||
|
useCallback
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (!chat.removed && useCallback) {
|
||||||
|
this.callback(this.chats[chatId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MembershipUpdateEvent_EventType.MEMBERS_ADDED: {
|
||||||
|
if (chat && chat.admins?.includes(signer)) {
|
||||||
|
chat.members.push(...event.event.members);
|
||||||
|
if (chat.members.includes(thisUser)) {
|
||||||
|
chat.removed = false;
|
||||||
|
await this.addChat(chat, useCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MembershipUpdateEvent_EventType.NAME_CHANGED: {
|
||||||
|
if (chat) {
|
||||||
|
if (chat.admins?.includes(signer)) {
|
||||||
|
chat.name = event.event.name;
|
||||||
|
this.callback(chat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async decodeUpdateMessage(
|
private async decodeUpdateMessage(
|
||||||
message: WakuMessage,
|
message: WakuMessage,
|
||||||
useCallback: boolean
|
useCallback: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if (message.payload) {
|
if (message?.payload) {
|
||||||
const membershipUpdate = MembershipUpdateMessage.decode(
|
const membershipUpdate = MembershipUpdateMessage.decode(
|
||||||
message?.payload
|
message.payload
|
||||||
);
|
);
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
membershipUpdate.events.map(async (event) => {
|
membershipUpdate.events.map(
|
||||||
const signer = event.signer ? bufToHex(event.signer) : "";
|
async (event) =>
|
||||||
const thisUser = bufToHex(this.identity.publicKey);
|
await this.handleUpdateEvent(
|
||||||
const chatId = membershipUpdate.chatId;
|
membershipUpdate.chatId,
|
||||||
const chat: GroupChat | undefined = this.chats[chatId];
|
event,
|
||||||
|
useCallback
|
||||||
if (signer) {
|
)
|
||||||
switch (event.event.type) {
|
)
|
||||||
case MembershipUpdateEvent_EventType.CHAT_CREATED: {
|
|
||||||
await this.addChat(
|
|
||||||
{
|
|
||||||
chatId: chatId,
|
|
||||||
members: event.event.members,
|
|
||||||
admins: [signer],
|
|
||||||
removed: false,
|
|
||||||
},
|
|
||||||
useCallback
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MembershipUpdateEvent_EventType.MEMBER_REMOVED: {
|
|
||||||
if (chat) {
|
|
||||||
chat.members = chat.members.filter(
|
|
||||||
(member) => !event.event.members.includes(member)
|
|
||||||
);
|
|
||||||
if (event.event.members.includes(thisUser)) {
|
|
||||||
await this.removeChat(
|
|
||||||
{
|
|
||||||
...chat,
|
|
||||||
removed: true,
|
|
||||||
},
|
|
||||||
useCallback
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (!chat.removed && useCallback) {
|
|
||||||
this.callback(this.chats[chatId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MembershipUpdateEvent_EventType.MEMBERS_ADDED: {
|
|
||||||
if (chat) {
|
|
||||||
chat.members.push(...event.event.members);
|
|
||||||
if (
|
|
||||||
chat.members.includes(thisUser) &&
|
|
||||||
chat.admins?.includes(signer)
|
|
||||||
) {
|
|
||||||
chat.removed = false;
|
|
||||||
await this.addChat(chat, useCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MembershipUpdateEvent_EventType.NAME_CHANGED: {
|
|
||||||
if (chat) {
|
|
||||||
if (chat.admins?.includes(signer)) {
|
|
||||||
chat.name = event.event.name;
|
|
||||||
this.callback(chat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} 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];
|
||||||
|
|
Loading…
Reference in New Issue