mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 20:13:30 +01:00
Merge branch 'master' into voice-rewrite
This commit is contained in:
@@ -13,6 +13,19 @@ class CategoryChannel extends GuildChannel {
|
|||||||
get children() {
|
get children() {
|
||||||
return this.guild.channels.filter(c => c.parentID === this.id);
|
return this.guild.channels.filter(c => c.parentID === this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the category parent of this channel.
|
||||||
|
* <warn>It is not currently possible to set the parent of a CategoryChannel.</warn>
|
||||||
|
* @method setParent
|
||||||
|
* @memberof CategoryChannel
|
||||||
|
* @instance
|
||||||
|
* @param {?GuildChannel|Snowflake} channel Parent channel
|
||||||
|
* @param {Object} [options={}] Options to pass
|
||||||
|
* @param {boolean} [options.lockPermissions=true] Lock the permissions to what the parent's permissions are
|
||||||
|
* @param {string} [options.reason] Reason for modifying the parent of this channel
|
||||||
|
* @returns {Promise<GuildChannel>}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = CategoryChannel;
|
module.exports = CategoryChannel;
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ class Emoji extends Base {
|
|||||||
*/
|
*/
|
||||||
this.managed = data.managed;
|
this.managed = data.managed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this emoji is animated
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.animated = data.animated;
|
||||||
|
|
||||||
this._roles = data.roles;
|
this._roles = data.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +91,7 @@ class Emoji extends Base {
|
|||||||
* @readonly
|
* @readonly
|
||||||
*/
|
*/
|
||||||
get url() {
|
get url() {
|
||||||
return this.client.rest.cdn.Emoji(this.id);
|
return this.client.rest.cdn.Emoji(this.id, this.animated ? 'gif' : 'png');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,7 +204,11 @@ class Emoji extends Base {
|
|||||||
* msg.reply(`Hello! ${emoji}`);
|
* msg.reply(`Hello! ${emoji}`);
|
||||||
*/
|
*/
|
||||||
toString() {
|
toString() {
|
||||||
return this.requiresColons ? `<:${this.name}:${this.id}>` : this.name;
|
if (!this.id || !this.requiresColons) {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<${this.animated ? 'a' : ''}:${this.name}:${this.id}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -910,8 +910,8 @@ class Guild extends Base {
|
|||||||
/**
|
/**
|
||||||
* Creates a new channel in the guild.
|
* Creates a new channel in the guild.
|
||||||
* @param {string} name The name of the new channel
|
* @param {string} name The name of the new channel
|
||||||
* @param {string} type The type of the new channel, either `text`, `voice`, or `category`
|
|
||||||
* @param {Object} [options] Options
|
* @param {Object} [options] Options
|
||||||
|
* @param {string} [options.type='text'] The type of the new channel, either `text`, `voice`, or `category`
|
||||||
* @param {boolean} [options.nsfw] Whether the new channel is nsfw
|
* @param {boolean} [options.nsfw] Whether the new channel is nsfw
|
||||||
* @param {number} [options.bitrate] Bitrate of the new channel in bits (only voice)
|
* @param {number} [options.bitrate] Bitrate of the new channel in bits (only voice)
|
||||||
* @param {number} [options.userLimit] Maximum amount of users allowed in the new channel (only voice)
|
* @param {number} [options.userLimit] Maximum amount of users allowed in the new channel (only voice)
|
||||||
@@ -925,7 +925,7 @@ class Guild extends Base {
|
|||||||
* .then(channel => console.log(`Created new channel ${channel}`))
|
* .then(channel => console.log(`Created new channel ${channel}`))
|
||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
createChannel(name, type, { nsfw, bitrate, userLimit, parent, overwrites, reason } = {}) {
|
createChannel(name, { type, nsfw, bitrate, userLimit, parent, overwrites, reason } = {}) {
|
||||||
if (overwrites instanceof Collection || overwrites instanceof Array) {
|
if (overwrites instanceof Collection || overwrites instanceof Array) {
|
||||||
overwrites = overwrites.map(overwrite => {
|
overwrites = overwrites.map(overwrite => {
|
||||||
let allow = overwrite.allow || (overwrite.allowed ? overwrite.allowed.bitfield : 0);
|
let allow = overwrite.allow || (overwrite.allowed ? overwrite.allowed.bitfield : 0);
|
||||||
@@ -955,7 +955,7 @@ class Guild extends Base {
|
|||||||
return this.client.api.guilds(this.id).channels.post({
|
return this.client.api.guilds(this.id).channels.post({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
type: ChannelTypes[type.toUpperCase()],
|
type: type ? ChannelTypes[type.toUpperCase()] : 'text',
|
||||||
nsfw,
|
nsfw,
|
||||||
bitrate,
|
bitrate,
|
||||||
user_limit: userLimit,
|
user_limit: userLimit,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const { MessageNotificationTypes } = require('../util/Constants');
|
|||||||
const { Error, TypeError } = require('../errors');
|
const { Error, TypeError } = require('../errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a guild channel (e.g. text channels and voice channels).
|
* Represents a guild channel (i.g. a {@link TextChannel}, {@link VoiceChannel} or {@link CategoryChannel}).
|
||||||
* @extends {Channel}
|
* @extends {Channel}
|
||||||
*/
|
*/
|
||||||
class GuildChannel extends Channel {
|
class GuildChannel extends Channel {
|
||||||
@@ -323,14 +323,15 @@ class GuildChannel extends Channel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the category parent of this channel.
|
* Sets the category parent of this channel.
|
||||||
* @param {GuildChannel|Snowflake} channel Parent channel
|
* @param {?GuildChannel|Snowflake} channel Parent channel
|
||||||
* @param {boolean} [options.lockPermissions] Lock the permissions to what the parent's permissions are
|
* @param {Object} [options={}] Options to pass
|
||||||
|
* @param {boolean} [options.lockPermissions=true] Lock the permissions to what the parent's permissions are
|
||||||
* @param {string} [options.reason] Reason for modifying the parent of this channel
|
* @param {string} [options.reason] Reason for modifying the parent of this channel
|
||||||
* @returns {Promise<GuildChannel>}
|
* @returns {Promise<GuildChannel>}
|
||||||
*/
|
*/
|
||||||
setParent(channel, { lockPermissions = true, reason } = {}) {
|
setParent(channel, { lockPermissions = true, reason } = {}) {
|
||||||
return this.edit({
|
return this.edit({
|
||||||
parentID: channel.id ? channel.id : channel,
|
parentID: channel !== null ? channel.id ? channel.id : channel : null,
|
||||||
lockPermissions,
|
lockPermissions,
|
||||||
}, reason);
|
}, reason);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,10 +377,10 @@ class Message extends Base {
|
|||||||
}
|
}
|
||||||
if (!options.content) options.content = content;
|
if (!options.content) options.content = content;
|
||||||
|
|
||||||
const { data, files } = await createMessage(this, options);
|
const { data } = await createMessage(this, options);
|
||||||
|
|
||||||
return this.client.api.channels[this.channel.id].messages[this.id]
|
return this.client.api.channels[this.channel.id].messages[this.id]
|
||||||
.patch({ data, files })
|
.patch({ data })
|
||||||
.then(d => {
|
.then(d => {
|
||||||
const clone = this._clone();
|
const clone = this._clone();
|
||||||
clone._patch(d);
|
clone._patch(d);
|
||||||
|
|||||||
@@ -76,17 +76,18 @@ class Collector extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
handleCollect(...args) {
|
handleCollect(...args) {
|
||||||
const collect = this.collect(...args);
|
const collect = this.collect(...args);
|
||||||
if (!collect || !this.filter(...args, this.collected)) return;
|
|
||||||
|
|
||||||
this.collected.set(collect.key, collect.value);
|
if (collect && this.filter(...args, this.collected)) {
|
||||||
|
this.collected.set(collect.key, collect.value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever an element is collected.
|
* Emitted whenever an element is collected.
|
||||||
* @event Collector#collect
|
* @event Collector#collect
|
||||||
* @param {*} element The element that got collected
|
* @param {*} element The element that got collected
|
||||||
* @param {...*} args The arguments emitted by the listener
|
* @param {...*} args The arguments emitted by the listener
|
||||||
*/
|
*/
|
||||||
this.emit('collect', collect.value, ...args);
|
this.emit('collect', collect.value, ...args);
|
||||||
|
}
|
||||||
this.checkEnd();
|
this.checkEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,18 +19,31 @@ module.exports = async function createMessage(channel, options) {
|
|||||||
if (isNaN(options.nonce) || options.nonce < 0) throw new RangeError('MESSAGE_NONCE_TYPE');
|
if (isNaN(options.nonce) || options.nonce < 0) throw new RangeError('MESSAGE_NONCE_TYPE');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let { content } = options;
|
||||||
if (options instanceof MessageEmbed) options = webhook ? { embeds: [options] } : { embed: options };
|
if (options instanceof MessageEmbed) options = webhook ? { embeds: [options] } : { embed: options };
|
||||||
if (options instanceof MessageAttachment) options = { files: [options.file] };
|
if (options instanceof MessageAttachment) options = { files: [options.file] };
|
||||||
|
|
||||||
|
if (content instanceof Array || options instanceof Array) {
|
||||||
|
const which = content instanceof Array ? content : options;
|
||||||
|
const attachments = which.filter(item => item instanceof MessageAttachment);
|
||||||
|
const embeds = which.filter(item => item instanceof MessageEmbed);
|
||||||
|
if (attachments.length) options = { files: attachments };
|
||||||
|
if (embeds.length) options = { embeds };
|
||||||
|
if ((embeds.length || attachments.length) && content instanceof Array) {
|
||||||
|
content = null;
|
||||||
|
options.content = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
|
if (options.reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
|
||||||
const id = channel.client.users.resolveID(options.reply);
|
const id = channel.client.users.resolveID(options.reply);
|
||||||
const mention = `<@${options.reply instanceof GuildMember && options.reply.nickname ? '!' : ''}${id}>`;
|
const mention = `<@${options.reply instanceof GuildMember && options.reply.nickname ? '!' : ''}${id}>`;
|
||||||
if (options.split) options.split.prepend = `${mention}, ${options.split.prepend || ''}`;
|
if (options.split) options.split.prepend = `${mention}, ${options.split.prepend || ''}`;
|
||||||
options.content = `${mention}${typeof options.content !== 'undefined' ? `, ${options.content}` : ''}`;
|
content = `${mention}${typeof options.content !== 'undefined' ? `, ${options.content}` : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.content) {
|
if (content) {
|
||||||
options.content = Util.resolveString(options.content);
|
options.content = Util.resolveString(content);
|
||||||
if (options.split && typeof options.split !== 'object') options.split = {};
|
if (options.split && typeof options.split !== 'object') options.split = {};
|
||||||
// Wrap everything in a code block
|
// Wrap everything in a code block
|
||||||
if (typeof options.code !== 'undefined' && (typeof options.code !== 'boolean' || options.code === true)) {
|
if (typeof options.code !== 'undefined' && (typeof options.code !== 'boolean' || options.code === true)) {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ function makeImageUrl(root, { format = 'webp', size } = {}) {
|
|||||||
exports.Endpoints = {
|
exports.Endpoints = {
|
||||||
CDN(root) {
|
CDN(root) {
|
||||||
return {
|
return {
|
||||||
Emoji: emojiID => `${root}/emojis/${emojiID}.png`,
|
Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`,
|
||||||
Asset: name => `${root}/assets/${name}`,
|
Asset: name => `${root}/assets/${name}`,
|
||||||
DefaultAvatar: number => `${root}/embed/avatars/${number}.png`,
|
DefaultAvatar: number => `${root}/embed/avatars/${number}.png`,
|
||||||
Avatar: (userID, hash, format = 'default', size) => {
|
Avatar: (userID, hash, format = 'default', size) => {
|
||||||
|
|||||||
@@ -70,18 +70,21 @@ class Util {
|
|||||||
* Parses emoji info out of a string. The string must be one of:
|
* Parses emoji info out of a string. The string must be one of:
|
||||||
* * A UTF-8 emoji (no ID)
|
* * A UTF-8 emoji (no ID)
|
||||||
* * A URL-encoded UTF-8 emoji (no ID)
|
* * A URL-encoded UTF-8 emoji (no ID)
|
||||||
* * A Discord custom emoji (`<:name:id>`)
|
* * A Discord custom emoji (`<:name:id>` or `<a:name:id>`)
|
||||||
* @param {string} text Emoji string to parse
|
* @param {string} text Emoji string to parse
|
||||||
* @returns {Object} Object with `name` and `id` properties
|
* @returns {Object} Object with `animated`, `name`, and `id` properties
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static parseEmoji(text) {
|
static parseEmoji(text) {
|
||||||
if (text.includes('%')) text = decodeURIComponent(text);
|
if (text.includes('%')) text = decodeURIComponent(text);
|
||||||
if (text.includes(':')) {
|
if (text.includes(':')) {
|
||||||
const [name, id] = text.split(':');
|
const m = text.match(/<?(a)?:(\w{2,32}):(\d{17,19})>?/);
|
||||||
return { name, id };
|
if (!m) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return { animated: Boolean(m[1]), name: m[2], id: m[3] };
|
||||||
} else {
|
} else {
|
||||||
return { name: text, id: null };
|
return { animated: false, name: text, id: null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user