Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"discord.js": "^14.25.1",
"tsx": "^4.21.0",
"typesafe-i18n": "^5.26.2",
"zod": "^4.2.1"
"zod": "^4.3.4"
},
"devDependencies": {
"@types/node": "^25.0.3"
Expand Down
61 changes: 4 additions & 57 deletions apps/bot/src/commands/staff/bot-profile/command.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import { Command, container, customId } from '@ticketer/djs-framework';
import {
ActionRowBuilder,
HeadingLevel,
heading,
MessageFlags,
PermissionFlagsBits,
StringSelectMenuBuilder,
StringSelectMenuOptionBuilder,
TextDisplayBuilder,
} from 'discord.js';
import { Command } from '@ticketer/djs-framework';
import { PermissionFlagsBits } from 'discord.js';
import { getTranslations, translate } from '@/i18n';
import { configurationMenu } from './helpers';

const dataTranslations = translate().commands['bot-profile'].data;

Expand All @@ -21,51 +13,6 @@ export default class extends Command.Interaction {
.setDefaultMemberPermissions(PermissionFlagsBits.ChangeNickname | PermissionFlagsBits.ManageGuild);

public execute({ interaction }: Command.Context<'chat'>) {
const translations = translate(interaction.guildLocale).commands['bot-profile'].command.container;

void interaction.reply({
components: [
container({
builder: (cont) =>
cont
.addTextDisplayComponents(
new TextDisplayBuilder().setContent(heading(translations.heading(), HeadingLevel.Three)),
)
.addActionRowComponents(
new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(
new StringSelectMenuBuilder()
.setCustomId(customId('bot_profile_menu'))
.setMinValues(1)
.setMaxValues(1)
.setPlaceholder(translations.menu.placeholder())
.setOptions(
new StringSelectMenuOptionBuilder()
.setEmoji('🪪')
.setLabel(translations.menu.name.label())
.setDescription(translations.menu.name.description())
.setValue('name'),
new StringSelectMenuOptionBuilder()
.setEmoji('📔')
.setLabel(translations.menu.bio.label())
.setDescription(translations.menu.bio.description())
.setValue('bio'),
new StringSelectMenuOptionBuilder()
.setEmoji('👤')
.setLabel(translations.menu.avatar.label())
.setDescription(translations.menu.avatar.description())
.setValue('avatar'),
new StringSelectMenuOptionBuilder()
.setEmoji('🖼️')
.setLabel(translations.menu.banner.label())
.setDescription(translations.menu.banner.description())
.setValue('banner'),
),
),
),
client: interaction.client,
}),
],
flags: [MessageFlags.IsComponentsV2],
});
void interaction.reply(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}
}
63 changes: 63 additions & 0 deletions apps/bot/src/commands/staff/bot-profile/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { container, customId } from '@ticketer/djs-framework';
import {
ActionRowBuilder,
type Client,
HeadingLevel,
heading,
type InteractionReplyOptions,
type Locale,
MessageFlags,
StringSelectMenuBuilder,
StringSelectMenuOptionBuilder,
TextDisplayBuilder,
} from 'discord.js';
import { translate } from '@/i18n';

export function configurationMenu({ client, locale }: { client: Client<true>; locale: Locale }) {
const translations = translate(locale).commands['bot-profile'].command.container;

return {
components: [
container({
builder: (cont) =>
cont
.addTextDisplayComponents(
new TextDisplayBuilder().setContent(heading(translations.heading(), HeadingLevel.Three)),
)
.addActionRowComponents(
new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(
new StringSelectMenuBuilder()
.setCustomId(customId('bot_profile_menu'))
.setMinValues(1)
.setMaxValues(1)
.setPlaceholder(translations.menu.placeholder())
.setOptions(
new StringSelectMenuOptionBuilder()
.setEmoji('🪪')
.setLabel(translations.menu.name.label())
.setDescription(translations.menu.name.description())
.setValue('name'),
new StringSelectMenuOptionBuilder()
.setEmoji('📔')
.setLabel(translations.menu.bio.label())
.setDescription(translations.menu.bio.description())
.setValue('bio'),
new StringSelectMenuOptionBuilder()
.setEmoji('👤')
.setLabel(translations.menu.avatar.label())
.setDescription(translations.menu.avatar.description())
.setValue('avatar'),
new StringSelectMenuOptionBuilder()
.setEmoji('🖼️')
.setLabel(translations.menu.banner.label())
.setDescription(translations.menu.banner.description())
.setValue('banner'),
),
),
),
client,
}),
],
flags: [MessageFlags.IsComponentsV2],
} satisfies InteractionReplyOptions;
}
29 changes: 18 additions & 11 deletions apps/bot/src/commands/staff/bot-profile/modal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { container, customId, DeferReply, Modal, userEmbedError } from '@ticketer/djs-framework';
import { container, customId, DeferUpdate, Modal, userEmbedError } from '@ticketer/djs-framework';
import {
ContainerBuilder,
codeBlock,
Expand All @@ -13,6 +13,7 @@ import {
} from 'discord.js';
import { prettifyError, z } from 'zod';
import { translate } from '@/i18n';
import { configurationMenu } from './helpers';

export default class extends Modal.Interaction {
public readonly customIds = [customId('bot_profile_menu_name')];
Expand Down Expand Up @@ -53,15 +54,15 @@ export default class extends Modal.Interaction {
});
}

await interaction.deferReply();
await interaction.deferUpdate();
let me = await interaction.guild.members.fetchMe();
const oldName = me.displayName;

me = await interaction.guild.members.editMe({ nick });
const guildTranslations = translate(interaction.guildLocale).commands['bot-profile'].command.modals.name.response
.success;

return interaction.editReply({
interaction.editReply({
components: [
container({
builder: (cont) =>
Expand All @@ -83,6 +84,7 @@ export default class extends Modal.Interaction {
],
flags: [MessageFlags.IsComponentsV2],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}
}

Expand Down Expand Up @@ -111,7 +113,7 @@ export class Bio extends Modal.Interaction {
});
}

await interaction.deferReply();
await interaction.deferUpdate();
await interaction.guild.members.editMe({ bio });

const guildTranslations = translate(interaction.guildLocale).commands['bot-profile'].command.modals.bio.response
Expand All @@ -132,17 +134,18 @@ export class Bio extends Modal.Interaction {
reply.addTextDisplayComponents(new TextDisplayBuilder().setContent(codeBlock(bio)));
}

return interaction.editReply({
interaction.editReply({
components: [container({ builder: reply, client: interaction.client })],
flags: [MessageFlags.IsComponentsV2],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}
}

export class Avatar extends Modal.Interaction {
public readonly customIds = [customId('bot_profile_menu_avatar')];

@DeferReply()
@DeferUpdate
public async execute({ interaction }: Modal.Context) {
const avatar = interaction.fields.getUploadedFiles('avatar', false)?.at(0)?.url ?? '';
let me = await interaction.guild.members.fetchMe();
Expand All @@ -154,7 +157,7 @@ export class Avatar extends Modal.Interaction {
const translatons = translate(interaction.locale).commands['bot-profile'].command.modals.avatar.response.errors
.unknown;

return interaction.editReply({
interaction.editReply({
embeds: [
userEmbedError({
client: interaction.client,
Expand All @@ -164,12 +167,13 @@ export class Avatar extends Modal.Interaction {
}),
],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}

const translatons = translate(interaction.guildLocale).commands['bot-profile'].command.modals.avatar.response
.success;

return interaction.editReply({
interaction.editReply({
components: [
container({
builder: (cont) =>
Expand All @@ -191,13 +195,14 @@ export class Avatar extends Modal.Interaction {
],
flags: [MessageFlags.IsComponentsV2],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}
}

export class Banner extends Modal.Interaction {
public readonly customIds = [customId('bot_profile_menu_banner')];

@DeferReply()
@DeferUpdate
public async execute({ interaction }: Modal.Context) {
const banner = interaction.fields.getUploadedFiles('banner', false)?.at(0)?.url ?? '';
// Force fetch due to caching issues.
Expand All @@ -210,7 +215,7 @@ export class Banner extends Modal.Interaction {
const translations = translate(interaction.locale).commands['bot-profile'].command.modals.banner.response.errors
.unknown;

return interaction.editReply({
interaction.editReply({
embeds: [
userEmbedError({
client: interaction.client,
Expand All @@ -220,6 +225,7 @@ export class Banner extends Modal.Interaction {
}),
],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}

const translations = translate(interaction.locale).commands['bot-profile'].command.modals.banner.response.success;
Expand Down Expand Up @@ -253,9 +259,10 @@ export class Banner extends Modal.Interaction {
reply.addMediaGalleryComponents(builder);
}

return interaction.editReply({
interaction.editReply({
components: [container({ builder: reply, client: interaction.client })],
flags: [MessageFlags.IsComponentsV2],
});
return interaction.followUp(configurationMenu({ client: interaction.client, locale: interaction.guildLocale }));
}
}
Loading