diff --git a/bot/modules/inventory/inventory.interaction.ts b/bot/modules/inventory/inventory.interaction.ts new file mode 100644 index 0000000..459e03d --- /dev/null +++ b/bot/modules/inventory/inventory.interaction.ts @@ -0,0 +1,71 @@ +import type { StringSelectMenuInteraction, ButtonInteraction, MessageFlags } from "discord.js"; +import { inventoryService } from "@shared/modules/inventory/inventory.service"; +import { getLootboxResultMessage } from "./inventory.view"; +import type { ItemUsageData } from "@shared/lib/types"; +import { getGuildConfig } from "@shared/lib/config"; + +export interface InventoryState { + ownerId: string; + viewerId: string; + page: number; + selectedItemId: number | null; +} + +/** + * Extracts the viewer user ID from an inventory custom ID. + * Custom IDs follow the format: inv_{action}_{viewerId} + */ +export function parseInventoryCustomId(customId: string): { action: string; viewerId: string } | null { + const match = customId.match(/^inv_(\w+?)_(\d+)$/); + if (!match) return null; + return { action: match[1]!, viewerId: match[2]! }; +} + +/** + * Checks if a custom ID belongs to the inventory system. + */ +export function isInventoryInteraction(customId: string): boolean { + return customId.startsWith("inv_"); +} + +/** + * Handles the "Use" button — executes item effects. + * Returns the result messages array from inventoryService.useItem, + * plus handles role-based effects that require the guild member. + */ +export async function executeItemUse( + interaction: ButtonInteraction, + userId: string, + itemId: number, +): Promise<{ results: any[]; usageData: ItemUsageData | null; item: any }> { + const result = await inventoryService.useItem(userId, itemId); + + // Handle role effects (same logic as /use command) + const usageData = result.usageData; + if (usageData) { + const guildConfig = await getGuildConfig(interaction.guildId!); + const colorRoles = guildConfig.colorRoles ?? []; + + for (const effect of usageData.effects) { + if (effect.type === "TEMP_ROLE" || effect.type === "COLOR_ROLE") { + try { + const member = await interaction.guild?.members.fetch(userId); + if (member) { + if (effect.type === "TEMP_ROLE") { + await member.roles.add(effect.roleId); + } else if (effect.type === "COLOR_ROLE") { + const rolesToRemove = colorRoles.filter((r: string) => member.roles.cache.has(r)); + if (rolesToRemove.length > 0) await member.roles.remove(rolesToRemove); + await member.roles.add(effect.roleId); + } + } + } catch (e) { + console.error("Failed to assign role in inventory use:", e); + result.results.push("⚠️ Failed to assign role (Check bot permissions)"); + } + } + } + } + + return result; +}