Skip to content

Commit

Permalink
fix: rework hub management as modal doesn't support SelectMenu anymor…
Browse files Browse the repository at this point in the history
…e (sadge)
  • Loading branch information
YoannMa committed Jan 2, 2024
1 parent 20d5b54 commit 3083b48
Show file tree
Hide file tree
Showing 6 changed files with 402 additions and 100 deletions.
150 changes: 117 additions & 33 deletions src/modules/voice/applicationCommands/voice.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
'use strict';

const { ApplicationCommand } = require('../../../core');
const { PermissionFlagsBits } = require('discord.js');
const { PermissionFlagsBits, channelMention } = require('discord.js');
const Lunr = require('lunr');

const { ApplicationCommand } = require('../../../core');

module.exports = class Voice extends ApplicationCommand {

Expand All @@ -23,61 +25,143 @@ module.exports = class Voice extends ApplicationCommand {
description : 'Manage Hubs',
subcommands : {
// list : { method : 'listHub', description : 'List all hubs' },
create : { method : 'createHub', description : 'Create a new hub' }
// edit : {
// method : 'editHub',
// description : 'Edit an existing hub',
// options : {
// id : {
// type : ApplicationCommand.SubTypes.String,
// description : 'Hub ID',
// autocomplete : 'autocomplete',
// required : true
// }
// }
// },
// delete : {
// method : 'deleteHub',
// description : 'Delete an existing hub',
// options : {
// id : {
// type : ApplicationCommand.SubTypes.String,
// description : 'Hub ID',
// autocomplete : 'autocomplete',
// required : true
// }
// }
// }
create : {
method : 'createHub',
description : 'Create a new hub',
options : {
name : {
description : 'Hub name',
type : ApplicationCommand.SubTypes.String,
required : true
},
'default-size' : {
description : 'Default size of the temporary channels',
type : ApplicationCommand.SubTypes.Integer,
required : false,
min : 0,
max : 99
},
'default-type' : {
description : 'Default visibility of the temporary channels',
type : ApplicationCommand.SubTypes.String,
required : false,
choices : {
'Public' : 'public',
'Locked' : 'locked',
'Private' : 'private'
}
}
}
},
edit : {
method : 'editHub',
description : 'Edit an existing hub',
options : {
hub : {
description : 'Hub',
type : ApplicationCommand.SubTypes.String,
autocomplete : 'autocompleteHub',
required : true
}
}
},
delete : {
method : 'deleteHub',
description : 'Delete an existing hub',
options : {
hub : {
description : 'Hub',
type : ApplicationCommand.SubTypes.String,
autocomplete : 'autocompleteHub',
required : true
}
}
}
}
}
};
}

