From 0912d957918cb93b0d0607d305fd9d92c1f1cce5 Mon Sep 17 00:00:00 2001
From: Tiago Grosso <tiagogrosso99@gmail.com>
Date: Sat, 24 Aug 2024 23:08:05 +0100
Subject: [PATCH] feat: add setting for default queue page size

---
 CHANGELOG.md                                  |  1 +
 .../migration.sql                             | 19 +++++++++++++
 schema.prisma                                 |  1 +
 src/commands/config.ts                        | 27 +++++++++++++++++++
 src/commands/queue.ts                         | 13 ++++++---
 5 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 migrations/20240824215313_add_default_queue_page_size/migration.sql

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7630ee4..5b3b5e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added 
 - An optional `page-size` to `/queue` command 
+- Add `default-queue-page-size` setting
 
 ## [2.9.3] - 2024-08-19
 
diff --git a/migrations/20240824215313_add_default_queue_page_size/migration.sql b/migrations/20240824215313_add_default_queue_page_size/migration.sql
new file mode 100644
index 0000000..ff3866a
--- /dev/null
+++ b/migrations/20240824215313_add_default_queue_page_size/migration.sql
@@ -0,0 +1,19 @@
+-- RedefineTables
+PRAGMA foreign_keys=OFF;
+CREATE TABLE "new_Setting" (
+    "guildId" TEXT NOT NULL PRIMARY KEY,
+    "playlistLimit" INTEGER NOT NULL DEFAULT 50,
+    "secondsToWaitAfterQueueEmpties" INTEGER NOT NULL DEFAULT 30,
+    "leaveIfNoListeners" BOOLEAN NOT NULL DEFAULT true,
+    "queueAddResponseEphemeral" BOOLEAN NOT NULL DEFAULT false,
+    "autoAnnounceNextSong" BOOLEAN NOT NULL DEFAULT false,
+    "defaultVolume" INTEGER NOT NULL DEFAULT 100,
+    "defaultQueuePageSize" INTEGER NOT NULL DEFAULT 10,
+    "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updatedAt" DATETIME NOT NULL
+);
+INSERT INTO "new_Setting" ("autoAnnounceNextSong", "createdAt", "defaultVolume", "guildId", "leaveIfNoListeners", "playlistLimit", "queueAddResponseEphemeral", "secondsToWaitAfterQueueEmpties", "updatedAt") SELECT "autoAnnounceNextSong", "createdAt", "defaultVolume", "guildId", "leaveIfNoListeners", "playlistLimit", "queueAddResponseEphemeral", "secondsToWaitAfterQueueEmpties", "updatedAt" FROM "Setting";
+DROP TABLE "Setting";
+ALTER TABLE "new_Setting" RENAME TO "Setting";
+PRAGMA foreign_key_check;
+PRAGMA foreign_keys=ON;
diff --git a/schema.prisma b/schema.prisma
index d7b9de8..65c3aee 100644
--- a/schema.prisma
+++ b/schema.prisma
@@ -31,6 +31,7 @@ model Setting {
   queueAddResponseEphemeral      Boolean  @default(false)
   autoAnnounceNextSong           Boolean  @default(false)
   defaultVolume                  Int      @default(100)
+  defaultQueuePageSize           Int      @default(10)
   createdAt                      DateTime @default(now())
   updatedAt                      DateTime @updatedAt
 }
diff --git a/src/commands/config.ts b/src/commands/config.ts
index f866e82..c9aa0e3 100644
--- a/src/commands/config.ts
+++ b/src/commands/config.ts
@@ -56,6 +56,15 @@ export default class implements Command {
         .setMinValue(0)
         .setMaxValue(100)
         .setRequired(true)))
+    .addSubcommand(subcommand => subcommand
+      .setName('set-default-queue-page-size')
+      .setDescription('set the default page size of the /queue command')
+      .addIntegerOption(option => option
+        .setName('page-size')
+        .setDescription('page size of the /queue command')
+        .setMinValue(1)
+        .setMaxValue(50)
+        .setRequired(true)))
     .addSubcommand(subcommand => subcommand
       .setName('get')
       .setDescription('show all settings'));
@@ -171,6 +180,23 @@ export default class implements Command {
         break;
       }
 
+      case 'set-default-queue-page-size': {
+        const value = interaction.options.getInteger('page-size')!;
+
+        await prisma.setting.update({
+          where: {
+            guildId: interaction.guild!.id,
+          },
+          data: {
+            defaultQueuePageSize: value,
+          },
+        });
+
+        await interaction.reply('👍 default queue page size updated');
+
+        break;
+      }
+
       case 'get': {
         const embed = new EmbedBuilder().setTitle('Config');
 
@@ -185,6 +211,7 @@ export default class implements Command {
           'Auto announce next song in queue': config.autoAnnounceNextSong ? 'yes' : 'no',
           'Add to queue reponses show for requester only': config.autoAnnounceNextSong ? 'yes' : 'no',
           'Default Volume': config.defaultVolume,
+          'Default queue page size': config.defaultQueuePageSize,
         };
 
         let description = '';
diff --git a/src/commands/queue.ts b/src/commands/queue.ts
index d627c7f..60472b0 100644
--- a/src/commands/queue.ts
+++ b/src/commands/queue.ts
@@ -5,6 +5,7 @@ import {TYPES} from '../types.js';
 import PlayerManager from '../managers/player.js';
 import Command from './index.js';
 import {buildQueueEmbed} from '../utils/build-embed.js';
+import {getGuildSettings} from '../utils/get-guild-settings.js';
 
 @injectable()
 export default class implements Command {
@@ -17,7 +18,9 @@ export default class implements Command {
       .setRequired(false))
     .addIntegerOption(option => option
       .setName('page-size')
-      .setDescription('how many items to display per page [default: 10]')
+      .setDescription('how many items to display per page [default: 10, max: 50]')
+      .setMinValue(1)
+      .setMaxValue(50)
       .setRequired(false));
 
   private readonly playerManager: PlayerManager;
@@ -27,12 +30,16 @@ export default class implements Command {
   }
 
   public async execute(interaction: ChatInputCommandInteraction) {
-    const player = this.playerManager.get(interaction.guild!.id);
+    const guildId = interaction.guild!.id;
+    const player = this.playerManager.get(guildId);
+
+    const pageSizeFromOptions = interaction.options.getInteger('page-size');
+    const pageSize = pageSizeFromOptions ?? (await getGuildSettings(guildId)).defaultQueuePageSize;
 
     const embed = buildQueueEmbed(
       player,
       interaction.options.getInteger('page') ?? 1,
-      interaction.options.getInteger('page-size') ?? 10,
+      pageSize,
     );
 
     await interaction.reply({embeds: [embed]});