diff --git a/packages/react-chat/src/hooks/useMessenger.ts b/packages/react-chat/src/hooks/useMessenger.ts index cfee210..5a0dd2f 100644 --- a/packages/react-chat/src/hooks/useMessenger.ts +++ b/packages/react-chat/src/hooks/useMessenger.ts @@ -176,14 +176,18 @@ export function useMessenger(chatId: string, chatIdList: string[]) { const sendMessage = useCallback( async (messageText: string, image?: Uint8Array) => { - const mediaContent = image + // TODO: A message can either contain text or media, not both. + const content = image ? { image, imageType: 1, - contentType: 1, + contentType: 2, } - : undefined; - await messenger?.sendMessage(messageText, chatId, mediaContent); + : { + text: messageText, + contentType: 0, + }; + await messenger?.sendMessage(chatId, content); addNewMessageRaw( messenger?.identity.publicKey ?? new Uint8Array(), messageText, diff --git a/packages/status-communities/src/chat.ts b/packages/status-communities/src/chat.ts index b3403f5..86ea041 100644 --- a/packages/status-communities/src/chat.ts +++ b/packages/status-communities/src/chat.ts @@ -1,4 +1,4 @@ -import { ChatMessage, MediaContent } from "./chat_message"; +import { ChatMessage, Content } from "./chat_message"; import { chatIdToContentTopic } from "./contentTopic"; import { createSymKeyFromPassword } from "./encryption"; @@ -24,15 +24,14 @@ export class Chat { return chatIdToContentTopic(this.id); } - public createMessage(text: string, mediaContent?: MediaContent): ChatMessage { + public createMessage(content: Content): ChatMessage { const { timestamp, clock } = this._nextClockAndTimestamp(); const message = ChatMessage.createMessage( clock, timestamp, - text, this.id, - mediaContent + content ); this._updateClockFromMessage(message); diff --git a/packages/status-communities/src/chat_message.spec.ts b/packages/status-communities/src/chat_message.spec.ts index 451e3d8..18638d4 100644 --- a/packages/status-communities/src/chat_message.spec.ts +++ b/packages/status-communities/src/chat_message.spec.ts @@ -23,13 +23,7 @@ describe("Chat Message", () => { contentType: ContentType.Image, }; - const message = ChatMessage.createMessage( - 1, - 1, - "Some text", - "chat-id", - imageContent - ); + const message = ChatMessage.createMessage(1, 1, "chat-id", imageContent); const buf = message.encode(); const dec = ChatMessage.decode(buf); @@ -50,13 +44,7 @@ describe("Chat Message", () => { contentType: ContentType.Audio, }; - const message = ChatMessage.createMessage( - 1, - 1, - "Some text", - "chat-id", - audioContent - ); + const message = ChatMessage.createMessage(1, 1, "chat-id", audioContent); const buf = message.encode(); const dec = ChatMessage.decode(buf); @@ -77,13 +65,7 @@ describe("Chat Message", () => { contentType: ContentType.Sticker, }; - const message = ChatMessage.createMessage( - 1, - 1, - "Some text", - "chat-id", - stickerContent - ); + const message = ChatMessage.createMessage(1, 1, "chat-id", stickerContent); const buf = message.encode(); const dec = ChatMessage.decode(buf); diff --git a/packages/status-communities/src/chat_message.ts b/packages/status-communities/src/chat_message.ts index 961f735..65148a3 100644 --- a/packages/status-communities/src/chat_message.ts +++ b/packages/status-communities/src/chat_message.ts @@ -10,14 +10,24 @@ import { } from "./proto/communities/v1/chat_message"; import { ImageType, MessageType } from "./proto/communities/v1/enums"; -export type MediaContent = StickerContent | ImageContent | AudioContent; +export type Content = + | TextContent + | StickerContent + | ImageContent + | AudioContent; export enum ContentType { + Text, Sticker, Image, Audio, } +export interface TextContent { + text: string; + contentType: ContentType.Text; +} + export interface StickerContent { hash: string; pack: number; @@ -37,15 +47,19 @@ export interface AudioContent { contentType: ContentType.Audio; } -function isSticker(content: MediaContent): content is StickerContent { +function isText(content: Content): content is TextContent { + return content.contentType === ContentType.Text; +} + +function isSticker(content: Content): content is StickerContent { return content.contentType === ContentType.Sticker; } -function isImage(content: MediaContent): content is ImageContent { +function isImage(content: Content): content is ImageContent { return content.contentType === ContentType.Image; } -function isAudio(content: MediaContent): content is AudioContent { +function isAudio(content: Content): content is AudioContent { return content.contentType === ContentType.Audio; } @@ -60,44 +74,42 @@ export class ChatMessage { public static createMessage( clock: number, timestamp: number, - text: string, chatId: string, - mediaContent?: MediaContent + content: Content ): ChatMessage { - let sticker, image, audio; + let sticker, + image, + audio, + text = "Upgrade to the latest version to see this media content."; let contentType = ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN; - if (mediaContent) { - if (isSticker(mediaContent)) { - if (!mediaContent.hash || !mediaContent.pack) - throw "Malformed Sticker Content"; - sticker = { - hash: mediaContent.hash, - pack: mediaContent.pack, - }; - contentType = ChatMessage_ContentType.CONTENT_TYPE_STICKER; - } else if (isImage(mediaContent)) { - if (!mediaContent.image || !mediaContent.imageType) - throw "Malformed Image Content"; - image = { - payload: mediaContent.image, - type: mediaContent.imageType, - }; - contentType = ChatMessage_ContentType.CONTENT_TYPE_IMAGE; - } else if (isAudio(mediaContent)) { - if ( - !mediaContent.audio || - !mediaContent.audioType || - !mediaContent.durationMs - ) - throw "Malformed Audio Content"; - audio = { - payload: mediaContent.audio, - type: mediaContent.audioType, - durationMs: mediaContent.durationMs, - }; - contentType = ChatMessage_ContentType.CONTENT_TYPE_AUDIO; - } + if (isText(content)) { + if (!content.text) throw "Malformed Text Content"; + text = content.text; + contentType = ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN; + } else if (isSticker(content)) { + if (!content.hash || !content.pack) throw "Malformed Sticker Content"; + sticker = { + hash: content.hash, + pack: content.pack, + }; + contentType = ChatMessage_ContentType.CONTENT_TYPE_STICKER; + } else if (isImage(content)) { + if (!content.image || !content.imageType) throw "Malformed Image Content"; + image = { + payload: content.image, + type: content.imageType, + }; + contentType = ChatMessage_ContentType.CONTENT_TYPE_IMAGE; + } else if (isAudio(content)) { + if (!content.audio || !content.audioType || !content.durationMs) + throw "Malformed Audio Content"; + audio = { + payload: content.audio, + type: content.audioType, + durationMs: content.durationMs, + }; + contentType = ChatMessage_ContentType.CONTENT_TYPE_AUDIO; } const proto = { diff --git a/packages/status-communities/src/messenger.spec.ts b/packages/status-communities/src/messenger.spec.ts index ad7799a..cdc5396 100644 --- a/packages/status-communities/src/messenger.spec.ts +++ b/packages/status-communities/src/messenger.spec.ts @@ -3,6 +3,7 @@ import debug from "debug"; import { utils } from "js-waku"; import { ApplicationMetadataMessage } from "./application_metadata_message"; +import { ContentType } from "./chat_message"; import { Identity } from "./identity"; import { Messenger } from "./messenger"; @@ -73,7 +74,10 @@ describe("Messenger", () => { }, testChatId); }); - await messengerAlice.sendMessage(text, testChatId); + await messengerAlice.sendMessage(testChatId, { + text, + contentType: ContentType.Text, + }); const receivedMessage = await receivedMessagePromise; @@ -95,7 +99,10 @@ describe("Messenger", () => { }, testChatId); }); - await messengerAlice.sendMessage(text, testChatId); + await messengerAlice.sendMessage(testChatId, { + text, + contentType: ContentType.Text, + }); const receivedMessage = await receivedMessagePromise; diff --git a/packages/status-communities/src/messenger.ts b/packages/status-communities/src/messenger.ts index b2f66f1..305b77d 100644 --- a/packages/status-communities/src/messenger.ts +++ b/packages/status-communities/src/messenger.ts @@ -4,7 +4,7 @@ import { CreateOptions as WakuCreateOptions } from "js-waku/build/main/lib/waku" import { ApplicationMetadataMessage } from "./application_metadata_message"; import { Chat } from "./chat"; -import { ChatMessage, MediaContent } from "./chat_message"; +import { ChatMessage, Content } from "./chat_message"; import { Identity } from "./identity"; import { ApplicationMetadataMessage_Type } from "./proto/status/v1/application_metadata_message"; @@ -72,15 +72,11 @@ export class Messenger { /** * Sends a message on the given chat Id. */ - public async sendMessage( - text: string, - chatId: string, - mediaContent?: MediaContent - ): Promise { + public async sendMessage(chatId: string, content: Content): Promise { const chat = this.chatsById.get(chatId); if (!chat) throw `Failed to send message, chat not joined: ${chatId}`; - const chatMessage = chat.createMessage(text, mediaContent); + const chatMessage = chat.createMessage(content); const appMetadataMessage = ApplicationMetadataMessage.create( chatMessage.encode(),