diff --git a/src/discord/MusicPlayer/Join.ts b/src/discord/MusicPlayer/Join.ts index a6b2113..0f5b7e7 100644 --- a/src/discord/MusicPlayer/Join.ts +++ b/src/discord/MusicPlayer/Join.ts @@ -70,7 +70,7 @@ const EMBEDS = { export async function joinVoiceChannelProcedure (data: Interaction | Message, instance: (DiscordMusicPlayerInstance | null), voiceChannel: (VoiceChannel | StageChannel)) { const isSlashCommand = data instanceof CommandInteraction && data.isCommand(); - const isAcceptableInteraction = data instanceof Interaction && data.isSelectMenu(); + const isAcceptableInteraction = data instanceof Interaction && (data.isSelectMenu() || data.isButton()); const isMessage = data instanceof Message; if ((!isSlashCommand && !isAcceptableInteraction) && !isMessage) return; diff --git a/src/discord/MusicPlayer/Play.ts b/src/discord/MusicPlayer/Play.ts index 27f2e07..6d4c3b7 100644 --- a/src/discord/MusicPlayer/Play.ts +++ b/src/discord/MusicPlayer/Play.ts @@ -1,4 +1,4 @@ -import { Message, CommandInteraction, Interaction, VoiceChannel, MessageActionRow, Permissions, DMChannel, TextChannel } from "discord.js"; +import { Message, CommandInteraction, Interaction, VoiceChannel, MessageActionRow, Permissions, MessageButton, TextChannel } from "discord.js"; import { makeErrorEmbed, makeSuccessEmbed, makeProcessingEmbed, sendMessage, sendMessageOrInteractionResponse, makeInfoEmbed } from "../../utils/DiscordMessage"; import DiscordProvider from "../../providers/Discord"; import Environment from "../../providers/Environment"; @@ -181,7 +181,30 @@ export default class Play { instance.addTrackToQueue(result[0]); if(result.length > 1) { - // TODO: Let user choose the video + + // If the first result title is exact match with the query or first title contains half the space of the query, it's probably a sentence + // then we don't need to show the search results + if(result[0].title === query || result[0].title && (Math.ceil((result[0].title.split(" ").length - 1) / 2) === Math.ceil((query.split(" ").length - 1) / 2))) return; + + // The query length is too long to fit in json + if(query.length > 100 - 51) return; + + const row = new MessageActionRow() + .addComponents( + new MessageButton() + .setEmoji('🔎') + .setCustomId(JSON.stringify({ + module: 'MP_S', + action: 'search', + data: { + q: query + } + })) + .setLabel(' Not this? Search!') + .setStyle('PRIMARY') + ) + + return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.ADDED_QUEUE(data, result[0])], components: [row] }); } return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.ADDED_QUEUE(data, result[0])] }); diff --git a/src/discord/MusicPlayer/Search.ts b/src/discord/MusicPlayer/Search.ts index a14d64f..84c8222 100644 --- a/src/discord/MusicPlayer/Search.ts +++ b/src/discord/MusicPlayer/Search.ts @@ -1,4 +1,4 @@ -import { Message, CommandInteraction, Interaction, VoiceChannel, MessageActionRow, Permissions, DMChannel, TextChannel, MessageSelectMenu, MessageSelectOptionData } from "discord.js"; +import { Message, CommandInteraction, Interaction, VoiceChannel, MessageActionRow, DMChannel, TextChannel, MessageSelectMenu, MessageSelectOptionData, GuildMember } from "discord.js"; import { makeErrorEmbed, makeSuccessEmbed, makeProcessingEmbed, sendMessage, sendMessageOrInteractionResponse, makeInfoEmbed } from "../../utils/DiscordMessage"; import DiscordProvider from "../../providers/Discord"; import Environment from "../../providers/Environment"; @@ -51,19 +51,41 @@ export default class Search { await this.process(message, args); } - async interactionCreate(interaction: CommandInteraction) { + async interactionCreate(interaction: Interaction) { if (interaction.isCommand()) { if (typeof interaction.commandName === 'undefined') return; if ((interaction.commandName).toLowerCase() !== 'search') return; await this.process(interaction, interaction.options); } + else if (interaction.isButton()) { + if(!interaction.guild || !interaction.guildId) return; + if (!this.tryParseJSONObject(interaction.customId)) return; + + let payload = JSON.parse(interaction.customId); + if(!interaction.member?.user?.id) return; + + /* + Discord have 100 char custom id char limit + So we need to shorten our json. + MP_P stands for MusicPlayer_Search + data.q stands for data.query + */ + + if (typeof payload.module === 'undefined' || + typeof payload.action === 'undefined' || + payload.module !== 'MP_S' || + payload.action !== 'search') return; + + await this.process(interaction, payload.data.q); + } } async process(data: Interaction | Message, args: any) { const isSlashCommand = data instanceof CommandInteraction && data.isCommand(); + const isButton = data instanceof Interaction && data.isButton(); const isMessage = data instanceof Message; - if (!isSlashCommand && !isMessage) return; + if (!isSlashCommand && !isMessage && !isButton) return; if (!data.member) return; if (!data.guild) return; @@ -85,15 +107,22 @@ export default class Search { else if (isSlashCommand) { query = args.getSubcommand(); } + else if (isButton) { + query = args; + } if (!query) return; if (!(data.channel instanceof TextChannel)) return; + let guildMember = data.member; - if (!data.member.voice.channel) + if(isButton) + guildMember = data.guild.members.cache.get(data.user.id)! + + if (!guildMember.voice.channel) return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.USER_NOT_IN_VOICECHANNEL(data)] }); - let voiceChannel = data.member.voice.channel; + let voiceChannel = guildMember.voice.channel; if (!DiscordMusicPlayer.isGuildInstanceExists(data.guildId)) { await joinVoiceChannelProcedure(data, null, voiceChannel); @@ -129,7 +158,7 @@ export default class Search { module: 'MP_SM', action: 'play', data: { - r: data.member.id, + r: guildMember.id, v: voiceChannel.id } })) @@ -155,4 +184,17 @@ export default class Search { } + tryParseJSONObject(jsonString: string) { + try { + let o = JSON.parse(jsonString); + if (o && typeof o === "object") { + return true; + //return o; + } + } + catch (e) { } + + return false; + } + } \ No newline at end of file diff --git a/src/utils/DiscordMessage.ts b/src/utils/DiscordMessage.ts index 8363c00..5b50c75 100644 --- a/src/utils/DiscordMessage.ts +++ b/src/utils/DiscordMessage.ts @@ -101,7 +101,7 @@ export async function sendMessageOrInteractionResponse(data: Message | Interacti const isSlashCommand = data instanceof Interaction && data.isCommand(); const isMessage = data instanceof Message; - if(isSlashCommand || (data instanceof Interaction && data.isSelectMenu())) { + if(isSlashCommand || (data instanceof Interaction && ( data.isSelectMenu() || data.isButton()))) { if(!data.replied) { let message; try {