embed fields

This commit is contained in:
MapleLeaf
2021-12-21 10:51:14 -06:00
parent 6b13617c7c
commit a4119bf694
5 changed files with 73 additions and 14 deletions

View File

@@ -19,6 +19,7 @@ function KitchenSink() {
url="https://example.com" url="https://example.com"
timestamp={new Date().toISOString()} timestamp={new Date().toISOString()}
thumbnailUrl="https://example.com/thumbnail.png" thumbnailUrl="https://example.com/thumbnail.png"
imageUrl="https://example.com/image.png"
author={{ author={{
name: "the author", name: "the author",
url: "https://example.com", url: "https://example.com",
@@ -35,10 +36,6 @@ function KitchenSink() {
<EmbedField name="field name" inline> <EmbedField name="field name" inline>
field content but inline field content but inline
</EmbedField> </EmbedField>
<EmbedImage url="https://example.com/image.png" />
<EmbedImage url="https://example.com/image.png" />
<EmbedImage url="https://example.com/image.png" />
<EmbedImage url="https://example.com/image.png" />
</Embed> </Embed>
{/* files */} {/* files */}
<File url="data:sdklfjs" /> <File url="data:sdklfjs" />

View File

@@ -9,8 +9,8 @@
- [x] title - text children, url - [x] title - text children, url
- [x] footer - icon url, timestamp, text children - [x] footer - icon url, timestamp, text children
- [x] thumbnail - url - [x] thumbnail - url
- [ ] image - url - [x] image - url
- [ ] fields - name, value, inline - [x] fields - name, value, inline
- message components - message components
- [ ] buttons - [ ] buttons
- [ ] links - [ ] links
@@ -20,6 +20,7 @@
# cool ideas / polish # cool ideas / polish
- [ ] files - [ ] files
- [ ] stickers
- [ ] user mention component - [ ] user mention component
- [ ] channel mention component - [ ] channel mention component
- [ ] timestamp component - [ ] timestamp component

34
src/embed-field.tsx Normal file
View File

@@ -0,0 +1,34 @@
import type { MessageEmbedOptions } from "discord.js"
import React from "react"
import { ContainerInstance } from "./container-instance.js"
import { pick } from "./helpers/pick.js"
export type EmbedFieldProps = {
name: string
children: React.ReactNode
inline?: boolean
}
export function EmbedField(props: EmbedFieldProps) {
return (
<reacord-element createInstance={() => new EmbedFieldInstance(props)}>
{props.children}
</reacord-element>
)
}
class EmbedFieldInstance extends ContainerInstance {
readonly name = "EmbedField"
constructor(private readonly props: EmbedFieldProps) {
super({ warnOnNonTextChildren: true })
}
override renderToEmbed(options: MessageEmbedOptions) {
options.fields ??= []
options.fields.push({
...pick(this.props, "name", "inline"),
value: this.getChildrenText(),
})
}
}

View File

@@ -12,6 +12,7 @@ export type EmbedProps = {
color?: ColorResolvable color?: ColorResolvable
url?: string url?: string
timestamp?: Date | number | string timestamp?: Date | number | string
imageUrl?: string
thumbnailUrl?: string thumbnailUrl?: string
author?: { author?: {
name?: string name?: string
@@ -48,6 +49,10 @@ class EmbedInstance extends ContainerInstance {
getEmbedOptions(): MessageEmbedOptions { getEmbedOptions(): MessageEmbedOptions {
const options: MessageEmbedOptions = { const options: MessageEmbedOptions = {
...this.props, ...this.props,
image: this.props.imageUrl ? { url: this.props.imageUrl } : undefined,
thumbnail: this.props.thumbnailUrl
? { url: this.props.thumbnailUrl }
: undefined,
author: { author: {
...this.props.author, ...this.props.author,
iconURL: this.props.author?.iconUrl, iconURL: this.props.author?.iconUrl,

View File

@@ -2,6 +2,7 @@
import type { Message, MessageOptions } from "discord.js" import type { Message, MessageOptions } from "discord.js"
import { Client, TextChannel } from "discord.js" import { Client, TextChannel } from "discord.js"
import React from "react" import React from "react"
import { EmbedField } from "./embed-field.js"
import { omit } from "./helpers/omit.js" import { omit } from "./helpers/omit.js"
import { raise } from "./helpers/raise.js" import { raise } from "./helpers/raise.js"
import type { ReacordRoot } from "./main" import type { ReacordRoot } from "./main"
@@ -79,6 +80,8 @@ test("empty embed author", async () => {
test("kitchen sink", async () => { test("kitchen sink", async () => {
const timestamp = Date.now() const timestamp = Date.now()
const image =
"https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024"
await root.render( await root.render(
<> <>
@@ -89,23 +92,26 @@ test("kitchen sink", async () => {
title="the embed" title="the embed"
url="https://example.com" url="https://example.com"
timestamp={timestamp} timestamp={timestamp}
thumbnailUrl="https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024" imageUrl={image}
thumbnailUrl={image}
author={{ author={{
name: "hi craw", name: "hi craw",
url: "https://example.com", url: "https://example.com",
iconUrl: iconUrl: image,
"https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024",
}} }}
footer={{ footer={{
text: "the footer", text: "the footer",
iconUrl: iconUrl: image,
"https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024",
}} }}
> >
description <Text>more description</Text> description <Text>more description</Text>
</Embed> </Embed>
<Embed> <Embed>
another <Text>hi</Text> another <Text>hi</Text>
<EmbedField name="field name">field content</EmbedField>
<EmbedField name="field name" inline>
field content but inline
</EmbedField>
</Embed> </Embed>
</>, </>,
) )
@@ -116,6 +122,8 @@ test("kitchen sink", async () => {
{ {
color: 0xfe_ee_ef, color: 0xfe_ee_ef,
description: "description more description", description: "description more description",
image: { url: image },
thumbnail: { url: image },
author: { author: {
name: "hi craw", name: "hi craw",
url: "https://example.com", url: "https://example.com",
@@ -131,7 +139,17 @@ test("kitchen sink", async () => {
title: "the embed", title: "the embed",
url: "https://example.com", url: "https://example.com",
}, },
{ description: "another hi" }, {
description: "another hi",
fields: [
{ name: "field name", value: "field content", inline: false },
{
name: "field name",
value: "field content but inline",
inline: true,
},
],
},
], ],
}, },
]) ])
@@ -163,8 +181,12 @@ function extractMessageData(message: Message): MessageOptions {
color: embed.color ?? undefined, color: embed.color ?? undefined,
fields: nonEmptyOrUndefined(embed.fields), fields: nonEmptyOrUndefined(embed.fields),
author: embed.author ? omit(embed.author, "proxyIconURL") : undefined, author: embed.author ? omit(embed.author, "proxyIconURL") : undefined,
thumbnail: embed.thumbnail ?? undefined, thumbnail: embed.thumbnail
image: embed.image ?? undefined, ? omit(embed.thumbnail, "proxyURL", "width", "height")
: undefined,
image: embed.image
? omit(embed.image, "proxyURL", "width", "height")
: undefined,
video: embed.video ?? undefined, video: embed.video ?? undefined,
footer: embed.footer ? omit(embed.footer, "proxyIconURL") : undefined, footer: embed.footer ? omit(embed.footer, "proxyIconURL") : undefined,
})), })),