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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 7 deletions

View file

@ -57,13 +57,14 @@ export const Default = {
author={{
avatar: '/assets/discordjs.png',
username: 'Guide Bot',
url: 'https://discord.js.org',
}}
footer={{
content: 'Sometimes, titles just have to be.',
icon: '/assets/discordjs.png',
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!
</DiscordMessageEmbed>
@ -73,6 +74,7 @@ export const Default = {
username: 'Guide Bot',
}}
footer={{ content: "When one amazing title just wasn't enough." }}
thumbnail={{ alt: 'discord.js logo', image: '/assets/discordjs.png' }}
title={{ title: 'Another amazing title' }}
>
Multiple embeds!
@ -104,6 +106,13 @@ export const Default = {
},
]}
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!' }}
/>
</>

View file

@ -3,6 +3,8 @@ import { DiscordMessageEmbedAuthor, type IDiscordMessageEmbedAuthor } from './Me
import type { IDiscordMessageEmbedField } from './MessageEmbedField.jsx';
import { DiscordMessageEmbedFields } from './MessageEmbedFields.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';
export interface IDiscordMessageEmbed {
@ -11,7 +13,8 @@ export interface IDiscordMessageEmbed {
fields?: IDiscordMessageEmbedField[];
footer?: IDiscordMessageEmbedFooter | undefined;
footerNode?: ReactNode | undefined;
timestamp?: string;
image?: IDiscordMessageEmbedImage;
thumbnail?: IDiscordMessageEmbedThumbnail;
title?: IDiscordMessageEmbedTitle | undefined;
titleNode?: ReactNode | undefined;
}
@ -22,21 +25,26 @@ export function DiscordMessageEmbed({
fields,
title,
titleNode,
image,
children,
thumbnail,
footer,
footerNode,
}: PropsWithChildren<IDiscordMessageEmbed>) {
return (
<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="max-w-128">
<div className="max-w-128 flex">
<div className="pb-4 pl-3 pr-4 pt-2">
{author ? <DiscordMessageEmbedAuthor {...author} /> : authorNode ?? null}
{title ? <DiscordMessageEmbedTitle {...title} /> : titleNode ?? null}
{children ? <div className="mt-2 text-sm">{children}</div> : null}
{fields ? <DiscordMessageEmbedFields fields={fields} /> : null}
{image ? <DiscordMessageEmbedImage {...image} /> : null}
{footer ? <DiscordMessageEmbedFooter {...footer} /> : footerNode ?? null}
</div>
{thumbnail ? <DiscordMessageEmbedThumbnail {...thumbnail} /> : null}
</div>
</div>
</div>

View file

@ -1,13 +1,25 @@
export interface IDiscordMessageEmbedAuthor {
avatar: string;
url?: string;
username: string;
}
export function DiscordMessageEmbedAuthor({ avatar, username }: IDiscordMessageEmbedAuthor) {
export function DiscordMessageEmbedAuthor({ avatar, url, username }: IDiscordMessageEmbedAuthor) {
return (
<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} />
<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>
);
}

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 {
title: string;
url?: string;
}
export function DiscordMessageEmbedTitle({ title }: IDiscordMessageEmbedTitle) {
return <div className="mt-2 font-medium">{title}</div>;
export function DiscordMessageEmbedTitle({ title, url }: IDiscordMessageEmbedTitle) {
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>
);
}