feat(ui): support embed image, thumbnail, author url, and url (#9478)

This commit is contained in:
Almeida
2023-04-30 15:56:34 +01:00
committed by GitHub
parent ad217cc760
commit f27631175a
6 changed files with 66 additions and 7 deletions

View File

@@ -57,13 +57,14 @@ export const Default = {
author={{ author={{
avatar: '/assets/discordjs.png', avatar: '/assets/discordjs.png',
username: 'Guide Bot', username: 'Guide Bot',
url: 'https://discord.js.org',
}} }}
footer={{ footer={{
content: 'Sometimes, titles just have to be.', content: 'Sometimes, titles just have to be.',
icon: '/assets/discordjs.png', icon: '/assets/discordjs.png',
timestamp: 'Today at 21:02', timestamp: 'Today at 21:02',
}} }}
title={{ title: 'An amazing title' }} title={{ title: 'An amazing title', url: 'https://discord.js.org' }}
> >
This is a description. You can put a description here. It must be descriptive! This is a description. You can put a description here. It must be descriptive!
</DiscordMessageEmbed> </DiscordMessageEmbed>
@@ -73,6 +74,7 @@ export const Default = {
username: 'Guide Bot', username: 'Guide Bot',
}} }}
footer={{ content: "When one amazing title just wasn't enough." }} footer={{ content: "When one amazing title just wasn't enough." }}
thumbnail={{ alt: 'discord.js logo', image: '/assets/discordjs.png' }}
title={{ title: 'Another amazing title' }} title={{ title: 'Another amazing title' }}
> >
Multiple embeds! Multiple embeds!
@@ -104,6 +106,13 @@ export const Default = {
}, },
]} ]}
footer={{ timestamp: 'Today at 21:02' }} footer={{ timestamp: 'Today at 21:02' }}
image={{
alt: 'discord.js logo',
url: '/assets/discordjs.png',
width: 300,
height: 300,
}}
thumbnail={{ alt: 'discord.js logo', image: '/assets/discordjs.png' }}
title={{ title: 'Fields are also supported!' }} title={{ title: 'Fields are also supported!' }}
/> />
</> </>

View File

