Skip to content

Commit

Permalink
serious role position stuff (#1159)
Browse files Browse the repository at this point in the history
* serious role position stuff

* kill meh

* Update Role.js

* Update Guild.js

* Update Role.js
  • Loading branch information
devsnek authored and amishshah committed Feb 1, 2017
1 parent a2d6791 commit 1e94a9e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/client/actions/GuildRoleCreate.js
Expand Up @@ -12,6 +12,7 @@ class GuildRoleCreate extends Action {
const role = new Role(guild, data.role);
guild.roles.set(role.id, role);
if (!already) client.emit(Constants.Events.GUILD_ROLE_CREATE, role);

return {
role,
};
Expand Down
27 changes: 7 additions & 20 deletions src/structures/Guild.js
Expand Up @@ -7,6 +7,7 @@ const Constants = require('../util/Constants');
const Collection = require('../util/Collection');
const cloneObject = require('../util/CloneObject');
const arraysEqual = require('../util/ArraysEqual');
const moveElementInArray = require('../util/MoveElementInArray');

/**
* Represents a guild (or a server) on Discord.
Expand Down Expand Up @@ -643,9 +644,10 @@ class Guild {
* 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
* @param {boolean} [relative=false] Position moves the role relative to its current position
* @returns {Promise<Guild>}
*/
setRolePosition(role, position) {
setRolePosition(role, position, relative = false) {
if (typeof role === 'string') {
role = this.roles.get(role);
if (!role) return Promise.reject(new Error('Supplied role is not a role or string.'));
Expand All @@ -654,27 +656,12 @@ class Guild {
position = Number(position);
if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));

const lowestAffected = Math.min(role.position, position);
const highestAffected = Math.max(role.position, position);
let updatedRoles = Object.assign([], this.roles.array()
.sort((r1, r2) => r1.position !== r2.position ? r1.position - r2.position : r1.id - r2.id));

const rolesToUpdate = this.roles.filter(r => r.position >= lowestAffected && r.position <= highestAffected);

// stop role positions getting stupidly inflated
if (position > role.position) {
position = rolesToUpdate.first().position;
} else {
position = rolesToUpdate.last().position;
}

const updatedRoles = [];

for (const uRole of rolesToUpdate.values()) {
updatedRoles.push({
id: uRole.id,
position: uRole.id === role.id ? position : uRole.position + (position < role.position ? 1 : -1),
});
}
moveElementInArray(updatedRoles, role, position, relative);

updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));
return this.client.rest.methods.setRolePositions(this.id, updatedRoles);
}

Expand Down
17 changes: 14 additions & 3 deletions src/structures/Role.js
Expand Up @@ -48,7 +48,7 @@ class Role {
this.hoist = data.hoist;

/**
* The position of the role in the role manager
* The position of the role from the API
* @type {number}
*/
this.position = data.position;
Expand Down Expand Up @@ -122,6 +122,16 @@ class Role {
return clientMember.highestRole.comparePositionTo(this) > 0;
}

/**
* The position of the role in the role manager
* @type {number}
*/
get calculatedPosition() {
const sorted = this.guild.roles.array()
.sort((r1, r2) => r1.position !== r2.position ? r1.position - r2.position : r1.id - r2.id);
return sorted.indexOf(sorted.find(r => r.id === this.id));
}

/**
* Get an object mapping permission names to whether or not the role enables that permission
* @returns {Object<string, boolean>}
Expand Down Expand Up @@ -246,15 +256,16 @@ class Role {
/**
* Set the position of the role
* @param {number} position The position of the role
* @param {boolean} [relative=false] Move the position relative to its current value
* @returns {Promise<Role>}
* @example
* // set the position of the role
* role.setPosition(1)
* .then(r => console.log(`Role position: ${r.position}`))
* .catch(console.error);
*/
setPosition(position) {
return this.guild.setRolePosition(this, position).then(() => this);
setPosition(position, relative) {
return this.guild.setRolePosition(this, position, relative).then(() => this);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/util/MoveElementInArray.js
@@ -0,0 +1,17 @@
/**
* Moves an element in an array *in place*
* @param {Array} array Array to modify
* @param {*} element Element to move
* @param {number} newIndex Index or offset to move the element to
* @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index
* @returns {Array}
*/
module.exports = function moveElementInArray(array, element, newIndex, offset = false) {
const index = array.indexOf(element);
newIndex = (offset ? index : 0) + newIndex;
if (newIndex > -1 && newIndex < array.length) {
const removedElement = array.splice(index, 1)[0];
array.splice(newIndex, 0, removedElement);
}
return array;
};

0 comments on commit 1e94a9e

Please sign in to comment.