organization
This commit is contained in:
@@ -7,8 +7,9 @@ import type {
|
|||||||
} from "discord.js"
|
} from "discord.js"
|
||||||
import type { Action } from "./action-queue.js"
|
import type { Action } from "./action-queue.js"
|
||||||
import { ActionQueue } from "./action-queue.js"
|
import { ActionQueue } from "./action-queue.js"
|
||||||
import type { MessageNode } from "./node-tree.js"
|
import { collectInteractionHandlers } from "./collect-interaction-handlers"
|
||||||
import { collectInteractionHandlers, getMessageOptions } from "./node-tree.js"
|
import { createMessageOptions } from "./create-message-options"
|
||||||
|
import type { MessageNode } from "./node.js"
|
||||||
|
|
||||||
export class ChannelRenderer {
|
export class ChannelRenderer {
|
||||||
private channel: TextBasedChannels
|
private channel: TextBasedChannels
|
||||||
@@ -60,12 +61,12 @@ export class ChannelRenderer {
|
|||||||
return this.actions.done()
|
return this.actions.done()
|
||||||
}
|
}
|
||||||
|
|
||||||
private createUpdateMessageAction(tree: MessageNode): Action {
|
private createUpdateMessageAction(node: MessageNode): Action {
|
||||||
return {
|
return {
|
||||||
id: "updateMessage",
|
id: "updateMessage",
|
||||||
priority: 0,
|
priority: 0,
|
||||||
run: async () => {
|
run: async () => {
|
||||||
const options = getMessageOptions(tree)
|
const options = createMessageOptions(node)
|
||||||
|
|
||||||
// eslint-disable-next-line unicorn/prefer-ternary
|
// eslint-disable-next-line unicorn/prefer-ternary
|
||||||
if (this.message) {
|
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 {
|
import type {
|
||||||
BaseMessageComponentOptions,
|
BaseMessageComponentOptions,
|
||||||
ButtonInteraction,
|
|
||||||
ColorResolvable,
|
|
||||||
EmojiResolvable,
|
|
||||||
MessageActionRowOptions,
|
MessageActionRowOptions,
|
||||||
MessageEmbedOptions,
|
MessageEmbedOptions,
|
||||||
MessageOptions,
|
MessageOptions,
|
||||||
} from "discord.js"
|
} from "discord.js"
|
||||||
import type { ButtonStyle } from "./components/button.js"
|
|
||||||
import { last } from "./helpers/last.js"
|
import { last } from "./helpers/last.js"
|
||||||
import { toUpper } from "./helpers/to-upper.js"
|
import { toUpper } from "./helpers/to-upper.js"
|
||||||
|
import type { EmbedNode, MessageNode, Node } from "./node"
|
||||||
|
|
||||||
export type MessageNode = {
|
export function createMessageOptions(node: MessageNode): MessageOptions {
|
||||||
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 {
|
|
||||||
if (node.children.length === 0) {
|
if (node.children.length === 0) {
|
||||||
// can't send an empty message
|
// can't send an empty message
|
||||||
return { content: "_ _" }
|
return { content: "_ _" }
|
||||||
@@ -183,7 +114,7 @@ function addActionRowItems(components: ActionRowOptions[], nodes: Node[]) {
|
|||||||
if (node.type === "button") {
|
if (node.type === "button") {
|
||||||
actionRow.components.push({
|
actionRow.components.push({
|
||||||
type: "BUTTON",
|
type: "BUTTON",
|
||||||
label: node.children.map(getNodeText).join("") || "_ _",
|
label: node.children.map(getNodeText).join(""),
|
||||||
style: node.style ? toUpper(node.style) : "SECONDARY",
|
style: node.style ? toUpper(node.style) : "SECONDARY",
|
||||||
emoji: node.emoji,
|
emoji: node.emoji,
|
||||||
disabled: node.disabled,
|
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 { ReactNode } from "react"
|
||||||
import type { Node } from "./node-tree"
|
import type { Node } from "./node"
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace JSX {
|
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 ReactReconciler from "react-reconciler"
|
||||||
import type { ChannelRenderer } from "./channel-renderer.js"
|
import type { ChannelRenderer } from "./channel-renderer.js"
|
||||||
import { raise } from "./helpers/raise.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
|
type ElementTag = string
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user