From a4119bf694be72d16c737964dbefb4b47b5cd394 Mon Sep 17 00:00:00 2001 From: MapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com> Date: Tue, 21 Dec 2021 10:51:14 -0600 Subject: [PATCH] embed fields --- example.js | 5 +---- notes.md | 5 +++-- src/embed-field.tsx | 34 ++++++++++++++++++++++++++++++++++ src/embed.tsx | 5 +++++ src/rendering.test.tsx | 38 ++++++++++++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 src/embed-field.tsx diff --git a/example.js b/example.js index 60efcf5..ee4eaab 100644 --- a/example.js +++ b/example.js @@ -19,6 +19,7 @@ function KitchenSink() { url="https://example.com" timestamp={new Date().toISOString()} thumbnailUrl="https://example.com/thumbnail.png" + imageUrl="https://example.com/image.png" author={{ name: "the author", url: "https://example.com", @@ -35,10 +36,6 @@ function KitchenSink() { field content but inline - - - - {/* files */} diff --git a/notes.md b/notes.md index 554c1a1..5a0818c 100644 --- a/notes.md +++ b/notes.md @@ -9,8 +9,8 @@ - [x] title - text children, url - [x] footer - icon url, timestamp, text children - [x] thumbnail - url - - [ ] image - url - - [ ] fields - name, value, inline + - [x] image - url + - [x] fields - name, value, inline - message components - [ ] buttons - [ ] links @@ -20,6 +20,7 @@ # cool ideas / polish - [ ] files +- [ ] stickers - [ ] user mention component - [ ] channel mention component - [ ] timestamp component diff --git a/src/embed-field.tsx b/src/embed-field.tsx new file mode 100644 index 0000000..df87e03 --- /dev/null +++ b/src/embed-field.tsx @@ -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 ( + new EmbedFieldInstance(props)}> + {props.children} + + ) +} + +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(), + }) + } +} diff --git a/src/embed.tsx b/src/embed.tsx index 8a69212..66e935b 100644 --- a/src/embed.tsx +++ b/src/embed.tsx @@ -12,6 +12,7 @@ export type EmbedProps = { color?: ColorResolvable url?: string timestamp?: Date | number | string + imageUrl?: string thumbnailUrl?: string author?: { name?: string @@ -48,6 +49,10 @@ class EmbedInstance extends ContainerInstance { getEmbedOptions(): MessageEmbedOptions { const options: MessageEmbedOptions = { ...this.props, + image: this.props.imageUrl ? { url: this.props.imageUrl } : undefined, + thumbnail: this.props.thumbnailUrl + ? { url: this.props.thumbnailUrl } + : undefined, author: { ...this.props.author, iconURL: this.props.author?.iconUrl, diff --git a/src/rendering.test.tsx b/src/rendering.test.tsx index a95935c..83f567e 100644 --- a/src/rendering.test.tsx +++ b/src/rendering.test.tsx @@ -2,6 +2,7 @@ import type { Message, MessageOptions } from "discord.js" import { Client, TextChannel } from "discord.js" import React from "react" +import { EmbedField } from "./embed-field.js" import { omit } from "./helpers/omit.js" import { raise } from "./helpers/raise.js" import type { ReacordRoot } from "./main" @@ -79,6 +80,8 @@ test("empty embed author", async () => { test("kitchen sink", async () => { const timestamp = Date.now() + const image = + "https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024" await root.render( <> @@ -89,23 +92,26 @@ test("kitchen sink", async () => { title="the embed" url="https://example.com" timestamp={timestamp} - thumbnailUrl="https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024" + imageUrl={image} + thumbnailUrl={image} author={{ name: "hi craw", url: "https://example.com", - iconUrl: - "https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024", + iconUrl: image, }} footer={{ text: "the footer", - iconUrl: - "https://cdn.discordapp.com/avatars/109677308410875904/3e53fcb70760a08fa63f73376ede5d1f.png?size=1024", + iconUrl: image, }} > description more description another hi + field content + + field content but inline + , ) @@ -116,6 +122,8 @@ test("kitchen sink", async () => { { color: 0xfe_ee_ef, description: "description more description", + image: { url: image }, + thumbnail: { url: image }, author: { name: "hi craw", url: "https://example.com", @@ -131,7 +139,17 @@ test("kitchen sink", async () => { title: "the embed", 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, fields: nonEmptyOrUndefined(embed.fields), author: embed.author ? omit(embed.author, "proxyIconURL") : undefined, - thumbnail: embed.thumbnail ?? undefined, - image: embed.image ?? undefined, + thumbnail: embed.thumbnail + ? omit(embed.thumbnail, "proxyURL", "width", "height") + : undefined, + image: embed.image + ? omit(embed.image, "proxyURL", "width", "height") + : undefined, video: embed.video ?? undefined, footer: embed.footer ? omit(embed.footer, "proxyIconURL") : undefined, })),