queued updates via rxjs

This commit is contained in:
MapleLeaf
2021-12-25 11:12:17 -06:00
parent c74f8df231
commit 433e445c1d
4 changed files with 48 additions and 27 deletions

View File

@@ -30,7 +30,7 @@
"immer": "^9.0.7", "immer": "^9.0.7",
"nanoid": "^3.1.30", "nanoid": "^3.1.30",
"react-reconciler": "^0.26.2", "react-reconciler": "^0.26.2",
"react-tree-reconciler": "^1.2.0" "rxjs": "^7.4.0"
}, },
"peerDependencies": { "peerDependencies": {
"discord.js": "^13.3", "discord.js": "^13.3",

View File

@@ -17,6 +17,7 @@ createCommandHandler(client, [
description: "shows a counter button", description: "shows a counter button",
run: (interaction) => { run: (interaction) => {
manager.create(interaction).render(<Counter />) manager.create(interaction).render(<Counter />)
manager.create(interaction).render(<Counter />)
}, },
}, },
]) ])

18
pnpm-lock.yaml generated
View File

@@ -30,7 +30,7 @@ importers:
prettier: ^2.5.1 prettier: ^2.5.1
react: ^17.0.2 react: ^17.0.2
react-reconciler: ^0.26.2 react-reconciler: ^0.26.2
react-tree-reconciler: ^1.2.0 rxjs: ^7.4.0
tsup: ^5.11.7 tsup: ^5.11.7
typescript: ^4.5.4 typescript: ^4.5.4
vite: ^2.7.6 vite: ^2.7.6
@@ -42,7 +42,7 @@ importers:
immer: 9.0.7 immer: 9.0.7
nanoid: 3.1.30 nanoid: 3.1.30
react-reconciler: 0.26.2_react@17.0.2 react-reconciler: 0.26.2_react@17.0.2
react-tree-reconciler: 1.2.0_cfedea9b3ed0faf0dded75c187406c5e rxjs: 7.4.0
devDependencies: devDependencies:
'@itsmapleleaf/configs': 1.1.2 '@itsmapleleaf/configs': 1.1.2
'@typescript-eslint/eslint-plugin': 5.8.0_836011a006f4f5d67178564baf2b6d34 '@typescript-eslint/eslint-plugin': 5.8.0_836011a006f4f5d67178564baf2b6d34
@@ -4830,18 +4830,6 @@ packages:
scheduler: 0.20.2 scheduler: 0.20.2
dev: false dev: false
/react-tree-reconciler/1.2.0_cfedea9b3ed0faf0dded75c187406c5e:
resolution: {integrity: sha512-DmILQhig+Nnh1tOrYFn7Tary077qW943vdjYqRUWLpYLMP5vS/+k0ICNTPQVNaLQJhh4nDCvVUhFxcSSTzYvHA==}
engines: {node: '>=12'}
peerDependencies:
'@types/react': '*'
dependencies:
'@types/react': 17.0.37
react-reconciler: 0.26.2_react@17.0.2
transitivePeerDependencies:
- react
dev: false
/react/17.0.2: /react/17.0.2:
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@@ -5050,7 +5038,6 @@ packages:
resolution: {integrity: sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==} resolution: {integrity: sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==}
dependencies: dependencies:
tslib: 2.1.0 tslib: 2.1.0
dev: true
/safe-buffer/5.1.2: /safe-buffer/5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
@@ -5536,7 +5523,6 @@ packages:
/tslib/2.1.0: /tslib/2.1.0:
resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==} resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==}
dev: true
/tslib/2.3.1: /tslib/2.3.1:
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}

View File

@@ -3,25 +3,29 @@ import type {
MessageComponentInteraction, MessageComponentInteraction,
MessageOptions, MessageOptions,
} from "discord.js" } from "discord.js"
import { Subject } from "rxjs"
import { concatMap } from "rxjs/operators"
import { Container } from "./container.js" import { Container } from "./container.js"
import type { Node } from "./node.js" import type { Node } from "./node.js"
// keep track of interaction ids which have replies,
// so we know whether to call reply() or followUp()
const repliedInteractionIds = new Set<string>()
export class Renderer { export class Renderer {
readonly nodes = new Container<Node<unknown>>() readonly nodes = new Container<Node<unknown>>()
private componentInteraction?: MessageComponentInteraction private componentInteraction?: MessageComponentInteraction
private messageId?: string
private updates = new Subject<MessageOptions>()
constructor(private interaction: CommandInteraction) {} constructor(private interaction: CommandInteraction) {
this.updates
.pipe(concatMap((options) => this.updateMessage(options)))
.subscribe()
}
render() { render() {
const options = this.getMessageOptions() this.updates.next(this.getMessageOptions())
if (this.componentInteraction) {
this.componentInteraction.update(options).catch(console.error)
this.componentInteraction = undefined
} else if (this.interaction.replied) {
this.interaction.editReply(options).catch(console.error)
} else {
this.interaction.reply(options).catch(console.error)
}
} }
handleInteraction(interaction: MessageComponentInteraction) { handleInteraction(interaction: MessageComponentInteraction) {
@@ -44,4 +48,34 @@ export class Renderer {
} }
return options return options
} }
private async updateMessage(options: MessageOptions) {
if (this.componentInteraction) {
const promise = this.componentInteraction.update(options)
this.componentInteraction = undefined
await promise
return
}
if (this.messageId) {
await this.interaction.channel?.messages.edit(this.messageId, options)
return
}
if (repliedInteractionIds.has(this.interaction.id)) {
const message = await this.interaction.followUp({
...options,
fetchReply: true,
})
this.messageId = message.id
return
}
repliedInteractionIds.add(this.interaction.id)
const message = await this.interaction.reply({
...options,
fetchReply: true,
})
this.messageId = message.id
}
} }