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
This commit is contained in:
Pavel 2022-06-15 11:51:56 +02:00 committed by GitHub
parent 112cd0d9ab
commit 72d1e679fc
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
3 changed files with 79 additions and 34 deletions

View File

@ -1,12 +1,15 @@
import { hexToBytes } from 'ethereum-cryptography/utils'
import { PageDirection } from 'js-waku' import { PageDirection } from 'js-waku'
import { ChatMessage as ChatMessageProto } from '~/protos/chat-message' import {
import { CommunityRequestToJoin } from '~/protos/communities' ChatMessage as ChatMessageProto,
DeleteMessage,
EditMessage,
} from '~/protos/chat-message'
import { EmojiReaction } from '~/protos/emoji-reaction' import { EmojiReaction } from '~/protos/emoji-reaction'
import { idToContentTopic } from '../contentTopic' import { idToContentTopic } from '../contentTopic'
import { createSymKeyFromPassword } from '../encryption' import { createSymKeyFromPassword } from '../encryption'
import { containsOnlyEmoji } from '../helpers/contains-only-emoji'
import { getReactions } from './community/get-reactions' import { getReactions } from './community/get-reactions'
import type { MessageType } from '../../protos/enums' import type { MessageType } from '../../protos/enums'
@ -26,7 +29,6 @@ export type ChatMessage = ChatMessageProto & {
} }
export class Chat { export class Chat {
private readonly community: Community
private readonly client: Client private readonly client: Client
public readonly uuid: string public readonly uuid: string
@ -40,7 +42,6 @@ export class Chat {
public readonly messageCallbacks: Set<(messages: ChatMessage[]) => void> public readonly messageCallbacks: Set<(messages: ChatMessage[]) => void>
constructor(options: { constructor(options: {
community: Community
client: Client client: Client
uuid: string uuid: string
id: string id: string
@ -50,7 +51,6 @@ export class Chat {
description: CommunityChat description: CommunityChat
}) { }) {
this.client = options.client this.client = options.client
this.community = options.community
this.uuid = options.uuid this.uuid = options.uuid
this.id = options.id this.id = options.id
@ -76,7 +76,6 @@ export class Chat {
const symmetricKey = await createSymKeyFromPassword(id) const symmetricKey = await createSymKeyFromPassword(id)
return new Chat({ return new Chat({
community,
client, client,
uuid, uuid,
id, id,
@ -91,6 +90,10 @@ export class Chat {
return this.messages return this.messages
} }
public getMessage = (id: string) => {
return this.messages.find(message => message.messageId === id)
}
public onChange = (callback: (description: CommunityChat) => void) => { public onChange = (callback: (description: CommunityChat) => void) => {
this.chatCallbacks.add(callback) this.chatCallbacks.add(callback)
@ -351,7 +354,7 @@ export class Chat {
responseTo: '', responseTo: '',
ensName: '', ensName: '',
chatId: this.id, chatId: this.id,
messageType: 'COMMUNITY_CHAT', messageType: 'COMMUNITY_CHAT' as MessageType,
contentType: ChatMessageProto.ContentType.TEXT_PLAIN, contentType: ChatMessageProto.ContentType.TEXT_PLAIN,
sticker: { hash: '', pack: 0 }, sticker: { hash: '', pack: 0 },
image: { 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 ( public sendReaction = async (
chatId: string,
messageId: string, messageId: string,
reaction: keyof ChatMessage['reactions'] reaction: keyof ChatMessage['reactions']
) => { ) => {
@ -397,10 +442,10 @@ export class Chat {
const payload = EmojiReaction.encode({ const payload = EmojiReaction.encode({
clock: BigInt(Date.now()), clock: BigInt(Date.now()),
chatId: chatId, chatId: this.id,
messageType: 'COMMUNITY_CHAT' as MessageType, messageType: 'COMMUNITY_CHAT' as MessageType,
messageId, messageId,
type: reaction, type: reaction as EmojiReaction.Type,
retracted, retracted,
grant: new Uint8Array([]), grant: new Uint8Array([]),
}) })
@ -412,20 +457,4 @@ export class Chat {
this.symmetricKey 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
)
}
} }

View File

@ -1,5 +1,7 @@
import { hexToBytes } from 'ethereum-cryptography/utils'
import { waku_message } from 'js-waku' import { waku_message } from 'js-waku'
import { CommunityRequestToJoin } from '~/protos/communities'
import { MessageType } from '~/protos/enums' import { MessageType } from '~/protos/enums'
import { getDifferenceByKeys } from '~/src/helpers/get-difference-by-keys' import { getDifferenceByKeys } from '~/src/helpers/get-difference-by-keys'
import { getObjectsDifference } from '~/src/helpers/get-objects-difference' import { getObjectsDifference } from '~/src/helpers/get-objects-difference'
@ -19,6 +21,7 @@ export class Community {
private client: Client private client: Client
public publicKey: string public publicKey: string
public id: string
private contentTopic!: string private contentTopic!: string
private symmetricKey!: Uint8Array private symmetricKey!: Uint8Array
public description!: CommunityDescription public description!: CommunityDescription
@ -28,7 +31,9 @@ export class Community {
constructor(client: Client, publicKey: string) { constructor(client: Client, publicKey: string) {
this.client = client this.client = client
this.publicKey = publicKey this.publicKey = publicKey
this.id = publicKey.replace(/^0[xX]/, '')
this.chats = new Map() this.chats = new Map()
this.#members = new Map() this.#members = new Map()
@ -232,4 +237,20 @@ export class Community {
this.callback = undefined 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
)
}
} }

View File

@ -77,16 +77,11 @@ export const ChatMessage = (props: Props) => {
const userProfileDialog = useDialog(UserProfileDialog) const userProfileDialog = useDialog(UserProfileDialog)
const handleMessageSubmit = (message: string) => { const handleMessageSubmit = (message: string) => {
client.community.chats.get(chatId).sendTextMessage( client.community.chats.get(chatId).sendTextMessage(message)
message,
'0x0fa999097568d1fdcc39108a08d75340bd2cee5ec59c36799007150d0a9fc896'
)
} }
const handleReaction = (reaction: Reaction) => { const handleReaction = (reaction: Reaction) => {
client.community client.community.getChatById(chatId).sendReaction(messageId, reaction)
.getChatById(chatId)
.sendReaction(chatId, messageId, reaction)
} }
const handleReplyClick = () => { const handleReplyClick = () => {