reply instance deletion
This commit is contained in:
@@ -100,6 +100,9 @@ function createReacordMessage(message: Discord.Message): Message {
|
|||||||
components: message.components,
|
components: message.components,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
delete: async () => {
|
||||||
|
await message.delete()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export type ReacordConfig<InteractionInit> = {
|
|||||||
export type ReacordInstance = {
|
export type ReacordInstance = {
|
||||||
render: (content: ReactNode) => void
|
render: (content: ReactNode) => void
|
||||||
deactivate: () => void
|
deactivate: () => void
|
||||||
|
destroy: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Reacord<InteractionInit> {
|
export class Reacord<InteractionInit> {
|
||||||
@@ -53,6 +54,10 @@ export class Reacord<InteractionInit> {
|
|||||||
deactivate: () => {
|
deactivate: () => {
|
||||||
this.deactivate(renderer)
|
this.deactivate(renderer)
|
||||||
},
|
},
|
||||||
|
destroy: () => {
|
||||||
|
this.renderers = this.renderers.filter((it) => it !== renderer)
|
||||||
|
renderer.destroy()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export type MessageSelectOptionOptions = {
|
|||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
edit(options: MessageOptions): Promise<void>
|
edit(options: MessageOptions): Promise<void>
|
||||||
|
delete(): Promise<void>
|
||||||
disableComponents(): Promise<void>
|
disableComponents(): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,9 @@ import type { Node } from "./node.js"
|
|||||||
// so we know whether to call reply() or followUp()
|
// so we know whether to call reply() or followUp()
|
||||||
const repliedInteractionIds = new Set<string>()
|
const repliedInteractionIds = new Set<string>()
|
||||||
|
|
||||||
type UpdatePayload = {
|
type UpdatePayload =
|
||||||
options: MessageOptions
|
| { action: "update" | "deactivate"; options: MessageOptions }
|
||||||
action: "update" | "deactivate"
|
| { action: "destroy" }
|
||||||
}
|
|
||||||
|
|
||||||
export class Renderer {
|
export class Renderer {
|
||||||
readonly nodes = new Container<Node<unknown>>()
|
readonly nodes = new Container<Node<unknown>>()
|
||||||
@@ -49,6 +48,11 @@ export class Renderer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.active = false
|
||||||
|
this.updates.next({ action: "destroy" })
|
||||||
|
}
|
||||||
|
|
||||||
handleComponentInteraction(interaction: ComponentInteraction) {
|
handleComponentInteraction(interaction: ComponentInteraction) {
|
||||||
this.componentInteraction = interaction
|
this.componentInteraction = interaction
|
||||||
for (const node of this.nodes) {
|
for (const node of this.nodes) {
|
||||||
@@ -70,31 +74,37 @@ export class Renderer {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateMessage({ options, action }: UpdatePayload) {
|
private async updateMessage(payload: UpdatePayload) {
|
||||||
if (action === "deactivate" && this.message) {
|
if (payload.action === "destroy") {
|
||||||
this.updateSubscription.unsubscribe()
|
this.updateSubscription.unsubscribe()
|
||||||
await this.message.disableComponents()
|
await this.message?.delete()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.action === "deactivate") {
|
||||||
|
this.updateSubscription.unsubscribe()
|
||||||
|
await this.message?.disableComponents()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.componentInteraction) {
|
if (this.componentInteraction) {
|
||||||
const promise = this.componentInteraction.update(options)
|
const promise = this.componentInteraction.update(payload.options)
|
||||||
this.componentInteraction = undefined
|
this.componentInteraction = undefined
|
||||||
await promise
|
await promise
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.message) {
|
if (this.message) {
|
||||||
await this.message.edit(options)
|
await this.message.edit(payload.options)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repliedInteractionIds.has(this.interaction.id)) {
|
if (repliedInteractionIds.has(this.interaction.id)) {
|
||||||
this.message = await this.interaction.followUp(options)
|
this.message = await this.interaction.followUp(payload.options)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repliedInteractionIds.add(this.interaction.id)
|
repliedInteractionIds.add(this.interaction.id)
|
||||||
this.message = await this.interaction.reply(options)
|
this.message = await this.interaction.reply(payload.options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import type {
|
|||||||
} from "./internal/message"
|
} from "./internal/message"
|
||||||
|
|
||||||
export class TestAdapter implements Adapter<TestCommandInteraction> {
|
export class TestAdapter implements Adapter<TestCommandInteraction> {
|
||||||
readonly messages: TestMessage[] = []
|
messages: TestMessage[] = []
|
||||||
|
|
||||||
private componentInteractionListener: (
|
private componentInteractionListener: (
|
||||||
interaction: ComponentInteraction,
|
interaction: ComponentInteraction,
|
||||||
@@ -60,6 +60,10 @@ export class TestAdapter implements Adapter<TestCommandInteraction> {
|
|||||||
raise(`Couldn't find select with placeholder "${placeholder}"`)
|
raise(`Couldn't find select with placeholder "${placeholder}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeMessage(message: TestMessage) {
|
||||||
|
this.messages = this.messages.filter((m) => m !== message)
|
||||||
|
}
|
||||||
|
|
||||||
private createButtonActions(
|
private createButtonActions(
|
||||||
button: MessageButtonOptions,
|
button: MessageButtonOptions,
|
||||||
message: TestMessage,
|
message: TestMessage,
|
||||||
@@ -88,7 +92,7 @@ export class TestAdapter implements Adapter<TestCommandInteraction> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TestMessage implements Message {
|
export class TestMessage implements Message {
|
||||||
constructor(public options: MessageOptions) {}
|
constructor(public options: MessageOptions, private adapter: TestAdapter) {}
|
||||||
|
|
||||||
async edit(options: MessageOptions): Promise<void> {
|
async edit(options: MessageOptions): Promise<void> {
|
||||||
this.options = options
|
this.options = options
|
||||||
@@ -103,6 +107,10 @@ export class TestMessage implements Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delete(): Promise<void> {
|
||||||
|
this.adapter.removeMessage(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TestCommandInteraction implements CommandInteraction {
|
export class TestCommandInteraction implements CommandInteraction {
|
||||||
@@ -113,7 +121,7 @@ export class TestCommandInteraction implements CommandInteraction {
|
|||||||
constructor(private adapter: TestAdapter) {}
|
constructor(private adapter: TestAdapter) {}
|
||||||
|
|
||||||
private createMesssage(messageOptions: MessageOptions): Message {
|
private createMesssage(messageOptions: MessageOptions): Message {
|
||||||
const message = new TestMessage(messageOptions)
|
const message = new TestMessage(messageOptions, this.adapter)
|
||||||
this.adapter.messages.push(message)
|
this.adapter.messages.push(message)
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import { Button, Embed, EmbedField, EmbedTitle } from "../library/main"
|
|||||||
import { TestCommandInteraction } from "../library/testing"
|
import { TestCommandInteraction } from "../library/testing"
|
||||||
import { setupReacordTesting } from "./setup-testing"
|
import { setupReacordTesting } from "./setup-testing"
|
||||||
|
|
||||||
|
test("rendering behavior", async () => {
|
||||||
const { reacord, adapter, assertMessages } = setupReacordTesting()
|
const { reacord, adapter, assertMessages } = setupReacordTesting()
|
||||||
|
|
||||||
test("rendering behavior", async () => {
|
|
||||||
const reply = reacord.createCommandReply(new TestCommandInteraction(adapter))
|
const reply = reacord.createCommandReply(new TestCommandInteraction(adapter))
|
||||||
reply.render(<KitchenSinkCounter onDeactivate={() => reply.deactivate()} />)
|
reply.render(<KitchenSinkCounter onDeactivate={() => 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
|
||||||
|
<Embed>some embed</Embed>
|
||||||
|
<Button label="some button" onClick={() => {}} />
|
||||||
|
</>,
|
||||||
|
)
|
||||||
|
|
||||||
|
await assertMessages([
|
||||||
|
{
|
||||||
|
content: "some text",
|
||||||
|
embeds: [{ description: "some embed" }],
|
||||||
|
actionRows: [
|
||||||
|
[{ type: "button", style: "secondary", label: "some button" }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
reply.destroy()
|
||||||
|
await assertMessages([])
|
||||||
|
})
|
||||||
|
|
||||||
// test multiple instances that can be updated independently,
|
// test multiple instances that can be updated independently,
|
||||||
// + old instances getting deactivated once the limit is reached
|
// + old instances getting deactivated once the limit is reached
|
||||||
test.todo("multiple instances")
|
test.todo("multiple instances")
|
||||||
|
|||||||
7
todo.md
7
todo.md
@@ -22,9 +22,14 @@
|
|||||||
- [x] action row
|
- [x] action row
|
||||||
- [x] button onClick
|
- [x] button onClick
|
||||||
- [x] deactivate
|
- [x] deactivate
|
||||||
- [ ] destroy
|
- [x] destroy
|
||||||
- [ ] docs
|
- [ ] docs
|
||||||
|
|
||||||
|
# internal
|
||||||
|
|
||||||
|
- [ ] combine `MessageOptions` and `Message` into a single message object (?)
|
||||||
|
- [ ] consider always calling `deferUpdate` on component interactions
|
||||||
|
|
||||||
# cool ideas / polish
|
# cool ideas / polish
|
||||||
|
|
||||||
- [ ] message property on reacord instance
|
- [ ] message property on reacord instance
|
||||||
|
|||||||
Reference in New Issue
Block a user