@@ -3,6 +3,8 @@ import { DiscordMessageEmbedAuthor, type IDiscordMessageEmbedAuthor } from './Me
import type { IDiscordMessageEmbedField } from './MessageEmbedField.jsx'; import type { IDiscordMessageEmbedField } from './MessageEmbedField.jsx';
import { DiscordMessageEmbedFields } from './MessageEmbedFields.jsx'; import { DiscordMessageEmbedFields } from './MessageEmbedFields.jsx';
import { DiscordMessageEmbedFooter, type IDiscordMessageEmbedFooter } from './MessageEmbedFooter.jsx'; import { DiscordMessageEmbedFooter, type IDiscordMessageEmbedFooter } from './MessageEmbedFooter.jsx';
import { DiscordMessageEmbedImage, type IDiscordMessageEmbedImage } from './MessageEmbedImage.jsx';
import { DiscordMessageEmbedThumbnail, type IDiscordMessageEmbedThumbnail } from './MessageEmbedThumbnail.jsx';
import { DiscordMessageEmbedTitle, type IDiscordMessageEmbedTitle } from './MessageEmbedTitle.jsx'; import { DiscordMessageEmbedTitle, type IDiscordMessageEmbedTitle } from './MessageEmbedTitle.jsx';
export interface IDiscordMessageEmbed { export interface IDiscordMessageEmbed {
@@ -11,7 +13,8 @@ export interface IDiscordMessageEmbed {
fields?: IDiscordMessageEmbedField[]; fields?: IDiscordMessageEmbedField[];
footer?: IDiscordMessageEmbedFooter | undefined; footer?: IDiscordMessageEmbedFooter | undefined;
footerNode?: ReactNode | undefined; footerNode?: ReactNode | undefined;
timestamp?: string; image?: IDiscordMessageEmbedImage;
thumbnail?: IDiscordMessageEmbedThumbnail;
title?: IDiscordMessageEmbedTitle | undefined; title?: IDiscordMessageEmbedTitle | undefined;
titleNode?: ReactNode | undefined; titleNode?: ReactNode | undefined;
} }
@@ -22,21 +25,26 @@ export function DiscordMessageEmbed({
fields, fields,
title, title,
titleNode, titleNode,
image,
children, children,
thumbnail,
footer, footer,
footerNode, footerNode,
}: PropsWithChildren<IDiscordMessageEmbed>) { }: PropsWithChildren<IDiscordMessageEmbed>) {
return ( return (
<div className="py-0.5" id="outer-embed-wrapper"> <div className="py-0.5" id="outer-embed-wrapper">
<div className="grid max-w-max border-l-4 border-l-blurple rounded bg-[rgb(47_49_54)]" id="embed-wrapper"> <div className="grid max-w-max border-l-4 border-l-blurple rounded bg-[rgb(47_49_54)]" id="embed-wrapper">
<div className="max-w-128"> <div className="max-w-128 flex">
<div className="pb-4 pl-3 pr-4 pt-2"> <div className="pb-4 pl-3 pr-4 pt-2">
{author ? <DiscordMessageEmbedAuthor {...author} /> : authorNode ?? null} {author ? <DiscordMessageEmbedAuthor {...author} /> : authorNode ?? null}
{title ? <DiscordMessageEmbedTitle {...title} /> : titleNode ?? null} {title ? <DiscordMessageEmbedTitle {...title} /> : titleNode ?? null}
{children ? <div className="mt-2 text-sm">{children}</div> : null} {children ? <div className="mt-2 text-sm">{children}</div> : null}
{fields ? <DiscordMessageEmbedFields fields={fields} /> : null} {fields ? <DiscordMessageEmbedFields fields={fields} /> : null}
{image ? <DiscordMessageEmbedImage {...image} /> : null}
{footer ? <DiscordMessageEmbedFooter {...footer} /> : footerNode ?? null} {footer ? <DiscordMessageEmbedFooter {...footer} /> : footerNode ?? null}
</div> </div>
{thumbnail ? <DiscordMessageEmbedThumbnail {...thumbnail} /> : null}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,13 +1,25 @@
export interface IDiscordMessageEmbedAuthor { export interface IDiscordMessageEmbedAuthor {
avatar: string; avatar: string;
url?: string;
username: string; username: string;
} }
export function DiscordMessageEmbedAuthor({ avatar, username }: IDiscordMessageEmbedAuthor) { export function DiscordMessageEmbedAuthor({ avatar, url, username }: IDiscordMessageEmbedAuthor) {
return ( return (
<div className="mt-2 flex place-items-center"> <div className="mt-2 flex place-items-center">
<img alt={`${username}'s avatar`} className="mr-2 h-6 w-6 select-none rounded-full" src={avatar} /> <img alt={`${username}'s avatar`} className="mr-2 h-6 w-6 select-none rounded-full" src={avatar} />
<span className="text-sm font-medium hover:underline">{username}</span> {url ? (
<a
className="text-sm font-medium hover:underline"
href={url}
rel="noreferrer noopener external"
target="_blank"
>
{username}
</a>
) : (
<span className="text-sm font-medium">{username}</span>
)}
</div> </div>
); );
} }

View File

@@ -0,0 +1,10 @@
export interface IDiscordMessageEmbedImage {
alt: string;
height: number;
url: string;
width: number;
}
export function DiscordMessageEmbedImage({ alt, height, url, width }: IDiscordMessageEmbedImage) {
return <img alt={alt} className="mt-4" height={height} src={url} width={width} />;
}

View File

@@ -0,0 +1,8 @@
export interface IDiscordMessageEmbedThumbnail {
alt: string;
image: string;
}
export function DiscordMessageEmbedThumbnail({ alt, image }: IDiscordMessageEmbedThumbnail) {
return <img alt={alt} className="mr-4 mt-4 aspect-square h-20" height={80} src={image} width={80} />;
}

View File

@@ -1,7 +1,19 @@
export interface IDiscordMessageEmbedTitle { export interface IDiscordMessageEmbedTitle {
title: string; title: string;
url?: string;
} }
export function DiscordMessageEmbedTitle({ title }: IDiscordMessageEmbedTitle) { export function DiscordMessageEmbedTitle({ title, url }: IDiscordMessageEmbedTitle) {
return <div className="mt-2 font-medium">{title}</div>; return url ? (
<a
className="mt-2 font-medium text-blue-500 hover:underline"
href={url}
rel="noreferrer noopener external"
target="_blank"
>
{title}
</a>
) : (
<div className="mt-2 font-medium">{title}</div>
);
} }