feat: Reminders #44
4 changed files with 97 additions and 18 deletions
|
@ -1,9 +1,9 @@
|
||||||
import { ModalActionRowComponentBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
import { ModalActionRowComponentBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, Colors, EmbedBuilder, ModalBuilder, TextInputBuilder, TextInputStyle } from 'discord.js';
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, ModalBuilder, TextInputBuilder, TextInputStyle } from 'discord.js';
|
||||||
import { collect } from '../../buttons/loader';
|
import { collect } from '../../buttons/loader';
|
||||||
import { getLocale, getLocalizations } from '../../utils/locales';
|
import { getLocale, getLocalizations } from '../../utils/locales';
|
||||||
import { getFilename } from '../../utils/misc';
|
import { getFilename } from '../../utils/misc';
|
||||||
import { checkOwnershipReminder, deleteReminder, getReminderInfo, newReminder } from '../../utils/reminder';
|
import { checkOwnershipReminder, deleteReminder, embedListReminders, getReminderInfo, newReminder } from '../../utils/reminder';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: (client: Client) => {
|
data: (client: Client) => {
|
||||||
|
@ -186,20 +186,20 @@ export default {
|
||||||
// Show modal to user to get at least the time
|
// Show modal to user to get at least the time
|
||||||
const modal = new ModalBuilder()
|
const modal = new ModalBuilder()
|
||||||
.setCustomId('reminderGUI')
|
.setCustomId('reminderGUI')
|
||||||
.setTitle(loc?.get('c_reminder_name').capitalize());
|
.setTitle(loc.get('c_reminder_name').capitalize());
|
||||||
|
|
||||||
const timeGUI = new TextInputBuilder()
|
const timeGUI = new TextInputBuilder()
|
||||||
.setCustomId('reminderGUI-time')
|
.setCustomId('reminderGUI-time')
|
||||||
.setLabel(loc?.get('c_reminder_sub1_opt1_name').capitalize())
|
.setLabel(loc.get('c_reminder_sub1_opt1_name').capitalize())
|
||||||
.setStyle(TextInputStyle.Short)
|
.setStyle(TextInputStyle.Short)
|
||||||
.setPlaceholder('1h')
|
.setPlaceholder('1h')
|
||||||
.setRequired(true);
|
.setRequired(true);
|
||||||
|
|
||||||
const messageGUI = new TextInputBuilder()
|
const messageGUI = new TextInputBuilder()
|
||||||
.setCustomId('reminderGUI-message')
|
.setCustomId('reminderGUI-message')
|
||||||
.setLabel(loc?.get('c_reminder_sub1_opt2_name').capitalize())
|
.setLabel(loc.get('c_reminder_sub1_opt2_name').capitalize())
|
||||||
.setStyle(TextInputStyle.Paragraph)
|
.setStyle(TextInputStyle.Paragraph)
|
||||||
.setPlaceholder(loc?.get('c_reminder_sub1_opt2_desc'))
|
.setPlaceholder(loc.get('c_reminder_sub1_opt2_desc'))
|
||||||
.setRequired(false);
|
.setRequired(false);
|
||||||
|
|
||||||
modal.addComponents(
|
modal.addComponents(
|
||||||
|
@ -239,10 +239,9 @@ export default {
|
||||||
collect(client, interaction, idPrec);
|
collect(client, interaction, idPrec);
|
||||||
collect(client, interaction, idNext);
|
collect(client, interaction, idNext);
|
||||||
|
|
||||||
const list = new EmbedBuilder()
|
const page = interaction.options.getInteger(loc_default?.get(`c_${filename}_sub2_opt2_name`) as string) ?? 1;
|
||||||
.setColor(Colors.DarkGrey)
|
|
||||||
.setTitle(`List title of ${user.tag}`)
|
const list = await embedListReminders(client, user, interaction.guildId, page, interaction.locale);
|
||||||
.setDescription('List desc');
|
|
||||||
|
|
||||||
return await interaction.reply({ ephemeral: true, embeds: [list], components: [row] });
|
return await interaction.reply({ ephemeral: true, embeds: [list], components: [row] });
|
||||||
}
|
}
|
||||||
|
@ -251,12 +250,12 @@ export default {
|
||||||
?.toLowerCase() ?? '': {
|
?.toLowerCase() ?? '': {
|
||||||
const id = interaction.options.getInteger(loc_default?.get(`c_${filename}_sub3_opt1_name`) as string);
|
const id = interaction.options.getInteger(loc_default?.get(`c_${filename}_sub3_opt1_name`) as string);
|
||||||
if (id === null) {
|
if (id === null) {
|
||||||
return interaction.reply({ content: loc?.get('c_reminder2'), ephemeral: true });
|
return interaction.reply({ content: loc.get('c_reminder2'), ephemeral: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the ID exists and belongs to the user
|
// Check if the ID exists and belongs to the user
|
||||||
if (await checkOwnershipReminder(client, id, interaction.user.id, interaction.guildId ?? '0')) {
|
if (await checkOwnershipReminder(client, id, interaction.user.id, interaction.guildId ?? '0')) {
|
||||||
return interaction.reply({ content: loc?.get('c_reminder3'), ephemeral: true });
|
return interaction.reply({ content: loc.get('c_reminder3'), ephemeral: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop timeout
|
// Stop timeout
|
||||||
|
@ -264,7 +263,7 @@ export default {
|
||||||
clearTimeout(reminderInfo.timeout_id);
|
clearTimeout(reminderInfo.timeout_id);
|
||||||
|
|
||||||
// Delete from database
|
// Delete from database
|
||||||
deleteReminder(client, reminderInfo.creation_date, reminderInfo.user_id);
|
deleteReminder(client, Number(reminderInfo.creation_date), reminderInfo.user_id);
|
||||||
|
|
||||||
return interaction.reply({ content: `Reminder **#${id}** supprimé !`, ephemeral: true });
|
return interaction.reply({ content: `Reminder **#${id}** supprimé !`, ephemeral: true });
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,5 +39,10 @@
|
||||||
"c_reminder1": "Un rappel a été configuré pour dans",
|
"c_reminder1": "Un rappel a été configuré pour dans",
|
||||||
"c_reminder2": "L'ID renseigné n'est pas valide.",
|
"c_reminder2": "L'ID renseigné n'est pas valide.",
|
||||||
"c_reminder3": "Rappel non trouvé, pas sur le bon serveur ou qui ne vous appartiens pas.",
|
"c_reminder3": "Rappel non trouvé, pas sur le bon serveur ou qui ne vous appartiens pas.",
|
||||||
"c_reminder4": "Utilisateur inconnu."
|
"c_reminder4": "Utilisateur inconnu.",
|
||||||
|
"c_reminder5": "Rappels de",
|
||||||
|
"c_reminder6": "Page ",
|
||||||
|
"c_reminder7": "Pas de message",
|
||||||
|
"c_reminder8": "Expire dans",
|
||||||
|
"c_reminder9": "Fais le"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Client } from 'discord.js';
|
import { Client, Colors, EmbedBuilder, User } from 'discord.js';
|
||||||
import { getLocale } from './locales';
|
import { getLocale } from './locales';
|
||||||
import { strToSeconds } from './time';
|
import { showDate, strToSeconds, timeDeltaToString } from './time';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option possible for reminders
|
* Option possible for reminders
|
||||||
|
@ -32,11 +32,11 @@ export type dbReminder = {
|
||||||
expiration_date: number,
|
expiration_date: number,
|
||||||
option_id: OptionReminder,
|
option_id: OptionReminder,
|
||||||
channel_id: string | null,
|
channel_id: string | null,
|
||||||
creation_date: number,
|
creation_date: string,
|
||||||
user_id: string,
|
user_id: string,
|
||||||
guild_id: string | null,
|
guild_id: string | null,
|
||||||
locale: string,
|
locale: string,
|
||||||
timeout_id: number
|
timeout_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,3 +243,67 @@ export const updateReminder = (client: Client, data: dbReminder) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of reminders for a user in a specified context
|
||||||
|
* @param client Client
|
||||||
|
* @param userId user ID
|
||||||
|
* @param guildId guild ID
|
||||||
|
* @returns List of reminders of a user in a guild
|
||||||
|
*/
|
||||||
|
const listReminders = async (client: Client, userId: string, guildId: string | null) => {
|
||||||
|
return await new Promise((ok, ko) => {
|
||||||
|
// Check the ownership
|
||||||
|
client.db.all('SELECT data, creation_date, expiration_date, id FROM reminder \
|
||||||
|
WHERE user_id = ? AND (guild_id = ? OR guild_id = 0)', [
|
||||||
|
userId, guildId ?? 0], (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
ko(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send all the current reminders
|
||||||
|
ok(row);
|
||||||
|
});
|
||||||
|
}) as dbReminder[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const embedListReminders = async (client: Client, user: User, guildId: string | null, page: number, local: string) => {
|
||||||
|
const loc = getLocale(client, local);
|
||||||
|
const reminders = await listReminders(client, user.id, guildId);
|
||||||
|
|
||||||
|
const elementPerPage = 5;
|
||||||
|
let pageMax = Math.floor(reminders.length / elementPerPage);
|
||||||
|
|
||||||
|
if (pageMax <= 1) {
|
||||||
|
page = 1;
|
||||||
|
pageMax = 1;
|
||||||
|
}
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setColor(Colors.DarkGrey)
|
||||||
|
.setDescription(`${loc.get('c_reminder5')} ${user} • ${loc.get('c_reminder6')} ${page}/${pageMax}`)
|
||||||
|
.setThumbnail(user.displayAvatarURL());
|
||||||
|
|
||||||
|
const limit = elementPerPage * page;
|
||||||
|
|
||||||
|
if (reminders.length > 0 && page <= pageMax) {
|
||||||
|
let curseur = limit - elementPerPage - 1;
|
||||||
|
reminders.forEach((remind) => {
|
||||||
|
if (curseur <= limit) {
|
||||||
|
let text = remind.data ?? loc.get('c_reminder7');
|
||||||
|
if (text.length > 1024) {
|
||||||
|
text = `${text.substring(0, 1021)}...`;
|
||||||
|
}
|
||||||
|
const expiration = `${loc.get('c_reminder8')} ${timeDeltaToString(remind.expiration_date)}`;
|
||||||
|
embed.addFields({
|
||||||
|
name: `#${remind.id} • ${loc.get('c_reminder9')} ${showDate(local, loc, new Date(Number(remind.creation_date)))}\n${expiration}`,
|
||||||
|
value: text,
|
||||||
|
inline: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
curseur++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
};
|
||||||
|
|
|
@ -41,3 +41,14 @@ export const strToSeconds = (time: string) => {
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculating the difference between a date and now
|
||||||
|
* @param time Time
|
||||||
|
* @returns Delta between the time and now
|
||||||
|
*/
|
||||||
|
export const timeDeltaToString = (time: number) => {
|
||||||
|
const now = Date.now();
|
||||||
|
// TODO adapt the output and not always parse the time as seconds
|
||||||
|
return `${strToSeconds(`${now - time}`)} secs`;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue