feat: Implement structured lootbox results with image support and display referenced items in shop listings.

This commit is contained in:
syntaxbullet
2026-02-08 16:07:13 +01:00
parent ee088ad84b
commit 5e8683a19f
9 changed files with 359 additions and 64 deletions

View File

@@ -1,20 +1,18 @@
import { createCommand } from "@shared/lib/utils";
import {
SlashCommandBuilder,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
type BaseGuildTextChannel,
PermissionFlagsBits,
MessageFlags
} from "discord.js";
import { inventoryService } from "@shared/modules/inventory/inventory.service";
import { createSuccessEmbed, createErrorEmbed, createBaseEmbed } from "@lib/embeds";
import { createErrorEmbed } from "@lib/embeds";
import { UserError } from "@shared/lib/errors";
import { items } from "@db/schema";
import { ilike, isNotNull, and } from "drizzle-orm";
import { ilike, isNotNull, and, inArray } from "drizzle-orm";
import { DrizzleClient } from "@shared/db/DrizzleClient";
import { getShopListingMessage } from "@/modules/economy/shop.view";
import { EffectType, LootType } from "@shared/lib/constants";
export const listing = createCommand({
data: new SlashCommandBuilder()
@@ -54,14 +52,42 @@ export const listing = createCommand({
return;
}
// Prepare context for lootboxes
const context: { referencedItems: Map<number, { name: string; rarity: string }> } = { referencedItems: new Map() };
const usageData = item.usageData as any;
const lootboxEffect = usageData?.effects?.find((e: any) => e.type === EffectType.LOOTBOX);
if (lootboxEffect && lootboxEffect.pool) {
const itemIds = lootboxEffect.pool
.filter((drop: any) => drop.type === LootType.ITEM && drop.itemId)
.map((drop: any) => drop.itemId);
if (itemIds.length > 0) {
// Remove duplicates
const uniqueIds = [...new Set(itemIds)] as number[];
const referencedItems = await DrizzleClient.select({
id: items.id,
name: items.name,
rarity: items.rarity
}).from(items).where(inArray(items.id, uniqueIds));
for (const ref of referencedItems) {
context.referencedItems.set(ref.id, { name: ref.name, rarity: ref.rarity || 'C' });
}
}
}
const listingMessage = getShopListingMessage({
...item,
rarity: item.rarity || undefined,
formattedPrice: `${item.price} 🪙`,
price: item.price
});
}, context);
try {
await targetChannel.send(listingMessage);
await targetChannel.send(listingMessage as any);
await interaction.editReply({ content: `✅ Listing for **${item.name}** posted in ${targetChannel}.` });
} catch (error: any) {
if (error instanceof UserError) {