docs: add inventory display redesign spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
117
docs/superpowers/specs/2026-03-28-inventory-display-redesign.md
Normal file
117
docs/superpowers/specs/2026-03-28-inventory-display-redesign.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Inventory Display Redesign
|
||||
|
||||
## Overview
|
||||
|
||||
Redesign the `/inventory` command from a basic embed listing to a polished Components V2 experience with rarity indicators, paginated list view, item detail view with artwork, and inline item management actions.
|
||||
|
||||
## Rarity Emoji Mapping
|
||||
|
||||
Add a `squareEmoji` field to `RARITY_CONFIG` in `shared/lib/rarity.ts`:
|
||||
|
||||
| Rarity | squareEmoji | Existing emoji | Color hex |
|
||||
|--------|-------------|----------------|-----------|
|
||||
| C | 🟤 | 📦 | 0x95A5A6 |
|
||||
| R | 🔵 | 📦 | 0x3498DB |
|
||||
| SR | 🟣 | ✨ | 0x9B59B6 |
|
||||
| SSR | 🟡 | 🌟 | 0xF1C40F |
|
||||
|
||||
Non-item rarities (CURRENCY, XP, NOTHING) do not get square emojis. The existing `emoji` field remains unchanged (used by lootbox results).
|
||||
|
||||
## List View
|
||||
|
||||
The `/inventory [user]` command renders a Components V2 message:
|
||||
|
||||
1. **Header** — `TextDisplayBuilder`: `# 📦 {username}'s Inventory` with subtitle showing total item count.
|
||||
2. **Separator**
|
||||
3. **Item rows** (5 per page) — Each item is a `TextDisplayBuilder` line: `{squareEmoji} **{Item Name}** — {Rarity Label} · {Type} · ×{quantity}`
|
||||
4. **Separator**
|
||||
5. **Select menu** — `StringSelectMenuBuilder` populated with the 5 items on the current page. Placeholder: "Select an item for details". Each option shows item name and rarity label.
|
||||
6. **Navigation row** — `ActionRowBuilder`: `◀ Previous` (disabled on page 1), disabled `Page X/Y` indicator button, `Next ▶` (disabled on last page).
|
||||
|
||||
**Container:** `ContainerBuilder` with accent color from the highest-rarity item on the current page.
|
||||
|
||||
**Sorting:** Items sorted by rarity descending (SSR → SR → R → C), then alphabetically within the same rarity.
|
||||
|
||||
**Empty state:** If inventory is empty, show: "No items yet. Visit the shop or complete quests to earn items!"
|
||||
|
||||
**Collector:** `createMessageComponentCollector` with 2-minute idle timeout. On timeout, disable all interactive components.
|
||||
|
||||
## Detail View
|
||||
|
||||
Shown when a user selects an item from the dropdown or uses `/inventory view <item>`:
|
||||
|
||||
1. **Header section** — `SectionBuilder`:
|
||||
- `TextDisplayBuilder`: `{squareEmoji} **{Item Name}**` with subtitle `-# {Rarity Label} · {Type}`
|
||||
- `ThumbnailBuilder` with the item's `iconUrl`
|
||||
2. **Artwork** — `MediaGalleryBuilder` displaying the item's `imageUrl`
|
||||
3. **Description** — `TextDisplayBuilder` with the item's `description`
|
||||
4. **Separator**
|
||||
5. **Stats row** — `TextDisplayBuilder`: `Owned: **×{quantity}**` and `Value: **{price} 🪙**` (or "Not tradeable" if price is null)
|
||||
6. **Action buttons** — `ActionRowBuilder`:
|
||||
- `◀ Back` (primary) — returns to list view at the same page
|
||||
- `🧪 Use` (success) — only shown if item type is CONSUMABLE with effects defined
|
||||
- `🗑 Discard` (danger) — drops one unit of the item
|
||||
|
||||
**Container:** `ContainerBuilder` with accent color matching the item's rarity color.
|
||||
|
||||
### Use Button Flow
|
||||
|
||||
Calls `inventoryService.useItem()` and shows the result inline. Then returns to the detail view with updated quantity. If quantity reaches 0, returns to the list view.
|
||||
|
||||
### Discard Flow
|
||||
|
||||
1. Clicking `🗑 Discard` replaces the action row with a confirmation: "Discard 1× {Item Name}?" with `Confirm` (danger) and `Cancel` (secondary) buttons.
|
||||
2. On confirm: calls `inventoryService.removeItem(userId, itemId, 1)`, returns to detail view with updated quantity. If quantity reaches 0, returns to list view.
|
||||
3. On cancel: returns to the normal detail view action buttons.
|
||||
|
||||
## `/inventory view <item>` Subcommand
|
||||
|
||||
Adds a `view` subcommand with a required `item` string option that has autocomplete. Autocomplete queries the user's inventory items (reusing the pattern from `getAutocompleteItems`). Goes directly to the detail view. The Back button returns to the full paginated list at page 1.
|
||||
|
||||
## Item Selection Entry Points
|
||||
|
||||
Two ways to reach the detail view:
|
||||
- **Select menu dropdown** on the inventory list — for browsing
|
||||
- **`/inventory view <item>`** subcommand — for direct access when the user knows the item name
|
||||
|
||||
Both render the same detail view.
|
||||
|
||||
## Interaction Custom IDs
|
||||
|
||||
All custom IDs include the invoking user's ID to prevent other users from interacting:
|
||||
|
||||
| Custom ID | Purpose |
|
||||
|-----------|---------|
|
||||
| `inv_select_{userId}` | Item select menu |
|
||||
| `inv_prev_{userId}` | Previous page button |
|
||||
| `inv_next_{userId}` | Next page button |
|
||||
| `inv_back_{userId}` | Back to list from detail |
|
||||
| `inv_use_{userId}` | Use item button |
|
||||
| `inv_discard_{userId}` | Discard item button |
|
||||
| `inv_discard_confirm_{userId}` | Confirm discard |
|
||||
| `inv_discard_cancel_{userId}` | Cancel discard |
|
||||
|
||||
## File Changes
|
||||
|
||||
### Modified
|
||||
|
||||
- **`shared/lib/rarity.ts`** — Add `squareEmoji` field to `RARITY_CONFIG` entries for C, R, SR, SSR.
|
||||
- **`bot/commands/inventory/inventory.ts`** — Rewrite to CV2 with pagination collector. Add `view` subcommand with autocomplete. Command setup and collector logic live here.
|
||||
- **`bot/modules/inventory/inventory.view.ts`** — Replace `getInventoryEmbed` with `getInventoryListMessage` (builds the paginated CV2 list) and add `getItemDetailMessage` (builds the detail CV2 view). `getLootboxResultMessage` is untouched.
|
||||
|
||||
### New
|
||||
|
||||
- **`bot/modules/inventory/inventory.interaction.ts`** — Handles all inventory interaction routing: select menu item selection, pagination buttons, back navigation, use item, discard + confirmation flow.
|
||||
|
||||
### Unchanged
|
||||
|
||||
- `shared/modules/inventory/inventory.service.ts` — Already provides `getInventory`, `useItem`, `removeItem`, `getAutocompleteItems`.
|
||||
- Database schema — All required fields (`iconUrl`, `imageUrl`, `description`, `rarity`, `type`, `price`) already exist on the items table.
|
||||
|
||||
## Pagination Details
|
||||
|
||||
- **Items per page:** 5
|
||||
- **Page calculation:** `totalPages = Math.ceil(items.length / 5)`
|
||||
- **Page clamping:** `safePage = Math.min(page, totalPages - 1)` to handle items being consumed while browsing
|
||||
- **Collector timeout:** 2 minutes idle, matching the quest system pattern
|
||||
- **On timeout:** Edit message to disable all buttons and the select menu
|
||||
Reference in New Issue
Block a user