diff --git a/src/modules/note.ts b/src/modules/note.ts index 5afa524..4e373cc 100644 --- a/src/modules/note.ts +++ b/src/modules/note.ts @@ -13,6 +13,7 @@ import {getWarns} from './warn.js'; import type {Snowflake, User} from 'discord.js'; import {Colors, EmbedBuilder} from 'discord.js'; +/** A note added to a user */ interface Note { contents: string; addedBy: Snowflake; @@ -20,10 +21,8 @@ interface Note { } /** The main DB structure for notes */ -interface userRecord { - // The user with notes +interface UserRecord { user: Snowflake; - // A list of all of their notes notes: Note[]; } @@ -33,9 +32,9 @@ const NOTE_COLLECTION_NAME = 'notes'; /** * @param user The user to get the DB record of */ -async function getRecord(user: User): Promise { +async function getRecord(user: User): Promise { const db: Db = util.mongo.fetchValue(); - const records: Collection = db.collection(NOTE_COLLECTION_NAME); + const records: Collection = db.collection(NOTE_COLLECTION_NAME); return await records.findOne({user: user.id}); } @@ -45,7 +44,7 @@ async function getRecord(user: User): Promise { */ async function deleteRecord(user: User): Promise { const db: Db = util.mongo.fetchValue(); - const records: Collection = db.collection(NOTE_COLLECTION_NAME); + const records: Collection = db.collection(NOTE_COLLECTION_NAME); await records.deleteOne({user: user.id}); } @@ -58,7 +57,7 @@ const notes = new util.RootModule('note', 'Add or delete notes from users', [ notes.registerSubModule( new util.SubModule( 'add', - 'Add a note to an user', + 'Add a note to someone', [ { type: util.ModuleOptionType.User, @@ -74,19 +73,20 @@ notes.registerSubModule( }, ], async (args, interaction) => { - const userArg: string = args + const targetId: string = args .find(arg => arg.name === 'user')! .value!.toString(); - const user = await util.client.users.fetch(userArg); - - if (interaction.user.id === user.id) { - return util.embed.errorEmbed('You cannot add a note for yourself'); - } const noteContents: string = args .find(arg => arg.name === 'note')! .value!.toString(); + const target = await util.client.users.fetch(targetId); + + if (interaction.user.id === target.id) { + return util.embed.errorEmbed('You cannot add a note for yourself'); + } + const note: Note = { contents: noteContents, addedBy: interaction.user.id, @@ -94,19 +94,18 @@ notes.registerSubModule( }; const db: Db = util.mongo.fetchValue(); - const records: Collection = + const records: Collection = db.collection(NOTE_COLLECTION_NAME); - const record: userRecord | null = await getRecord(user); + const record: UserRecord | null = await getRecord(target); // The user already has notes, just append the new one and return early if (record !== null) { record.notes.push(note); - // Updates the user Record await records .updateOne( - {user: user.id}, + {user: target.id}, {$set: {notes: record.notes}}, {upsert: true} ) @@ -118,9 +117,9 @@ notes.registerSubModule( return util.embed.successEmbed('Succesfully added that note'); } - // The stcructure sent to the DB - const structuredRecord: userRecord = { - user: user.id, + // The user didn't have an existing record, so create one + const structuredRecord: UserRecord = { + user: target.id, notes: [note], }; @@ -138,7 +137,7 @@ notes.registerSubModule( notes.registerSubModule( new util.SubModule( 'clear', - 'Clear the notes of an user', + 'Clear someones notes', [ { type: util.ModuleOptionType.User, @@ -148,26 +147,27 @@ notes.registerSubModule( }, ], async args => { - const userArg: string = args + const targetId: string = args .find(arg => arg.name === 'user')! .value!.toString(); - const user = await util.client.users.fetch(userArg); + const target = await util.client.users.fetch(targetId); - const record: userRecord | null = await getRecord(user); + const record: UserRecord | null = await getRecord(target); - // The user already has notes, just append to them and return early if (record === null) { - return util.embed.errorEmbed(`\`${user.tag}\` doesn't have any notes`); + return util.embed.errorEmbed( + `\`${target.tag}\` doesn't have any notes` + ); } - await deleteRecord(user).catch(err => { + await deleteRecord(target).catch(err => { return util.embed.errorEmbed( - `Database call failed with erorr ${(err as Error).name}` + `Database call failed with error ${(err as Error).name}` ); }); return util.embed.successEmbed( - `Succesfully removed notes for \`${user.tag}\`` + `Succesfully removed notes for \`${target.tag}\`` ); } ) @@ -186,16 +186,17 @@ notes.registerSubModule( }, ], async (args, interaction) => { - const userArg: string = args + const targetId: string = args .find(arg => arg.name === 'user')! .value!.toString(); - const user = await util.client.users.fetch(userArg); + const target = await util.client.users.fetch(targetId); - const record: userRecord | null = await getRecord(user); + const record: UserRecord | null = await getRecord(target); - // The user already has notes, just append to them and return early if (record === null) { - return util.embed.errorEmbed(`\`${user.tag}\` doesn't have any notes`); + return util.embed.errorEmbed( + `\`${target.tag}\` doesn't have any notes` + ); } // Shoves the notes into a JSON string, then into a buffer to send as an attachment @@ -206,7 +207,7 @@ notes.registerSubModule( files: [ { attachment: file, - name: `notes_for_${user.id}_${util.formatDate(new Date())}.json`, + name: `notes_for_${target.id}_${util.formatDate(new Date())}.json`, }, ], }); @@ -228,47 +229,43 @@ const whois = new util.RootModule( }, ], async (args, interaction) => { - const userArg: string = args + const targetId: string = args .find(arg => arg.name === 'user')! .value!.toString(); - const member = await interaction.guild!.members.fetch(userArg).catch(); + const member = await interaction.guild!.members.fetch(targetId); - if (member === null) { - return util.embed.errorEmbed( - `Couldn't find the user \`${userArg}\` in the server` - ); - } - - // Defines base embed attributes - const embed: EmbedBuilder = new EmbedBuilder(); - - embed.setColor(Colors.DarkBlue); - embed.setTitle(`User info for \`${member.user.tag}\``); - embed.setThumbnail(member.displayAvatarURL()); + const embed: EmbedBuilder = new EmbedBuilder() + .setColor(Colors.DarkBlue) + .setTitle(`User info for \`${member.user.tag}\``) + .setThumbnail(member.displayAvatarURL()); if (member.user.bot) { embed.setDescription('**Note: This is a bot account!**'); } - const fields = []; - - // Addd info fields - fields.push({ - name: 'Created at', - value: util.formatDate(member.user.createdAt), - inline: true, - }); - fields.push({ - name: 'Joined at', - value: util.formatDate(member.joinedAt!), - inline: true, - }); - fields.push({ - name: 'Status', - value: member.presence?.status ?? 'offline', - inline: true, - }); - fields.push({name: 'Nickname', value: member.displayName, inline: true}); + const fields = [ + { + name: 'Created at', + value: util.formatDate(member.user.createdAt), + inline: true, + }, + { + name: 'Joined at', + value: util.formatDate(member.joinedAt!), + inline: true, + }, + { + name: 'Status', + value: member.presence?.status ?? 'offline', + inline: true, + }, + { + name: 'Nickname', + value: member.displayName, + inline: true, + }, + ]; + let roles: string = member.roles.cache .filter(role => role.name !== '@everyone') .map(role => role.name) @@ -279,7 +276,7 @@ const whois = new util.RootModule( } fields.push({name: 'Roles', value: roles, inline: true}); - // Handling for warns if the invoker is able to kick members + // If the invoker is able to kick members, list warnings as well if (interaction.memberPermissions!.has('KickMembers')) { const warnings = await getWarns(member.id); @@ -297,15 +294,25 @@ const whois = new util.RootModule( } } - // Handling for notes - const record: userRecord | null = await getRecord(member.user); + // Finally, list notes + const record: UserRecord | null = await getRecord(member.user); + // Is left undefined if there aren't any notes, otherwise is used in the footer to list + // the amount of notes as well as any potential trimming that happened + let footerText; let noteCount = 0; if (record !== null) { + footerText = `${record.notes.length} total notes`; // Iterate through all notes and add them to the embed - for (const note of record.notes) { + for (const note of record.notes.reverse()) { noteCount++; - + // Limit of four notes so the embed isn't too long + if (noteCount > 4) { + footerText += ` ${ + record.notes.length - 4 + } more notes trimmed, use \`/note get \` to get them`; + break; + } const noteAuthor: User = await util.client.users.fetch(note.addedBy); fields.push({ @@ -316,10 +323,13 @@ const whois = new util.RootModule( } } - embed.setFooter({text: `${noteCount} total notes`}); + // Only set if there were notes + if (footerText) { + embed.setFooter({text: footerText}); + } embed.setFields(fields); - await util.replyToInteraction(interaction, {embeds: [embed]}); + return embed.toJSON(); } );