move renderers to subfolder

This commit is contained in:
MapleLeaf
2021-12-28 13:53:23 -06:00
parent c64ba9eaaa
commit d89db1ceeb
7 changed files with 15 additions and 15 deletions

View File

@@ -0,0 +1,13 @@
import type { Channel } from "../channel"
import type { Message, MessageOptions } from "../message"
import { Renderer } from "./renderer"
export class ChannelMessageRenderer extends Renderer {
constructor(private channel: Channel) {
super()
}
protected createMessage(options: MessageOptions): Promise<Message> {
return this.channel.send(options)
}
}

View File

@@ -0,0 +1,22 @@
import type { CommandInteraction } from "../interaction"
import type { Message, MessageOptions } from "../message"
import { Renderer } from "./renderer"
// keep track of interaction ids which have replies,
// so we know whether to call reply() or followUp()
const repliedInteractionIds = new Set<string>()
export class CommandReplyRenderer extends Renderer {
constructor(private interaction: CommandInteraction) {
super()
}
protected createMessage(options: MessageOptions): Promise<Message> {
if (repliedInteractionIds.has(this.interaction.id)) {
return this.interaction.followUp(options)
}
repliedInteractionIds.add(this.interaction.id)
return this.interaction.reply(options)
}
}

View File

@@ -0,0 +1,105 @@
import { Subject } from "rxjs"
import { concatMap } from "rxjs/operators"
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 }
| { action: "destroy" }
export abstract class Renderer {
readonly nodes = new Container<Node<unknown>>()
private componentInteraction?: ComponentInteraction
private message?: Message
private active = true
private updates = new Subject<UpdatePayload>()
private updateSubscription = this.updates
.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")
return
}
this.updates.next({
options: this.getMessageOptions(),
action: "update",
})
}
deactivate() {
this.active = false
this.updates.next({
options: this.getMessageOptions(),
action: "deactivate",
})
}
destroy() {
this.active = false
this.updates.next({ action: "destroy" })
}
handleComponentInteraction(interaction: ComponentInteraction) {
this.componentInteraction = interaction
this.deferUpdateTimeout.run()
for (const node of this.nodes) {
if (node.handleComponentInteraction(interaction)) {
return true
}
}
}
protected abstract createMessage(options: MessageOptions): Promise<Message>
private getMessageOptions(): MessageOptions {
const options: MessageOptions = {
content: "",
embeds: [],
actionRows: [],
}
for (const node of this.nodes) {
node.modifyMessageOptions(options)
}
return options
}
private async updateMessage(payload: UpdatePayload) {
if (payload.action === "destroy") {
this.updateSubscription.unsubscribe()
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(payload.options)
this.componentInteraction = undefined
this.deferUpdateTimeout.cancel()
await promise
return
}
if (this.message) {
await this.message.edit(payload.options)
return
}
this.message = await this.createMessage(payload.options)
}
}