Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1762b52

Browse files
committed
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: https://git.vylpes.xyz/External/card-drop/pulls/365 Reviewed-by: VylpesTester <[email protected]> Co-authored-by: Ethan Lane <[email protected]> Co-committed-by: Ethan Lane <[email protected]>
1 parent 5ebc5ff commit 1762b52

File tree

11 files changed

+146
-7
lines changed

11 files changed

+146
-7
lines changed

src/bot.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const client = new CoreClient([
3838

3939
Registry.RegisterCommands();
4040
Registry.RegisterButtonEvents();
41+
Registry.RegisterStringDropdownEvents();
4142

4243
if (!existsSync(`${process.env.DATA_DIR}/cards`) && process.env.GDRIVESYNC_AUTO && process.env.GDRIVESYNC_AUTO == "true") {
4344
console.log("Card directory not found, syncing...");

src/buttonEvents/Inventory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default class Inventory extends ButtonEvent {
1111
const page = interaction.customId.split(" ")[2];
1212

1313
AppLogger.LogSilly("Button/Inventory", `Parameters: userid=${userid}, page=${page}`);
14-
14+
1515
await interaction.deferUpdate();
1616

1717
const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid);
@@ -34,7 +34,7 @@ export default class Inventory extends ButtonEvent {
3434
await interaction.editReply({
3535
files: [ embed.image ],
3636
embeds: [ embed.embed ],
37-
components: [ embed.row ],
37+
components: [ embed.row1, embed.row2 ],
3838
});
3939
} catch (e) {
4040
AppLogger.LogError("Button/Inventory", `Error generating inventory page for ${member.user.username} with id ${member.user.id}: ${e}`);

src/client/client.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ import AppLogger from "./appLogger";
1717
import TimerHelper from "../helpers/TimerHelper";
1818
import GiveCurrency from "../timers/GiveCurrency";
1919
import PurgeClaims from "../timers/PurgeClaims";
20+
import StringDropdownEventItem from "../contracts/StringDropdownEventItem";
21+
import {StringDropdownEvent} from "../type/stringDropdownEvent";
2022

2123
export class CoreClient extends Client {
2224
private static _commandItems: ICommandItem[];
2325
private static _eventExecutors: EventExecutors;
2426
private static _buttonEvents: IButtonEventItem[];
27+
private static _stringDropdowns: StringDropdownEventItem[];
2528

2629
private _events: Events;
2730
private _util: Util;
@@ -45,6 +48,10 @@ export class CoreClient extends Client {
4548
return this._buttonEvents;
4649
}
4750

51+
public static get stringDropdowns(): StringDropdownEventItem[] {
52+
return this._stringDropdowns;
53+
}
54+
4855
constructor(intents: number[]) {
4956
super({ intents: intents });
5057
dotenv.config();
@@ -59,6 +66,7 @@ export class CoreClient extends Client {
5966

6067
CoreClient._commandItems = [];
6168
CoreClient._buttonEvents = [];
69+
CoreClient._stringDropdowns = [];
6270

6371
this._events = new Events();
6472
this._util = new Util();
@@ -408,4 +416,19 @@ export class CoreClient extends Client {
408416
AppLogger.LogVerbose("Client", `Registered Button Event: ${buttonId}`);
409417
}
410418
}
419+
420+
public static RegisterStringDropdownEvent(dropdownId: string, event: StringDropdownEvent, environment: Environment = Environment.All) {
421+
const item: StringDropdownEventItem = {
422+
DropdownId: dropdownId,
423+
Event: event,
424+
Environment: environment,
425+
};
426+
427+
if ((environment & CoreClient.Environment) == CoreClient.Environment) {
428+
CoreClient._stringDropdowns.push(item);
429+
430+
AppLogger.LogVerbose("Client", `Registered String Dropdown Event: ${dropdownId}`);
431+
}
432+
}
411433
}
434+

src/client/events.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ChatInputCommand from "./interactionCreate/ChatInputCommand";
33
import Button from "./interactionCreate/Button";
44
import AppLogger from "./appLogger";
55
import NewUserDiscovery from "./interactionCreate/middleware/NewUserDiscovery";
6+
import StringDropdown from "./interactionCreate/StringDropdown";
67

78
export class Events {
89
public async onInteractionCreate(interaction: Interaction) {
@@ -19,6 +20,11 @@ export class Events {
1920
AppLogger.LogVerbose("Client", `Button: ${interaction.customId}`);
2021
Button.onButtonClicked(interaction);
2122
}
23+
24+
if (interaction.isStringSelectMenu()) {
25+
AppLogger.LogVerbose("Client", `StringDropdown: ${interaction.customId}`);
26+
StringDropdown.onStringDropdownSelected(interaction);
27+
}
2228
}
2329

2430
// Emit when bot is logged in and ready to use
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {StringSelectMenuInteraction} from "discord.js";
2+
import {CoreClient} from "../client";
3+
import AppLogger from "../appLogger";
4+
5+
export default class StringDropdown {
6+
public static async onStringDropdownSelected(interaction: StringSelectMenuInteraction) {
7+
if (!interaction.isStringSelectMenu()) return;
8+
9+
const item = CoreClient.stringDropdowns.find(x => x.DropdownId == interaction.customId.split(" ")[0]);
10+
11+
if (!item) {
12+
AppLogger.LogVerbose("StringDropdown", `Event not found: ${interaction.customId}`);
13+
14+
await interaction.reply("Event not found");
15+
return;
16+
}
17+
18+
try {
19+
AppLogger.LogDebug("StringDropdown", `Executing ${interaction.customId}`);
20+
21+
item.Event.execute(interaction);
22+
} catch (e) {
23+
AppLogger.LogError("StringDropdown", `Error occurred while executing event: ${interaction.customId}`);
24+
AppLogger.LogError("StringDropdown", e as string);
25+
26+
await interaction.reply("An error occurred while executing the event");
27+
}
28+
}
29+
}

src/commands/inventory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default class Inventory extends Command {
4747
await interaction.followUp({
4848
files: [ embed.image ],
4949
embeds: [ embed.embed ],
50-
components: [ embed.row ],
50+
components: [ embed.row1, embed.row2 ],
5151
});
5252
} catch (e) {
5353
AppLogger.LogError("Commands/Inventory", e as string);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {Environment} from "../constants/Environment";
2+
import {StringDropdownEvent} from "../type/stringDropdownEvent";
3+
4+
interface StringDropdownEventItem {
5+
DropdownId: string,
6+
Event: StringDropdownEvent,
7+
Environment: Environment,
8+
}
9+
10+
export default StringDropdownEventItem;

src/helpers/InventoryHelper.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
1+
import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from "discord.js";
22
import Inventory from "../database/entities/app/Inventory";
33
import { CoreClient } from "../client/client";
44
import EmbedColours from "../constants/EmbedColours";
@@ -24,7 +24,8 @@ interface InventoryPageCards {
2424

2525
interface ReturnedInventoryPage {
2626
embed: EmbedBuilder,
27-
row: ActionRowBuilder<ButtonBuilder>,
27+
row1: ActionRowBuilder<ButtonBuilder>,
28+
row2: ActionRowBuilder<StringSelectMenuBuilder>,
2829
image: AttachmentBuilder,
2930
}
3031

@@ -99,7 +100,7 @@ export default class InventoryHelper {
99100
.setColor(EmbedColours.Ok)
100101
.setImage("attachment://page.png");
101102

102-
const row = new ActionRowBuilder<ButtonBuilder>()
103+
const row1 = new ActionRowBuilder<ButtonBuilder>()
103104
.addComponents(
104105
new ButtonBuilder()
105106
.setCustomId(`inventory ${userid} ${page - 1}`)
@@ -112,9 +113,23 @@ export default class InventoryHelper {
112113
.setStyle(ButtonStyle.Primary)
113114
.setDisabled(page + 1 == pages.length));
114115

116+
let pageNum = 0;
117+
118+
const row2 = new ActionRowBuilder<StringSelectMenuBuilder>()
119+
.addComponents(
120+
new StringSelectMenuBuilder()
121+
.setCustomId("inventory")
122+
.setPlaceholder(`${currentPage.name} (${currentPage.seriesSubpage + 1})`)
123+
.addOptions(...pages.map(x =>
124+
new StringSelectMenuOptionBuilder()
125+
.setLabel(`${x.name} (${x.seriesSubpage + 1})`.substring(0, 100))
126+
.setDescription(`Page ${pageNum + 1}`)
127+
.setDefault(currentPage.id == x.id)
128+
.setValue(`${userid} ${pageNum++}`))));
129+
115130
const buffer = await ImageHelper.GenerateCardImageGrid(currentPage.cards.map(x => ({ id: x.id, path: x.path })));
116131
const image = new AttachmentBuilder(buffer, { name: "page.png" });
117132

118-
return { embed, row, image };
133+
return { embed, row1, row2, image };
119134
}
120135
}

src/registry.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import SeriesEvent from "./buttonEvents/Series";
3131
import TradeButtonEvent from "./buttonEvents/Trade";
3232
import ViewButtonEvent from "./buttonEvents/View";
3333

34+
// String Dropdown Event Imports
35+
import InventoryStringDropdown from "./stringDropdowns/Inventory";
36+
3437
export default class Registry {
3538
public static RegisterCommands() {
3639
// Global Commands
@@ -64,4 +67,8 @@ export default class Registry {
6467
CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent());
6568
CoreClient.RegisterButtonEvent("view", new ViewButtonEvent());
6669
}
70+
71+
public static RegisterStringDropdownEvents() {
72+
CoreClient.RegisterStringDropdownEvent("inventory", new InventoryStringDropdown());
73+
}
6774
}

src/stringDropdowns/Inventory.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {StringSelectMenuInteraction} from "discord.js";
2+
import {StringDropdownEvent} from "../type/stringDropdownEvent";
3+
import AppLogger from "../client/appLogger";
4+
import InventoryHelper from "../helpers/InventoryHelper";
5+
6+
export default class Inventory extends StringDropdownEvent {
7+
public override async execute(interaction: StringSelectMenuInteraction) {
8+
if (!interaction.guild) return;
9+
10+
const userid = interaction.values[0].split(" ")[0];
11+
const page = interaction.values[0].split(" ")[1];
12+
13+
AppLogger.LogDebug("StringDropdown/Inventory", `Parameters: userid=${userid}, page=${page}`);
14+
15+
await interaction.deferUpdate();
16+
17+
const member = interaction.guild.members.cache.find(x => x.id == userid) || await interaction.guild.members.fetch(userid);
18+
19+
if (!member) {
20+
await interaction.reply("Unable to find user.");
21+
return;
22+
}
23+
24+
try {
25+
const embed = await InventoryHelper.GenerateInventoryPage(member.user.username, member.user.id, Number(page));
26+
27+
if (!embed) {
28+
await interaction.followUp("No page for user found.");
29+
return;
30+
}
31+
32+
await interaction.editReply({
33+
files: [ embed.image ],
34+
embeds: [ embed.embed ],
35+
components: [ embed.row1, embed.row2 ],
36+
});
37+
} catch (e) {
38+
AppLogger.LogError("StringDropdown/Inventory", `Error generating inventory page for ${member.user.username} with id ${member.user.id}: ${e}`);
39+
40+
await interaction.followUp("An error has occurred running this command.");
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)