forked from syntaxbullet/AuroraBot-discord
93 lines
4.2 KiB
TypeScript
93 lines
4.2 KiB
TypeScript
import { createCommand } from "@/lib/utils";
|
|
import { SlashCommandBuilder, EmbedBuilder, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle, ThreadAutoArchiveDuration } from "discord.js";
|
|
import { TradeService } from "@/modules/trade/trade.service";
|
|
import { updateTradeDashboard } from "@/modules/trade/trade.interaction";
|
|
import { createErrorEmbed, createWarningEmbed } from "@lib/embeds";
|
|
|
|
export const trade = createCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("trade")
|
|
.setDescription("Start a trade with another player")
|
|
.addUserOption(option =>
|
|
option.setName("user")
|
|
.setDescription("The user to trade with")
|
|
.setRequired(true)
|
|
),
|
|
execute: async (interaction) => {
|
|
const targetUser = interaction.options.getUser("user", true);
|
|
|
|
if (targetUser.id === interaction.user.id) {
|
|
await interaction.reply({ embeds: [createWarningEmbed("You cannot trade with yourself.")], ephemeral: true });
|
|
return;
|
|
}
|
|
|
|
if (targetUser.bot) {
|
|
await interaction.reply({ embeds: [createWarningEmbed("You cannot trade with bots.")], ephemeral: true });
|
|
return;
|
|
}
|
|
|
|
// Create Thread
|
|
const channel = interaction.channel;
|
|
if (!channel || channel.type === ChannelType.DM) {
|
|
await interaction.reply({ embeds: [createErrorEmbed("Cannot start trade in DMs.")], ephemeral: true });
|
|
return;
|
|
}
|
|
|
|
// Check if we can create threads
|
|
// Assuming permissions are fine.
|
|
|
|
await interaction.reply({ content: `🔄 Setting up trade with ${targetUser}...` });
|
|
const message = await interaction.fetchReply();
|
|
|
|
let thread;
|
|
try {
|
|
thread = await message.startThread({
|
|
name: `trade-${interaction.user.username}-${targetUser.username}`,
|
|
autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
|
|
reason: "Trading Session"
|
|
});
|
|
} catch (e) {
|
|
// Fallback if message threads fail, try channel threads (private preferred)
|
|
// But startThread on message is usually easiest.
|
|
try {
|
|
await message.delete();
|
|
} catch (err) {
|
|
console.error("Failed to delete setup message", err);
|
|
}
|
|
await interaction.followUp({ embeds: [createErrorEmbed("Failed to create trade thread. Check permissions.")], ephemeral: true });
|
|
return;
|
|
}
|
|
|
|
// Setup Session
|
|
TradeService.createSession(thread.id,
|
|
{ id: interaction.user.id, username: interaction.user.username },
|
|
{ id: targetUser.id, username: targetUser.username }
|
|
);
|
|
|
|
// Send Dashboard to Thread
|
|
const embed = new EmbedBuilder()
|
|
.setTitle("🤝 Trading Session")
|
|
.setDescription(`Trade started between ${interaction.user} and ${targetUser}.\nUse the controls below to build your offer.`)
|
|
.setColor(0xFFD700)
|
|
.addFields(
|
|
{ name: interaction.user.username, value: "*Empty Offer*", inline: true },
|
|
{ name: targetUser.username, value: "*Empty Offer*", inline: true }
|
|
)
|
|
.setFooter({ text: "Both parties must click Lock to confirm trade." });
|
|
|
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
|
.addComponents(
|
|
new ButtonBuilder().setCustomId('trade_add_item').setLabel('Add Item').setStyle(ButtonStyle.Secondary),
|
|
new ButtonBuilder().setCustomId('trade_add_money').setLabel('Add Money').setStyle(ButtonStyle.Success),
|
|
new ButtonBuilder().setCustomId('trade_remove_item').setLabel('Remove Item').setStyle(ButtonStyle.Secondary),
|
|
new ButtonBuilder().setCustomId('trade_lock').setLabel('Lock / Unlock').setStyle(ButtonStyle.Primary),
|
|
new ButtonBuilder().setCustomId('trade_cancel').setLabel('Cancel').setStyle(ButtonStyle.Danger),
|
|
);
|
|
|
|
await thread.send({ content: `${interaction.user} ${targetUser} Welcome to your trading session!`, embeds: [embed], components: [row] });
|
|
|
|
// Update original reply
|
|
await interaction.editReply({ content: `✅ Trade opened: <#${thread.id}>` });
|
|
}
|
|
});
|