From 356bcc2a657dec538ddb6b7d176e8964ef18975b Mon Sep 17 00:00:00 2001 From: RogueException Date: Tue, 13 Oct 2015 05:17:57 -0300 Subject: [PATCH] Added role reordering --- src/Discord.Net/API/Common.cs | 2 ++ src/Discord.Net/API/Requests.cs | 15 ++++++++ src/Discord.Net/DiscordAPIClient.cs | 11 ++++++ src/Discord.Net/DiscordClient.API.cs | 53 +++++++++++++++++++++++++--- src/Discord.Net/Models/Role.cs | 4 +++ 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/Discord.Net/API/Common.cs b/src/Discord.Net/API/Common.cs index d85e773f4..f05b829ca 100644 --- a/src/Discord.Net/API/Common.cs +++ b/src/Discord.Net/API/Common.cs @@ -263,6 +263,8 @@ namespace Discord.API public uint? Permissions; [JsonProperty("name")] public string Name; + [JsonProperty("position")] + public int? Position; [JsonProperty("hoist")] public bool? Hoist; [JsonProperty("color")] diff --git a/src/Discord.Net/API/Requests.cs b/src/Discord.Net/API/Requests.cs index f2d9b49fc..b60ee0fd8 100644 --- a/src/Discord.Net/API/Requests.cs +++ b/src/Discord.Net/API/Requests.cs @@ -144,6 +144,21 @@ namespace Discord.API [JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] public uint? Color; } + internal sealed class ReorderRolesRequest : IEnumerable + { + public sealed class Role + { + [JsonProperty("id")] + public string Id; + [JsonProperty("position")] + public uint Position; + } + private IEnumerable _roles; + public ReorderRolesRequest(IEnumerable roles) { _roles = roles; } + + public IEnumerator GetEnumerator() => _roles.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _roles.GetEnumerator(); + } //Servers internal sealed class CreateServerRequest diff --git a/src/Discord.Net/DiscordAPIClient.cs b/src/Discord.Net/DiscordAPIClient.cs index 852c445f6..cd34bc169 100644 --- a/src/Discord.Net/DiscordAPIClient.cs +++ b/src/Discord.Net/DiscordAPIClient.cs @@ -278,6 +278,17 @@ namespace Discord var request = new EditRoleRequest { Name = name, Permissions = permissions, Hoist = hoist, Color = color }; return _rest.Patch(Endpoints.ServerRole(serverId, roleId), request); } + public Task ReorderRoles(string serverId, IEnumerable roleIds, int startPos = 0) + { + if (serverId == null) throw new ArgumentNullException(nameof(serverId)); + if (roleIds == null) throw new ArgumentNullException(nameof(roleIds)); + if (startPos < 0) throw new ArgumentOutOfRangeException(nameof(startPos), "startPos must be a positive integer."); + + uint pos = (uint)startPos; + var roles = roleIds.Select(x => new ReorderRolesRequest.Role { Id = x, Position = pos++ }); + var request = new ReorderRolesRequest(roles); + return _rest.Patch(Endpoints.ServerRoles(serverId), request); + } //Servers public Task CreateServer(string name, string region) diff --git a/src/Discord.Net/DiscordClient.API.cs b/src/Discord.Net/DiscordClient.API.cs index f03fa3950..f69307126 100644 --- a/src/Discord.Net/DiscordClient.API.cs +++ b/src/Discord.Net/DiscordClient.API.cs @@ -652,19 +652,43 @@ namespace Discord return _api.CreateRole(serverId); } - public Task EditRole(string roleId, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null) - => EditRole(_roles[roleId], name: name, permissions: permissions, color: color, hoist: hoist); - public Task EditRole(Role role, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null) + public Task EditRole(string roleId, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null, int? position = null) + => EditRole(_roles[roleId], name: name, permissions: permissions, color: color, hoist: hoist, position: position); + public async Task EditRole(Role role, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null, int? position = null) { CheckReady(); if (role == null) throw new NullReferenceException(nameof(role)); //TODO: Stop defaulting to cache variables once the server stops 500ing at us - return _api.EditRole(role.ServerId, role.Id, + await _api.EditRole(role.ServerId, role.Id, name: name ?? role.Name, permissions: permissions?.RawValue ?? role.Permissions.RawValue, color: color?.RawValue ?? role.Color.RawValue, hoist: hoist ?? role.Hoist); + + if (position != null) + { + int oldPos = role.Position; + int newPos = position.Value; + int minPos; + Role[] roles = role.Server.Roles.OrderBy(x => x.Position).ToArray(); + + if (oldPos < newPos) //Moving Down + { + minPos = oldPos; + for (int i = oldPos; i < newPos; i++) + roles[i] = roles[i + 1]; + roles[newPos] = role; + } + else //(oldPos > newPos) Moving Up + { + minPos = newPos; + for (int i = oldPos; i > newPos; i--) + roles[i] = roles[i - 1]; + roles[newPos] = role; + } + await _api.ReorderRoles(role.ServerId, roles.Skip(minPos).Select(x => x.Id), minPos); + } } public Task DeleteRole(Role role) @@ -678,6 +702,27 @@ namespace Discord return _api.DeleteRole(serverId, roleId); } + public Task ReorderRoles(Server server, IEnumerable roles, int startPos = 0) + => ReorderChannels(server.Id, roles, startPos); + public Task ReorderRoles(string serverId, IEnumerable roles, int startPos = 0) + { + if (serverId == null) throw new ArgumentNullException(nameof(serverId)); + if (roles == null) throw new ArgumentNullException(nameof(roles)); + if (startPos < 0) throw new ArgumentOutOfRangeException(nameof(startPos), "startPos must be a positive integer."); + + var roleIds = roles.Select(x => + { + if (x is string) + return x as string; + else if (x is Role) + return (x as Role).Id; + else + throw new ArgumentException("Channels must be a collection of string or Role.", nameof(roles)); + }); + + return _api.ReorderRoles(serverId, roleIds, startPos); + } + //Servers /// Creates a new server with the provided name and region (see Regions). public async Task CreateServer(string name, string region) diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 985e687f0..153db05be 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -14,6 +14,8 @@ namespace Discord public string Name { get; private set; } /// If true, this role is displayed isolated from other users. public bool Hoist { get; private set; } + /// Returns the position of this channel in the role list for this server. + public int Position { get; private set; } /// Returns the color of this role. public PackedColor Color { get; private set; } @@ -51,6 +53,8 @@ namespace Discord Name = model.Name; if (model.Hoist != null) Hoist = model.Hoist.Value; + if (model.Position != null) + Position = model.Position.Value; if (model.Color != null) Color.SetRawValue(model.Color.Value); if (model.Permissions != null)