listHub(interaction) {
/**
* @param {import('discord.js').AutocompleteInteraction} interaction
* @param {string} hub
*/
async autocompleteHub(interaction, { hub }) {

const { HubService } = this.services();

const { index, channels } = await HubService.buildAutoComplete(interaction.guild);

if (hub.length === 0) {

return interaction.respond(
channels.slice(0, 25)
.map(({ name, parent, id }) => ({ name : `${ parent.name } - ${ name }`, value : id }))
);
}

const results = index.query((q) => {

q.term(hub, { boost : 3 });
q.term(hub, { boost : 2, wildcard : Lunr.Query.wildcard.TRAILING });
q.term(hub, { boost : 1, editDistance : 1 });
});

return interaction.respond(results.map(({ ref }) => {

const channel = channels.find((c) => c.id === ref);

return { name : `${ channel.parent.name } - ${ channel.name }`, value : ref };
}));
}

createHub(interaction) {
async createHub(interaction, { name, 'default-size' : defaultSize = 10, 'default-type' : defaultType = 'public' }) {

const { HubView } = this.views();
const { HubService } = this.services();

const hub = await HubService.createHub(interaction.guild, name, { defaultSize, defaultType });

return HubView.createHub(interaction);
return interaction.reply({ content : `Channel ${ channelMention(hub.channel.id) } created ✅`, ephemeral : true });
}

editHub(interaction) {
/**
* @param {import('discord.js').ApplicationCommandInteraction} interaction
* @param {string} hub
*/
async editHub(interaction, { hub : hubId }) {

const { HubService } = this.services();
const { HubView } = this.views();

const hub = await HubService.getHub(interaction.guild.id, hubId);

if (!hub) {

return interaction.reply({ content : `Hub ${ hubId } not found ❌`, ephemeral : true });
}

return interaction.reply(HubView.editHub(hub));
}

deleteHub(interaction) {
/**
* @param {import('discord.js').ApplicationCommandInteraction} interaction
* @param {string} hub
*/
async deleteHub(interaction, { hub : hubId }) {

const { HubService } = this.services();

const hub = await HubService.getHub(interaction.guild.id, hubId);

if (!hub) {

return interaction.reply({ content : `Hub ${ hubId } not found ❌`, ephemeral : true });
}

const name = hub.channel.name;

await HubService.deleteHub(hub);

return interaction.reply({ content : `Hub "${ name }" deleted ✅`, ephemeral : true });
}
};
113 changes: 113 additions & 0 deletions src/modules/voice/interactions/hub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use strict';

const { MessageMentions : { ChannelsPattern }, channelMention } = require('discord.js');

const { Interaction, Util } = require('../../../core');

class Hub extends Interaction {

constructor() {

super('hub', { category : 'voice' });
}

static get interactions() {

return {
editDefaultSize : { method : 'editDefaultSize', customId : 'voice:hub:edit_default_size' },

setDefaultSize : { method : 'setDefaultSize', customId : 'voice:hub:set_default_size' },
setDefaultType : { method : 'setDefaultType', customId : 'voice:hub:set_default_type' }
};
}

/**
* @param {import('discord.js').MessageComponentInteraction} interaction
* @param {function(hub : Hub) : Promise<Hub|null>} handler
*/
async handle(interaction, handler) {

const { HubService } = this.services();

if (!interaction.guildId) {

return null;
}

const hubId = interaction.message.content.match(ChannelsPattern)?.groups?.id;

if (!hubId) {

return;
}

let hub = await HubService.getHub(interaction.guildId, hubId);

if (!hub) {

return;
}

hub = await handler(hub);

if (hub) {

await HubService.update(hub);
setTimeout(() => interaction.deleteReply(), Util.SECOND * 5);
}
}

/**
* @param {import('discord.js').ButtonInteraction} interaction
**/
editDefaultSize(interaction) {

const { HubView } = this.views();

return this.handle(interaction, async (hub) => {

await interaction.reply(HubView.editDefaultSize(hub));
});
}

/** ***************************************************************************** **/

/**
* @param {import('discord.js').MentionableSelectMenuInteraction} interaction
**/
setDefaultSize(interaction) {

return this.handle(interaction, async (hub) => {

hub.config.defaultSize = parseInt(interaction.values.pop(), 10);

if (isNaN(hub.config.defaultSize)) {

await interaction.reply({ content : `Invalid default size ❌`, ephemeral : true });

return;
}

await interaction.reply({ content : `Changed default size for ${ channelMention(hub.channel.id) } ✅`, ephemeral : true });

return hub;
});
}

/**
* @param {import('discord.js').SelectMenuInteraction} interaction
**/
setDefaultType(interaction) {

return this.handle(interaction, async (hub) => {

hub.config.defaultType = interaction.values.pop();

await interaction.reply({ content : `Changed default size for ${ channelMention(hub.channel.id) } ✅`, ephemeral : true });

return hub;
});
}
}

module.exports = Hub;
11 changes: 7 additions & 4 deletions src/modules/voice/listeners/voiceChannelDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ module.exports = class ChannelDeleteListener extends Listener {
*/
async exec(channel) {

const { HubService } = this.services();
const { HubService, TemporaryChannelService } = this.services();

if (!channel.guildId) {

return;
}

const hub = await HubService.getHub(channel.guildId, channel.id);
if (await HubService.exist(channel.guildId, channel.id)) {

if (hub) {
await HubService.deleteById(channel.guildId, channel.id);
}

if (await TemporaryChannelService.exist(channel.guildId, channel.id)) {

await HubService.deleteHub(hub);
await TemporaryChannelService.deleteById(channel.guildId, channel.id);
}
}
};
Loading

0 comments on commit 3083b48

Please sign in to comment.