From a832b564690b1eb2b0d7dce00f129b8687d8604b Mon Sep 17 00:00:00 2001 From: Frangu Vlad Date: Wed, 24 Jan 2018 21:47:20 +0200 Subject: [PATCH] GuildEmoji: Move all role related functions to a separate store (#2271) * Prepare to work on moving all role functions to a Store And yes, this is *another* patch branch cause I messed up my master branch to hell * Move all emoji role related functions to its own store Tested everything and it works! (With a reload of the client) Also had to change a value in DataStore#holds holds.name for GuildEmojis would return the emoji name instead of the class name * New Line * Thanks JS for circular dependency! Because we can't have nice things... * Do space's request * Fix equals * Fix space's point. Raw API data has the role property as an array of IDs --- src/index.js | 1 + src/stores/GuildEmojiRoleStore.js | 110 ++++++++++++++++++++++++++++++ src/structures/GuildEmoji.js | 82 +++------------------- 3 files changed, 121 insertions(+), 72 deletions(-) create mode 100644 src/stores/GuildEmojiRoleStore.js diff --git a/src/index.js b/src/index.js index bbbb32ab3..b89d9ce56 100644 --- a/src/index.js +++ b/src/index.js @@ -28,6 +28,7 @@ module.exports = { ClientPresenceStore: require('./stores/ClientPresenceStore'), GuildChannelStore: require('./stores/GuildChannelStore'), GuildEmojiStore: require('./stores/GuildEmojiStore'), + GuildEmojiRoleStore: require('./stores/GuildEmojiRoleStore'), GuildMemberStore: require('./stores/GuildMemberStore'), GuildMemberRoleStore: require('./stores/GuildMemberRoleStore'), GuildStore: require('./stores/GuildStore'), diff --git a/src/stores/GuildEmojiRoleStore.js b/src/stores/GuildEmojiRoleStore.js new file mode 100644 index 000000000..2471fb5fe --- /dev/null +++ b/src/stores/GuildEmojiRoleStore.js @@ -0,0 +1,110 @@ +const DataStore = require('./DataStore'); +const Collection = require('../util/Collection'); +const { TypeError } = require('../errors'); + +/** + * Stores emoji roles + * @extends {DataStore} + */ +class GuildEmojiRoleStore extends DataStore { + constructor(emoji) { + super(emoji.client, null, require('../structures/GuildEmoji')); + this.emoji = emoji; + this.guild = emoji.guild; + } + + /** + * Adds a role (or multiple roles) to the list of roles that can use this emoji. + * @param {RoleResolvable|RoleResolvable[]|Collection} roleOrRoles The role or roles to add + * @returns {Promise} + */ + add(roleOrRoles) { + if (roleOrRoles instanceof Collection) return this.add(roleOrRoles.keyArray()); + if (!(roleOrRoles instanceof Array)) return this.add([roleOrRoles]); + + roleOrRoles = roleOrRoles.map(r => this.guild.roles.resolve(r)); + + if (roleOrRoles.includes(null)) { + return Promise.reject(new TypeError('INVALID_TYPE', 'roles', + 'Array or Collection of Roles or Snowflakes', true)); + } else { + for (const role of roleOrRoles) super.set(role.id, role); + } + + return this.set(this); + } + + /** + * Removes a role (or multiple roles) from the list of roles that can use this emoji. + * @param {RoleResolvable|RoleResolvable[]|Collection} roleOrRoles The role or roles to remove + * @returns {Promise} + */ + remove(roleOrRoles) { + if (roleOrRoles instanceof Collection) return this.remove(roleOrRoles.keyArray()); + if (!(roleOrRoles instanceof Array)) return this.remove([roleOrRoles]); + + roleOrRoles = roleOrRoles.map(r => this.guild.roles.resolveID(r)); + + if (roleOrRoles.includes(null)) { + return Promise.reject(new TypeError('INVALID_TYPE', 'roles', + 'Array or Collection of Roles or Snowflakes', true)); + } else { + for (const role of roleOrRoles) super.remove(role); + } + + return this.set(this); + } + + /** + * Sets the role(s) that can use this emoji. + * @param {Collection|RoleResolvable[]} roles The roles or role IDs to apply + * @returns {Promise} + * @example + * // Set the emoji's roles to a single role + * guildEmoji.roles.set(['391156570408615936']) + * .then(console.log) + * .catch(console.error); + * @example + * // Remove all roles from an emoji + * guildEmoji.roles.set([]) + * .then(console.log) + * .catch(console.error); + */ + set(roles) { + return this.emoji.edit({ roles }); + } + + /** + * Patches the roles for this store + * @param {Snowflake[]} roles The new roles + * @private + */ + _patch(roles) { + this.clear(); + + for (let role of roles) { + role = this.guild.roles.resolve(role); + if (role) super.set(role.id, role); + } + } + + /** + * Resolves a RoleResolvable to a Role object. + * @method resolve + * @memberof GuildEmojiRoleStore + * @instance + * @param {RoleResolvable} role The role resolvable to resolve + * @returns {?Role} + */ + + /** + * Resolves a RoleResolvable to a role ID string. + * @method resolveID + * @memberof GuildEmojiRoleStore + * @instance + * @param {RoleResolvable} role The role resolvable to resolve + * @returns {?Snowflake} + */ +} + +module.exports = GuildEmojiRoleStore; diff --git a/src/structures/GuildEmoji.js b/src/structures/GuildEmoji.js index 6bf63152d..df0c1169b 100644 --- a/src/structures/GuildEmoji.js +++ b/src/structures/GuildEmoji.js @@ -1,7 +1,6 @@ -const Collection = require('../util/Collection'); +const GuildEmojiRoleStore = require('../stores/GuildEmojiRoleStore'); const Snowflake = require('../util/Snowflake'); const Emoji = require('./Emoji'); -const { TypeError } = require('../errors'); /** * Represents a custom emoji. @@ -17,6 +16,12 @@ class GuildEmoji extends Emoji { */ this.guild = guild; + /** + * A collection of roles this emoji is active for (empty if all), mapped by role ID + * @type {GuildEmojiRoleStore} + */ + this.roles = new GuildEmojiRoleStore(this); + this._patch(data); } @@ -35,7 +40,7 @@ class GuildEmoji extends Emoji { */ this.managed = data.managed; - this._roles = data.roles; + if (data.roles) this.roles._patch(data.roles); } /** @@ -56,19 +61,6 @@ class GuildEmoji extends Emoji { return new Date(this.createdTimestamp); } - /** - * A collection of roles this emoji is active for (empty if all), mapped by role ID - * @type {Collection} - * @readonly - */ - get roles() { - const roles = new Collection(); - for (const role of this._roles) { - if (this.guild.roles.has(role)) roles.set(role, this.guild.roles.get(role)); - } - return roles; - } - /** * Data for editing an emoji. * @typedef {Object} GuildEmojiEditData @@ -106,60 +98,6 @@ class GuildEmoji extends Emoji { return this.edit({ name }, reason); } - /** - * Adds a role to the list of roles that can use this emoji. - * @param {Role} role The role to add - * @returns {Promise} - */ - addRestrictedRole(role) { - return this.addRestrictedRoles([role]); - } - - /** - * Adds multiple roles to the list of roles that can use this emoji. - * @param {Collection|RoleResolvable[]} roles Roles to add - * @returns {Promise} - */ - addRestrictedRoles(roles) { - const newRoles = new Collection(this.roles); - for (let role of roles instanceof Collection ? roles.values() : roles) { - role = this.guild.roles.resolve(role); - if (!role) { - return Promise.reject(new TypeError('INVALID_TYPE', 'roles', - 'Array or Collection of Roles or Snowflakes', true)); - } - newRoles.set(role.id, role); - } - return this.edit({ roles: newRoles }); - } - - /** - * Removes a role from the list of roles that can use this emoji. - * @param {Role} role The role to remove - * @returns {Promise} - */ - removeRestrictedRole(role) { - return this.removeRestrictedRoles([role]); - } - - /** - * Removes multiple roles from the list of roles that can use this emoji. - * @param {Collection|RoleResolvable[]} roles Roles to remove - * @returns {Promise} - */ - removeRestrictedRoles(roles) { - const newRoles = new Collection(this.roles); - for (let role of roles instanceof Collection ? roles.values() : roles) { - role = this.guild.roles.resolve(role); - if (!role) { - return Promise.reject(new TypeError('INVALID_TYPE', 'roles', - 'Array or Collection of Roles or Snowflakes', true)); - } - if (newRoles.has(role.id)) newRoles.delete(role.id); - } - return this.edit({ roles: newRoles }); - } - /** * Deletes the emoji. * @param {string} [reason] Reason for deleting the emoji @@ -182,13 +120,13 @@ class GuildEmoji extends Emoji { other.name === this.name && other.managed === this.managed && other.requiresColons === this.requiresColons && - other._roles === this._roles + other.roles.every(role => this.roles.has(role.id)) ); } else { return ( other.id === this.id && other.name === this.name && - other._roles === this._roles + other.roles.every(role => this.roles.has(role)) ); } }