feat: Reminders #44
4 changed files with 97 additions and 18 deletions
|
@ -1,9 +1,9 @@
|
|||
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 { getLocale, getLocalizations } from '../../utils/locales';
|
||||
import { getFilename } from '../../utils/misc';
|
||||
import { checkOwnershipReminder, deleteReminder, getReminderInfo, newReminder } from '../../utils/reminder';
|
||||
import { checkOwnershipReminder, deleteReminder, embedListReminders, getReminderInfo, newReminder } from '../../utils/reminder';
|
||||
|
||||
export default {
|
||||
data: (client: Client) => {
|
||||
|
@ -186,20 +186,20 @@ export default {
|
|||
// Show modal to user to get at least the time
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId('reminderGUI')
|
||||
.setTitle(loc?.get('c_reminder_name').capitalize());
|
||||
.setTitle(loc.get('c_reminder_name').capitalize());
|
||||
|
||||
const timeGUI = new TextInputBuilder()
|
||||
.setCustomId('reminderGUI-time')
|
||||
.setLabel(loc?.get('c_reminder_sub1_opt1_name').capitalize())
|
||||
.setLabel(loc.get('c_reminder_sub1_opt1_name').capitalize())
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setPlaceholder('1h')
|
||||
.setRequired(true);
|
||||
|
||||
const messageGUI = new TextInputBuilder()
|
||||
.setCustomId('reminderGUI-message')
|
||||
.setLabel(loc?.get('c_reminder_sub1_opt2_name').capitalize())
|
||||
.setLabel(loc.get('c_reminder_sub1_opt2_name').capitalize())
|
||||
.setStyle(TextInputStyle.Paragraph)
|
||||
.setPlaceholder(loc?.get('c_reminder_sub1_opt2_desc'))
|
||||
.setPlaceholder(loc.get('c_reminder_sub1_opt2_desc'))
|
||||
.setRequired(false);
|
||||
|
||||
modal.addComponents(
|
||||
|
@ -239,10 +239,9 @@ export default {
|
|||
collect(client, interaction, idPrec);
|
||||
collect(client, interaction, idNext);
|
||||
|
||||
const list = new EmbedBuilder()
|
||||
.setColor(Colors.DarkGrey)
|
||||
.setTitle(`List title of ${user.tag}`)
|
||||
.setDescription('List desc');
|
||||
const page = interaction.options.getInteger(loc_default?.get(`c_${filename}_sub2_opt2_name`) as string) ?? 1;
|
||||
|
||||
const list = await embedListReminders(client, user, interaction.guildId, page, interaction.locale);
|
||||
|
||||
return await interaction.reply({ ephemeral: true, embeds: [list], components: [row] });
|
||||
}
|
||||
|
@ -251,12 +250,12 @@ export default {
|
|||
?.toLowerCase() ?? '': {
|
||||
const id = interaction.options.getInteger(loc_default?.get(`c_${filename}_sub3_opt1_name`) as string);
|
||||
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
|
||||
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
|
||||
|
@ -264,7 +263,7 @@ export default {
|
|||
clearTimeout(reminderInfo.timeout_id);
|
||||
|
||||
// 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 });
|
||||
}
|
||||
|
|
|
@ -39,5 +39,10 @@
|
|||
"c_reminder1": "Un rappel a été configuré pour dans",
|
||||
"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_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 { strToSeconds } from './time';
|
||||
import { showDate, strToSeconds, timeDeltaToString } from './time';
|
||||
|
||||
/**
|
||||
* Option possible for reminders
|
||||
|
@ -32,11 +32,11 @@ export type dbReminder = {
|
|||
expiration_date: number,
|
||||
option_id: OptionReminder,
|
||||
channel_id: string | null,
|
||||
creation_date: number,
|
||||
creation_date: string,
|
||||
user_id: string,
|
||||
guild_id: string | null,
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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