From 5fc4606ef91a772d1af74f360903527e33f073ba Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Sun, 27 Apr 2025 02:01:24 +0200 Subject: [PATCH] feat: soundboard forward port --- .../discord.js/src/managers/GuildManager.js | 4 +- .../managers/GuildSoundboardSoundManager.js | 58 +++++++++++++------ packages/discord.js/src/structures/Guild.js | 7 +++ .../src/structures/SoundboardSound.js | 8 +-- packages/discord.js/typings/index.d.ts | 10 +++- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/packages/discord.js/src/managers/GuildManager.js b/packages/discord.js/src/managers/GuildManager.js index 0e3984c240d0..89696163b36e 100644 --- a/packages/discord.js/src/managers/GuildManager.js +++ b/packages/discord.js/src/managers/GuildManager.js @@ -285,8 +285,8 @@ class GuildManager extends CachedManager { /** * @typedef {Object} FetchSoundboardSoundsOptions - * @param {Snowflake[]} guildIds The ids of the guilds to fetch soundboard sounds for - * @param {number} [time=10_000] The timeout for receipt of the soundboard sounds + * @property {Snowflake[]} guildIds The ids of the guilds to fetch soundboard sounds for + * @property {number} [time=10_000] The timeout for receipt of the soundboard sounds */ /** diff --git a/packages/discord.js/src/managers/GuildSoundboardSoundManager.js b/packages/discord.js/src/managers/GuildSoundboardSoundManager.js index 94eb1088c85c..59e923aed26b 100644 --- a/packages/discord.js/src/managers/GuildSoundboardSoundManager.js +++ b/packages/discord.js/src/managers/GuildSoundboardSoundManager.js @@ -105,7 +105,7 @@ class GuildSoundboardSoundManager extends CachedManager { * Data for editing a soundboard sound. * @typedef {Object} GuildSoundboardSoundEditOptions * @property {string} [name] The name of the soundboard sound - * @property {?number} [volume] The volume of the soundboard sound, from 0 to 1 + * @property {?number} [volume] The volume (a double) of the soundboard sound, from 0 (inclusive) to 1 * @property {?Snowflake} [emojiId] The emoji id of the soundboard sound * @property {?string} [emojiName] The emoji name of the soundboard sound * @property {string} [reason] The reason for editing the soundboard sound @@ -157,35 +157,57 @@ class GuildSoundboardSoundManager extends CachedManager { await this.client.rest.delete(Routes.guildSoundboardSound(this.guild.id, soundId), { reason }); } + /** + * Options used to fetch a soundboard sound. + * @typedef {BaseFetchOptions} FetchSoundboardSoundOptions + * @property {SoundboardSoundResolvable} soundboardSound The soundboard sound to fetch + */ + + /** + * Options used to fetch soundboard sounds from Discord + * @typedef {Object} FetchGuildSoundboardSoundsOptions + * @property {boolean} [cache] Whether to cache the fetched soundboard sounds + */ + + /* eslint-disable max-len */ /** * Obtains one or more soundboard sounds from Discord, or the soundboard sound cache if they're already available. - * @param {Snowflake} [id] The soundboard sound's id - * @param {BaseFetchOptions} [options] Additional options for this fetch + * @param {SoundboardSoundResolvable|FetchSoundboardSoundOptions|FetchGuildSoundboardSoundsOptions} [options] Options for fetching soundboard sound(s) * @returns {Promise>} * @example - * // Fetch all soundboard sounds from the guild - * guild.soundboardSounds.fetch() - * .then(sounds => console.log(`There are ${sounds.size} soundboard sounds.`)) - * .catch(console.error); - * @example * // Fetch a single soundboard sound * guild.soundboardSounds.fetch('222078108977594368') * .then(sound => console.log(`The soundboard sound name is: ${sound.name}`)) * .catch(console.error); + * @example + * // Fetch all soundboard sounds from the guild + * guild.soundboardSounds.fetch() + * .then(sounds => console.log(`There are ${sounds.size} soundboard sounds.`)) + * .catch(console.error); */ - async fetch(id, { cache = true, force = false } = {}) { - if (id) { - if (!force) { - const existing = this.cache.get(id); - if (existing) return existing; - } - - const sound = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, id)); - return this._add(sound, cache); + /* eslint-enable max-len */ + async fetch(options) { + if (!options) return this._fetchMany(); + const { cache, force, soundboardSound } = options; + const resolvedSoundboardSound = this.resolveId(soundboardSound ?? options); + if (resolvedSoundboardSound) return this._fetchSingle({ cache, force, soundboardSound: resolvedSoundboardSound }); + return this._fetchMany({ cache }); + } + + async _fetchSingle({ cache, force, soundboardSound } = {}) { + if (!force) { + const existing = this.cache.get(soundboardSound); + if (existing) return existing; } + const data = await this.client.rest.get(Routes.guildSoundboardSound(this.guild.id, soundboardSound)); + return this._add(data, cache); + } + + async _fetchMany({ cache } = {}) { const data = await this.client.rest.get(Routes.guildSoundboardSounds(this.guild.id)); - return new Collection(data.map(sound => [sound.sound_id, this._add(sound, cache)])); + + return data.items.reduce((coll, sound) => coll.set(sound.sound_id, this._add(sound, cache)), new Collection()); } } diff --git a/packages/discord.js/src/structures/Guild.js b/packages/discord.js/src/structures/Guild.js index 8c971bb660e9..c6e1b901e4f3 100644 --- a/packages/discord.js/src/structures/Guild.js +++ b/packages/discord.js/src/structures/Guild.js @@ -489,6 +489,13 @@ class Guild extends AnonymousGuild { } else { this.incidentsData ??= null; } + + if (data.soundboard_sounds) { + this.soundboardSounds.cache.clear(); + for (const soundboardSound of data.soundboard_sounds) { + this.soundboardSounds._add(soundboardSound); + } + } } /** diff --git a/packages/discord.js/src/structures/SoundboardSound.js b/packages/discord.js/src/structures/SoundboardSound.js index 2bfbae9ea3f6..647cccd5ccd7 100644 --- a/packages/discord.js/src/structures/SoundboardSound.js +++ b/packages/discord.js/src/structures/SoundboardSound.js @@ -181,8 +181,8 @@ class SoundboardSound extends Base { this.available === other.available && this.name === other.name && this.volume === other.volume && - this.emojiId === other.emojiId && - this.emojiName === other.emojiName && + this._emoji?.id === other._emoji?.id && + this._emoji?.name === other._emoji?.name && this.guildId === other.guildId && this.user?.id === other.user?.id ); @@ -193,8 +193,8 @@ class SoundboardSound extends Base { this.available === other.available && this.name === other.name && this.volume === other.volume && - this.emojiId === other.emoji_id && - this.emojiName === other.emoji_name && + (this._emoji?.id ?? null) === other.emoji_id && + (this._emoji?.name ?? null) === other.emoji_name && this.guildId === other.guild_id && this.user?.id === other.user?.id ); diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index b8520649fac1..1a9798b81fc2 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -4290,8 +4290,15 @@ export interface GuildSoundboardSoundEditOptions { volume?: number | null; emojiId?: Snowflake | null; emojiName?: string | null; + reason?: string; +} + +export interface FetchGuildSoundboardSoundOptions extends BaseFetchOptions { + soundboardSound: SoundboardSoundResolvable; } +export interface FetchGuildSoundboardSoundsOptions extends Pick {} + export class GuildSoundboardSoundManager extends CachedManager { private constructor(guild: Guild, iterable?: Iterable); public guild: Guild; @@ -5804,8 +5811,7 @@ export interface GuildAuditLogsEntryTargetField { ApplicationCommand: ApplicationCommand | { id: Snowflake }; AutoModeration: AutoModerationRule; GuildOnboardingPrompt: GuildOnboardingPrompt | { id: Snowflake; [x: string]: unknown }; - // TODO: Update when https://github.com/discordjs/discord.js/pull/10590 is merged - SoundboardSound: { id: Snowflake }; + SoundboardSound: SoundboardSound | { id: Snowflake }; } export interface GuildAuditLogsFetchOptions {