Enhance welcome module with embed text rendering and autorole management
- Updated the welcome embed functionality to allow for user mentions in titles, authors, and footers, while maintaining clickable mentions in descriptions. - Implemented autorole assignment logic with checks for role manageability and hierarchy, including detailed logging for skipped roles. - Improved the WebUI to display real user and guild data in the welcome embed preview, enhancing user experience. - Refactored the welcome text rendering to support additional options for mention handling based on the context of the embed fields.
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import type { MessageComponentsV2, WelcomeConfigDashboard, WelcomeEmbed } from '@nexumi/shared';
|
||||
import type {
|
||||
DashboardGuild,
|
||||
MessageComponentsV2,
|
||||
SessionUser,
|
||||
WelcomeConfigDashboard,
|
||||
WelcomeEmbed
|
||||
} from '@nexumi/shared';
|
||||
import { FieldAnchor } from '@/components/layout/field-anchor';
|
||||
import { useTranslations } from '@/components/locale-provider';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -25,16 +31,44 @@ import { Textarea } from '@/components/ui/textarea';
|
||||
import type { SettingsSaveResult } from '@/components/settings/settings-form';
|
||||
import { SettingsForm } from '@/components/settings/settings-form';
|
||||
|
||||
const WELCOME_PREVIEW_VARS = {
|
||||
user: '@Alex',
|
||||
'user.name': 'Alex',
|
||||
'user.tag': 'Alex',
|
||||
'user.id': '123456789012345678',
|
||||
'user.avatar': 'https://cdn.discordapp.com/embed/avatars/0.png',
|
||||
server: 'Nexumi',
|
||||
'server.icon': 'https://cdn.discordapp.com/embed/avatars/1.png',
|
||||
memberCount: '128'
|
||||
};
|
||||
function discordDefaultAvatarUrl(userId: string): string {
|
||||
try {
|
||||
const index = Number((BigInt(userId) >> 22n) % 6n);
|
||||
return `https://cdn.discordapp.com/embed/avatars/${index}.png`;
|
||||
} catch {
|
||||
return 'https://cdn.discordapp.com/embed/avatars/0.png';
|
||||
}
|
||||
}
|
||||
|
||||
function userAvatarUrl(user: SessionUser): string {
|
||||
return user.avatar
|
||||
? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=256`
|
||||
: discordDefaultAvatarUrl(user.id);
|
||||
}
|
||||
|
||||
function guildIconUrl(guild: DashboardGuild): string {
|
||||
return guild.icon
|
||||
? `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=128`
|
||||
: discordDefaultAvatarUrl(guild.id);
|
||||
}
|
||||
|
||||
/** Preview placeholders from the logged-in dashboard user and current guild. */
|
||||
export function buildWelcomePreviewVars(
|
||||
user: SessionUser,
|
||||
guild: DashboardGuild
|
||||
): Record<string, string> {
|
||||
const displayName = user.globalName?.trim() || user.username;
|
||||
return {
|
||||
user: `@${displayName}`,
|
||||
'user.name': displayName,
|
||||
'user.tag': user.username,
|
||||
'user.id': user.id,
|
||||
'user.avatar': userAvatarUrl(user),
|
||||
server: guild.name,
|
||||
'server.icon': guildIconUrl(guild),
|
||||
memberCount: '—'
|
||||
};
|
||||
}
|
||||
|
||||
interface LocalWelcomeValue extends Omit<
|
||||
WelcomeConfigDashboard,
|
||||
@@ -85,9 +119,10 @@ async function saveWelcome(guildId: string, value: LocalWelcomeValue): Promise<S
|
||||
interface WelcomeFormProps {
|
||||
guildId: string;
|
||||
initialValue: WelcomeConfigDashboard;
|
||||
previewVars: Record<string, string>;
|
||||
}
|
||||
|
||||
export function WelcomeForm({ guildId, initialValue }: WelcomeFormProps) {
|
||||
export function WelcomeForm({ guildId, initialValue, previewVars }: WelcomeFormProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
@@ -162,7 +197,7 @@ export function WelcomeForm({ guildId, initialValue }: WelcomeFormProps) {
|
||||
<DiscordEmbedBuilder
|
||||
value={value.welcomeEmbed}
|
||||
onChange={(welcomeEmbed) => setValue((prev) => ({ ...prev, welcomeEmbed }))}
|
||||
previewVars={WELCOME_PREVIEW_VARS}
|
||||
previewVars={previewVars}
|
||||
placeholderPreset="welcome"
|
||||
/>
|
||||
</div>
|
||||
@@ -176,7 +211,7 @@ export function WelcomeForm({ guildId, initialValue }: WelcomeFormProps) {
|
||||
guildId={guildId}
|
||||
value={value.welcomeComponents}
|
||||
onChange={(welcomeComponents) => setValue((prev) => ({ ...prev, welcomeComponents }))}
|
||||
previewVars={WELCOME_PREVIEW_VARS}
|
||||
previewVars={previewVars}
|
||||
placeholderPreset="welcome"
|
||||
/>
|
||||
</div>
|
||||
@@ -312,7 +347,7 @@ export function WelcomeForm({ guildId, initialValue }: WelcomeFormProps) {
|
||||
<DiscordEmbedBuilder
|
||||
value={value.leaveEmbed}
|
||||
onChange={(leaveEmbed) => setValue((prev) => ({ ...prev, leaveEmbed }))}
|
||||
previewVars={WELCOME_PREVIEW_VARS}
|
||||
previewVars={previewVars}
|
||||
placeholderPreset="welcome"
|
||||
titlePlaceholder={t('modulePages.welcome.leaveEmbedTitlePlaceholder')}
|
||||
descriptionPlaceholder={t('modulePages.welcome.leaveEmbedDescriptionPlaceholder')}
|
||||
@@ -328,7 +363,7 @@ export function WelcomeForm({ guildId, initialValue }: WelcomeFormProps) {
|
||||
guildId={guildId}
|
||||
value={value.leaveComponents}
|
||||
onChange={(leaveComponents) => setValue((prev) => ({ ...prev, leaveComponents }))}
|
||||
previewVars={WELCOME_PREVIEW_VARS}
|
||||
previewVars={previewVars}
|
||||
placeholderPreset="welcome"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user