From 1e6abe587bfc6706bdc2ce299fd7f3f6f557c078 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Thu, 19 Jan 2017 11:10:54 -0600 Subject: [PATCH 01/30] no more (#1117) --- src/util/Collection.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/Collection.js b/src/util/Collection.js index bca75f5b8..13ab31cc3 100644 --- a/src/util/Collection.js +++ b/src/util/Collection.js @@ -137,7 +137,8 @@ class Collection extends Map { * Searches for a single item where its specified property's value is identical to the given value * (`item[prop] === value`), or the given function returns a truthy value. In the latter case, this is identical to * [Array.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). - * Do not use this to obtain an item by its ID. Instead, use `collection.get(id)`. See + * All collections used in Discord.js are mapped using their `id` property, and if you want to find by id you + * should use the `get` method. See * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) for details. * @param {string|Function} propOrFn The property to test against, or the function to test with * @param {*} [value] The expected value - only applicable and required if using a property for the first argument @@ -150,7 +151,6 @@ class Collection extends Map { find(propOrFn, value) { if (typeof propOrFn === 'string') { if (typeof value === 'undefined') throw new Error('Value must be specified.'); - if (propOrFn === 'id') throw new RangeError('Don\'t use .find() with IDs. Instead, use .get(id).'); for (const item of this.values()) { if (item[propOrFn] === value) return item; } From 030060164913ba072f692711f01c910bc5db4a72 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Thu, 19 Jan 2017 11:11:24 -0600 Subject: [PATCH 02/30] remove redundant editing (#1116) * remove redundant editing * update docs --- src/client/rest/RESTMethods.js | 5 +++-- src/structures/Guild.js | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 744136e9f..da1f2142b 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -323,8 +323,9 @@ class RESTMethods { ); } - createGuildRole(guild) { - return this.rest.makeRequest('post', Constants.Endpoints.guildRoles(guild.id), true).then(role => + createGuildRole(guild, data) { + if (data.color) data.color = this.client.resolver.resolveColor(data.color); + return this.rest.makeRequest('post', Constants.Endpoints.guildRoles(guild.id), true, data).then(role => this.client.actions.GuildRoleCreate.handle({ guild_id: guild.id, role, diff --git a/src/structures/Guild.js b/src/structures/Guild.js index dff0f610a..2a9c3d90d 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -608,7 +608,7 @@ class Guild { } /** - * Creates a new role in the guild, and optionally updates it with the given information. + * Creates a new role in the guild with given information * @param {RoleData} [data] The data to update the role with * @returns {Promise} * @example @@ -618,14 +618,15 @@ class Guild { * .catch(console.error); * @example * // create a new role with data - * guild.createRole({ name: 'Super Cool People' }) - * .then(role => console.log(`Created role ${role}`)) - * .catch(console.error) + * guild.createRole({ + * name: 'Super Cool People', + * color: 'BLUE', + * }) + * .then(role => console.log(`Created role ${role}`)) + * .catch(console.error) */ createRole(data) { - const create = this.client.rest.methods.createGuildRole(this); - if (!data) return create; - return create.then(role => role.edit(data)); + return this.client.rest.methods.createGuildRole(this, data); } /** From f51ba3fb062ce7dcd9f8aa03ebdfe88f3d8666b0 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Thu, 19 Jan 2017 22:04:14 -0500 Subject: [PATCH 03/30] Update to Webpack 2.2 stable --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 43386b460..f38600fb3 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "eslint": "^3.13.0", "parallel-webpack": "^1.6.0", "uglify-js": "mishoo/UglifyJS2#harmony", - "webpack": "2.2.0-rc.4" + "webpack": "^2.2.0" }, "engines": { "node": ">=6.0.0" From 3545e731c0abee01864605d6761ac83cadeee12b Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Thu, 19 Jan 2017 22:07:02 -0500 Subject: [PATCH 04/30] Renamed webpack build script --- deploy/deploy.sh | 4 ++-- package.json | 2 +- webpack.config.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 1ad30ac08..c59d0b09c 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -6,14 +6,14 @@ set -e function tests { npm run lint npm run test-docs - VERSIONED=false npm run web-dist + VERSIONED=false npm run webpack exit 0 } function build { npm run lint npm run docs - VERSIONED=false npm run web-dist + VERSIONED=false npm run webpack } # For revert branches, do nothing diff --git a/package.json b/package.json index f38600fb3..63ba4b0b6 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "docs": "docgen --source src --custom docs/index.yml --output docs/docs.json", "test-docs": "docgen --source src --custom docs/index.yml", "lint": "eslint src", - "web-dist": "node ./node_modules/parallel-webpack/bin/run.js" + "webpack": "parallel-webpack" }, "repository": { "type": "git", diff --git a/webpack.config.js b/webpack.config.js index 501279ee6..72bcca5a0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,5 @@ /* - ONLY RUN BUILDS WITH `npm run web-dist`! + ONLY RUN BUILDS WITH `npm run webpack`! DO NOT USE NORMAL WEBPACK! IT WILL NOT WORK! */ From 306ea97f99acb91b2dd28b14f0367e65c48be814 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Sat, 21 Jan 2017 10:37:28 -0600 Subject: [PATCH 05/30] fix guild member fetching edge cases (#1115) * thx4tipprogrammixluvubye * consistancy * make this loop for some reason * so impatient --- .../packets/handlers/GuildMembersChunk.js | 12 +++++--- src/structures/Guild.js | 30 +++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/client/websocket/packets/handlers/GuildMembersChunk.js b/src/client/websocket/packets/handlers/GuildMembersChunk.js index 02a3c3cbd..e67c1d425 100644 --- a/src/client/websocket/packets/handlers/GuildMembersChunk.js +++ b/src/client/websocket/packets/handlers/GuildMembersChunk.js @@ -1,7 +1,7 @@ -// ##untested## - const AbstractHandler = require('./AbstractHandler'); const Constants = require('../../../../util/Constants'); +// uncomment in v12 +// const Collection = require('../../../../util/Collection'); class GuildMembersChunkHandler extends AbstractHandler { handle(packet) { @@ -10,9 +10,13 @@ class GuildMembersChunkHandler extends AbstractHandler { const guild = client.guilds.get(data.guild_id); if (!guild) return; + // uncomment in v12 + // const members = new Collection(); + // + // for (const member of data.members) members.set(member.id, guild._addMember(member, false)); + const members = data.members.map(member => guild._addMember(member, false)); - guild._checkChunks(); client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members); client.ws.lastHeartbeatAck = true; @@ -22,7 +26,7 @@ class GuildMembersChunkHandler extends AbstractHandler { /** * Emitted whenever a chunk of guild members is received (all members come from the same guild) * @event Client#guildMembersChunk - * @param {GuildMember[]} members The members in the chunk + * @param {Collection} members The members in the chunk */ module.exports = GuildMembersChunkHandler; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 2a9c3d90d..457593cc9 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -337,7 +337,6 @@ class Guild { * @returns {Promise} */ fetchMember(user, cache = true) { - if (this._fetchWaiter) return Promise.reject(new Error('Already fetching guild members.')); user = this.client.resolver.resolveUser(user); if (!user) return Promise.reject(new Error('User is not cached. Use Client.fetchUser first.')); if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id)); @@ -347,17 +346,17 @@ class Guild { /** * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members, * this should not be necessary. - * @param {string} [query=''] An optional query to provide when fetching members + * @param {string} [query=''] Limit fetch to members with similar usernames * @returns {Promise} */ fetchMembers(query = '') { return new Promise((resolve, reject) => { - if (this._fetchWaiter) throw new Error(`Already fetching guild members in ${this.id}.`); if (this.memberCount === this.members.size) { + // uncomment in v12 + // resolve(this.members) resolve(this); return; } - this._fetchWaiter = resolve; this.client.ws.send({ op: Constants.OPCodes.REQUEST_GUILD_MEMBERS, d: { @@ -366,7 +365,17 @@ class Guild { limit: 0, }, }); - this._checkChunks(); + const handler = (members, guild) => { + if (guild.id !== this.id) return; + if (this.memberCount === this.members.size) { + this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler); + // uncomment in v12 + // resolve(this.members) + resolve(this); + return; + } + }; + this.client.on(Constants.Events.GUILD_MEMBERS_CHUNK, handler); this.client.setTimeout(() => reject(new Error('Members didn\'t arrive in time.')), 120 * 1000); }); } @@ -812,7 +821,6 @@ class Guild { this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member); } - this._checkChunks(); return member; } @@ -842,7 +850,6 @@ class Guild { _removeMember(guildMember) { this.members.delete(guildMember.id); - this._checkChunks(); } _memberSpeakUpdate(user, speaking) { @@ -866,15 +873,6 @@ class Guild { } this.presences.set(id, new Presence(presence)); } - - _checkChunks() { - if (this._fetchWaiter) { - if (this.members.size === this.memberCount) { - this._fetchWaiter(this); - this._fetchWaiter = null; - } - } - } } module.exports = Guild; From c73e501243162cf46cdedb48ab087886619b1bee Mon Sep 17 00:00:00 2001 From: Programmix Date: Sat, 21 Jan 2017 16:48:17 -0800 Subject: [PATCH 06/30] Fix RESTMethods.removeMessageReaction (fixes #1114) (#1126) --- src/client/rest/RESTMethods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index da1f2142b..b6983e338 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -694,7 +694,7 @@ class RESTMethods { removeMessageReaction(message, emoji, user) { let endpoint = Constants.Endpoints.selfMessageReaction(message.channel.id, message.id, emoji); if (user !== this.client.user.id) { - endpoint = Constants.Endpoints.userMessageReaction(message.channel.id, message.id, emoji, null, user.id); + endpoint = Constants.Endpoints.userMessageReaction(message.channel.id, message.id, emoji, null, user); } return this.rest.makeRequest('delete', endpoint, true).then(() => this.client.actions.MessageReactionRemove.handle({ From 4b2053133de837677bd00b58cf0bc1d15f826abb Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Tue, 24 Jan 2017 15:53:26 -0600 Subject: [PATCH 07/30] more profile stuff (#1131) --- src/structures/UserProfile.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/structures/UserProfile.js b/src/structures/UserProfile.js index 77f097ca9..66a6c1616 100644 --- a/src/structures/UserProfile.js +++ b/src/structures/UserProfile.js @@ -42,6 +42,12 @@ class UserProfile { */ this.premium = data.premium; + /** + * The date since which the user has had Discord Premium + * @type {?Date} + */ + this.premiumSince = data.premium_since ? new Date(data.premium_since) : null; + for (const guild of data.mutual_guilds) { if (this.client.guilds.has(guild.id)) { this.mutualGuilds.set(guild.id, this.client.guilds.get(guild.id)); From c1a5bee61f1df2192c1bc9ac2fe59c11d3c3156a Mon Sep 17 00:00:00 2001 From: Programmix Date: Tue, 24 Jan 2017 13:55:36 -0800 Subject: [PATCH 08/30] GuildMembersChunk packet handler hotfix (#1125) * GuildMembersChunk packet handler hotfix * Add limit, resolve properly if a query is used * Document new GuildMemberChunk param --- src/client/websocket/packets/handlers/GuildMembersChunk.js | 3 ++- src/structures/Guild.js | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/client/websocket/packets/handlers/GuildMembersChunk.js b/src/client/websocket/packets/handlers/GuildMembersChunk.js index e67c1d425..bee51571a 100644 --- a/src/client/websocket/packets/handlers/GuildMembersChunk.js +++ b/src/client/websocket/packets/handlers/GuildMembersChunk.js @@ -17,7 +17,7 @@ class GuildMembersChunkHandler extends AbstractHandler { const members = data.members.map(member => guild._addMember(member, false)); - client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members); + client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members, guild); client.ws.lastHeartbeatAck = true; } @@ -27,6 +27,7 @@ class GuildMembersChunkHandler extends AbstractHandler { * Emitted whenever a chunk of guild members is received (all members come from the same guild) * @event Client#guildMembersChunk * @param {Collection} members The members in the chunk + * @param {Guild} guild The guild related to the member chunk */ module.exports = GuildMembersChunkHandler; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 457593cc9..643a30ac9 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -347,9 +347,10 @@ class Guild { * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members, * this should not be necessary. * @param {string} [query=''] Limit fetch to members with similar usernames + * @param {number} [limit=0] Maximum number of members to request * @returns {Promise} */ - fetchMembers(query = '') { + fetchMembers(query = '', limit = 0) { return new Promise((resolve, reject) => { if (this.memberCount === this.members.size) { // uncomment in v12 @@ -362,12 +363,12 @@ class Guild { d: { guild_id: this.id, query, - limit: 0, + limit, }, }); const handler = (members, guild) => { if (guild.id !== this.id) return; - if (this.memberCount === this.members.size) { + if (this.memberCount === this.members.size || members.length < 1000) { this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler); // uncomment in v12 // resolve(this.members) From 5173583e26358b2336edd1551f0c2cf936fec88a Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 24 Jan 2017 22:55:59 +0100 Subject: [PATCH 09/30] Fix empty search query parameters (#1119) The search function was sending request to stuff like: search?author_id=&content=&channel_id=135823828352838352 --- src/client/rest/RESTMethods.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index b6983e338..bc683a51a 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -165,8 +165,9 @@ class RESTMethods { search(target, options) { options = transformSearchOptions(options, this.client); + for (const key in options) if (options[key] === undefined) delete options[key]; - const queryString = querystring.stringify(options); + const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&'); let type; if (target instanceof Channel) { From ba7c2db36436a31fb08e50cb3fa3f05ae460fa93 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 24 Jan 2017 16:56:19 -0500 Subject: [PATCH 10/30] Fix createEmoji/deleteEmoji action name. (#1110) --- src/client/rest/RESTMethods.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index bc683a51a..fb4987299 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -561,12 +561,12 @@ class RESTMethods { createEmoji(guild, image, name) { return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, { name, image }) - .then(data => this.client.actions.EmojiCreate.handle(data, guild).emoji); + .then(data => this.client.actions.GuildEmojiCreate.handle(data, guild).emoji); } deleteEmoji(emoji) { return this.rest.makeRequest('delete', `${Constants.Endpoints.guildEmojis(emoji.guild.id)}/${emoji.id}`, true) - .then(() => this.client.actions.EmojiDelete.handle(emoji).data); + .then(() => this.client.actions.GuildEmojiDelete.handle(emoji).data); } getWebhook(id, token) { From ba11f762842cf60f0ccaf09af31c7cf7cc9d3376 Mon Sep 17 00:00:00 2001 From: Programmix Date: Thu, 26 Jan 2017 13:20:40 -0800 Subject: [PATCH 11/30] Fix patching message reactions (fixes #1071) (#1137) --- src/structures/Message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/Message.js b/src/structures/Message.js index 45e7d7efe..be352b730 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -232,7 +232,7 @@ class Message { if (data.reactions.length > 0) { for (const reaction of data.reactions) { const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; - this.reactions.set(id, new MessageReaction(this, data.emoji, data.count, data.me)); + this.reactions.set(id, new MessageReaction(this, reaction.emoji, reaction.count, reaction.me)); } } } From 87b600f78ff12ca6936d94a90ff0c0acc32964ab Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Thu, 26 Jan 2017 15:21:43 -0600 Subject: [PATCH 12/30] switch to os shim for safety (#1136) * switch to os shim for safety * Update Client.js --- src/client/Client.js | 3 ++- src/client/websocket/WebSocketManager.js | 2 +- src/index.js | 2 +- src/util/Constants.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index e04db3899..48589813a 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -1,3 +1,4 @@ +const os = require('os'); const EventEmitter = require('events').EventEmitter; const mergeDefault = require('../util/MergeDefault'); const Constants = require('../util/Constants'); @@ -216,7 +217,7 @@ class Client extends EventEmitter { * @readonly */ get browser() { - return typeof window !== 'undefined'; + return os.platform() === 'browser'; } /** diff --git a/src/client/websocket/WebSocketManager.js b/src/client/websocket/WebSocketManager.js index 89136d276..da4d812bc 100644 --- a/src/client/websocket/WebSocketManager.js +++ b/src/client/websocket/WebSocketManager.js @@ -1,4 +1,4 @@ -const browser = typeof window !== 'undefined'; +const browser = require('os').platform() === 'browser'; const EventEmitter = require('events').EventEmitter; const Constants = require('../../util/Constants'); const convertArrayBuffer = require('../../util/ConvertArrayBuffer'); diff --git a/src/index.js b/src/index.js index d6cdffc97..163819de7 100644 --- a/src/index.js +++ b/src/index.js @@ -46,4 +46,4 @@ module.exports = { Constants: require('./util/Constants'), }; -if (typeof window !== 'undefined') window.Discord = module.exports; // eslint-disable-line no-undef +if (require('os').platform() === 'browser') window.Discord = module.exports; // eslint-disable-line no-undef diff --git a/src/util/Constants.js b/src/util/Constants.js index 3bfc67520..48f1cfec9 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -51,7 +51,7 @@ exports.DefaultOptions = { */ ws: { large_threshold: 250, - compress: typeof window === 'undefined', + compress: require('os').platform() !== 'browser', properties: { $os: process ? process.platform : 'discord.js', $browser: 'discord.js', From c7f5b44e03da0ef9ae1909c03d2a7d1dc576f8ad Mon Sep 17 00:00:00 2001 From: Pg Biel Date: Thu, 26 Jan 2017 19:24:08 -0200 Subject: [PATCH 13/30] Add User.lastMessage, GuildMember.lastMessage and TextBasedChannel.lastMessage (#1135) * Add User.lastMessage * User.lastMessage and GuildMember.lastMessage * User, GuildMember and TextBasedChannel lastMessage * Update MessageCreate.js --- src/client/actions/MessageCreate.js | 25 ++++++++++++++++---- src/structures/GuildMember.js | 6 +++++ src/structures/User.js | 6 +++++ src/structures/interface/TextBasedChannel.js | 6 +++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/client/actions/MessageCreate.js b/src/client/actions/MessageCreate.js index 00fc1e93d..542d5459d 100644 --- a/src/client/actions/MessageCreate.js +++ b/src/client/actions/MessageCreate.js @@ -14,17 +14,32 @@ class MessageCreateAction extends Action { for (let i = 0; i < data.length; i++) { messages[i] = channel._cacheMessage(new Message(channel, data[i], client)); } - channel.lastMessageID = messages[messages.length - 1].id; - if (user) user.lastMessageID = messages[messages.length - 1].id; - if (member) member.lastMessageID = messages[messages.length - 1].id; + const lastMessage = messages[messages.length - 1]; + channel.lastMessageID = lastMessage.id; + channel.lastMessage = lastMessage; + if (user) { + user.lastMessageID = lastMessage.id; + user.lastMessage = lastMessage; + } + if (member) { + member.lastMessageID = lastMessage.id; + member.lastMessage = lastMessage; + } return { messages, }; } else { const message = channel._cacheMessage(new Message(channel, data, client)); channel.lastMessageID = data.id; - if (user) user.lastMessageID = data.id; - if (member) member.lastMessageID = data.id; + channel.lastMessage = message; + if (user) { + user.lastMessageID = data.id; + user.lastMessage = message; + } + if (member) { + member.lastMessageID = data.id; + member.lastMessage = message; + } return { message, }; diff --git a/src/structures/GuildMember.js b/src/structures/GuildMember.js index c3cb86cdb..af3c5be30 100644 --- a/src/structures/GuildMember.js +++ b/src/structures/GuildMember.js @@ -39,6 +39,12 @@ class GuildMember { * @type {?Snowflake} */ this.lastMessageID = null; + + /** + * The Message object of the last message sent by the member in their guild, if one was sent. + * @type {?Message} + */ + this.lastMessage = null; } setup(data) { diff --git a/src/structures/User.js b/src/structures/User.js index 6beb3f352..94dbd4883 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -55,6 +55,12 @@ class User { * @type {?Snowflake} */ this.lastMessageID = null; + + /** + * The Message object of the last message sent by the user, if one was sent. + * @type {?Message} + */ + this.lastMessage = null; } patch(data) { diff --git a/src/structures/interface/TextBasedChannel.js b/src/structures/interface/TextBasedChannel.js index 6eabec25d..662ee1351 100644 --- a/src/structures/interface/TextBasedChannel.js +++ b/src/structures/interface/TextBasedChannel.js @@ -20,6 +20,12 @@ class TextBasedChannel { * @type {?Snowflake} */ this.lastMessageID = null; + + /** + * The Message object of the last message in the channel, if one was sent. + * @type {?Message} + */ + this.lastMessage = null; } /** From 2beb77ab5c89664a674802b47cd123b8a5c363af Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Sat, 28 Jan 2017 04:07:53 -0600 Subject: [PATCH 14/30] check if a guildchannel is deletable (#1143) * Update GuildChannel.js * eghhh * Update GuildChannel.js --- src/structures/GuildChannel.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index ef5687c43..7b26adf58 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -281,6 +281,16 @@ class GuildChannel extends Channel { return equal; } + /** + * Whether the channel is deletable by the client user. + * @type {boolean} + * @readonly + */ + get deletable() { + return this.id !== this.guild.id && + this.permissionsFor(this.client.user).hasPermission(Constants.PermissionFlags.MANAGE_CHANNELS); + } + /** * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. * @returns {string} From 448c93615b45acb521305f210c1a5c2c5f04ee08 Mon Sep 17 00:00:00 2001 From: Digitroinc Date: Sun, 29 Jan 2017 13:58:35 -0500 Subject: [PATCH 15/30] fix splitting messages #1148) * fix for issue #1120 * build fix --- src/client/rest/RESTMethods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index fb4987299..96920e035 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -97,7 +97,7 @@ class RESTMethods { const options = index === list.length ? { tts, embed } : { tts }; chan.send(list[index], options, index === list.length ? file : null).then((message) => { messages.push(message); - if (index >= list.length) return resolve(messages); + if (index >= list.length - 1) return resolve(messages); return sendChunk(list, ++index); }); }(content, 0)); From 5059c59a31b7577f779175ee788108a9b32ec48d Mon Sep 17 00:00:00 2001 From: Programmix Date: Sun, 29 Jan 2017 11:02:54 -0800 Subject: [PATCH 16/30] Message patching: clear mention collections (#1138) * Message patching: clear mention collections Fixes #1089 When discord sends an array of mentions, it is a full list of mentions -- therefore, we should clear the old mention collection. The same goes for when we re-analyze the message for channel mentions. * Use Collection.clear() instead of new Collection --- src/structures/Message.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/structures/Message.js b/src/structures/Message.js index be352b730..6f4331487 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -197,12 +197,13 @@ class Message { if (data.type === 6) this.system = true; } if (data.attachments) { - this.attachments = new Collection(); + this.attachments.clear(); for (const attachment of data.attachments) { this.attachments.set(attachment.id, new Attachment(this, attachment)); } } if (data.mentions) { + this.mentions.users.clear(); for (const mention of data.mentions) { let user = this.client.users.get(mention.id); if (user) { @@ -214,6 +215,7 @@ class Message { } } if (data.mention_roles) { + this.mentions.roles.clear(); for (const mention of data.mention_roles) { const role = this.channel.guild.roles.get(mention); if (role) this.mentions.roles.set(role.id, role); @@ -221,6 +223,7 @@ class Message { } if (data.id) this.id = data.id; if (this.channel.guild && data.content) { + this.mentions.channels.clear(); const channMentionsRaw = data.content.match(/<#([0-9]{14,20})>/g) || []; for (const raw of channMentionsRaw) { const chan = this.channel.guild.channels.get(raw.match(/([0-9]{14,20})/g)[0]); @@ -228,7 +231,7 @@ class Message { } } if (data.reactions) { - this.reactions = new Collection(); + this.reactions.clear(); if (data.reactions.length > 0) { for (const reaction of data.reactions) { const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; From 8ee0acf44c052c08926437a92cff0de2aa283f2d Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Sun, 29 Jan 2017 13:10:25 -0600 Subject: [PATCH 17/30] make d.js great again (#1149) get out, donald * AGHHH * FUHFUHFUHFUHUFHUHF --- README.md | 2 +- docs/general/welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0408d3b9f..faf48bd90 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ discord.js is a powerful node.js module that allows you to interact with the - Object-oriented - Predictable abstractions - Performant -- Nearly 100% coverage of the Discord API +- 100% coverage of the Discord API ## Installation **Node.js 6.0.0 or newer is required.** diff --git a/docs/general/welcome.md b/docs/general/welcome.md index c7791f3da..5fb960c04 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -27,7 +27,7 @@ discord.js is a powerful node.js module that allows you to interact with the - Object-oriented - Predictable abstractions - Performant -- Nearly 100% coverage of the Discord API +- 100% coverage of the Discord API ## Installation **Node.js 6.0.0 or newer is required.** From e9ab9c9f92c5793d5613240c180bf23ab64f4ad0 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Mon, 30 Jan 2017 20:21:53 -0500 Subject: [PATCH 18/30] Improve scripts --- deploy/deploy.sh | 2 +- package.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/deploy/deploy.sh b/deploy/deploy.sh index c59d0b09c..c132a20f6 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -5,7 +5,7 @@ set -e function tests { npm run lint - npm run test-docs + npm run docs:test VERSIONED=false npm run webpack exit 0 } diff --git a/package.json b/package.json index 63ba4b0b6..2354ba925 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,11 @@ "main": "./src/index", "types": "./typings/index.d.ts", "scripts": { - "test": "eslint src && docgen --source src --custom docs/index.yml", + "test": "npm run lint && npm run docs:test", "docs": "docgen --source src --custom docs/index.yml --output docs/docs.json", - "test-docs": "docgen --source src --custom docs/index.yml", + "docs:test": "docgen --source src --custom docs/index.yml", "lint": "eslint src", + "lint:fix": "eslint --fix src", "webpack": "parallel-webpack" }, "repository": { From 2e1310ae72ea1befc4c9bc915689c8a3370f9ab2 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Mon, 30 Jan 2017 21:23:06 -0500 Subject: [PATCH 19/30] Add web build docs, many other minor doc changes --- CONTRIBUTING.md | 2 +- README.md | 14 +++---------- docs/examples/avatars.js | 8 ++++---- docs/examples/ping.js | 10 +++++----- docs/general/welcome.md | 43 ++++++++++++++++++++++++++-------------- docs/index.yml | 4 ++++ docs/topics/web.md | 38 +++++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 docs/topics/web.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 361069497..102f1171f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing If you wish to contribute to the discord.js codebase or documentation, feel free to fork the repository and submit a pull request. We use ESLint to enforce a consistent coding style, so having that set up in your editor of choice -is a great boon to your coding process. +is a great boon to your development process. ## Setup To get ready to work on the codebase, please do the following: diff --git a/README.md b/README.md index faf48bd90..5ac91d608 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ discord.js is a powerful node.js module that allows you to interact with the ## Installation **Node.js 6.0.0 or newer is required.** -Ignore any warnings about unmet peer dependencies - all peer dependencies are optional. +Ignore any warnings about unmet peer dependencies, as they're are optional. Without voice support: `npm install discord.js --save` With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus --save` @@ -62,19 +62,11 @@ client.login('your token'); A bot template using discord.js can be generated using [generator-discordbot](https://www.npmjs.com/package/generator-discordbot). -## Web distributions -Web builds of discord.js that are fully capable of running in browsers are available [here](https://github.com/hydrabolt/discord.js/tree/webpack). -These are built using [Webpack 2](https://webpack.js.org/). The API is identical, but rather than using `require('discord.js')`, -the entire `Discord` object is available as a global (on the `window` object). -The ShardingManager and any voice-related functionality is unavailable in these builds. - ## Links -* [Website](https://discord.js.org/) +* [Website](https://discord.js.org/) ([source](https://github.com/hydrabolt/discord.js-site)) +* [Documentation](https://discord.js.org/#/docs) * [Discord.js server](https://discord.gg/bRCvFy9) * [Discord API server](https://discord.gg/rV4BwdK) -* [Documentation](https://discord.js.org/#/docs) -* [Legacy (v8) documentation](http://discordjs.readthedocs.io/en/8.2.0/docs_client.html) -* [Examples](https://github.com/hydrabolt/discord.js/tree/master/docs/examples) * [GitHub](https://github.com/hydrabolt/discord.js) * [NPM](https://www.npmjs.com/package/discord.js) * [Related libraries](https://discordapi.com/unofficial/libs.html) (see also [discord-rpc](https://www.npmjs.com/package/discord-rpc)) diff --git a/docs/examples/avatars.js b/docs/examples/avatars.js index 796d942bd..81375c5f4 100644 --- a/docs/examples/avatars.js +++ b/docs/examples/avatars.js @@ -6,19 +6,19 @@ const Discord = require('discord.js'); // create an instance of a Discord Client, and call it bot -const bot = new Discord.Client(); +const client = new Discord.Client(); // the token of your bot - https://discordapp.com/developers/applications/me const token = 'your bot token here'; // the ready event is vital, it means that your bot will only start reacting to information // from Discord _after_ ready is emitted. -bot.on('ready', () => { +client.on('ready', () => { console.log('I am ready!'); }); // create an event listener for messages -bot.on('message', message => { +client.on('message', message => { // if the message is "what is my avatar", if (message.content === 'what is my avatar') { // send the user's avatar URL @@ -27,4 +27,4 @@ bot.on('message', message => { }); // log our bot in -bot.login(token); +client.login(token); diff --git a/docs/examples/ping.js b/docs/examples/ping.js index 4cede6a80..be2611847 100644 --- a/docs/examples/ping.js +++ b/docs/examples/ping.js @@ -5,20 +5,20 @@ // import the discord.js module const Discord = require('discord.js'); -// create an instance of a Discord Client, and call it bot -const bot = new Discord.Client(); +// create an instance of a Discord Client +const client = new Discord.Client(); // the token of your bot - https://discordapp.com/developers/applications/me const token = 'your bot token here'; // the ready event is vital, it means that your bot will only start reacting to information // from Discord _after_ ready is emitted. -bot.on('ready', () => { +client.on('ready', () => { console.log('I am ready!'); }); // create an event listener for messages -bot.on('message', message => { +client.on('message', message => { // if the message is "ping", if (message.content === 'ping') { // send "pong" to the same channel. @@ -27,4 +27,4 @@ bot.on('message', message => { }); // log our bot in -bot.login(token); +client.login(token); diff --git a/docs/general/welcome.md b/docs/general/welcome.md index 5fb960c04..ff4528428 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -31,7 +31,7 @@ discord.js is a powerful node.js module that allows you to interact with the ## Installation **Node.js 6.0.0 or newer is required.** -Ignore any warnings about unmet peer dependencies - all of them are optional. +Ignore any warnings about unmet peer dependencies, as they're are optional. Without voice support: `npm install discord.js --save` With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus --save` @@ -43,29 +43,42 @@ Using opusscript is only recommended for development environments where node-opu For production bots, using node-opus should be considered a necessity, especially if they're going to be running on multiple servers. ### Optional packages -- [uws](https://www.npmjs.com/package/uws) for much a much faster WebSocket connection (`npm install uws --save`) +- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws --save`) - [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack --save`) -## Web distributions -Web builds of discord.js that are fully capable of running in browsers are available [here](https://github.com/hydrabolt/discord.js/tree/webpack). -These are built by [Webpack 2](https://webpack.js.org/). The API is identical, but rather than using `require('discord.js')`, -the entire `Discord` object is available as a global (on the `window` object). -The ShardingManager and any voice-related functionality is unavailable in these builds. +## Example Usage +```js +const Discord = require('discord.js'); +const client = new Discord.Client(); -## Guides -* [LuckyEvie's general guide](https://eslachance.gitbooks.io/discord-js-bot-guide/content/) -* [York's v9 upgrade guide](https://yorkaargh.wordpress.com/2016/09/03/updating-discord-js-bots/) +client.on('ready', () => { + console.log('I am ready!'); +}); + +client.on('message', message => { + if (message.content === 'ping') { + message.reply('pong'); + } +}); + +client.login('your token'); +``` + +A bot template using discord.js can be generated using [generator-discordbot](https://www.npmjs.com/package/generator-discordbot). ## Links -* [Website](https://discord.js.org/) +* [Website](https://discord.js.org/) ([source](https://github.com/hydrabolt/discord.js-site)) +* [Documentation](https://discord.js.org/#/docs) * [Discord.js server](https://discord.gg/bRCvFy9) * [Discord API server](https://discord.gg/rV4BwdK) -* [Documentation](https://discord.js.org/#/docs) -* [Legacy (v8) documentation](http://discordjs.readthedocs.io/en/8.2.0/docs_client.html) -* [Examples](https://github.com/hydrabolt/discord.js/tree/master/docs/examples) * [GitHub](https://github.com/hydrabolt/discord.js) * [NPM](https://www.npmjs.com/package/discord.js) -* [Related libraries](https://discordapi.com/unofficial/libs.html) +* [Related libraries](https://discordapi.com/unofficial/libs.html) (see also [discord-rpc](https://www.npmjs.com/package/discord-rpc)) + +## Contributing +Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the +[documentation](https://discord.js.org/#/docs). +See [the contribution guide](CONTRIBUTING.md) if you'd like to submit a PR. ## Help If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle diff --git a/docs/index.yml b/docs/index.yml index 4bf13c7e3..94444f298 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -6,6 +6,10 @@ path: updating.md - name: FAQ path: faq.md +- name: Topics + files: + - name: Web builds + path: web.md - name: Examples files: - name: Ping diff --git a/docs/topics/web.md b/docs/topics/web.md new file mode 100644 index 000000000..dde94ad17 --- /dev/null +++ b/docs/topics/web.md @@ -0,0 +1,38 @@ +# Web builds +In addition to your usual Node applications, discord.js has special distributions available that are capable of running in web browsers. +This is useful for client-side web apps that need to interact with the Discord API. +[Webpack 2](https://webpack.js.org/) is used to generate these builds + +## Usage +You can obtain your desired version of discord.js' web build from the [webpack branch](https://github.com/hydrabolt/discord.js/tree/webpack) of the GitHub repository. +There is a file for each branch and version of the library, and the ones ending in `.min.js` are minified to substantially reduce the size of the source code. + +Include the file on the page just as you would any other JS library, like so: +```html + +``` + +Rather than importing discord.js with `require('discord.js')`, the entire `Discord` object is available as a global (on the `window`) object. +The usage of the API isn't any different from using it in Node.js. + +## Restrictions +- Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries, + which web browsers do not support. +- The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards. +- Neither of the optional packages (uws and erlpack) are usable, since they're native libraries. + +## Example +```html + + +``` From f73fd4ec2910c8ad3f94853f3b9fde3cdab3a65c Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Mon, 30 Jan 2017 21:27:28 -0500 Subject: [PATCH 20/30] get grammer gooder --- docs/topics/web.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/web.md b/docs/topics/web.md index dde94ad17..3e0e83837 100644 --- a/docs/topics/web.md +++ b/docs/topics/web.md @@ -1,7 +1,7 @@ # Web builds In addition to your usual Node applications, discord.js has special distributions available that are capable of running in web browsers. This is useful for client-side web apps that need to interact with the Discord API. -[Webpack 2](https://webpack.js.org/) is used to generate these builds +[Webpack 2](https://webpack.js.org/) is used to build these. ## Usage You can obtain your desired version of discord.js' web build from the [webpack branch](https://github.com/hydrabolt/discord.js/tree/webpack) of the GitHub repository. From 94483ae1940f3b5cdf4c988915ce11631c2c258b Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Mon, 30 Jan 2017 21:52:41 -0500 Subject: [PATCH 21/30] GOODER --- README.md | 2 +- docs/general/welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5ac91d608..e2378afab 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ discord.js is a powerful node.js module that allows you to interact with the ## Installation **Node.js 6.0.0 or newer is required.** -Ignore any warnings about unmet peer dependencies, as they're are optional. +Ignore any warnings about unmet peer dependencies, as they're optional. Without voice support: `npm install discord.js --save` With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus --save` diff --git a/docs/general/welcome.md b/docs/general/welcome.md index ff4528428..d78672a6c 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -31,7 +31,7 @@ discord.js is a powerful node.js module that allows you to interact with the ## Installation **Node.js 6.0.0 or newer is required.** -Ignore any warnings about unmet peer dependencies, as they're are optional. +Ignore any warnings about unmet peer dependencies, as they're optional. Without voice support: `npm install discord.js --save` With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus --save` From 18729b25c7c52f6d35b28c0cb5e74c38dc66e030 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 30 Jan 2017 22:47:05 -0500 Subject: [PATCH 22/30] Add support to edit emojis (#1142) * Add support to edit emojis * Fixes for coding style. * Add and use guildEmoji constants for updateEmoji * Just use the Constant * Fix typo in edit documentation * Specify property types * Fix ridiculous typo. * Update Emoji.js --- src/client/ClientDataManager.js | 1 + src/client/actions/GuildEmojiUpdate.js | 5 ++++- src/client/rest/RESTMethods.js | 8 ++++++++ src/structures/Emoji.js | 21 +++++++++++++++++++++ src/util/Constants.js | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/client/ClientDataManager.js b/src/client/ClientDataManager.js index 32b442b73..e663e107e 100644 --- a/src/client/ClientDataManager.js +++ b/src/client/ClientDataManager.js @@ -123,6 +123,7 @@ class ClientDataManager { const oldEmoji = cloneObject(currentEmoji); currentEmoji.setup(newData); this.client.emit(Constants.Events.GUILD_EMOJI_UPDATE, oldEmoji, currentEmoji); + return currentEmoji; } } diff --git a/src/client/actions/GuildEmojiUpdate.js b/src/client/actions/GuildEmojiUpdate.js index 94bfa24d9..593e54b2d 100644 --- a/src/client/actions/GuildEmojiUpdate.js +++ b/src/client/actions/GuildEmojiUpdate.js @@ -2,7 +2,10 @@ const Action = require('./Action'); class GuildEmojiUpdateAction extends Action { handle(oldEmoji, newEmoji) { - this.client.dataManager.updateEmoji(oldEmoji, newEmoji); + const emoji = this.client.dataManager.updateEmoji(oldEmoji, newEmoji); + return { + emoji, + }; } } diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 96920e035..4e65257ab 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -564,6 +564,14 @@ class RESTMethods { .then(data => this.client.actions.GuildEmojiCreate.handle(data, guild).emoji); } + updateEmoji(emoji, _data) { + const data = {}; + if (_data.name) data.name = _data.name; + if (_data.roles) data.roles = _data.roles.map(r => r.id ? r.id : r); + return this.rest.makeRequest('patch', Constants.Endpoints.guildEmoji(emoji.guild.id, emoji.id), true, data) + .then(newEmoji => this.client.actions.GuildEmojiUpdate.handle(emoji, newEmoji).emoji); + } + deleteEmoji(emoji) { return this.rest.makeRequest('delete', `${Constants.Endpoints.guildEmojis(emoji.guild.id)}/${emoji.id}`, true) .then(() => this.client.actions.GuildEmojiDelete.handle(emoji).data); diff --git a/src/structures/Emoji.js b/src/structures/Emoji.js index 519092c28..b860e25c6 100644 --- a/src/structures/Emoji.js +++ b/src/structures/Emoji.js @@ -101,6 +101,27 @@ class Emoji { return encodeURIComponent(this.name); } + /** + * Data for editing an emoji + * @typedef {Object} EmojiEditData + * @property {string} [name] The name of the emoji + * @property {Collection|Array} [roles] Roles to restrict emoji to + */ + + /** + * Edits the emoji + * @param {EmojiEditData} data The new data for the emoji + * @returns {Promise} + * @example + * // edit a emoji + * emoji.edit({name: 'newemoji'}) + * .then(e => console.log(`Edited emoji ${e}`)) + * .catch(console.error); + */ + edit(data) { + return this.client.rest.methods.updateEmoji(this, data); + } + /** * When concatenated with a string, this automatically returns the emoji mention rather than the object. * @returns {string} diff --git a/src/util/Constants.js b/src/util/Constants.js index 48f1cfec9..130ede43f 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -125,6 +125,7 @@ const Endpoints = exports.Endpoints = { guildMemberNickname: (guildID) => `${Endpoints.guildMember(guildID, '@me')}/nick`, guildChannels: (guildID) => `${Endpoints.guild(guildID)}/channels`, guildEmojis: (guildID) => `${Endpoints.guild(guildID)}/emojis`, + guildEmoji: (guildID, emojiID) => `${Endpoints.guildEmojis(guildID)}/${emojiID}`, guildSearch: (guildID) => `${Endpoints.guild(guildID)}/messages/search`, guildVoiceRegions: (guildID) => `${Endpoints.guild(guildID)}/regions`, From 565c640bc6cfda9e814b598c4d57be4cc90dcdf6 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Mon, 30 Jan 2017 21:47:27 -0600 Subject: [PATCH 23/30] Add role support to emoji creation (#1141) * add role support to emojis * specify types --- src/client/rest/RESTMethods.js | 8 +++++--- src/structures/Guild.js | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 4e65257ab..1815f7357 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -559,9 +559,11 @@ class RESTMethods { .then(data => data.pruned); } - createEmoji(guild, image, name) { - return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, { name, image }) - .then(data => this.client.actions.GuildEmojiCreate.handle(data, guild).emoji); + createEmoji(guild, image, name, roles) { + const data = { image, name }; + if (roles) data.roles = roles.map(r => r.id ? r.id : r); + return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, data) + .then(emoji => this.client.actions.GuildEmojiCreate.handle(emoji, guild).emoji); } updateEmoji(emoji, _data) { diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 643a30ac9..2c4c93b22 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -682,6 +682,7 @@ class Guild { * Creates a new custom emoji in the guild. * @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji. * @param {string} name The name for the emoji. + * @param {Collection|Role[]} [roles] Roles to limit the emoji to * @returns {Promise} The created emoji. * @example * // create a new emoji from a url @@ -694,13 +695,13 @@ class Guild { * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) * .catch(console.error); */ - createEmoji(attachment, name) { + createEmoji(attachment, name, roles) { return new Promise(resolve => { if (typeof attachment === 'string' && attachment.startsWith('data:')) { - resolve(this.client.rest.methods.createEmoji(this, attachment, name)); + resolve(this.client.rest.methods.createEmoji(this, attachment, name, roles)); } else { this.client.resolver.resolveBuffer(attachment).then(data => - resolve(this.client.rest.methods.createEmoji(this, data, name)) + resolve(this.client.rest.methods.createEmoji(this, data, name, roles)) ); } }); From f4724d61b2833f43fc3b8dc82c47ae230e005c53 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Mon, 30 Jan 2017 22:54:33 -0500 Subject: [PATCH 24/30] Fix #1095 --- src/client/websocket/WebSocketManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/websocket/WebSocketManager.js b/src/client/websocket/WebSocketManager.js index da4d812bc..1770430fb 100644 --- a/src/client/websocket/WebSocketManager.js +++ b/src/client/websocket/WebSocketManager.js @@ -155,7 +155,7 @@ class WebSocketManager extends EventEmitter { } destroy() { - this.ws.close(1000); + if (this.ws) this.ws.close(1000); this._queue = []; this.status = Constants.Status.IDLE; } From 8da915f6a1190624de45d746d842124dfca8c5bc Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Mon, 30 Jan 2017 21:56:14 -0600 Subject: [PATCH 25/30] expose createDM (#1151) * expose createDM * Update User.js * in v12 we are removing these, kay? * Update GuildMember.js * Update User.js --- src/structures/GuildMember.js | 10 +++++++++- src/structures/User.js | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/structures/GuildMember.js b/src/structures/GuildMember.js index af3c5be30..79dd91fc7 100644 --- a/src/structures/GuildMember.js +++ b/src/structures/GuildMember.js @@ -395,12 +395,20 @@ class GuildMember { return this.edit({ nick }); } + /** + * Creates a DM channel between the client and the member + * @returns {Promise} + */ + createDM() { + return this.user.createDM(); + } + /** * Deletes any DMs with this guild member * @returns {Promise} */ deleteDM() { - return this.client.rest.methods.deleteChannel(this); + return this.user.deleteDM(); } /** diff --git a/src/structures/User.js b/src/structures/User.js index 94dbd4883..939d3f157 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -179,6 +179,14 @@ class User { return this.client.channels.filter(c => c.type === 'dm').find(c => c.recipient.id === this.id); } + /** + * Creates a DM channel between the client and the user + * @returns {Promise} + */ + createDM() { + return this.client.rest.methods.createDM(this); + } + /** * Deletes a DM channel (if one exists) between the client and the user. Resolves with the channel if successful. * @returns {Promise} From ed42d7bd85392e5273aee5d46d99ed4b100c83fb Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 31 Jan 2017 00:49:11 -0500 Subject: [PATCH 26/30] Fix backwards GuildEmojiCreate parameters (#1153) --- src/client/rest/RESTMethods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 1815f7357..6991b4a80 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -563,7 +563,7 @@ class RESTMethods { const data = { image, name }; if (roles) data.roles = roles.map(r => r.id ? r.id : r); return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, data) - .then(emoji => this.client.actions.GuildEmojiCreate.handle(emoji, guild).emoji); + .then(emoji => this.client.actions.GuildEmojiCreate.handle(guild, emoji).emoji); } updateEmoji(emoji, _data) { From a5b901f4ef965f082848d7ed8da6074d4aaff9ba Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Wed, 1 Feb 2017 01:52:22 -0500 Subject: [PATCH 27/30] Update ws and opusscript --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2354ba925..b19ef003b 100644 --- a/package.json +++ b/package.json @@ -37,12 +37,12 @@ "pako": "^1.0.0", "superagent": "^3.3.0", "tweetnacl": "^0.14.0", - "ws": "^1.1.1" + "ws": "^2.0.0" }, "peerDependencies": { "erlpack": "hammerandchisel/erlpack", "node-opus": "^0.2.0", - "opusscript": "^0.0.1", + "opusscript": "^0.0.2", "uws": "^0.12.0" }, "devDependencies": { From d51e45f3b926533e9f59834ffab8ae196947155c Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Wed, 1 Feb 2017 02:01:36 -0500 Subject: [PATCH 28/30] Add bufferutil info, and uws warning --- README.md | 5 ++++- docs/general/welcome.md | 5 ++++- package.json | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2378afab..4ae6a28ff 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,11 @@ Using opusscript is only recommended for development environments where node-opu For production bots, using node-opus should be considered a necessity, especially if they're going to be running on multiple servers. ### Optional packages -- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws --save`) +- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the `ws` WebSocket connection (`npm install bufferutil --save`) - [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack --save`) +- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws --save`) + **Note:** This package does not handle disconnects entirely correctly, which causes automatic reconnection to Discord to not function. + If you use this package, it may be wise to destroy + recreate the client entirely or restart the process upon disconnect. ## Example Usage ```js diff --git a/docs/general/welcome.md b/docs/general/welcome.md index d78672a6c..52e84a814 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -43,8 +43,11 @@ Using opusscript is only recommended for development environments where node-opu For production bots, using node-opus should be considered a necessity, especially if they're going to be running on multiple servers. ### Optional packages -- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws --save`) +- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the `ws` WebSocket connection (`npm install bufferutil --save`) - [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack --save`) +- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws --save`) + **Note:** This package does not handle disconnects entirely correctly, which causes automatic reconnection to Discord to not function. + If you use this package, it may be wise to destroy + recreate the client entirely or restart the process upon disconnect. ## Example Usage ```js diff --git a/package.json b/package.json index b19ef003b..0af8f452d 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "ws": "^2.0.0" }, "peerDependencies": { + "bufferutil": "^1.3.0", "erlpack": "hammerandchisel/erlpack", "node-opus": "^0.2.0", "opusscript": "^0.0.2", From c40a51195402a9968f093e088deb0ae99949e9e7 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Wed, 1 Feb 2017 02:03:42 -0500 Subject: [PATCH 29/30] Change wording slightly --- docs/topics/web.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/web.md b/docs/topics/web.md index 3e0e83837..cb8b53524 100644 --- a/docs/topics/web.md +++ b/docs/topics/web.md @@ -19,7 +19,7 @@ The usage of the API isn't any different from using it in Node.js. - Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries, which web browsers do not support. - The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards. -- Neither of the optional packages (uws and erlpack) are usable, since they're native libraries. +- None of the optional packages are usable, since they're native libraries. ## Example ```html From 187f43aebdbe107c4bfcb18a91e788af640e6fba Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Wed, 1 Feb 2017 02:06:24 -0500 Subject: [PATCH 30/30] Make a letter lowercase --- README.md | 2 +- docs/general/welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ae6a28ff..574d1366e 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ For production bots, using node-opus should be considered a necessity, especiall **Note:** This package does not handle disconnects entirely correctly, which causes automatic reconnection to Discord to not function. If you use this package, it may be wise to destroy + recreate the client entirely or restart the process upon disconnect. -## Example Usage +## Example usage ```js const Discord = require('discord.js'); const client = new Discord.Client(); diff --git a/docs/general/welcome.md b/docs/general/welcome.md index 52e84a814..fa78d5741 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -49,7 +49,7 @@ For production bots, using node-opus should be considered a necessity, especiall **Note:** This package does not handle disconnects entirely correctly, which causes automatic reconnection to Discord to not function. If you use this package, it may be wise to destroy + recreate the client entirely or restart the process upon disconnect. -## Example Usage +## Example usage ```js const Discord = require('discord.js'); const client = new Discord.Client();