diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js index 331d8ce2a..024db857c 100644 --- a/src/client/actions/ActionsManager.js +++ b/src/client/actions/ActionsManager.js @@ -23,6 +23,7 @@ class ActionsManager { this.register('GuildEmojiCreate'); this.register('GuildEmojiDelete'); this.register('GuildEmojiUpdate'); + this.register('GuildRolesPositionUpdate'); } register(name) { diff --git a/src/client/actions/GuildRolesPositionUpdate.js b/src/client/actions/GuildRolesPositionUpdate.js new file mode 100644 index 000000000..46530b596 --- /dev/null +++ b/src/client/actions/GuildRolesPositionUpdate.js @@ -0,0 +1,30 @@ +const Action = require('./Action'); + +class GuildRolesPositionUpdate extends Action { + handle(data) { + const client = this.client; + + const guild = client.guilds.get(data.guild_id); + if (guild) { + for (const partialRole of data.roles) { + const role = guild.roles.get(partialRole.id); + if (role) { + role.position = partialRole.position; + } + } + } + + return { + guild, + }; + } +} + +/** + * Emitted whenever a guild role is created. + * @event Client#guildRoleCreate + * @param {Guild} guild The guild that the role was created in. + * @param {Role} role The role that was created. + */ + +module.exports = GuildRolesPositionUpdate; diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index a2bf2800b..371647403 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -677,6 +677,19 @@ class RESTMethods { }).catch(reject); }); } + + setRolePositions(guildID, roles) { + return new Promise((resolve, reject) => { + this.rest.makeRequest('patch', Constants.Endpoints.guildRoles(guildID), true, roles) + .then(() => { + resolve(this.rest.client.actions.GuildRolesPositionUpdate.handle({ + guild_id: guildID, + roles, + }).guild); + }) + .catch(reject); + }); + } } module.exports = RESTMethods; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 7c7fcd4a9..d9c7f6ed9 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -630,6 +630,32 @@ class Guild { return this.client.rest.methods.deleteGuild(this); } + /** + * Set the position of a role in this guild + * @param {string|Role} role the role to edit, can be a role object or a role ID. + * @param {number} position the new position of the role + * @returns {Promise} + */ + setRolePosition(role, position) { + if (role instanceof Role) { + role = role.id; + } else if (typeof role !== 'string') { + return Promise.reject(new Error('Supplied role is not a role or string')); + } + + position = Number(position); + if (isNaN(position)) { + return Promise.reject(new Error('Supplied position is not a number')); + } + + const updatedRoles = this.roles.array().map(r => ({ + id: r.id, + position: r.id === role ? position : (r.position < position ? r.position : r.position + 1), + })); + + return this.client.rest.methods.setRolePositions(this.id, updatedRoles); + } + /** * Whether this Guild equals another Guild. It compares all properties, so for most operations * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often diff --git a/src/structures/Role.js b/src/structures/Role.js index f2a52ac87..4bbb6c55b 100644 --- a/src/structures/Role.js +++ b/src/structures/Role.js @@ -230,7 +230,7 @@ class Role { * .catch(console.error); */ setPosition(position) { - return this.client.rest.methods.updateGuildRole(this, { position }); + return this.guild.setRolePosition(this, position); } /** diff --git a/test/random.js b/test/random.js index 502c43456..efc8662f6 100644 --- a/test/random.js +++ b/test/random.js @@ -8,7 +8,7 @@ const client = new Discord.Client({ fetchAllMembers: false, apiRequestMethod: 's const { email, password, token, usertoken, song } = require('./auth.json'); -client.login(usertoken).then(atoken => console.log('logged in with token ' + atoken)).catch(console.error); +client.login(token).then(atoken => console.log('logged in with token ' + atoken)).catch(console.error); client.ws.on('send', console.log);