feat: Reminders #44
9 changed files with 159 additions and 24 deletions
|
@ -1,5 +1,5 @@
|
|||
import { SlashCommandBuilder } from '@discordjs/builders';
|
||||
import { Client, ChatInputCommandInteraction } from 'discord.js';
|
||||
import { ModalActionRowComponentBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||
import { Client, ChatInputCommandInteraction, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder } from 'discord.js';
|
||||
import { getLocalizations } from '../../utils/locales';
|
||||
import { getFilename } from '../../utils/misc';
|
||||
import { strToSeconds } from '../../utils/time';
|
||||
|
@ -160,7 +160,6 @@ export default {
|
|||
// plus user-friendly avec une interface (et en plus c'est
|
||||
// nouveau et cool)
|
||||
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
let time = interaction.options.getString(loc_default?.get(`c_${filename}_sub1_opt1_name`) as string);
|
||||
const message = interaction.options.getString(loc_default?.get(`c_${filename}_sub1_opt2_name`) as string);
|
||||
let option = OptionReminder.Nothing;
|
||||
|
@ -178,16 +177,36 @@ export default {
|
|||
}
|
||||
|
||||
seconds = strToSeconds(time);
|
||||
|
||||
// Add the remind to the db
|
||||
client.db.run('INSERT INTO reminder ( \
|
||||
data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id \
|
||||
) VALUES ( ?, ?, ?, ?, ?, ?, ?);', [message, interaction.createdAt.getTime() + seconds, option.valueOf(), interaction.channelId, interaction.createdAt.getTime(), interaction.user.id, interaction.guildId]);
|
||||
|
||||
// Send confirmation to user
|
||||
// TODO: local
|
||||
await interaction.reply(`${option} - ${seconds}`);
|
||||
} else {
|
||||
// Boîte de dialogue
|
||||
seconds = 0;
|
||||
// GUI
|
||||
// TODO: local
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId('reminderGUI')
|
||||
.setTitle('LOC_reminder');
|
||||
|
||||
// TODO: local
|
||||
const timeGUI = new TextInputBuilder()
|
||||
.setCustomId('timeGUI')
|
||||
.setLabel('LOC_time')
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setPlaceholder('1h')
|
||||
.setRequired(true);
|
||||
|
||||
modal.addComponents(new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(timeGUI));
|
||||
|
||||
await interaction.showModal(modal);
|
||||
|
||||
// Response of the modal in /src/modals/misc/reminder
|
||||
}
|
||||
|
||||
client.db.run('INSERT INTO reminder ( \
|
||||
data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id \
|
||||
) VALUES ( ?, ?, ?, ?, ?, ?, ?);', [message, interaction.createdAt.getTime() + seconds, option.valueOf(), interaction.channelId, interaction.createdAt.getTime(), interaction.user.id, interaction.guildId]);
|
||||
|
||||
break;
|
||||
}
|
||||
// List reminders
|
||||
|
|
|
@ -3,16 +3,34 @@ import { getLocale } from '../../utils/locales';
|
|||
|
||||
/** https://discord.js.org/#/docs/discord.js/main/class/Client?scrollTo=e-interactionCreate */
|
||||
export default (interaction: Interaction, client: Client) => {
|
||||
if (interaction.type === InteractionType.ApplicationCommand) {
|
||||
const command = client.commands.list.get(interaction.commandName);
|
||||
if (!command) {
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
return interaction.reply({
|
||||
content: loc.get('e_interacreate_no_command'),
|
||||
ephemeral: true,
|
||||
});
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
switch (interaction.type) {
|
||||
case InteractionType.ApplicationCommand: {
|
||||
const command = client.commands.list.get(interaction.commandName);
|
||||
if (!command) {
|
||||
return interaction.reply({
|
||||
content: loc.get('e_interacreate_no_command'),
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
return command.interaction(interaction, client);
|
||||
}
|
||||
|
||||
return command.interaction(interaction, client);
|
||||
case InteractionType.ModalSubmit: {
|
||||
const modal = client.modals.list.get(interaction.customId);
|
||||
if (!modal) {
|
||||
return interaction.reply({
|
||||
// TODO: locale
|
||||
content: `can't find ${interaction.customId}`,
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
|
||||
return modal.interaction(interaction, client);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@ export default async (client: Client) => {
|
|||
);
|
||||
|
||||
// Remove extension
|
||||
// TODO: use utils functions
|
||||
const event_type_ext = event_file.split('.');
|
||||
const ext = event_type_ext.pop();
|
||||
if (!(ext === 'js' || ext === 'ts')) {
|
||||
|
|
22
src/index.ts
22
src/index.ts
|
@ -1,5 +1,6 @@
|
|||
import loadClient, { quit } from './utils/client';
|
||||
import loadEvents from './events/loader';
|
||||
import loadModals from './modals/loader';
|
||||
import loadCommands from './commands/loader';
|
||||
|
||||
import { logStart } from './utils/misc';
|
||||
|
@ -19,27 +20,37 @@ const run = async () => {
|
|||
const client_name = 'Client';
|
||||
await loadClient()
|
||||
.then(async client => {
|
||||
console.log(logStart(client_name, true));
|
||||
|
||||
// Events Discord.JS
|
||||
const events_name = 'Events';
|
||||
await loadEvents(client)
|
||||
.then(() => console.log(logStart(events_name, true)))
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
throw logStart(events_name, false);
|
||||
});
|
||||
|
||||
// Connect the bot to Discord.com
|
||||
await client.login(client.config.token_discord);
|
||||
|
||||
// Modals Discord.JS
|
||||
const modals_name = 'Modals';
|
||||
await loadModals(client)
|
||||
.then(() => console.log(logStart(modals_name, true)))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
throw logStart(modals_name, false);
|
||||
});
|
||||
|
||||
// Commands Slash Discord.JS
|
||||
const commands_name = 'Commands';
|
||||
await loadCommands(client)
|
||||
.then(() => console.log(logStart(commands_name, true)))
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
throw logStart(commands_name, false);
|
||||
});
|
||||
|
||||
console.log(logStart(client_name, true));
|
||||
console.log(`Botanique "${client.user?.username}" v${client.config.version} started!`);
|
||||
|
||||
// ^C
|
||||
|
@ -48,7 +59,8 @@ const run = async () => {
|
|||
// Container force closed
|
||||
process.on('SIGTERM', () => quit(client));
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
throw logStart(client_name, false);
|
||||
});
|
||||
};
|
||||
|
|
36
src/modals/loader.ts
Normal file
36
src/modals/loader.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { readdir } from 'fs/promises';
|
||||
import { removeExtension } from '../utils/misc';
|
||||
import { Client } from 'discord.js';
|
||||
|
||||
export default async (client: Client) => {
|
||||
// Dossier des modals
|
||||
const modals_categories = (await readdir(__dirname))
|
||||
.filter(element => !element.endsWith('.js') && !element.endsWith('.ts'));
|
||||
|
||||
await Promise.all(
|
||||
// For each categorie
|
||||
modals_categories.map(async modals_category => {
|
||||
// Retrieve all the commands
|
||||
const modal_files = await readdir(`${__dirname}/${modals_category}`);
|
||||
|
||||
// Add the category to the collection for the help command
|
||||
client.modals.categories.set(
|
||||
modals_category,
|
||||
modal_files.map(removeExtension),
|
||||
);
|
||||
|
||||
// Add the modal
|
||||
return Promise.all(
|
||||
modal_files.map(async modal_file => {
|
||||
const modal = (
|
||||
await import(`../modals/${modals_category}/${modal_file}`)
|
||||
).default;
|
||||
|
||||
// Add it to the collection so the interaction will work
|
||||
client.modals.list.set(modal.data.name, modal);
|
||||
return modal.data;
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
21
src/modals/misc/reminderGUI.ts
Normal file
21
src/modals/misc/reminderGUI.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { ModalSubmitInteraction } from 'discord.js';
|
||||
import { getFilename } from '../../utils/misc';
|
||||
|
||||
export default {
|
||||
data: {
|
||||
name: getFilename(__filename),
|
||||
},
|
||||
interaction: async (interaction: ModalSubmitInteraction) => {
|
||||
if (!interaction.isModalSubmit()) {
|
||||
console.log('not modal called modal :/');
|
||||
return;
|
||||
}
|
||||
|
||||
const time = interaction.fields.fields.get('timeGUI')?.value;
|
||||
|
||||
return interaction.reply({
|
||||
content: `${time}`,
|
||||
ephemeral: true,
|
||||
});
|
||||
},
|
||||
};
|
|
@ -16,6 +16,28 @@ declare module 'discord.js' {
|
|||
/** Default lang used */
|
||||
default_lang: string
|
||||
},
|
||||
/** Store all the modals */
|
||||
modals: {
|
||||
categories: Collection<
|
||||
/** Category name */
|
||||
string,
|
||||
/** Name of the modals in the category */
|
||||
string[]
|
||||
>,
|
||||
list: Collection<
|
||||
/** Modal name */
|
||||
string,
|
||||
/** Modal itself */
|
||||
{
|
||||
/** Data about the modal */
|
||||
data: {
|
||||
name: string
|
||||
},
|
||||
/** How the modal interact */
|
||||
interaction: (interaction: ModalSubmitInteraction, client: Client) => unknown
|
||||
}
|
||||
>,
|
||||
}
|
||||
/** Store all the slash commands */
|
||||
commands: {
|
||||
categories: Collection<
|
||||
|
|
|
@ -19,6 +19,11 @@ export default async () => {
|
|||
default_lang: process.env.DEFAULT_LANG ?? 'fr',
|
||||
};
|
||||
|
||||
client.modals = {
|
||||
categories: new Collection(),
|
||||
list: new Collection(),
|
||||
};
|
||||
|
||||
client.commands = {
|
||||
categories: new Collection(),
|
||||
list: new Collection(),
|
||||
|
|
|
@ -7,6 +7,7 @@ import { GuildMember } from 'discord.js';
|
|||
* @returns String
|
||||
*/
|
||||
export const logStart = (name: string, status: boolean) => {
|
||||
// TODO Handle precision about the error if status is false
|
||||
return `> ${name} ${status === true ? '✅' : '❌'}`;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue