Merge branch 'TiagoGrosso-configurable-queue-page-size'

This commit is contained in:
Harry Jenkins 2024-08-28 16:44:18 +10:00
commit dede552ddd
6 changed files with 72 additions and 8 deletions

View file

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added
- An optional `page-size` to `/queue` command
- Add `default-queue-page-size` setting
## [2.9.3] - 2024-08-19 ## [2.9.3] - 2024-08-19
### Fixed ### Fixed

View file

@ -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;

View file

@ -31,6 +31,7 @@ model Setting {
queueAddResponseEphemeral Boolean @default(false) queueAddResponseEphemeral Boolean @default(false)
autoAnnounceNextSong Boolean @default(false) autoAnnounceNextSong Boolean @default(false)
defaultVolume Int @default(100) defaultVolume Int @default(100)
defaultQueuePageSize Int @default(10)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
} }

View file

@ -56,6 +56,15 @@ export default class implements Command {
.setMinValue(0) .setMinValue(0)
.setMaxValue(100) .setMaxValue(100)
.setRequired(true))) .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(30)
.setRequired(true)))
.addSubcommand(subcommand => subcommand .addSubcommand(subcommand => subcommand
.setName('get') .setName('get')
.setDescription('show all settings')); .setDescription('show all settings'));
@ -171,6 +180,23 @@ export default class implements Command {
break; 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': { case 'get': {
const embed = new EmbedBuilder().setTitle('Config'); 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', 'Auto announce next song in queue': config.autoAnnounceNextSong ? 'yes' : 'no',
'Add to queue reponses show for requester only': config.autoAnnounceNextSong ? 'yes' : 'no', 'Add to queue reponses show for requester only': config.autoAnnounceNextSong ? 'yes' : 'no',
'Default Volume': config.defaultVolume, 'Default Volume': config.defaultVolume,
'Default queue page size': config.defaultQueuePageSize,
}; };
let description = ''; let description = '';

View file

@ -5,6 +5,7 @@ import {TYPES} from '../types.js';
import PlayerManager from '../managers/player.js'; import PlayerManager from '../managers/player.js';
import Command from './index.js'; import Command from './index.js';
import {buildQueueEmbed} from '../utils/build-embed.js'; import {buildQueueEmbed} from '../utils/build-embed.js';
import {getGuildSettings} from '../utils/get-guild-settings.js';
@injectable() @injectable()
export default class implements Command { export default class implements Command {
@ -14,6 +15,12 @@ export default class implements Command {
.addIntegerOption(option => option .addIntegerOption(option => option
.setName('page') .setName('page')
.setDescription('page of queue to show [default: 1]') .setDescription('page of queue to show [default: 1]')
.setRequired(false))
.addIntegerOption(option => option
.setName('page-size')
.setDescription('how many items to display per page [default: 10, max: 30]')
.setMinValue(1)
.setMaxValue(30)
.setRequired(false)); .setRequired(false));
private readonly playerManager: PlayerManager; private readonly playerManager: PlayerManager;
@ -23,9 +30,17 @@ export default class implements Command {
} }
public async execute(interaction: ChatInputCommandInteraction) { 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 embed = buildQueueEmbed(player, interaction.options.getInteger('page') ?? 1); const pageSizeFromOptions = interaction.options.getInteger('page-size');
const pageSize = pageSizeFromOptions ?? (await getGuildSettings(guildId)).defaultQueuePageSize;
const embed = buildQueueEmbed(
player,
interaction.options.getInteger('page') ?? 1,
pageSize,
);
await interaction.reply({embeds: [embed]}); await interaction.reply({embeds: [embed]});
} }

View file

@ -5,8 +5,6 @@ import getProgressBar from './get-progress-bar.js';
import {prettyTime} from './time.js'; import {prettyTime} from './time.js';
import {truncate} from './string.js'; import {truncate} from './string.js';
const PAGE_SIZE = 10;
const getMaxSongTitleLength = (title: string) => { const getMaxSongTitleLength = (title: string) => {
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
const nonASCII = /[^\x00-\x7F]+/; const nonASCII = /[^\x00-\x7F]+/;
@ -77,7 +75,7 @@ export const buildPlayingMessageEmbed = (player: Player): EmbedBuilder => {
return message; return message;
}; };
export const buildQueueEmbed = (player: Player, page: number): EmbedBuilder => { export const buildQueueEmbed = (player: Player, page: number, pageSize: number): EmbedBuilder => {
const currentlyPlaying = player.getCurrent(); const currentlyPlaying = player.getCurrent();
if (!currentlyPlaying) { if (!currentlyPlaying) {
@ -85,14 +83,14 @@ export const buildQueueEmbed = (player: Player, page: number): EmbedBuilder => {
} }
const queueSize = player.queueSize(); const queueSize = player.queueSize();
const maxQueuePage = Math.ceil((queueSize + 1) / PAGE_SIZE); const maxQueuePage = Math.ceil((queueSize + 1) / pageSize);
if (page > maxQueuePage) { if (page > maxQueuePage) {
throw new Error('the queue isn\'t that big'); throw new Error('the queue isn\'t that big');
} }
const queuePageBegin = (page - 1) * PAGE_SIZE; const queuePageBegin = (page - 1) * pageSize;
const queuePageEnd = queuePageBegin + PAGE_SIZE; const queuePageEnd = queuePageBegin + pageSize;
const queuedSongs = player const queuedSongs = player
.getQueue() .getQueue()
.slice(queuePageBegin, queuePageEnd) .slice(queuePageBegin, queuePageEnd)