make positions for channels and roles nicer (#1211)

* make role calculated position nicer

* make channels sortable in a nice way too

* stupid git web rebase editor

* Update Guild.js

* Update Guild.js

* Update Guild.js

* Update Guild.js

* Update RESTMethods.js
This commit is contained in:
Gus Caplan
2017-04-01 01:28:54 -05:00
committed by Crawl
parent c4e5292516
commit a4e0af2e45
7 changed files with 142 additions and 54 deletions

View File

@@ -1,3 +1,4 @@
const Long = require('long');
const User = require('./User');
const Role = require('./Role');
const Emoji = require('./Emoji');
@@ -295,6 +296,15 @@ class Guild {
return this.roles.get(this.id);
}
/**
* Fetches a collection of roles in the current guild sorted by position.
* @type {Collection<Snowflake, Role>}
* @readonly
*/
get _sortedRoles() {
return this._sortPositionWithID(this.roles);
}
/**
* Returns the GuildMember form of a User object, if the user is present in the guild.
* @param {UserResolvable} user The user that you want to obtain the GuildMember of
@@ -687,31 +697,6 @@ class Guild {
return this.client.rest.methods.createGuildRole(this, data);
}
/**
* Set the position of a role in this guild
* @param {Role|Snowflake} 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, 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.'));
}
position = Number(position);
if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));
let updatedRoles = Object.assign([], this.roles.array()
.sort((r1, r2) => r1.position !== r2.position ? r1.position - r2.position : r1.id - r2.id));
Util.moveElementInArray(updatedRoles, role, position, relative);
updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));
return this.client.rest.methods.setRolePositions(this.id, updatedRoles);
}
/**
* Creates a new custom emoji in the guild.
* @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji.
@@ -919,6 +904,81 @@ class Guild {
}
this.presences.set(id, new Presence(presence));
}
/**
* 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, 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 snowflake.'));
}
position = Number(position);
if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));
let updatedRoles = this._sortedRoles().array();
Util.moveElementInArray(updatedRoles, role, position, relative);
updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));
return this.client.rest.methods.setRolePositions(this.id, updatedRoles);
}
/**
* Set the position of a channel in this guild
* @param {string|GuildChannel} channel The channel to edit, can be a channel object or a channel ID.
* @param {number} position The new position of the channel
* @param {boolean} [relative=false] Position Moves the channel relative to its current position
* @returns {Promise<Guild>}
*/
setChannelPosition(channel, position, relative = false) {
if (typeof channel === 'string') {
channel = this.channels.get(channel);
if (!channel) return Promise.reject(new Error('Supplied channel is not a channel or snowflake.'));
}
position = Number(position);
if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));
let updatedChannels = this._sortedChannels(channel.type).array();
Util.moveElementInArray(updatedChannels, channel, position, relative);
updatedChannels = updatedChannels.map((r, i) => ({ id: r.id, position: i }));
return this.client.rest.methods.setChannelPositions(this.id, updatedChannels);
}
/**
* Fetches a collection of channels in the current guild sorted by position.
* @param {string} type Channel type
* @returns {Collection<Snowflake, GuildChannel>}
*/
_sortedChannels(type) {
return this._sortPositionWithID(this.channels.filter(c => {
if (type === 'voice' && c.type === 'voice') return true;
else if (type !== 'voice' && c.type !== 'voice') return true;
else return type === c.type;
}));
}
/**
* Sorts a collection by object position or ID if the positions are equivalent.
* Intended to be identical to Discord's sorting method.
* @param {Collection} collection The collection to sort
* @returns {Collection}
*/
_sortPositionWithID(collection) {
return collection.sort((a, b) =>
a.position !== b.position ?
a.position - b.position :
Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber()
);
}
}
module.exports = Guild;