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
>,
)
@@ -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,
})),