diff --git a/handlers/buttons.js b/handlers/buttons.js index 9de0002..6179aa3 100644 --- a/handlers/buttons.js +++ b/handlers/buttons.js @@ -138,7 +138,13 @@ async function handleButton(interaction) { if (pendingCloses.has(interaction.channel.id)) { return interaction.reply({ content: 'A close is already pending for this ticket.', ephemeral: true }); } - await interaction.update({ content: `Closing ticket in ${timerSeconds} seconds. Use \`/cancel-close\` to abort.`, components: [] }); + const cancelRow = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('cancel_close') + .setLabel('Cancel Close') + .setStyle(ButtonStyle.Secondary) + ); + await interaction.update({ content: `Closing ticket in ${timerSeconds} seconds.`, components: [cancelRow] }); const timerId = setTimeout(async () => { pendingCloses.delete(interaction.channel.id); const freshTicket = await Ticket.findOne({ discordThreadId: interaction.channel.id }).lean(); @@ -156,6 +162,11 @@ async function handleButton(interaction) { } if (interaction.customId === 'cancel_close') { + const pending = pendingCloses.get(interaction.channel.id); + if (pending) { + clearTimeout(pending.timeout); + pendingCloses.delete(interaction.channel.id); + } return interaction.update({ content: 'Close cancelled.', components: [] }); } diff --git a/services/channelQueue.js b/services/channelQueue.js index 7cf153e..89e85da 100644 --- a/services/channelQueue.js +++ b/services/channelQueue.js @@ -35,9 +35,6 @@ function processQueue(channel, state) { setTimeout(async () => { state.processing = false; // New window - if (state.queue.length > 3) { - logWarn('renameQueue', `Channel ${channel.name} has ${state.queue.length} renames queued`).catch(() => {}); - } const item = state.queue.shift(); if (!item) return; item.started = true; @@ -77,19 +74,20 @@ function enqueueRename(channel, newName) { return Promise.resolve(); } - // At limit — queue it - const queueSize = state.queue.length + 1; - const queuedItem = { newName, started: false }; - state.queue.push(queuedItem); + // At limit — replace pending rename with latest + const isNew = state.queue.length === 0; + state.queue[0] = { newName, started: false }; + const queuedItem = state.queue[0]; - // Only notify if this rename is still waiting after ~2s. - setTimeout(() => { - if (queuedItem.started) return; - const estMinutes = Math.max(1, Math.ceil((queueSize * RENAME_WINDOW_MS) / 60000)); - channel.send(`⏳ Channel will be renamed in ~${estMinutes} minute${estMinutes === 1 ? '' : 's'}.`).catch(() => {}); - }, 2000); + if (isNew) { + setTimeout(() => { + if (queuedItem.started) return; + const estMinutes = Math.ceil(RENAME_WINDOW_MS / 60000); + channel.send(`⏳ Channel will be renamed in ~${estMinutes} minute${estMinutes === 1 ? '' : 's'}.`).catch(() => {}); + }, 2000); - processQueue(channel, state); + processQueue(channel, state); + } return Promise.resolve(); }