Skip to content

Commit

Permalink
revert to fix formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
ryandward committed Mar 10, 2024
1 parent 67b3ad8 commit 0143f15
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 177 deletions.
7 changes: 5 additions & 2 deletions commands/bank/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AttachmentBuilder, EmbedBuilder, SlashCommandBuilder, } from 'discord.j
import _ from 'lodash';
import { AppDataSource } from '../../app_data.js';
import { Bank } from '../../entities/Bank.js';
import { formatField, getImageUrl, getItemStatsText, getSpellDescription, getSpellLevels, } from './item_functions.js';
import { getImageUrl, getItemStatsText, getSpellDescription, getSpellLevels, } from './item_functions.js';
export const data = new SlashCommandBuilder()
.setName('find')
.setDescription('Find an item in the guild bank.')
Expand All @@ -12,6 +12,9 @@ export const data = new SlashCommandBuilder()
.setDescription('Item name to search for')
.setRequired(true)
.setAutocomplete(true));
export function formatField(field) {
return '```\n' + field.join('\n') + '\n```';
}
export async function autocomplete(interaction) {
try {
const focusedOption = interaction.options.getFocused(true);
Expand Down Expand Up @@ -68,9 +71,9 @@ export async function execute(interaction) {
itemText = itemText?.replace(/\[\[[^\]]*\|([^\]]+)\]\]/g, '$1');
itemText = itemText?.replace(/(.{1,45})(\s|$)/g, '$1\n');
const lineHeight = 25;
const padding = 50;
const lines = itemText.split('\n');
const textHeight = lines.length * lineHeight;
const padding = 50;
const canvasHeight = _.max([textHeight + padding, 200]);
const canvas = Canvas.createCanvas(700, canvasHeight);
const context = canvas.getContext('2d');
Expand Down
197 changes: 111 additions & 86 deletions commands/bank/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import {
EmbedBuilder,
SlashCommandBuilder,
} from 'discord.js';
import _ from 'lodash';
import { AppDataSource } from '../../app_data.js';
import { Bank } from '../../entities/Bank.js';
import {
formatField,
getImageUrl,
getItemStatsText,
getSpellDescription,
Expand All @@ -22,15 +22,21 @@ export const data = new SlashCommandBuilder()
.addStringOption(option =>
option
.setName('item')
.setDescription('The name of the item to search for')
.setDescription('Item name to search for')
.setRequired(true)
.setAutocomplete(true),
);

export function formatField(field: string[]): string {
return '```\n' + field.join('\n') + '\n```';
}

export async function autocomplete(interaction: AutocompleteInteraction) {
try {
const focusedOption = interaction.options.getFocused(true);
if (focusedOption && focusedOption.name === 'item') {
if (!focusedOption) return;

if (focusedOption.name === 'item') {
const searchTerm = `%${focusedOption.value}%`;
const items = await AppDataSource.manager
.createQueryBuilder(Bank, 'item')
Expand All @@ -41,7 +47,7 @@ export async function autocomplete(interaction: AutocompleteInteraction) {
.limit(10)
.getRawMany();

await interaction.respond(
return await interaction.respond(
items.map(item => ({
name: `(${item.Count}x) ${item.Name}`,
value: item.Name,
Expand All @@ -50,107 +56,126 @@ export async function autocomplete(interaction: AutocompleteInteraction) {
}
}
catch (error) {
console.error('Error in autocomplete:', error);
if (error instanceof Error) {
console.error('Error in autocomplete:', error);
}
}
}

export async function execute(interaction: CommandInteraction) {
try {
const itemName = interaction.options.get('item', true).value as string;
const itemData = await AppDataSource.manager.find(Bank, {
where: { Name: itemName },
});
if (itemData.length === 0) {
await interaction.reply('Item not found.');
return;
}
const { options } = interaction;

let itemText =
itemName.startsWith('Spell: ') || itemName.startsWith('Song: ')
? `${await getSpellLevels(itemName)}\n\n${await getSpellDescription(itemName)}`
: await getItemStatsText(itemName);

if (!itemText) {
await interaction.reply('Item not found.');
return;
if (!options.get('item')) {
throw new Error('You must provide an item to find.');
}
else {
const itemName = options.get('item')?.value as string;

itemText = itemText.replace(/\[\[[^\]]*\|([^\]]+)\]\]/g, '$1');
itemText = itemText.replace(/(.{1,45})(\s|$)/g, '$1\n');

const lineHeight = 25;
const padding = 50;
const lines = itemText.split('\n');
const textHeight = lines.length * lineHeight;
const canvasHeight = Math.max(textHeight + padding, 200);
const canvas = Canvas.createCanvas(700, canvasHeight);
const context = canvas.getContext('2d');

const background = await Canvas.loadImage('./images/stars.png');
context.drawImage(background, 0, 0, canvas.width, canvas.height);

const imageUrl = await getImageUrl(itemName);
if (imageUrl) {
const icon = await Canvas.loadImage(imageUrl);
context.drawImage(icon, canvas.width - 100, 25, 75, 75);
context.font = `${lineHeight}px sans-serif`;
context.fillStyle = '#ffffff';
lines.forEach((line, i) => {
context.fillText(line, 25, 25 + i * lineHeight);
const itemData = await AppDataSource.manager.find(Bank, {
where: { Name: itemName },
});
}

const attachment = new AttachmentBuilder(await canvas.encode('png'), {
name: 'item-stats-image.png',
});
// check if the itemName is a spell or a song
let itemText: string | null | undefined = '';

const isStack = itemData.some(item => item.Quantity > 1);
const bankers = itemData.map(item => item.Banker);

const embed = new EmbedBuilder()
.setTitle(':bank: Bank Record')
.setDescription(`**${itemName}**\n<t:${Math.floor(Date.now() / 1000)}:R>`)
.setColor('Green')
.setImage('attachment://item-stats-image.png');

const embedBuilder = [...new Set(bankers)].reduce((currentEmbed, banker) => {
const itemsOnBankers = itemData.filter(item => item.Banker === banker);
const sortedItems = itemsOnBankers.sort((a, b) => a.Location.localeCompare(b.Location));
const sortedItemLocations = formatField(
sortedItems.map(item => item.Location.replace('-', ' ')),
);
if (itemName.startsWith('Spell: ') || itemName.startsWith('Song: ')) {
const spellLevels = await getSpellLevels(itemName);
const spellDescription = await getSpellDescription(itemName);
itemText = `${spellLevels}\n\n${spellDescription}`;
// wrap newlines every 50 characters, but don't break words
}
else {
itemText = await getItemStatsText(itemName);
}

if (sortedItems.length === 0) {
return currentEmbed;
if (!itemText) {
await interaction.reply('Item not found.');
return;
}

currentEmbed.addFields(
{
name: `:bust_in_silhouette: ${banker}`,
value: `${sortedItems.length} matching item(s)`,
inline: false,
},
{ name: ':mag: Location', value: sortedItemLocations, inline: true },
);
if (isStack) {
currentEmbed.addFields({
name: ':money_bag: Stack',
value: formatField(sortedItems.map(item => item.Quantity.toString())),
inline: true,
});
itemText = itemText?.replace(/\[\[[^\]]*\|([^\]]+)\]\]/g, '$1');
itemText = itemText?.replace(/(.{1,45})(\s|$)/g, '$1\n');
const lineHeight = 25;
const lines = itemText.split('\n');
const textHeight = lines.length * lineHeight;
const padding = 50;
const canvasHeight = _.max([textHeight + padding, 200]) as number;
const canvas = Canvas.createCanvas(700, canvasHeight);
const context = canvas.getContext('2d');

const background = await Canvas.loadImage('./images/stars.png');
context.drawImage(background, 0, 0, canvas.width, canvas.height);

const imageUrl = await getImageUrl(itemName);

if (imageUrl) {
try {
const icon = await Canvas.loadImage(imageUrl);

context.drawImage(icon, canvas.width - 100, 25, 75, 75);
if (itemText) {
context.font = `${lineHeight}px sans-serif`;
context.fillStyle = '#ffffff';
lines.forEach((line, i) => {
context.fillText(line, 25, 25 + i * lineHeight + 25);
});
}
}
catch (error) {
console.error('Failed to load image:', error);
return;
}
}
return currentEmbed;
}, embed);

await interaction.reply({ embeds: [embedBuilder], files: [attachment] });
const attachment = new AttachmentBuilder(await canvas.encode('png'), {
name: 'item-stats-image.png',
});

const isStack = itemData.some(item => item.Quantity > 1);
const bankers = itemData.map(item => item.Banker);

const embed = new EmbedBuilder()
.setTitle(':bank: Bank Record')
.setDescription(`**${itemName}**\n<t:${Math.floor(Date.now() / 1000)}:R>`)
.setColor('Green')
.setImage('attachment://item-stats-image.png');

const embedBuilder = [...new Set(bankers)].reduce((currentEmbed: EmbedBuilder, banker) => {
const itemsOnBankers = itemData.filter(item => item.Banker === banker);
const sortedItems = itemsOnBankers.sort((a, b) => a.Location.localeCompare(b.Location));
const sortedItemLocations = formatField(
sortedItems.map(item => _.replace(item.Location, '-', ' ')),
);

if (sortedItems.length === 0) {
return currentEmbed;
}

currentEmbed.addFields(
{
name: `:bust_in_silhouette: ${banker}`,
value: `${sortedItems.length} matching item(s).`,
inline: false,
},
{ name: ':mag: Location', value: sortedItemLocations, inline: true },
);
if (isStack) {
currentEmbed.addFields({
name: ':money_bag: Stack',
value: formatField(sortedItems.map(item => item.Quantity.toString())),
inline: true,
});
}
return currentEmbed;
}, embed);

await interaction.reply({ embeds: [embedBuilder], files: [attachment] });
}
}
catch (error: unknown) {
console.error('Error in execute:', error);
catch (error) {
if (error instanceof Error) {
await interaction.reply(`Error in execute: ${error.message}`);
}
else {
await interaction.reply('An unknown error occurred.');
}
}
}
3 changes: 0 additions & 3 deletions commands/bank/item_functions.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import axios from 'axios';
import puppeteer from 'puppeteer';
export function formatField(field) {
return '```\n' + field.join('\n') + '\n```';
}
export async function getImageUrl(itemName) {
// Standardize the item name to ensure cache consistency
const standardizedItemName = itemName.replace('Song: ', '').replace('Spell: ', '');
Expand Down
Loading

0 comments on commit 0143f15

Please sign in to comment.