diff --git a/bingus-bot/src/contexts/reply.ts b/bingus-bot/src/contexts/reply.ts index 2fcfd4b..d9bbba7 100644 --- a/bingus-bot/src/contexts/reply.ts +++ b/bingus-bot/src/contexts/reply.ts @@ -1,11 +1,13 @@ import { + ActionRowBuilder, ApplicationCommandType, + ButtonBuilder, + ButtonStyle, ContextMenuCommandBuilder, - EmbedBuilder, MessageFlags, } from "discord.js"; import { ContextMenu } from "../index.js"; -import { fetchBingus } from "../util.js"; +import { EmbedList, fetchBingus, replyEmbed } from "../util.js"; export const replyContext: ContextMenu = { builder: new ContextMenuCommandBuilder() @@ -21,29 +23,39 @@ export const replyContext: ContextMenu = { try { await interaction.deferReply({ flags: MessageFlags.Ephemeral }); - const data = await fetchBingus(query); - if (data.length === 0) { + const data = (await fetchBingus(query))[0]; + if (!data) { await interaction.editReply("No results found."); return; } - interaction.targetMessage.reply({ + const show = new ButtonBuilder() + .setCustomId('show') + .setLabel("Show message") + .setStyle(ButtonStyle.Primary); + + const message = await interaction.editReply({ embeds: [ - new EmbedBuilder() - .setAuthor({ - name: `Triggered by ${interaction.user.displayName}`, - iconURL: interaction.user.avatarURL() ?? undefined, - }) - .setTitle(data[0].title) - .setDescription(data[0].text) - .setColor("#65459A") - .setFooter({ text: `${data[0].relevance.toFixed()}% relevant` }) - .data, + replyEmbed(interaction, data) ], + components: [new ActionRowBuilder().addComponents(show)], }); - await interaction.editReply("Replied to the message!"); + await message.awaitMessageComponent({ + time: EmbedList.MAX_TIME + }) + + interaction.editReply({ + content: "Replied to message!", + embeds: [], + components: [] + }); + interaction.targetMessage.reply({ + embeds: [ + replyEmbed(interaction, data) + ], + }); } catch (error) { console.error(error); interaction.editReply("An error occurred while fetching results."); diff --git a/bingus-bot/src/contexts/replyWithList.ts b/bingus-bot/src/contexts/replyWithList.ts index 3ebb259..c8fea0e 100644 --- a/bingus-bot/src/contexts/replyWithList.ts +++ b/bingus-bot/src/contexts/replyWithList.ts @@ -1,11 +1,12 @@ import { ApplicationCommandType, + ButtonBuilder, ContextMenuCommandBuilder, - EmbedBuilder, + ButtonStyle, MessageFlags, } from "discord.js"; import { ContextMenu } from "../index.js"; -import { EmbedList, fetchBingus } from "../util.js"; +import { EmbedList, fetchBingus, replyEmbed } from "../util.js"; export const replyListContext: ContextMenu = { builder: new ContextMenuCommandBuilder() @@ -28,37 +29,30 @@ export const replyListContext: ContextMenu = { } const data = await fetchBingus(query); - if (data.length === 0) { await interaction.editReply("No results found."); return; } - const embedList = new EmbedList(); - embedList.push( + const show = new ButtonBuilder() + .setCustomId('show') + .setLabel("Show message") + .setStyle(ButtonStyle.Primary) + + const embedListEph = new EmbedList(show); + embedListEph.push( ...data.slice(0, 5).map( (res) => - new EmbedBuilder() - .setAuthor({ - name: `Triggered by ${interaction.user.displayName}`, - iconURL: interaction.user.avatarURL() ?? undefined, - }) - .setTitle(res.title) - .setDescription(res.text) - .setColor("#65459A") - .setFooter({ text: `(${res.relevance.toFixed()}% relevant)` }) - .data, + replyEmbed(interaction, res) ), ); - await embedList.sendChannel( - interaction.targetMessage.channel, - interaction.user.id, - undefined, - { messageReference: interaction.targetMessage }, - ); + const selectedIndex = await embedListEph.sendChatInput(interaction) + + interaction.targetMessage.reply({ + embeds: [replyEmbed(interaction, data[selectedIndex])], + }); - await interaction.editReply("Replied to the message!"); } catch (error) { console.error(error); interaction.editReply("An error occurred while fetching results."); diff --git a/bingus-bot/src/util.ts b/bingus-bot/src/util.ts index 36e6877..ecf1bbc 100644 --- a/bingus-bot/src/util.ts +++ b/bingus-bot/src/util.ts @@ -7,6 +7,7 @@ import { ComponentType, EmbedBuilder, EmojiIdentifierResolvable, + MessageContextMenuCommandInteraction, ReplyOptions, SendableChannels, } from "discord.js"; @@ -33,11 +34,32 @@ export interface BingusFaqResponse { text: string; } +export function replyEmbed(interaction: MessageContextMenuCommandInteraction, res: BingusFaqResponse) { + + const embedBuilder = new EmbedBuilder() + .setAuthor({ + name: `Triggered by ${interaction.user.displayName}`, + iconURL: interaction.user.avatarURL() ?? undefined, + }) + .setTitle(res.title) + .setDescription(res.text) + .setColor("#65459A") + .setFooter({ text: `${res.relevance.toFixed()}% relevant` }) + .data + + return embedBuilder; +} + export class EmbedList { - static MAX_TIME = 300_000; + static readonly MAX_TIME = 300_000; embeds: APIEmbed[] = []; + _eph?: ButtonBuilder; index = 0; + constructor(eph?: ButtonBuilder) { + this._eph = eph; + } + push(...embed: APIEmbed[]): number { return this.embeds.push(...embed); } @@ -55,24 +77,23 @@ export class EmbedList { .setStyle(ButtonStyle.Secondary) .setDisabled(this.index === 0); - return new ActionRowBuilder().addComponents(prev, next); + return new ActionRowBuilder().addComponents(prev, next, ...(this._eph ? [this._eph] : [])); } get(): EmbedBuilder { const embed = this.embeds[this.index]; return new EmbedBuilder(embed).setFooter({ - text: `${this.index + 1}/${this.embeds.length} ${ - embed.footer?.text - }`.trim(), + text: `${this.index + 1}/${this.embeds.length} ${embed.footer?.text + }`.trim(), }); } - async sendChannel( channel: SendableChannels, who: string | null, content?: string, reply?: ReplyOptions, ) { + const edit = await channel.send({ content, embeds: [this.get()], @@ -101,6 +122,7 @@ export class EmbedList { return; } this.index--; + break; } await i.update({ @@ -115,18 +137,24 @@ export class EmbedList { } async sendChatInput( - interaction: ChatInputCommandInteraction, + interaction: ChatInputCommandInteraction | MessageContextMenuCommandInteraction, publicInteraction: boolean | undefined = true, - ) { + ): Promise { + + let resolvePromise: (value: number) => void; + const indexPromise = new Promise((resolve) => { + resolvePromise = resolve; + }); + const reply = await (interaction.deferred ? interaction.editReply({ - embeds: [this.get()], - components: [this.getActionRow()], - }) + embeds: [this.get()], + components: [this.getActionRow()], + }) : interaction.reply({ - embeds: [this.get()], - components: [this.getActionRow()], - })); + embeds: [this.get()], + components: [this.getActionRow()], + })); const collector = reply.createMessageComponentCollector({ componentType: ComponentType.Button, @@ -151,6 +179,14 @@ export class EmbedList { return; } this.index--; + break; + case "show": + resolvePromise(this.index); + interaction.editReply({ + content: "Replied to message!", + embeds: [], + components: [] + }); } await i.update({ @@ -163,7 +199,7 @@ export class EmbedList { await interaction.editReply({ components: [] }); }); - return collector; + return indexPromise; } }