diff --git a/src/buttonEvents/Inventory.ts b/src/buttonEvents/Inventory.ts index b501fdb..8356305 100644 --- a/src/buttonEvents/Inventory.ts +++ b/src/buttonEvents/Inventory.ts @@ -31,7 +31,7 @@ export default class Inventory extends ButtonEvent { return; } - await interaction.followUp({ + await interaction.editReply({ files: [ embed.image ], embeds: [ embed.embed ], components: [ embed.row ], diff --git a/src/buttonEvents/Series.ts b/src/buttonEvents/Series.ts index 0d98bfb..05bb426 100644 --- a/src/buttonEvents/Series.ts +++ b/src/buttonEvents/Series.ts @@ -24,11 +24,14 @@ export default class Series extends ButtonEvent { const seriesid = interaction.customId.split(" ")[2]; const page = interaction.customId.split(" ")[3]; - const embed = SeriesHelper.GenerateSeriesViewPage(Number(seriesid), Number(page)); + await interaction.deferUpdate(); - await interaction.update({ + const embed = await SeriesHelper.GenerateSeriesViewPage(Number(seriesid), Number(page)); + + await interaction.editReply({ embeds: [ embed!.embed ], components: [ embed!.row ], + files: [ embed!.image ], }); } @@ -42,4 +45,4 @@ export default class Series extends ButtonEvent { components: [ embed!.row ], }); } -} \ No newline at end of file +} diff --git a/src/commands/series.ts b/src/commands/series.ts index 2122355..94053a6 100644 --- a/src/commands/series.ts +++ b/src/commands/series.ts @@ -47,6 +47,8 @@ export default class Series extends Command { AppLogger.LogSilly("Commands/Series/View", `Parameters: id=${id?.value}`); + await interaction.deferReply(); + if (!id) return; const series = CoreClient.Cards.find(x => x.id == id.value); @@ -54,13 +56,17 @@ export default class Series extends Command { if (!series) { AppLogger.LogVerbose("Commands/Series/View", "Series not found."); - await interaction.reply("Series not found."); + await interaction.followUp("Series not found."); return; } - const embed = SeriesHelper.GenerateSeriesViewPage(series.id, 0); + const embed = await SeriesHelper.GenerateSeriesViewPage(series.id, 0); - await interaction.reply({ embeds: [ embed!.embed ], components: [ embed!.row ]}); + await interaction.followUp({ + embeds: [ embed!.embed ], + components: [ embed!.row ], + files: [ embed!.image ], + }); } private async ListSeries(interaction: CommandInteraction) { @@ -68,4 +74,4 @@ export default class Series extends Command { await interaction.reply({ embeds: [ embed!.embed ], components: [ embed!.row ]}); } -} \ No newline at end of file +} diff --git a/src/helpers/ImageHelper.ts b/src/helpers/ImageHelper.ts new file mode 100644 index 0000000..39b07bf --- /dev/null +++ b/src/helpers/ImageHelper.ts @@ -0,0 +1,43 @@ +import {createCanvas, loadImage} from "canvas"; +import path from "path"; +import AppLogger from "../client/appLogger"; +import {existsSync} from "fs"; + +export default class ImageHelper { + public static async GenerateCardImageGrid(paths: string[]): Promise { + const gridWidth = 3; + const gridHeight = Math.ceil(paths.length / gridWidth); + + const imageWidth = 526; + const imageHeight = 712; + + const canvasWidth = imageWidth * gridWidth; + const canvasHeight = imageHeight * gridHeight; + + const canvas = createCanvas(canvasWidth, canvasHeight); + const ctx = canvas.getContext("2d"); + + for (let i = 0; i < paths.length; i++) { + const filePath = path.join(process.env.DATA_DIR!, "cards", paths[i]); + + const exists = existsSync(filePath); + + if (!exists) { + AppLogger.LogError("ImageHelper/GenerateCardImageGrid", `Failed to load image from path ${paths[i]}`); + continue; + } + + const image = await loadImage(filePath); + + const x = i % gridWidth; + const y = Math.floor(i / gridWidth); + + const imageX = imageWidth * x; + const imageY = imageHeight * y; + + ctx.drawImage(image, imageX, imageY); + } + + return canvas.toBuffer(); + } +} diff --git a/src/helpers/InventoryHelper.ts b/src/helpers/InventoryHelper.ts index 0218ef8..4aab75e 100644 --- a/src/helpers/InventoryHelper.ts +++ b/src/helpers/InventoryHelper.ts @@ -5,8 +5,7 @@ import EmbedColours from "../constants/EmbedColours"; import { CardRarity, CardRarityToString } from "../constants/CardRarity"; import cloneDeep from "clone-deep"; import AppLogger from "../client/appLogger"; -import { createCanvas, loadImage } from "canvas"; -import path from "path"; +import ImageHelper from "./ImageHelper"; interface InventoryPage { id: number, @@ -113,44 +112,9 @@ export default class InventoryHelper { .setStyle(ButtonStyle.Primary) .setDisabled(page + 1 == pages.length)); - const buffer = await this.GenerateInventoryImage(currentPage); + const buffer = await ImageHelper.GenerateCardImageGrid(currentPage.cards.map(x => x.path)); const image = new AttachmentBuilder(buffer, { name: "page.png" }); return { embed, row, image }; } - - private static async GenerateInventoryImage(page: InventoryPage): Promise { - const gridWidth = 3; - const gridHeight = Math.ceil(page.cards.length / gridWidth); - - const imageWidth = 526; - const imageHeight = 712; - - const canvasWidth = imageWidth * gridWidth; - const canvasHeight = imageHeight * gridHeight; - - const canvas = createCanvas(canvasWidth, canvasHeight); - const ctx = canvas.getContext("2d"); - - for (let i = 0; i < page.cards.length; i++) { - const card = page.cards[i]; - - const image = await loadImage(path.join(process.env.DATA_DIR!, "cards", card.path)); - - if (!image) { - AppLogger.LogError("InventoryHelper/GenerateInventoryImage", `Failed to load image for card ${card.id}`); - continue; - } - - const x = i % gridWidth; - const y = Math.floor(i / gridWidth); - - const imageX = imageWidth * x; - const imageY = imageHeight * y; - - ctx.drawImage(image, imageX, imageY); - } - - return canvas.toBuffer(); - } } diff --git a/src/helpers/SeriesHelper.ts b/src/helpers/SeriesHelper.ts index d818f1a..9bb94a2 100644 --- a/src/helpers/SeriesHelper.ts +++ b/src/helpers/SeriesHelper.ts @@ -1,15 +1,16 @@ -import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; +import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import AppLogger from "../client/appLogger"; import cloneDeep from "clone-deep"; import { CoreClient } from "../client/client"; import EmbedColours from "../constants/EmbedColours"; import { CardRarityToString } from "../constants/CardRarity"; +import ImageHelper from "./ImageHelper"; export default class SeriesHelper { - public static GenerateSeriesViewPage(seriesId: number, page: number): { embed: EmbedBuilder, row: ActionRowBuilder } | null { + public static async GenerateSeriesViewPage(seriesId: number, page: number): Promise<{ embed: EmbedBuilder, row: ActionRowBuilder, image: AttachmentBuilder } | null> { AppLogger.LogSilly("Helpers/SeriesHelper", `Parameters: seriesId=${seriesId}, page=${page}`); - const itemsPerPage = 15; + const itemsPerPage = 9; const series = cloneDeep(CoreClient.Cards) .find(x => x.id == seriesId); @@ -37,7 +38,8 @@ export default class SeriesHelper { .setTitle(series.name) .setColor(EmbedColours.Ok) .setDescription(description) - .setFooter({ text: `${series.id} · ${totalCards} cards · Page ${page + 1} of ${totalPages}` }); + .setFooter({ text: `${series.id} · ${totalCards} cards · Page ${page + 1} of ${totalPages}` }) + .setImage("attachment://page.png"); const row = new ActionRowBuilder() .addComponents( @@ -52,7 +54,10 @@ export default class SeriesHelper { .setStyle(ButtonStyle.Primary) .setDisabled(page + 1 > totalPages)); - return { embed, row }; + const buffer = await ImageHelper.GenerateCardImageGrid(cardsOnPage.map(x => x.path)); + const image = new AttachmentBuilder(buffer, { name: "page.png" }); + + return { embed, row, image }; } public static GenerateSeriesListPage(page: number): { embed: EmbedBuilder, row: ActionRowBuilder } | null {