mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 08:33:30 +01:00
feat: stage channels (#5456)
* feat: add stage channel type * feat: initialise stage channel structure * feat: add STAGE_MODERATOR permissions bitfield * fix: typo in permissions * fix(Channel): type selection logic * feat: add rtcRegion to StageChannel and VoiceChannel * feat: rtc region editing for stage and voice channels * feat: stage channel userLimit * feat: add stage channels to exports * feat: add computed properties to stage channel * feat(VoiceState): include stage channel in docs * feat: allow ability to join stage channels * feat(StageChannel): join and leave methods * docs: add StageChannel link in GuildChannel docs * feat(VoiceState): suppress and requestToSpeakTimestamp * feat(StageChannel): setRequestToSpeak * refactor(StageChannel): update setRequestToSpeak * feat(VoiceState): add moveToSpeakers and moveToAudience * feat(VoiceState): add methods to move in/out of speakers * feat(VoiceState): add stage channel sanity checks * feat(Permissions): add REQUEST_TO_SPEAK * feat(VoiceState): simpler methods * docs(VoiceState): add documentation for new methods * refactor: remove unused error message * chore: remove debug statements * chore: revert changes to package-lock.json * docs(VoiceState): clarify suppress * docs(VoiceState): add missing @type param * feat(StageChannel): remove nsfw property * fix(VoiceState): check permissions in channel Co-authored-by: Advaith <advaithj1@gmail.com> * fix(VoiceState): instantiate error with new Co-authored-by: BannerBomb <BannerBomb55@gmail.com> * refactor(VoiceState): more readable API route builder Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> * style(VoiceState): fix lint errors * docs(VoiceState): add example usage for new methods * docs: setRTCRegion examples * chore: update typings * fix(VoiceState): calculate permissions for self * refactor(VoiceState): tidy up implementation * Update src/structures/VoiceState.js Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com> * refactor: vaporox's suggestions * style(VoiceState): fix linter errors * chore: update typings * chore: remove unused error message * refactor(VoiceState): use optional chaining Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> * chore: move getters below constructor in typings * refactor(StageChannel): optional chaining Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> * style(VoiceState): fix lint errors * docs: fix incorrect types Co-authored-by: izexi <43889168+izexi@users.noreply.github.com> * Update src/structures/VoiceChannel.js Co-authored-by: izexi <43889168+izexi@users.noreply.github.com> * Update src/structures/VoiceChannel.js Co-authored-by: izexi <43889168+izexi@users.noreply.github.com> * refactor(VoiceState): use optional chaining Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> * refactor(StageChannel): remove permission override check in joinable * refactor: make ChannelTypes a proper enum * Use createEnum Co-authored-by: izexi <43889168+izexi@users.noreply.github.com> * chore: remove unused code from Constants * refactor(StageChannel): remove unnecessary getters * chore: update typings * refactor: introduce BaseGuildVoiceChannel class * refactor(VoiceChannel): reduce code duplication * feat: export BaseGuildVoiceChannel * chore: update typings * docs: fix typos * refactor: move setRTCRegion to BaseGuildVoiceChannel * feat(VoiceState): remove permission checks * chore: update typings * Apply suggestions from code review Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com> * chore: update esm exports and typings * Update src/structures/VoiceState.js Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com> Co-authored-by: Advaith <advaithj1@gmail.com> Co-authored-by: BannerBomb <BannerBomb55@gmail.com> Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> Co-authored-by: Jan <66554238+vaporox@users.noreply.github.com> Co-authored-by: izexi <43889168+izexi@users.noreply.github.com> Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
This commit is contained in:
@@ -63,10 +63,22 @@ class VoiceState extends Base {
|
||||
*/
|
||||
this.streaming = data.self_stream || false;
|
||||
/**
|
||||
* The ID of the voice channel that this member is in
|
||||
* The ID of the voice or stage channel that this member is in
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.channelID = data.channel_id || null;
|
||||
/**
|
||||
* Whether this member is suppressed from speaking. This property is specific to stage channels only.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.suppress = data.suppress;
|
||||
/**
|
||||
* The time at which the member requested to speak. This property is specific to stage channels only.
|
||||
* @type {?number}
|
||||
*/
|
||||
this.requestToSpeakTimestamp = data.request_to_speak_timestamp
|
||||
? new Date(data.request_to_speak_timestamp).getTime()
|
||||
: null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -81,7 +93,7 @@ class VoiceState extends Base {
|
||||
|
||||
/**
|
||||
* The channel that the member is connected to
|
||||
* @type {?VoiceChannel}
|
||||
* @type {?VoiceChannel|StageChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
@@ -118,7 +130,7 @@ class VoiceState extends Base {
|
||||
|
||||
/**
|
||||
* Whether this member is currently speaking. A boolean if the information is available (aka
|
||||
* the bot is connected to any voice channel in the guild), otherwise this is null
|
||||
* the bot is connected to any voice channel or stage channel in the guild), otherwise this is `null`
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
@@ -147,7 +159,7 @@ class VoiceState extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the member from the voice channel.
|
||||
* Kicks the member from the channel.
|
||||
* @param {string} [reason] Reason for kicking member from the channel
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
@@ -196,6 +208,63 @@ class VoiceState extends Base {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the request to speak in the channel.
|
||||
* Only applicable for stage channels and for the client's own voice state.
|
||||
* @param {boolean} request Whether or not the client is requesting to become a speaker.
|
||||
* @example
|
||||
* // Making the client request to speak in a stage channel (raise its hand)
|
||||
* guild.me.voice.setRequestToSpeak(true);
|
||||
* @example
|
||||
* // Making the client cancel a request to speak
|
||||
* guild.me.voice.setRequestToSpeak(false);
|
||||
*/
|
||||
async setRequestToSpeak(request) {
|
||||
const channel = this.channel;
|
||||
if (channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
|
||||
if (this.client.user.id !== this.id) throw new Error('VOICE_STATE_NOT_OWN');
|
||||
|
||||
await this.client.api.guilds(this.guild.id, 'voice-states', '@me').patch({
|
||||
data: {
|
||||
channel_id: this.channelID,
|
||||
request_to_speak_timestamp: request ? new Date().toISOString() : null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppress/unsuppress the user. Only applicable for stage channels.
|
||||
* @param {boolean} suppressed - Whether or not the user should be suppressed.
|
||||
* @example
|
||||
* // Making the client a speaker
|
||||
* guild.me.voice.setSuppressed(false);
|
||||
* @example
|
||||
* // Making the client an audience member
|
||||
* guild.me.voice.setSuppressed(true);
|
||||
* @example
|
||||
* // Inviting another user to speak
|
||||
* voiceState.setSuppressed(false);
|
||||
* @example
|
||||
* // Moving another user to the audience, or cancelling their invite to speak
|
||||
* voiceState.setSuppressed(true);
|
||||
*/
|
||||
async setSuppressed(suppressed) {
|
||||
if (typeof suppressed !== 'boolean') throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed');
|
||||
|
||||
const channel = this.channel;
|
||||
if (channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
|
||||
const target = this.client.user.id === this.id ? '@me' : this.id;
|
||||
|
||||
await this.client.api.guilds(this.guild.id, 'voice-states', target).patch({
|
||||
data: {
|
||||
channel_id: this.channelID,
|
||||
suppress: suppressed,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return super.toJSON({
|
||||
id: true,
|
||||
|
||||
Reference in New Issue
Block a user