card-drop/src/helpers/InventoryHelper.ts
Ethan Lane 1762b525b2
All checks were successful
Deploy To Stage / build (push) Successful in 9s
Deploy To Stage / deploy (push) Successful in 16s
Add dropdown to /inventory command for quick navigation (#365)
- Add ability to handle dropdown menus with the bot
- Add a dropdown to the inventoryhelper
- Add handler for the dropdown to navigate to that page

#344

Reviewed-on: #365
Reviewed-by: VylpesTester <tester@vylpes.com>
Co-authored-by: Ethan Lane <ethan@vylpes.com>
Co-committed-by: Ethan Lane <ethan@vylpes.com>
2024-09-21 18:09:24 +01:00

135 lines
5 KiB
TypeScript

import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from "discord.js";
import Inventory from "../database/entities/app/Inventory";
import { CoreClient } from "../client/client";
import EmbedColours from "../constants/EmbedColours";
import { CardRarity, CardRarityToString } from "../constants/CardRarity";
import cloneDeep from "clone-deep";
import AppLogger from "../client/appLogger";
import ImageHelper from "./ImageHelper";
interface InventoryPage {
id: number,
name: string,
cards: InventoryPageCards[],
seriesSubpage: number,
}
interface InventoryPageCards {
id: string,
name: string,
type: CardRarity,
quantity: number,
path: string,
}
interface ReturnedInventoryPage {
embed: EmbedBuilder,
row1: ActionRowBuilder<ButtonBuilder>,
row2: ActionRowBuilder<StringSelectMenuBuilder>,
image: AttachmentBuilder,
}
export default class InventoryHelper {
public static async GenerateInventoryPage(username: string, userid: string, page: number): Promise<ReturnedInventoryPage | undefined> {
AppLogger.LogSilly("Helpers/InventoryHelper", `Parameters: username=${username}, userid=${userid}, page=${page}`);
const cardsPerPage = 9;
const inventory = await Inventory.FetchAllByUserId(userid);
if (!inventory || inventory.length == 0) return undefined;
const clientCards = cloneDeep(CoreClient.Cards);
const allSeriesClaimed = clientCards
.sort((a, b) => a.id - b.id)
.filter(x => {
x.cards = x.cards
.sort((a, b) => b.type - a.type)
.filter(y => inventory.find(z => z.CardNumber == y.id))
.filter(y => inventory.find(z => z.CardNumber == y.id)!.Quantity > 0);
return x;
});
const pages: InventoryPage[] = [];
for (const series of allSeriesClaimed) {
const seriesCards = series.cards;
for (let i = 0; i < seriesCards.length; i+= cardsPerPage) {
const cards = series.cards.slice(i, i + cardsPerPage);
const pageCards: InventoryPageCards[] = [];
for (const card of cards) {
const item = inventory.find(x => x.CardNumber == card.id);
if (!item) {
continue;
}
pageCards.push({
id: card.id,
name: card.name,
type: card.type,
quantity: item.Quantity,
path: card.path,
});
}
pages.push({
id: series.id,
name: series.name,
cards: pageCards,
seriesSubpage: i / cardsPerPage,
});
}
}
const currentPage = pages[page];
if (!currentPage) {
return undefined;
}
const embed = new EmbedBuilder()
.setTitle(username)
.setDescription(`**${currentPage.name} (${currentPage.seriesSubpage + 1})**\n${currentPage.cards.map(x => `[${x.id}] ${x.name} (${CardRarityToString(x.type)}) x${x.quantity}`).join("\n")}`)
.setFooter({ text: `Page ${page + 1} of ${pages.length}` })
.setColor(EmbedColours.Ok)
.setImage("attachment://page.png");
const row1 = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId(`inventory ${userid} ${page - 1}`)
.setLabel("Previous")
.setStyle(ButtonStyle.Primary)
.setDisabled(page == 0),
new ButtonBuilder()
.setCustomId(`inventory ${userid} ${page + 1}`)
.setLabel("Next")
.setStyle(ButtonStyle.Primary)
.setDisabled(page + 1 == pages.length));
let pageNum = 0;
const row2 = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId("inventory")
.setPlaceholder(`${currentPage.name} (${currentPage.seriesSubpage + 1})`)
.addOptions(...pages.map(x =>
new StringSelectMenuOptionBuilder()
.setLabel(`${x.name} (${x.seriesSubpage + 1})`.substring(0, 100))
.setDescription(`Page ${pageNum + 1}`)
.setDefault(currentPage.id == x.id)
.setValue(`${userid} ${pageNum++}`))));
const buffer = await ImageHelper.GenerateCardImageGrid(currentPage.cards.map(x => ({ id: x.id, path: x.path })));
const image = new AttachmentBuilder(buffer, { name: "page.png" });
return { embed, row1, row2, image };
}
}