organization
This commit is contained in:
@@ -7,8 +7,9 @@ import type {
|
||||
} from "discord.js"
|
||||
import type { Action } from "./action-queue.js"
|
||||
import { ActionQueue } from "./action-queue.js"
|
||||
import type { MessageNode } from "./node-tree.js"
|
||||
import { collectInteractionHandlers, getMessageOptions } from "./node-tree.js"
|
||||
import { collectInteractionHandlers } from "./collect-interaction-handlers"
|
||||
import { createMessageOptions } from "./create-message-options"
|
||||
import type { MessageNode } from "./node.js"
|
||||
|
||||
export class ChannelRenderer {
|
||||
private channel: TextBasedChannels
|
||||
@@ -60,12 +61,12 @@ export class ChannelRenderer {
|
||||
return this.actions.done()
|
||||
}
|
||||
|
||||
private createUpdateMessageAction(tree: MessageNode): Action {
|
||||
private createUpdateMessageAction(node: MessageNode): Action {
|
||||
return {
|
||||
id: "updateMessage",
|
||||
priority: 0,
|
||||
run: async () => {
|
||||
const options = getMessageOptions(tree)
|
||||
const options = createMessageOptions(node)
|
||||
|
||||
// eslint-disable-next-line unicorn/prefer-ternary
|
||||
if (this.message) {
|
||||
|
||||
20
src/collect-interaction-handlers.ts
Normal file
20
src/collect-interaction-handlers.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { ButtonInteraction } from "discord.js"
|
||||
import type { Node } from "./node"
|
||||
|
||||
type InteractionHandler = {
|
||||
type: "button"
|
||||
customId: string
|
||||
onClick: (interaction: ButtonInteraction) => void
|
||||
}
|
||||
|
||||
export function collectInteractionHandlers(node: Node): InteractionHandler[] {
|
||||
if (node.type === "button") {
|
||||
return [{ type: "button", customId: node.customId, onClick: node.onClick }]
|
||||
}
|
||||
|
||||
if ("children" in node) {
|
||||
return node.children.flatMap(collectInteractionHandlers)
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
@@ -1,83 +1,14 @@
|
||||
import type {
|
||||
BaseMessageComponentOptions,
|
||||
ButtonInteraction,
|
||||
ColorResolvable,
|
||||
EmojiResolvable,
|
||||
MessageActionRowOptions,
|
||||
MessageEmbedOptions,
|
||||
MessageOptions,
|
||||
} from "discord.js"
|
||||
import type { ButtonStyle } from "./components/button.js"
|
||||
import { last } from "./helpers/last.js"
|
||||
import { toUpper } from "./helpers/to-upper.js"
|
||||
import type { EmbedNode, MessageNode, Node } from "./node"
|
||||
|
||||
export type MessageNode = {
|
||||
type: "message"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
export type TextNode = {
|
||||
type: "text"
|
||||
text: string
|
||||
}
|
||||
|
||||
type TextElementNode = {
|
||||
type: "textElement"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type EmbedNode = {
|
||||
type: "embed"
|
||||
title?: string
|
||||
color?: ColorResolvable
|
||||
url?: string
|
||||
timestamp?: Date | number | string
|
||||
imageUrl?: string
|
||||
thumbnailUrl?: string
|
||||
author?: {
|
||||
name: string
|
||||
url?: string
|
||||
iconUrl?: string
|
||||
}
|
||||
footer?: {
|
||||
text: string
|
||||
iconUrl?: string
|
||||
}
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type EmbedFieldNode = {
|
||||
type: "embedField"
|
||||
name: string
|
||||
inline?: boolean
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type ActionRowNode = {
|
||||
type: "actionRow"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type ButtonNode = {
|
||||
type: "button"
|
||||
style?: ButtonStyle
|
||||
emoji?: EmojiResolvable
|
||||
disabled?: boolean
|
||||
customId: string
|
||||
onClick: (interaction: ButtonInteraction) => void
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
export type Node =
|
||||
| MessageNode
|
||||
| TextNode
|
||||
| TextElementNode
|
||||
| EmbedNode
|
||||
| EmbedFieldNode
|
||||
| ActionRowNode
|
||||
| ButtonNode
|
||||
|
||||
export function getMessageOptions(node: MessageNode): MessageOptions {
|
||||
export function createMessageOptions(node: MessageNode): MessageOptions {
|
||||
if (node.children.length === 0) {
|
||||
// can't send an empty message
|
||||
return { content: "_ _" }
|
||||
@@ -183,7 +114,7 @@ function addActionRowItems(components: ActionRowOptions[], nodes: Node[]) {
|
||||
if (node.type === "button") {
|
||||
actionRow.components.push({
|
||||
type: "BUTTON",
|
||||
label: node.children.map(getNodeText).join("") || "_ _",
|
||||
label: node.children.map(getNodeText).join(""),
|
||||
style: node.style ? toUpper(node.style) : "SECONDARY",
|
||||
emoji: node.emoji,
|
||||
disabled: node.disabled,
|
||||
@@ -192,21 +123,3 @@ function addActionRowItems(components: ActionRowOptions[], nodes: Node[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type InteractionHandler = {
|
||||
type: "button"
|
||||
customId: string
|
||||
onClick: (interaction: ButtonInteraction) => void
|
||||
}
|
||||
|
||||
export function collectInteractionHandlers(node: Node): InteractionHandler[] {
|
||||
if (node.type === "button") {
|
||||
return [{ type: "button", customId: node.customId, onClick: node.onClick }]
|
||||
}
|
||||
|
||||
if ("children" in node) {
|
||||
return node.children.flatMap(collectInteractionHandlers)
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
2
src/jsx.d.ts
vendored
2
src/jsx.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import type { ReactNode } from "react"
|
||||
import type { Node } from "./node-tree"
|
||||
import type { Node } from "./node"
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
|
||||
72
src/node.ts
Normal file
72
src/node.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type {
|
||||
ButtonInteraction,
|
||||
ColorResolvable,
|
||||
EmojiResolvable,
|
||||
} from "discord.js"
|
||||
import type { ButtonStyle } from "./components/button.jsx"
|
||||
|
||||
export type MessageNode = {
|
||||
type: "message"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
export type TextNode = {
|
||||
type: "text"
|
||||
text: string
|
||||
}
|
||||
|
||||
type TextElementNode = {
|
||||
type: "textElement"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
export type EmbedNode = {
|
||||
type: "embed"
|
||||
title?: string
|
||||
color?: ColorResolvable
|
||||
url?: string
|
||||
timestamp?: Date | number | string
|
||||
imageUrl?: string
|
||||
thumbnailUrl?: string
|
||||
author?: {
|
||||
name: string
|
||||
url?: string
|
||||
iconUrl?: string
|
||||
}
|
||||
footer?: {
|
||||
text: string
|
||||
iconUrl?: string
|
||||
}
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type EmbedFieldNode = {
|
||||
type: "embedField"
|
||||
name: string
|
||||
inline?: boolean
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type ActionRowNode = {
|
||||
type: "actionRow"
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
type ButtonNode = {
|
||||
type: "button"
|
||||
style?: ButtonStyle
|
||||
emoji?: EmojiResolvable
|
||||
disabled?: boolean
|
||||
customId: string
|
||||
onClick: (interaction: ButtonInteraction) => void
|
||||
children: Node[]
|
||||
}
|
||||
|
||||
export type Node =
|
||||
| MessageNode
|
||||
| TextNode
|
||||
| TextElementNode
|
||||
| EmbedNode
|
||||
| EmbedFieldNode
|
||||
| ActionRowNode
|
||||
| ButtonNode
|
||||
@@ -3,7 +3,7 @@ import { inspect } from "node:util"
|
||||
import ReactReconciler from "react-reconciler"
|
||||
import type { ChannelRenderer } from "./channel-renderer.js"
|
||||
import { raise } from "./helpers/raise.js"
|
||||
import type { MessageNode, Node, TextNode } from "./node-tree.js"
|
||||
import type { MessageNode, Node, TextNode } from "./node.js"
|
||||
|
||||
type ElementTag = string
|
||||
|
||||
|
||||
Reference in New Issue
Block a user