130 lines
3.8 KiB
TypeScript
130 lines
3.8 KiB
TypeScript
import { ButtonInteraction } from "discord.js";
|
|
import { triviaService } from "@shared/modules/trivia/trivia.service";
|
|
import { getTriviaResultView, getTriviaTimeoutView } from "./trivia.view";
|
|
import { UserError } from "@/lib/errors";
|
|
|
|
export async function handleTriviaInteraction(interaction: ButtonInteraction) {
|
|
const parts = interaction.customId.split('_');
|
|
|
|
// Check for "Give Up" button
|
|
if (parts.length >= 3 && parts[0] === 'trivia' && parts[1] === 'giveup') {
|
|
const sessionId = `${parts[2]}_${parts[3]}`;
|
|
const session = triviaService.getSession(sessionId);
|
|
|
|
if (!session) {
|
|
await interaction.reply({
|
|
content: '❌ This trivia question has expired or already been answered.',
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Validate ownership
|
|
if (session.userId !== interaction.user.id) {
|
|
await interaction.reply({
|
|
content: '❌ This isn\'t your trivia question!',
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
await interaction.deferUpdate();
|
|
|
|
// Process as incorrect (user gave up)
|
|
const result = await triviaService.submitAnswer(sessionId, interaction.user.id, false);
|
|
|
|
// Show timeout view (since they gave up)
|
|
const { components, flags } = getTriviaTimeoutView(
|
|
session.question.question,
|
|
session.question.correctAnswer,
|
|
session.allAnswers,
|
|
session.entryFee
|
|
);
|
|
|
|
await interaction.editReply({
|
|
components,
|
|
flags
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Handle answer button
|
|
if (parts.length < 5 || parts[0] !== 'trivia' || parts[1] !== 'answer') {
|
|
return;
|
|
}
|
|
|
|
const sessionId = `${parts[2]}_${parts[3]}`;
|
|
const answerIndexStr = parts[4];
|
|
|
|
if (!answerIndexStr) {
|
|
throw new UserError('Invalid answer format.');
|
|
}
|
|
|
|
const answerIndex = parseInt(answerIndexStr);
|
|
|
|
// Get session BEFORE deferring to check ownership
|
|
const session = triviaService.getSession(sessionId);
|
|
|
|
if (!session) {
|
|
// Session doesn't exist or expired
|
|
await interaction.reply({
|
|
content: '❌ This trivia question has expired or already been answered.',
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Validate ownership BEFORE deferring
|
|
if (session.userId !== interaction.user.id) {
|
|
// Wrong user trying to answer - send ephemeral error
|
|
await interaction.reply({
|
|
content: '❌ This isn\'t your trivia question! Use `/trivia` to start your own game.',
|
|
ephemeral: true
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Only defer if ownership is valid
|
|
await interaction.deferUpdate();
|
|
|
|
// Check timeout
|
|
if (new Date() > session.expiresAt) {
|
|
const { components, flags } = getTriviaTimeoutView(
|
|
session.question.question,
|
|
session.question.correctAnswer,
|
|
session.allAnswers,
|
|
session.entryFee
|
|
);
|
|
|
|
await interaction.editReply({
|
|
components,
|
|
flags
|
|
});
|
|
|
|
// Clean up session
|
|
await triviaService.submitAnswer(sessionId, interaction.user.id, false);
|
|
return;
|
|
}
|
|
|
|
// Check if correct
|
|
const isCorrect = answerIndex === session.correctIndex;
|
|
const userAnswer = session.allAnswers[answerIndex];
|
|
|
|
// Process result
|
|
const result = await triviaService.submitAnswer(sessionId, interaction.user.id, isCorrect);
|
|
|
|
// Update message with enhanced visual feedback
|
|
const { components, flags } = getTriviaResultView(
|
|
result,
|
|
session.question.question,
|
|
userAnswer,
|
|
session.allAnswers,
|
|
session.entryFee
|
|
);
|
|
|
|
await interaction.editReply({
|
|
components,
|
|
flags
|
|
});
|
|
}
|