From e514d144b2c6fe91013d519781692a65539e6701 Mon Sep 17 00:00:00 2001 From: Pavel <14926950+prichodko@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:51:56 +0200 Subject: [PATCH] Add more chat methods (#276) * add requestToJoin method * add editMessage method * add deleteMessage method * add todos * remove unnecessary parameter * add community ID property * add missing method --- packages/status-js/src/client/chat.ts | 83 +++++++++++++------ .../src/client/community/community.ts | 21 +++++ .../chat/components/chat-message/index.tsx | 9 +- 3 files changed, 79 insertions(+), 34 deletions(-) diff --git a/packages/status-js/src/client/chat.ts b/packages/status-js/src/client/chat.ts index c7229730..e17aa685 100644 --- a/packages/status-js/src/client/chat.ts +++ b/packages/status-js/src/client/chat.ts @@ -1,12 +1,15 @@ -import { hexToBytes } from 'ethereum-cryptography/utils' import { PageDirection } from 'js-waku' -import { ChatMessage as ChatMessageProto } from '~/protos/chat-message' -import { CommunityRequestToJoin } from '~/protos/communities' +import { + ChatMessage as ChatMessageProto, + DeleteMessage, + EditMessage, +} from '~/protos/chat-message' import { EmojiReaction } from '~/protos/emoji-reaction' import { idToContentTopic } from '../contentTopic' import { createSymKeyFromPassword } from '../encryption' +import { containsOnlyEmoji } from '../helpers/contains-only-emoji' import { getReactions } from './community/get-reactions' import type { MessageType } from '../../protos/enums' @@ -26,7 +29,6 @@ export type ChatMessage = ChatMessageProto & { } export class Chat { - private readonly community: Community private readonly client: Client public readonly uuid: string @@ -40,7 +42,6 @@ export class Chat { public readonly messageCallbacks: Set<(messages: ChatMessage[]) => void> constructor(options: { - community: Community client: Client uuid: string id: string @@ -50,7 +51,6 @@ export class Chat { description: CommunityChat }) { this.client = options.client - this.community = options.community this.uuid = options.uuid this.id = options.id @@ -76,7 +76,6 @@ export class Chat { const symmetricKey = await createSymKeyFromPassword(id) return new Chat({ - community, client, uuid, id, @@ -91,6 +90,10 @@ export class Chat { return this.messages } + public getMessage = (id: string) => { + return this.messages.find(message => message.messageId === id) + } + public onChange = (callback: (description: CommunityChat) => void) => { this.chatCallbacks.add(callback) @@ -351,7 +354,7 @@ export class Chat { responseTo: '', ensName: '', chatId: this.id, - messageType: 'COMMUNITY_CHAT', + messageType: 'COMMUNITY_CHAT' as MessageType, contentType: ChatMessageProto.ContentType.TEXT_PLAIN, sticker: { hash: '', pack: 0 }, image: { @@ -376,8 +379,50 @@ export class Chat { ) } + public editMessage = async (messageId: string, text: string) => { + // todo?: check if message exists + + if (text === '') { + throw new Error('Text message cannot be empty') + } + + const payload = EditMessage.encode({ + clock: BigInt(Date.now()), + text, + messageId, + chatId: this.id, + grant: new Uint8Array([]), + messageType: 'COMMUNITY_CHAT' as MessageType, + }) + + await this.client.sendWakuMessage( + 'TYPE_EDIT_MESSAGE', + payload, + this.contentTopic, + this.symmetricKey + ) + } + + public deleteMessage = async (messageId: string) => { + // todo: check if message exists + + const payload = DeleteMessage.encode({ + clock: BigInt(Date.now()), + messageId, + chatId: this.id, + grant: new Uint8Array([]), + messageType: 'COMMUNITY_CHAT' as MessageType, + }) + + await this.client.sendWakuMessage( + 'TYPE_DELETE_MESSAGE', + payload, + this.contentTopic, + this.symmetricKey + ) + } + public sendReaction = async ( - chatId: string, messageId: string, reaction: keyof ChatMessage['reactions'] ) => { @@ -397,10 +442,10 @@ export class Chat { const payload = EmojiReaction.encode({ clock: BigInt(Date.now()), - chatId: chatId, + chatId: this.id, messageType: 'COMMUNITY_CHAT' as MessageType, messageId, - type: reaction, + type: reaction as EmojiReaction.Type, retracted, grant: new Uint8Array([]), }) @@ -412,20 +457,4 @@ export class Chat { this.symmetricKey ) } - - public requestToJoin = async () => { - const payload = CommunityRequestToJoin.encode({ - clock: BigInt(Date.now()), - chatId: this.id, - communityId: hexToBytes(this.community.publicKey.replace(/^0[xX]/, '')), - ensName: '', - }) - - await this.client.sendWakuMessage( - 'TYPE_COMMUNITY_REQUEST_TO_JOIN', - payload, - this.contentTopic, - this.symmetricKey - ) - } } diff --git a/packages/status-js/src/client/community/community.ts b/packages/status-js/src/client/community/community.ts index b0348c9e..6c197621 100644 --- a/packages/status-js/src/client/community/community.ts +++ b/packages/status-js/src/client/community/community.ts @@ -1,5 +1,7 @@ +import { hexToBytes } from 'ethereum-cryptography/utils' import { waku_message } from 'js-waku' +import { CommunityRequestToJoin } from '~/protos/communities' import { MessageType } from '~/protos/enums' import { getDifferenceByKeys } from '~/src/helpers/get-difference-by-keys' import { getObjectsDifference } from '~/src/helpers/get-objects-difference' @@ -19,6 +21,7 @@ export class Community { private client: Client public publicKey: string + public id: string private contentTopic!: string private symmetricKey!: Uint8Array public description!: CommunityDescription @@ -28,7 +31,9 @@ export class Community { constructor(client: Client, publicKey: string) { this.client = client + this.publicKey = publicKey + this.id = publicKey.replace(/^0[xX]/, '') this.chats = new Map() this.#members = new Map() @@ -232,4 +237,20 @@ export class Community { this.callback = undefined } } + + public requestToJoin = async (chatId = '') => { + const payload = CommunityRequestToJoin.encode({ + clock: BigInt(Date.now()), + chatId, + communityId: hexToBytes(this.id), + ensName: '', + }) + + await this.client.sendWakuMessage( + 'TYPE_COMMUNITY_REQUEST_TO_JOIN', + payload, + this.contentTopic, + this.symmetricKey + ) + } } diff --git a/packages/status-react/src/routes/chat/components/chat-message/index.tsx b/packages/status-react/src/routes/chat/components/chat-message/index.tsx index c38bbe27..4297326b 100644 --- a/packages/status-react/src/routes/chat/components/chat-message/index.tsx +++ b/packages/status-react/src/routes/chat/components/chat-message/index.tsx @@ -77,16 +77,11 @@ export const ChatMessage = (props: Props) => { const userProfileDialog = useDialog(UserProfileDialog) const handleMessageSubmit = (message: string) => { - client.community.chats.get(chatId).sendTextMessage( - message, - '0x0fa999097568d1fdcc39108a08d75340bd2cee5ec59c36799007150d0a9fc896' - ) + client.community.chats.get(chatId).sendTextMessage(message) } const handleReaction = (reaction: Reaction) => { - client.community - .getChatById(chatId) - .sendReaction(chatId, messageId, reaction) + client.community.getChatById(chatId).sendReaction(messageId, reaction) } const handleReplyClick = () => {