feat: Add support for local asset URLs for shop item icons and images, attaching them to Discord messages.
All checks were successful
Deploy to Production / test (push) Successful in 42s
All checks were successful
Deploy to Production / test (push) Successful in 42s
This commit is contained in:
@@ -1,16 +1,46 @@
|
|||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, AttachmentBuilder } from "discord.js";
|
||||||
import { createBaseEmbed } from "@/lib/embeds";
|
import { createBaseEmbed } from "@/lib/embeds";
|
||||||
import { resolveAssetUrl } from "@shared/lib/assets";
|
import { resolveAssetUrl, isLocalAssetUrl } from "@shared/lib/assets";
|
||||||
|
import { join } from "path";
|
||||||
|
import { existsSync } from "fs";
|
||||||
|
|
||||||
export function getShopListingMessage(item: { id: number; name: string; description: string | null; formattedPrice: string; iconUrl: string | null; imageUrl: string | null; price: number | bigint }) {
|
export function getShopListingMessage(item: { id: number; name: string; description: string | null; formattedPrice: string; iconUrl: string | null; imageUrl: string | null; price: number | bigint }) {
|
||||||
// Resolve asset URLs to full URLs for Discord embeds
|
const files: AttachmentBuilder[] = [];
|
||||||
const resolvedIconUrl = resolveAssetUrl(item.iconUrl);
|
let thumbnailUrl = resolveAssetUrl(item.iconUrl);
|
||||||
const resolvedImageUrl = resolveAssetUrl(item.imageUrl);
|
let displayImageUrl = resolveAssetUrl(item.imageUrl);
|
||||||
|
|
||||||
|
// Handle local icon
|
||||||
|
if (item.iconUrl && isLocalAssetUrl(item.iconUrl)) {
|
||||||
|
const iconPath = join(process.cwd(), "bot/assets/graphics", item.iconUrl.replace(/^\/?assets\//, ""));
|
||||||
|
if (existsSync(iconPath)) {
|
||||||
|
const iconName = defaultName(item.iconUrl);
|
||||||
|
files.push(new AttachmentBuilder(iconPath, { name: iconName }));
|
||||||
|
thumbnailUrl = `attachment://${iconName}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle local image (avoid duplicate attachments if same as icon)
|
||||||
|
if (item.imageUrl && isLocalAssetUrl(item.imageUrl)) {
|
||||||
|
// If image is same as icon, just use the same attachment reference
|
||||||
|
if (item.imageUrl === item.iconUrl && thumbnailUrl?.startsWith("attachment://")) {
|
||||||
|
displayImageUrl = thumbnailUrl;
|
||||||
|
} else {
|
||||||
|
const imagePath = join(process.cwd(), "bot/assets/graphics", item.imageUrl.replace(/^\/?assets\//, ""));
|
||||||
|
if (existsSync(imagePath)) {
|
||||||
|
const imageName = defaultName(item.imageUrl);
|
||||||
|
// Check if we already attached this file (by name)
|
||||||
|
if (!files.find(f => f.name === imageName)) {
|
||||||
|
files.push(new AttachmentBuilder(imagePath, { name: imageName }));
|
||||||
|
}
|
||||||
|
displayImageUrl = `attachment://${imageName}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const embed = createBaseEmbed(`Shop: ${item.name}`, item.description || "No description available.", "Green")
|
const embed = createBaseEmbed(`Shop: ${item.name}`, item.description || "No description available.", "Green")
|
||||||
.addFields({ name: "Price", value: item.formattedPrice, inline: true })
|
.addFields({ name: "Price", value: item.formattedPrice, inline: true })
|
||||||
.setThumbnail(resolvedIconUrl)
|
.setThumbnail(thumbnailUrl)
|
||||||
.setImage(resolvedImageUrl)
|
.setImage(displayImageUrl)
|
||||||
.setFooter({ text: "Click the button below to purchase instantly." });
|
.setFooter({ text: "Click the button below to purchase instantly." });
|
||||||
|
|
||||||
const buyButton = new ButtonBuilder()
|
const buyButton = new ButtonBuilder()
|
||||||
@@ -21,5 +51,9 @@ export function getShopListingMessage(item: { id: number; name: string; descript
|
|||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buyButton);
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buyButton);
|
||||||
|
|
||||||
return { embeds: [embed], components: [row] };
|
return { embeds: [embed], components: [row], files };
|
||||||
|
}
|
||||||
|
|
||||||
|
function defaultName(path: string): string {
|
||||||
|
return path.split("/").pop() || "image.png";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user