From 9d9723d137914a02d089599af839e11ddbbea0a1 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 6 Oct 2021 14:51:45 +1100 Subject: [PATCH] Instantiate chat from community --- packages/status-communities/src/chat.ts | 1 + packages/status-communities/src/community.ts | 34 ++++++++++++++++ .../src/wire/community_chat.ts | 39 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/packages/status-communities/src/chat.ts b/packages/status-communities/src/chat.ts index 95457c87..54ee5da2 100644 --- a/packages/status-communities/src/chat.ts +++ b/packages/status-communities/src/chat.ts @@ -13,6 +13,7 @@ export class Chat { /** * Create a public chat room. + * [[Community.instantiateChat]] MUST be used for chats belonging to a community. */ public static async create(id: string): Promise { const symKey = await createSymKeyFromPassword(id); diff --git a/packages/status-communities/src/community.ts b/packages/status-communities/src/community.ts index 7801d8d3..4e616804 100644 --- a/packages/status-communities/src/community.ts +++ b/packages/status-communities/src/community.ts @@ -1,7 +1,9 @@ import debug from "debug"; import { Waku } from "js-waku"; +import { Chat } from "./chat"; import { bufToHex, hexToBuf } from "./utils"; +import { CommunityChat } from "./wire/community_chat"; import { CommunityDescription } from "./wire/community_description"; const dbg = debug("communities:community"); @@ -25,6 +27,7 @@ export class Community { * * @param publicKey The community's public key in hex format. * Can be found in the community's invite link: https://join.status.im/c/ + * @param waku The Waku instance, used to retrieve Community information from the network. */ public async instantiateCommunity( publicKey: string, @@ -58,4 +61,35 @@ export class Community { this.description = desc; } + + /** + * Instantiate [[Chat]] object based on the passed chat name. + * The Chat MUST already be part of the Community and the name MUST be exact (including casing). + * + * @throws string If the Community Description is unavailable or the chat is not found; + */ + public async instantiateChat(chatName: string): Promise { + if (!this.description) { + await this.refreshCommunityDescription(); + if (!this.description) + throw "Failed to retrieve community description, cannot instantiate chat"; + } + + let communityChat: CommunityChat | undefined; + let chatId: string | undefined; + + this.description.chats.forEach((_chat, _id) => { + if (chatId) return; + + if (_chat.identity?.displayName === chatName) { + chatId = _id; + communityChat = _chat; + } + }); + + if (!communityChat || !chatId) + throw `Failed to retrieve community community chat with name ${chatName}`; + + return Chat.create(chatId); + } } diff --git a/packages/status-communities/src/wire/community_chat.ts b/packages/status-communities/src/wire/community_chat.ts index 9cf04c97..915dfd5b 100644 --- a/packages/status-communities/src/wire/community_chat.ts +++ b/packages/status-communities/src/wire/community_chat.ts @@ -1,10 +1,20 @@ import { Reader } from "protobufjs"; +import { ChatIdentity } from "../proto/communities/v1/chat_identity"; import * as proto from "../proto/communities/v1/communities"; +import { + CommunityMember, + CommunityPermissions, +} from "../proto/communities/v1/communities"; export class CommunityChat { public constructor(public proto: proto.CommunityChat) {} + /** + * Decode the payload as CommunityChat message. + * + * @throws + */ static decode(bytes: Uint8Array): CommunityChat { const protoBuf = proto.CommunityChat.decode(Reader.create(bytes)); @@ -14,4 +24,33 @@ export class CommunityChat { encode(): Uint8Array { return proto.CommunityChat.encode(this.proto).finish(); } + + // TODO: check and document what is the key of the returned Map; + public get members(): Map { + const map = new Map(); + + for (const key of Object.keys(this.proto.members)) { + map.set(key, this.proto.members[key]); + } + + return map; + } + + public get permissions(): CommunityPermissions | undefined { + return this.proto.permissions; + } + + public get identity(): ChatIdentity | undefined { + return this.proto.identity; + } + + // TODO: Document this + public get categoryId(): string | undefined { + return this.proto.categoryId; + } + + // TODO: Document this + public get position(): number | undefined { + return this.proto.position; + } }