Refactor embed handling and enhance user experience across components

- Integrated the new `buildEmbedFromPayload` function in Scheduler, Tags, and Welcome components to streamline embed creation and management.
- Updated validation schemas to require embed content checks, ensuring robust data integrity for embeds.
- Enhanced localization files to include new placeholder descriptions and improve user guidance for embed fields.
- Refactored embed parsing logic to utilize the `WelcomeEmbedSchema`, improving consistency and validation across the application.
This commit is contained in:
TheOnlyMace
2026-07-22 22:30:46 +02:00
parent e7a3162494
commit 95eed45ec4
19 changed files with 500 additions and 146 deletions

View File

@@ -131,12 +131,73 @@ export const WelcomeMessageTypeSchema = z.enum(['TEXT', 'EMBED', 'IMAGE']);
export type WelcomeMessageType = z.infer<typeof WelcomeMessageTypeSchema>;
export const WelcomeEmbedSchema = z.object({
title: z.string().optional(),
description: z.string().optional(),
color: z.number().int().optional()
title: z.string().max(256).optional(),
description: z.string().max(4096).optional(),
/** Clickable title URL. */
url: z.string().max(2048).optional(),
color: z.number().int().optional(),
authorName: z.string().max(256).optional(),
authorIconUrl: z.string().max(2048).optional(),
authorUrl: z.string().max(2048).optional(),
thumbnailUrl: z.string().max(2048).optional(),
imageUrl: z.string().max(2048).optional(),
footerText: z.string().max(2048).optional(),
footerIconUrl: z.string().max(2048).optional(),
/** When true, Discord shows the current time in the footer area. */
timestamp: z.boolean().optional()
});
export type WelcomeEmbed = z.infer<typeof WelcomeEmbedSchema>;
/** True when the embed has any user-facing content beyond an optional color. */
export function embedHasContent(embed: WelcomeEmbed | null | undefined): boolean {
if (!embed) {
return false;
}
return Boolean(
embed.title?.trim() ||
embed.description?.trim() ||
embed.url?.trim() ||
embed.authorName?.trim() ||
embed.authorIconUrl?.trim() ||
embed.authorUrl?.trim() ||
embed.thumbnailUrl?.trim() ||
embed.imageUrl?.trim() ||
embed.footerText?.trim() ||
embed.footerIconUrl?.trim() ||
embed.timestamp
);
}
/**
* Applies a string renderer to every text/URL field of an embed payload.
* Used by Welcome/Tags/Scheduler before handing data to discord.js.
*/
export function mapEmbedTextFields(
embed: WelcomeEmbed,
render: (value: string) => string
): WelcomeEmbed {
const map = (value: string | undefined): string | undefined => {
if (!value?.trim()) {
return undefined;
}
return render(value);
};
return {
title: map(embed.title),
description: map(embed.description),
url: map(embed.url),
color: embed.color,
authorName: map(embed.authorName),
authorIconUrl: map(embed.authorIconUrl),
authorUrl: map(embed.authorUrl),
thumbnailUrl: map(embed.thumbnailUrl),
imageUrl: map(embed.imageUrl),
footerText: map(embed.footerText),
footerIconUrl: map(embed.footerIconUrl),
timestamp: embed.timestamp
};
}
export const VerificationModeSchema = z.enum(['BUTTON', 'CAPTCHA']);
export type VerificationMode = z.infer<typeof VerificationModeSchema>;