Replace all hardcoded custom ID strings with module-level constants. Each module now has *_CUSTOM_IDS in its types file, using functions for dynamic IDs and PREFIX for startsWith matching. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
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";
|
|
import { INVENTORY_CUSTOM_IDS } from "./inventory.types";
|
|
|
|
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(INVENTORY_CUSTOM_IDS.PREFIX);
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|