support embed singleton fields via props

This commit is contained in:
MapleLeaf
2021-12-20 19:11:07 -06:00
parent d1935d283a
commit 628c4b23d7
9 changed files with 128 additions and 78 deletions

View File

@@ -1,35 +0,0 @@
import type { MessageEmbedOptions } from "discord.js"
import type { ReactNode } from "react"
import React from "react"
import { ContainerInstance } from "./container-instance.js"
export type EmbedAuthorProps = {
url?: string
iconUrl?: string
children?: ReactNode
}
export function EmbedAuthor({ children, ...options }: EmbedAuthorProps) {
return (
<reacord-element createInstance={() => new EmbedAuthorInstance(options)}>
{children}
</reacord-element>
)
}
type EmbedAuthorOptions = Omit<EmbedAuthorProps, "children">
class EmbedAuthorInstance extends ContainerInstance {
readonly name = "EmbedAuthor"
constructor(private readonly props: EmbedAuthorOptions) {
super({ warnOnNonTextChildren: true })
}
override renderToEmbed(options: MessageEmbedOptions) {
options.author ??= {}
options.author.name = this.getChildrenText()
options.author.url = this.props.url
options.author.iconURL = this.props.iconUrl
}
}

View File

@@ -8,13 +8,26 @@ import React from "react"
import { ContainerInstance } from "./container-instance.js"
export type EmbedProps = {
title?: string
color?: ColorResolvable
url?: string
timestamp?: Date | number | string
thumbnailUrl?: string
author?: {
name?: string
url?: string
iconUrl?: string
}
footer?: {
text?: string
iconUrl?: string
}
children?: ReactNode
}
export function Embed(props: EmbedProps) {
return (
<reacord-element createInstance={() => new EmbedInstance(props.color)}>
<reacord-element createInstance={() => new EmbedInstance(props)}>
{props.children}
</reacord-element>
)
@@ -23,22 +36,31 @@ export function Embed(props: EmbedProps) {
class EmbedInstance extends ContainerInstance {
readonly name = "Embed"
constructor(readonly color?: ColorResolvable) {
constructor(readonly props: EmbedProps) {
super({ warnOnNonTextChildren: false })
}
override renderToMessage(message: MessageOptions) {
message.embeds ??= []
message.embeds.push(this.embedOptions)
message.embeds.push(this.getEmbedOptions())
}
get embedOptions(): MessageEmbedOptions {
/* eslint-disable unicorn/no-null */
getEmbedOptions(): MessageEmbedOptions {
const options: MessageEmbedOptions = {
color: this.color,
description: null as unknown as undefined,
...this.props,
author: {
...this.props.author,
iconURL: this.props.author?.iconUrl,
},
footer: {
text: "",
...this.props.footer,
iconURL: this.props.footer?.iconUrl,
},
timestamp: this.props.timestamp
? new Date(this.props.timestamp) // this _may_ need date-fns to parse this
: undefined,
}
/* eslint-enable unicorn/no-null */
for (const child of this.children) {
if (!child.renderToEmbed) {

View File

@@ -1,4 +1,3 @@
export * from "./embed-author.js"
export * from "./embed.js"
export * from "./root.js"
export * from "./text.js"