diff --git a/migrations/20240301214725_add_auto_announce_next_song/migration.sql b/migrations/20240301214725_add_auto_announce_next_song/migration.sql new file mode 100644 index 0000000..f863145 --- /dev/null +++ b/migrations/20240301214725_add_auto_announce_next_song/migration.sql @@ -0,0 +1,17 @@ +-- 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, + "autoAnnounceNextSong" BOOLEAN NOT NULL DEFAULT false, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); +INSERT INTO "new_Setting" ("createdAt", "guildId", "leaveIfNoListeners", "playlistLimit", "secondsToWaitAfterQueueEmpties", "updatedAt") SELECT "createdAt", "guildId", "leaveIfNoListeners", "playlistLimit", "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 556cd6b..10cc624 100644 --- a/schema.prisma +++ b/schema.prisma @@ -28,6 +28,7 @@ model Setting { playlistLimit Int @default(50) secondsToWaitAfterQueueEmpties Int @default(30) leaveIfNoListeners Boolean @default(true) + autoAnnounceNextSong Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } diff --git a/src/commands/config.ts b/src/commands/config.ts index 7f25a2e..9441dab 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -33,6 +33,13 @@ export default class implements Command { .setName('value') .setDescription('whether to leave when everyone else leaves') .setRequired(true))) + .addSubcommand(subcommand => subcommand + .setName('set-auto-announce-next-song') + .setDescription('set whether to announce the next song in the queue automatically') + .addBooleanOption(option => option + .setName('value') + .setDescription('whether to announce the next song in the queue automatically') + .setRequired(true))) .addSubcommand(subcommand => subcommand .setName('get') .setDescription('show all settings')); @@ -97,6 +104,23 @@ export default class implements Command { break; } + case 'set-auto-announce-next-song': { + const value = interaction.options.getBoolean('value')!; + + await prisma.setting.update({ + where: { + guildId: interaction.guild!.id, + }, + data: { + autoAnnounceNextSong: value, + }, + }); + + await interaction.reply('👍 auto announce setting updated'); + + break; + } + case 'get': { const embed = new EmbedBuilder().setTitle('Config'); @@ -108,6 +132,7 @@ export default class implements Command { ? 'never leave' : `${config.secondsToWaitAfterQueueEmpties}s`, 'Leave if there are no listeners': config.leaveIfNoListeners ? 'yes' : 'no', + 'Auto announce next song in queue': config.autoAnnounceNextSong ? 'yes' : 'no', }; let description = ''; diff --git a/src/services/player.ts b/src/services/player.ts index c17a536..bfd29ad 100644 --- a/src/services/player.ts +++ b/src/services/player.ts @@ -19,6 +19,7 @@ import { import FileCacheProvider from './file-cache.js'; import debug from '../utils/debug.js'; import {getGuildSettings} from '../utils/get-guild-settings.js'; +import {buildPlayingMessageEmbed} from '../utils/build-embed.js'; export enum MediaSource { Youtube, @@ -64,7 +65,7 @@ export default class { public guildId: string; public loopCurrentSong = false; public loopCurrentQueue = false; - + private currentChannel: VoiceChannel | undefined; private queue: QueuedSong[] = []; private queuePosition = 0; private audioPlayer: AudioPlayer | null = null; @@ -102,6 +103,8 @@ export default class { oldNetworking?.off('stateChange', networkStateChangeHandler); newNetworking?.on('stateChange', networkStateChangeHandler); /* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */ + + this.currentChannel = channel; }); } @@ -559,6 +562,14 @@ export default class { if (newState.status === AudioPlayerStatus.Idle && this.status === STATUS.PLAYING) { await this.forward(1); + // Auto announce the next song if configured to + const settings = await getGuildSettings(this.guildId); + const {autoAnnounceNextSong} = settings; + if (autoAnnounceNextSong && this.currentChannel) { + await this.currentChannel.send({ + embeds: this.getCurrent() ? [buildPlayingMessageEmbed(this)] : [], + }); + } } }