import { bugs, db } from "@/database"; import { getGuild } from "@/utils/queries"; import type { Client, ModalSubmitInteraction } from "discord.js"; import { eq, sql } from "drizzle-orm"; import { INPUT_IDS, MODAL_IDS, VALIDATION, constructContainer, } from "./_shared"; export async function handleNewBugModal( client: Client, interaction: ModalSubmitInteraction, ) { if (!interaction.guildId) return; const title = interaction.fields.getTextInputValue(INPUT_IDS.TITLE); const description = interaction.fields.getTextInputValue( INPUT_IDS.DESCRIPTION, ); const affected = interaction.fields.getStringSelectValues(INPUT_IDS.AFFECTED); const media = interaction.fields.getUploadedFiles(INPUT_IDS.MEDIA); await interaction.deferReply({ flags: ["Ephemeral"] }); const [{ count }] = await db .select({ count: sql`COUNT(*)`.mapWith(Number) }) .from(bugs) .where(eq(bugs.guildId, interaction.guildId)); const bugNumber = count + 1; const paddedNumber = bugNumber.toString().padStart(4, "0"); const bug = await db .insert(bugs) .values({ guildId: interaction.guildId, bugNumber: bugNumber, authorId: interaction.user.id, status: "open", title: title, description: description, projects: [...affected], sent: false, messageId: null, threadId: null, createdAt: new Date(), updatedAt: new Date(), closedAt: null, }) .returning(); // TODO)) media uploads to s3 const container = await constructContainer(bug[0], interaction.user.id); if (!container) return; const { data, exists } = await getGuild(interaction.guildId); if (!exists) return; const channelId = data.bug_channel_id; if (!channelId) return; const channel = await interaction.guild?.channels.fetch(channelId); if (!channel || !channel.isSendable()) return; // send message // TODO)) buttons const message = await channel.send({ components: [container], flags: ["IsComponentsV2"], }); // thread function truncateTitle(title: string, maxLength: number): string { return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title; } const threadName = `#${paddedNumber} ${truncateTitle(title, VALIDATION.THREAD_NAME_MAX_LENGTH)}`; const thread = await message.startThread({ name: threadName, autoArchiveDuration: 1440, }); // save & update user await db .update(bugs) .set({ messageId: message.id, threadId: thread.id, sent: true }) .where(eq(bugs.id, bug[0].id)); thread.send( "Use this space to discuss the bug, provide additional details, or ask questions.", ); interaction.editReply( `Bug #${paddedNumber} created successfully! Find it here: ${message.url}`, ); }