From 8db2a163056b61dd8686af18a65012eb5d681049 Mon Sep 17 00:00:00 2001 From: MapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com> Date: Mon, 27 Dec 2021 13:50:56 -0600 Subject: [PATCH] reply instance deletion --- library/core/adapters/discord-js-adapter.ts | 3 ++ library/core/reacord.ts | 5 ++++ library/internal/message.ts | 1 + library/internal/renderer.ts | 32 ++++++++++++++------- library/testing.ts | 14 +++++++-- test/reacord.test.tsx | 30 +++++++++++++++++-- todo.md | 7 ++++- 7 files changed, 75 insertions(+), 17 deletions(-) diff --git a/library/core/adapters/discord-js-adapter.ts b/library/core/adapters/discord-js-adapter.ts index 8897c6a..dff7a06 100644 --- a/library/core/adapters/discord-js-adapter.ts +++ b/library/core/adapters/discord-js-adapter.ts @@ -100,6 +100,9 @@ function createReacordMessage(message: Discord.Message): Message { components: message.components, }) }, + delete: async () => { + await message.delete() + }, } } diff --git a/library/core/reacord.ts b/library/core/reacord.ts index cacb349..8e23191 100644 --- a/library/core/reacord.ts +++ b/library/core/reacord.ts @@ -16,6 +16,7 @@ export type ReacordConfig = { export type ReacordInstance = { render: (content: ReactNode) => void deactivate: () => void + destroy: () => void } export class Reacord { @@ -53,6 +54,10 @@ export class Reacord { deactivate: () => { this.deactivate(renderer) }, + destroy: () => { + this.renderers = this.renderers.filter((it) => it !== renderer) + renderer.destroy() + }, } } diff --git a/library/internal/message.ts b/library/internal/message.ts index df89a31..a670a12 100644 --- a/library/internal/message.ts +++ b/library/internal/message.ts @@ -45,6 +45,7 @@ export type MessageSelectOptionOptions = { export type Message = { edit(options: MessageOptions): Promise + delete(): Promise disableComponents(): Promise } diff --git a/library/internal/renderer.ts b/library/internal/renderer.ts index 9256dd0..f2ad0b1 100644 --- a/library/internal/renderer.ts +++ b/library/internal/renderer.ts @@ -10,10 +10,9 @@ import type { Node } from "./node.js" // so we know whether to call reply() or followUp() const repliedInteractionIds = new Set() -type UpdatePayload = { - options: MessageOptions - action: "update" | "deactivate" -} +type UpdatePayload = + | { action: "update" | "deactivate"; options: MessageOptions } + | { action: "destroy" } export class Renderer { readonly nodes = new Container>() @@ -49,6 +48,11 @@ export class Renderer { }) } + destroy() { + this.active = false + this.updates.next({ action: "destroy" }) + } + handleComponentInteraction(interaction: ComponentInteraction) { this.componentInteraction = interaction for (const node of this.nodes) { @@ -70,31 +74,37 @@ export class Renderer { return options } - private async updateMessage({ options, action }: UpdatePayload) { - if (action === "deactivate" && this.message) { + private async updateMessage(payload: UpdatePayload) { + if (payload.action === "destroy") { this.updateSubscription.unsubscribe() - await this.message.disableComponents() + await this.message?.delete() + return + } + + if (payload.action === "deactivate") { + this.updateSubscription.unsubscribe() + await this.message?.disableComponents() return } if (this.componentInteraction) { - const promise = this.componentInteraction.update(options) + const promise = this.componentInteraction.update(payload.options) this.componentInteraction = undefined await promise return } if (this.message) { - await this.message.edit(options) + await this.message.edit(payload.options) return } if (repliedInteractionIds.has(this.interaction.id)) { - this.message = await this.interaction.followUp(options) + this.message = await this.interaction.followUp(payload.options) return } repliedInteractionIds.add(this.interaction.id) - this.message = await this.interaction.reply(options) + this.message = await this.interaction.reply(payload.options) } } diff --git a/library/testing.ts b/library/testing.ts index 42d3c47..8f8cd48 100644 --- a/library/testing.ts +++ b/library/testing.ts @@ -17,7 +17,7 @@ import type { } from "./internal/message" export class TestAdapter implements Adapter { - readonly messages: TestMessage[] = [] + messages: TestMessage[] = [] private componentInteractionListener: ( interaction: ComponentInteraction, @@ -60,6 +60,10 @@ export class TestAdapter implements Adapter { raise(`Couldn't find select with placeholder "${placeholder}"`) } + removeMessage(message: TestMessage) { + this.messages = this.messages.filter((m) => m !== message) + } + private createButtonActions( button: MessageButtonOptions, message: TestMessage, @@ -88,7 +92,7 @@ export class TestAdapter implements Adapter { } export class TestMessage implements Message { - constructor(public options: MessageOptions) {} + constructor(public options: MessageOptions, private adapter: TestAdapter) {} async edit(options: MessageOptions): Promise { this.options = options @@ -103,6 +107,10 @@ export class TestMessage implements Message { } } } + + async delete(): Promise { + this.adapter.removeMessage(this) + } } export class TestCommandInteraction implements CommandInteraction { @@ -113,7 +121,7 @@ export class TestCommandInteraction implements CommandInteraction { constructor(private adapter: TestAdapter) {} private createMesssage(messageOptions: MessageOptions): Message { - const message = new TestMessage(messageOptions) + const message = new TestMessage(messageOptions, this.adapter) this.adapter.messages.push(message) return message } diff --git a/test/reacord.test.tsx b/test/reacord.test.tsx index ddff245..922cf84 100644 --- a/test/reacord.test.tsx +++ b/test/reacord.test.tsx @@ -3,9 +3,9 @@ import { Button, Embed, EmbedField, EmbedTitle } from "../library/main" import { TestCommandInteraction } from "../library/testing" import { setupReacordTesting } from "./setup-testing" -const { reacord, adapter, assertMessages } = setupReacordTesting() - test("rendering behavior", async () => { + const { reacord, adapter, assertMessages } = setupReacordTesting() + const reply = reacord.createCommandReply(new TestCommandInteraction(adapter)) reply.render( reply.deactivate()} />) @@ -241,6 +241,32 @@ test("rendering behavior", async () => { ]) }) +test("delete", async () => { + const { reacord, adapter, assertMessages } = setupReacordTesting() + + const reply = reacord.createCommandReply(new TestCommandInteraction(adapter)) + reply.render( + <> + some text + some embed +