Rename warnings to notes

This commit is contained in:
Tarrgon
2025-05-29 10:34:11 -04:00
parent b5e631a965
commit 41299da489
8 changed files with 97 additions and 98 deletions
+3 -3
View File
@@ -1,12 +1,12 @@
import { ButtonInteraction, Client } from 'discord.js';
import { getWarningMessage } from '../utils/warning-utils';
import { getNoteMessage } from '../utils/note-utils';
export default {
name: 'warning-next',
name: 'note-next',
handler: async function (client: Client, interaction: ButtonInteraction, userId: string, page: string) {
await interaction.deferUpdate();
const message = await getWarningMessage(userId, parseInt(page) + 1);
const message = await getNoteMessage(userId, parseInt(page) + 1);
if (!message) return;
+3 -3
View File
@@ -1,12 +1,12 @@
import { ButtonInteraction, Client} from 'discord.js';
import { getWarningMessage } from '../utils/warning-utils';
import { getNoteMessage } from '../utils/note-utils';
export default {
name: 'warning-previous',
name: 'note-previous',
handler: async function (client: Client, interaction: ButtonInteraction, userId: string, page: string) {
await interaction.deferUpdate();
const message = await getWarningMessage(userId, parseInt(page) - 1);
const message = await getNoteMessage(userId, parseInt(page) - 1);
if (!message) return;
@@ -1,48 +1,47 @@
import { ApplicationCommandOptionType, ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, GuildBasedChannel, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
import { Database } from '../shared/Database';
import { channelIsInStaffCategory, getE621User } from '../utils';
import { config } from '../config';
import { getWarningMessage } from '../utils/warning-utils';
import { channelIsInStaffCategory } from '../utils';
import { getNoteMessage } from '../utils/note-utils';
export default {
name: 'warnings',
name: 'notes',
data: new SlashCommandBuilder()
.setName('warnings')
.setDescription('Add, view, or remove user warnings.')
.setName('notes')
.setDescription('Add, view, or remove user notes.')
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
.setContexts(InteractionContextType.Guild)
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
.addSubcommand(subcommand =>
subcommand
.setName('add')
.setDescription('Add warnings to a user.')
.setDescription('Add notes to a user.')
.addUserOption(option =>
option
.setName('user')
.setDescription('The user to add a warning to.')
.setDescription('The user to add a note to.')
.setRequired(true)
)
.addStringOption(option =>
option
.setName('reason')
.setDescription('The reason for the warning.')
.setDescription('The reason for the note.')
.setRequired(true)
)
)
.addSubcommand(subcommand =>
subcommand
.setName('remove')
.setDescription('Remove warnings from a user.')
.setDescription('Remove notes from a user.')
.addUserOption(option =>
option
.setName('user')
.setDescription('The user to remove a warning from.')
.setDescription('The user to remove a note from.')
.setRequired(true)
)
.addIntegerOption(option =>
option
.setName('warning')
.setDescription('The warning to remove.')
.setName('note')
.setDescription('The note to remove.')
.setRequired(true)
.setAutocomplete(true)
)
@@ -50,11 +49,11 @@ export default {
.addSubcommand(subcommand =>
subcommand
.setName('list')
.setDescription("List a user's warnings")
.setDescription("List a user's notes")
.addUserOption(option =>
option
.setName('user')
.setDescription('The user to list the warnings of.')
.setDescription('The user to list the notes of.')
.setRequired(true)
)
),
@@ -70,26 +69,26 @@ export default {
if (subcommand == 'add') {
const reason = interaction.options.getString('reason', true);
await Database.putWarning(user.id, reason, interaction.user.id);
await Database.putNote(user.id, reason, interaction.user.id);
if (isStaffChannel) interaction.editReply('Added warning.');
else interaction.editReply({ content: 'Added warning.' });
if (isStaffChannel) interaction.editReply('Added note.');
else interaction.editReply({ content: 'Added note.' });
} else if (subcommand == 'remove') {
const warningId = interaction.options.getInteger('warning', true);
const noteId = interaction.options.getInteger('note', true);
if (await Database.removeWarning(warningId)) {
if (isStaffChannel) interaction.editReply('Removed warning.');
else interaction.editReply({ content: 'Removed warning.' });
if (await Database.removeNote(noteId)) {
if (isStaffChannel) interaction.editReply('Removed note.');
else interaction.editReply({ content: 'Removed note.' });
} else {
if (isStaffChannel) interaction.editReply('Warning not found.');
else interaction.editReply({ content: 'Warning not found.' });
if (isStaffChannel) interaction.editReply('Note not found.');
else interaction.editReply({ content: 'Note not found.' });
}
} else if (subcommand == 'list') {
const warningMessage = await getWarningMessage(user.id, 1);
const noteMessage = await getNoteMessage(user.id, 1);
if (!warningMessage) return interaction.editReply(`No warnings found for <@${user.id}>`);
if (!noteMessage) return interaction.editReply(`No notes found for <@${user.id}>`);
interaction.editReply(warningMessage);
interaction.editReply(noteMessage);
}
},
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
@@ -101,9 +100,9 @@ export default {
const value = interaction.options.getFocused().toLowerCase();
const warnings = await Database.getWarnings(userId);
const notes = await Database.getNotes(userId);
const toRespond = warnings.filter(w => !value ? true : w.reason.toLowerCase().includes(value));
const toRespond = notes.filter(w => !value ? true : w.reason.toLowerCase().includes(value));
if (toRespond.length > 25) toRespond.length = 25;
interaction.respond(toRespond.map((w) => {
+10 -10
View File
@@ -3,7 +3,7 @@ import { open, Database as SqliteDatabase } from 'sqlite';
import { config } from '../config';
import DiscordOAuth2 from 'discord-oauth2';
import { serializeMessage, wait } from '../utils';
import { GuildSettings, LoggedMessage, TicketMessage, TicketPhrase, Warning } from '../types';
import { GuildSettings, LoggedMessage, TicketMessage, TicketPhrase, Note } from '../types';
import { Message } from '../events';
const DB_SCHEMA = `
@@ -53,7 +53,7 @@ const DB_SCHEMA = `
phrase TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS warnings (
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY,
user_id TEXT,
reason TEXT,
@@ -263,21 +263,21 @@ export class Database {
// -- END TICKETS --
// -- START WARNINGS --
// -- START NOTES --
static async putWarning(userId: string, reason: string, modId: string) {
await Database.db.run('INSERT INTO warnings(user_id, reason, mod_id) VALUES (?, ?, ?)', userId, reason, modId);
static async putNote(userId: string, reason: string, modId: string) {
await Database.db.run('INSERT INTO notes(user_id, reason, mod_id) VALUES (?, ?, ?)', userId, reason, modId);
}
static async removeWarning(id: number): Promise<boolean> {
const res = await Database.db.run('DELETE from warnings WHERE id = ?', id);
static async removeNote(id: number): Promise<boolean> {
const res = await Database.db.run('DELETE from notes WHERE id = ?', id);
return (res.changes ?? 0) > 0;
}
static async getWarnings(userId: string): Promise<Warning[]> {
return await Database.db.all<Warning[]>('SELECT * from warnings WHERE user_id = ?', userId);
static async getNotes(userId: string): Promise<Note[]> {
return await Database.db.all<Note[]>('SELECT * from notes WHERE user_id = ?', userId);
}
// -- END WARNINGS --
// -- END NOTES --
}
+1 -1
View File
@@ -32,7 +32,7 @@ export type TicketPhrase = {
phrase: string
}
export type Warning = {
export type Note = {
id: number
user_id: string
reason: string
+1 -1
View File
@@ -11,5 +11,5 @@ export * from './refresh-commands';
export * from './string-utils';
export * from './ticket-utils';
export * from './wait';
export * from './warning-utils';
export * from './note-utils';
export * from './whois';
+51
View File
@@ -0,0 +1,51 @@
import { ActionRowBuilder, APIEmbedField, ButtonBuilder, ButtonStyle, EmbedBuilder, GuildMember, MessageActionRowComponentBuilder, time } from 'discord.js';
import { Database } from '../shared/Database';
import { Note } from '../types';
type MessageContent = { content: string, components: ActionRowBuilder<ButtonBuilder>[] };
const NOTES_PER_PAGE = 5;
function getNoteText(note: Note): string {
const timestamp = time(new Date(note.timestamp));
return `### Note by <@${note.mod_id}> (${timestamp}):\n${note.reason}`;
}
export async function getNoteMessage(userId: string, page: number): Promise<MessageContent | null> {
const notes = await Database.getNotes(userId);
page = page - 1;
const maxPage = Math.floor(notes.length / NOTES_PER_PAGE);
if (notes.length == 0) return null;
const noteTexts: string[] = [];
for (let i = page * NOTES_PER_PAGE; i < page * NOTES_PER_PAGE + NOTES_PER_PAGE; i++) {
if (i >= notes.length) break;
noteTexts.push(getNoteText(notes[i]));
}
const prevPage = new ButtonBuilder()
.setLabel('Previous Page')
.setCustomId(`note-previous_${userId}_${page + 1}`)
.setDisabled(page == 0)
.setStyle(ButtonStyle.Primary);
const nextPage = new ButtonBuilder()
.setLabel('Next Page')
.setCustomId(`note-next_${userId}_${page + 1}`)
.setDisabled(page >= maxPage)
.setStyle(ButtonStyle.Primary);
const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(prevPage, nextPage);
return {
content: `<@${userId}>'s Notes\n` + noteTexts.join('\n\n') + `\n\n-# Page ${page + 1}/${maxPage + 1}`,
components: [row]
};
}
-51
View File
@@ -1,51 +0,0 @@
import { ActionRowBuilder, APIEmbedField, ButtonBuilder, ButtonStyle, EmbedBuilder, GuildMember, MessageActionRowComponentBuilder, time } from 'discord.js';
import { Database } from '../shared/Database';
import { Warning } from '../types';
type MessageContent = { content: string, components: ActionRowBuilder<ButtonBuilder>[] };
const WARNINGS_PER_PAGE = 5;
function getWarningText(warning: Warning): string {
const timestamp = time(new Date(warning.timestamp));
return `### Warning from <@${warning.mod_id}> (${timestamp}):\n${warning.reason}`;
}
export async function getWarningMessage(userId: string, page: number): Promise<MessageContent | null> {
const warnings = await Database.getWarnings(userId);
page = page - 1;
const maxPage = Math.floor(warnings.length / WARNINGS_PER_PAGE);
if (warnings.length == 0) return null;
const warningTexts: string[] = [];
for (let i = page * WARNINGS_PER_PAGE; i < page * WARNINGS_PER_PAGE + WARNINGS_PER_PAGE; i++) {
if (i >= warnings.length) break;
warningTexts.push(getWarningText(warnings[i]));
}
const prevPage = new ButtonBuilder()
.setLabel('Previous Page')
.setCustomId(`warning-previous_${userId}_${page + 1}`)
.setDisabled(page == 0)
.setStyle(ButtonStyle.Primary);
const nextPage = new ButtonBuilder()
.setLabel('Next Page')
.setCustomId(`warning-next_${userId}_${page + 1}`)
.setDisabled(page >= maxPage)
.setStyle(ButtonStyle.Primary);
const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(prevPage, nextPage);
return {
content: `<@${userId}>'s Warnings\n` + warningTexts.join('\n\n') + `\n\n-# Page ${page + 1}/${maxPage + 1}`,
components: [row]
};
}