From 8260ed0af5e69f39d65d8ee4eaa6e51157821e4f Mon Sep 17 00:00:00 2001 From: Piotr Suwala Date: Tue, 19 Sep 2023 12:02:14 +0200 Subject: [PATCH] feat(lib): add removing threads --- lib/src/entities/chat.ts | 23 ++++++++++++++++++ lib/src/entities/message.ts | 4 ++++ lib/src/entities/thread-channel.ts | 24 +++++++++++++++++-- lib/src/types.ts | 5 +++- lib/tests/channel.test.ts | 2 +- .../message-list/message-list.component.html | 1 + .../message-list/message-list.component.ts | 5 ++++ 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/lib/src/entities/chat.ts b/lib/src/entities/chat.ts index 3c1fe4ba..7f91069e 100644 --- a/lib/src/entities/chat.ts +++ b/lib/src/entities/chat.ts @@ -350,6 +350,7 @@ export class Chat { }) return ThreadChannel.fromDTO(this, { ...response.data, + parentMessage: message, parentChannelId: message.channelId, }) } catch (error) { @@ -381,6 +382,7 @@ export class Chat { const data = await Promise.all([ ThreadChannel.fromDTO(this, { ...response.data, + parentMessage: message, parentChannelId: message.channelId, }), this.sdk.addMessageAction({ @@ -400,6 +402,26 @@ export class Chat { } } + /** @internal */ + async removeThreadChannel(message: Message) { + if (!message.hasThread) { + throw "There is no thread to be deleted" + } + + const actionTimetoken = + message.actions?.threadRootId[this.getThreadId(message.channelId, message.timetoken)][0] + .actionTimetoken + if (!actionTimetoken) { + throw "There is no action timetoken corresponding to the thread" + } + + return this.sdk.removeMessageAction({ + channel: message.channelId, + messageTimetoken: message.timetoken, + actionTimetoken: String(actionTimetoken), + }) + } + /** * Channels */ @@ -885,6 +907,7 @@ export class Chat { threadChannel: ThreadChannel.fromDTO(this, { id: (channel as Channel).id, parentChannelId: parentChannel.id, + parentMessage: message, }), message: message as Message, user: user as User, diff --git a/lib/src/entities/message.ts b/lib/src/entities/message.ts index c9ea8c6b..04f5bb31 100644 --- a/lib/src/entities/message.ts +++ b/lib/src/entities/message.ts @@ -324,6 +324,10 @@ export class Message { return this.chat.createThreadChannel(this) } + removeThread() { + return this.chat.removeThreadChannel(this) + } + /** @internal */ private async deleteThread(params: DeleteParameters = {}) { if (this.hasThread) { diff --git a/lib/src/entities/thread-channel.ts b/lib/src/entities/thread-channel.ts index 4bcd51ce..24edb040 100644 --- a/lib/src/entities/thread-channel.ts +++ b/lib/src/entities/thread-channel.ts @@ -1,17 +1,25 @@ import { ObjectCustom, SetChannelMetadataResponse } from "pubnub" import { Channel, ChannelFields } from "./channel" import { Chat } from "./chat" -import { ThreadChannelDTOParams } from "../types" +import { DeleteParameters, ThreadChannelDTOParams } from "../types" import { ThreadMessage } from "./thread-message" import { getErrorProxiedEntity } from "../error-logging" +import { MESSAGE_THREAD_ID_PREFIX } from "../constants" +import { Message } from "./message" export class ThreadChannel extends Channel { readonly parentChannelId: string + /** @internal */ + readonly parentMessage: Message /** @internal */ - constructor(chat: Chat, params: ChannelFields & { parentChannelId: string }) { + constructor( + chat: Chat, + params: ChannelFields & { parentChannelId: string; parentMessage: Message } + ) { super(chat, params) this.parentChannelId = params.parentChannelId + this.parentMessage = params.parentMessage } /** @internal */ @@ -19,6 +27,7 @@ export class ThreadChannel extends Channel { const data = { id: params.id, parentChannelId: params.parentChannelId, + parentMessage: params.parentMessage, name: params.name || undefined, custom: params.custom || undefined, description: params.description || undefined, @@ -37,6 +46,7 @@ export class ThreadChannel extends Channel { )) as SetChannelMetadataResponse return ThreadChannel.fromDTO(this.chat, { ...response.data, + parentMessage: this.parentMessage, parentChannelId: this.parentChannelId, }) } @@ -45,6 +55,7 @@ export class ThreadChannel extends Channel { const response = await this.chat.pinMessageToChannel(null, this) return ThreadChannel.fromDTO(this.chat, { ...response.data, + parentMessage: this.parentMessage, parentChannelId: this.parentChannelId, }) } @@ -89,6 +100,15 @@ export class ThreadChannel extends Channel { } } + override async delete(options: DeleteParameters = {}) { + const data = await Promise.all([ + this.chat.removeThreadChannel(this.parentMessage), + super.delete(options), + ]) + + return data[1] + } + /** @internal */ protected emitUserMention({ userId, diff --git a/lib/src/types.ts b/lib/src/types.ts index c6ff8d57..76ddd0d8 100644 --- a/lib/src/types.ts +++ b/lib/src/types.ts @@ -109,7 +109,10 @@ export type ChannelDTOParams = OptionalAllBut { await user2.delete() }) //To be clarified deleting - test("should create reply to, and delete a thread", async () => { + test.only("should create reply to, and delete a thread", async () => { const messageText = "Test message" await channel.sendText(messageText) await sleep(150) // history calls have around 130ms of cache time diff --git a/samples/angular/src/chat-sdk/message-list/message-list.component.html b/samples/angular/src/chat-sdk/message-list/message-list.component.html index b7a20a5b..6ee3f1fa 100644 --- a/samples/angular/src/chat-sdk/message-list/message-list.component.html +++ b/samples/angular/src/chat-sdk/message-list/message-list.component.html @@ -42,6 +42,7 @@

Message List

Thread pinned message: {{ pinnedMessages[threadMessages[message.timetoken][0].channelId] }} +
diff --git a/samples/angular/src/chat-sdk/message-list/message-list.component.ts b/samples/angular/src/chat-sdk/message-list/message-list.component.ts index 1986507a..e73d4dfb 100644 --- a/samples/angular/src/chat-sdk/message-list/message-list.component.ts +++ b/samples/angular/src/chat-sdk/message-list/message-list.component.ts @@ -129,6 +129,7 @@ export class MessageListComponentChat { } const thread = await message.getThread() + const threadMessages = await thread!.getHistory() await this.getPinnedMessage(thread!) this.threadMessages[message.timetoken] = threadMessages.messages @@ -170,4 +171,8 @@ export class MessageListComponentChat { this.threadInputOpen = message.timetoken } + + async removeThread(message: Message) { + message.removeThread() + } }