defer update if there's no component update

This commit is contained in:
MapleLeaf
2021-12-27 21:41:14 -06:00
parent 3d89b4fe6f
commit 9ab1f2b689
7 changed files with 61 additions and 8 deletions

View File

@@ -18,6 +18,7 @@ export type ButtonInteraction = {
channelId: string
customId: string
update(options: MessageOptions): Promise<void>
deferUpdate(): Promise<void>
}
export type SelectInteraction = {
@@ -27,4 +28,5 @@ export type SelectInteraction = {
customId: string
values: string[]
update(options: MessageOptions): Promise<void>
deferUpdate(): Promise<void>
}

View File

@@ -4,6 +4,7 @@ import { Container } from "./container.js"
import type { ComponentInteraction } from "./interaction"
import type { Message, MessageOptions } from "./message"
import type { Node } from "./node.js"
import { Timeout } from "./timeout"
type UpdatePayload =
| { action: "update" | "deactivate"; options: MessageOptions }
@@ -20,6 +21,10 @@ export abstract class Renderer {
.pipe(concatMap((payload) => this.updateMessage(payload)))
.subscribe({ error: console.error })
private deferUpdateTimeout = new Timeout(500, () => {
this.componentInteraction?.deferUpdate().catch(console.error)
})
render() {
if (!this.active) {
console.warn("Attempted to update a deactivated message")
@@ -47,6 +52,7 @@ export abstract class Renderer {
handleComponentInteraction(interaction: ComponentInteraction) {
this.componentInteraction = interaction
this.deferUpdateTimeout.run()
for (const node of this.nodes) {
if (node.handleComponentInteraction(interaction)) {
return true
@@ -84,6 +90,7 @@ export abstract class Renderer {
if (this.componentInteraction) {
const promise = this.componentInteraction.update(payload.options)
this.componentInteraction = undefined
this.deferUpdateTimeout.cancel()
await promise
return
}

View File

@@ -0,0 +1,20 @@
export class Timeout {
private timeoutId?: NodeJS.Timeout
constructor(
private readonly time: number,
private readonly callback: () => void,
) {}
run() {
this.cancel()
this.timeoutId = setTimeout(this.callback, this.time)
}
cancel() {
if (this.timeoutId) {
clearTimeout(this.timeoutId)
this.timeoutId = undefined
}
}
}