Add support for channel categories (#907)
commit a85c5814a74e473e95fe172f0379cbc7f9f951d8
Author: Christopher F <computerizedtaco@gmail.com>
Date: Sat Jan 6 22:25:48 2018 -0500
Code cleanup
commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1
Author: Christopher F <computerizedtaco@gmail.com>
Date: Sat Jan 6 22:08:28 2018 -0500
Add support for channel categories (#907)
commit 41ed9106f2b05530acbf06b245c9aa618011d815
Author: mrspits4ever <spits.lucas@gmail.com>
Date: Thu Dec 14 20:02:57 2017 +0100
removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel
commit 71142c310847886dff80c49e9357dd0786d67a1b
Merge: 4589d731 678a7238
Author: mrspits4ever <spits.lucas@gmail.com>
Date: Wed Dec 13 21:17:53 2017 +0100
Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories
commit 4589d73187871c98485ed25c6d223706927af7ec
Author: mrspits4ever <spits.lucas@gmail.com>
Date: Wed Dec 13 21:17:46 2017 +0100
adressed requested changes
commit d59b038efa048b2279602e2015ddd2c185e58d63
Author: pegasy <pegasy@users.noreply.github.com>
Date: Mon Sep 25 18:53:23 2017 +0200
Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named.
commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f
Author: pegasy <pegasy@users.noreply.github.com>
Date: Sun Sep 24 19:08:25 2017 +0200
removed Guild from class name for ChannelCategory
Renamed all properties to use Category instead of Parent
Throw exception on GetUsers / GetInvites etc for categories
commit e18bd8c799d2327270021c05866cb2e97ad4671b
Author: pegasy <pegasy@users.noreply.github.com>
Date: Sun Sep 24 15:49:51 2017 +0200
Add support for channel categories (as its own channel type)
This commit is contained in:
@@ -26,5 +26,9 @@
|
||||
/// Move the channel to the following position. This is 0-based!
|
||||
/// </summary>
|
||||
public Optional<int> Position { get; set; }
|
||||
/// <summary>
|
||||
/// Sets the category for this channel
|
||||
/// </summary>
|
||||
public Optional<ulong?> CategoryId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
12
src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs
Normal file
12
src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public interface ICategoryChannel : IGuildChannel
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,10 @@ namespace Discord
|
||||
/// <summary> Gets the position of this channel in the guild's channel list, relative to others of the same type. </summary>
|
||||
int Position { get; }
|
||||
|
||||
/// <summary> Gets the parentid (category) of this channel in the guild's channel list. </summary>
|
||||
ulong? CategoryId { get; }
|
||||
/// <summary> Gets the parent channel (category) of this channel. </summary>
|
||||
Task<ICategoryChannel> GetCategoryAsync();
|
||||
/// <summary> Gets the guild this channel is a member of. </summary>
|
||||
IGuild Guild { get; }
|
||||
/// <summary> Gets the id of the guild this channel is a member of. </summary>
|
||||
@@ -23,7 +27,7 @@ namespace Discord
|
||||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null);
|
||||
/// <summary> Returns a collection of all invites to this channel. </summary>
|
||||
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null);
|
||||
|
||||
|
||||
/// <summary> Modifies this guild channel. </summary>
|
||||
Task ModifyAsync(Action<GuildChannelProperties> func, RequestOptions options = null);
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace Discord
|
||||
Task<IReadOnlyCollection<ITextChannel>> GetTextChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<ITextChannel> GetTextChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<IReadOnlyCollection<IVoiceChannel>> GetVoiceChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<IReadOnlyCollection<ICategoryChannel>> GetCategoriesAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<IVoiceChannel> GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<IVoiceChannel> GetAFKChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
Task<ITextChannel> GetSystemChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||
@@ -93,6 +94,8 @@ namespace Discord
|
||||
Task<ITextChannel> CreateTextChannelAsync(string name, RequestOptions options = null);
|
||||
/// <summary> Creates a new voice channel. </summary>
|
||||
Task<IVoiceChannel> CreateVoiceChannelAsync(string name, RequestOptions options = null);
|
||||
/// <summary> Creates a new channel category. </summary>
|
||||
Task<ICategoryChannel> CreateCategoryAsync(string name, RequestOptions options = null);
|
||||
|
||||
Task<IReadOnlyCollection<IGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null);
|
||||
Task<IGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null);
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Discord.API
|
||||
public Optional<int> Position { get; set; }
|
||||
[JsonProperty("permission_overwrites")]
|
||||
public Optional<Overwrite[]> PermissionOverwrites { get; set; }
|
||||
[JsonProperty("parent_id")]
|
||||
public ulong? CategoryId { get; set; }
|
||||
|
||||
//TextChannel
|
||||
[JsonProperty("topic")]
|
||||
|
||||
@@ -10,5 +10,7 @@ namespace Discord.API.Rest
|
||||
public Optional<string> Name { get; set; }
|
||||
[JsonProperty("position")]
|
||||
public Optional<int> Position { get; set; }
|
||||
[JsonProperty("parent_id")]
|
||||
public Optional<ulong?> CategoryId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ namespace Discord.Rest
|
||||
internal static class ChannelHelper
|
||||
{
|
||||
//General
|
||||
public static async Task DeleteAsync(IChannel channel, BaseDiscordClient client,
|
||||
public static async Task DeleteAsync(IChannel channel, BaseDiscordClient client,
|
||||
RequestOptions options)
|
||||
{
|
||||
{
|
||||
await client.ApiClient.DeleteChannelAsync(channel.Id, options).ConfigureAwait(false);
|
||||
}
|
||||
public static async Task<Model> ModifyAsync(IGuildChannel channel, BaseDiscordClient client,
|
||||
Action<GuildChannelProperties> func,
|
||||
public static async Task<Model> ModifyAsync(IGuildChannel channel, BaseDiscordClient client,
|
||||
Action<GuildChannelProperties> func,
|
||||
RequestOptions options)
|
||||
{
|
||||
var args = new GuildChannelProperties();
|
||||
@@ -28,12 +28,13 @@ namespace Discord.Rest
|
||||
var apiArgs = new API.Rest.ModifyGuildChannelParams
|
||||
{
|
||||
Name = args.Name,
|
||||
Position = args.Position
|
||||
Position = args.Position,
|
||||
CategoryId = args.CategoryId
|
||||
};
|
||||
return await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
|
||||
}
|
||||
public static async Task<Model> ModifyAsync(ITextChannel channel, BaseDiscordClient client,
|
||||
Action<TextChannelProperties> func,
|
||||
public static async Task<Model> ModifyAsync(ITextChannel channel, BaseDiscordClient client,
|
||||
Action<TextChannelProperties> func,
|
||||
RequestOptions options)
|
||||
{
|
||||
var args = new TextChannelProperties();
|
||||
@@ -42,13 +43,14 @@ namespace Discord.Rest
|
||||
{
|
||||
Name = args.Name,
|
||||
Position = args.Position,
|
||||
CategoryId = args.CategoryId,
|
||||
Topic = args.Topic,
|
||||
IsNsfw = args.IsNsfw
|
||||
};
|
||||
return await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
|
||||
}
|
||||
public static async Task<Model> ModifyAsync(IVoiceChannel channel, BaseDiscordClient client,
|
||||
Action<VoiceChannelProperties> func,
|
||||
public static async Task<Model> ModifyAsync(IVoiceChannel channel, BaseDiscordClient client,
|
||||
Action<VoiceChannelProperties> func,
|
||||
RequestOptions options)
|
||||
{
|
||||
var args = new VoiceChannelProperties();
|
||||
@@ -58,6 +60,7 @@ namespace Discord.Rest
|
||||
Bitrate = args.Bitrate,
|
||||
Name = args.Name,
|
||||
Position = args.Position,
|
||||
CategoryId = args.CategoryId,
|
||||
UserLimit = args.UserLimit.IsSpecified ? (args.UserLimit.Value ?? 0) : Optional.Create<int>()
|
||||
};
|
||||
return await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
|
||||
@@ -87,7 +90,7 @@ namespace Discord.Rest
|
||||
}
|
||||
|
||||
//Messages
|
||||
public static async Task<RestMessage> GetMessageAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
public static async Task<RestMessage> GetMessageAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
ulong id, RequestOptions options)
|
||||
{
|
||||
var guildId = (channel as IGuildChannel)?.GuildId;
|
||||
@@ -98,7 +101,7 @@ namespace Discord.Rest
|
||||
var author = GetAuthor(client, guild, model.Author.Value, model.WebhookId.ToNullable());
|
||||
return RestMessage.Create(client, channel, author, model);
|
||||
}
|
||||
public static IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
public static IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
ulong? fromMessageId, Direction dir, int limit, RequestOptions options)
|
||||
{
|
||||
if (dir == Direction.Around)
|
||||
@@ -124,7 +127,7 @@ namespace Discord.Rest
|
||||
foreach (var model in models)
|
||||
{
|
||||
var author = GetAuthor(client, guild, model.Author.Value, model.WebhookId.ToNullable());
|
||||
builder.Add(RestMessage.Create(client, channel, author, model));
|
||||
builder.Add(RestMessage.Create(client, channel, author, model));
|
||||
}
|
||||
return builder.ToImmutable();
|
||||
},
|
||||
@@ -180,7 +183,7 @@ namespace Discord.Rest
|
||||
var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS };
|
||||
var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false);
|
||||
return RestUserMessage.Create(client, channel, client.CurrentUser, model);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task DeleteMessagesAsync(ITextChannel channel, BaseDiscordClient client,
|
||||
IEnumerable<ulong> messageIds, RequestOptions options)
|
||||
@@ -277,7 +280,7 @@ namespace Discord.Rest
|
||||
{
|
||||
await client.ApiClient.TriggerTypingIndicatorAsync(channel.Id, options).ConfigureAwait(false);
|
||||
}
|
||||
public static IDisposable EnterTypingState(IMessageChannel channel, BaseDiscordClient client,
|
||||
public static IDisposable EnterTypingState(IMessageChannel channel, BaseDiscordClient client,
|
||||
RequestOptions options)
|
||||
=> new TypingNotifier(client, channel, options);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
Text = 0,
|
||||
DM = 1,
|
||||
Voice = 2,
|
||||
Group = 3
|
||||
Group = 3,
|
||||
Category = 4
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.Channel;
|
||||
|
||||
namespace Discord.Rest
|
||||
{
|
||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||
public class RestCategoryChannel : RestGuildChannel, ICategoryChannel
|
||||
{
|
||||
internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id)
|
||||
: base(discord, guild, id)
|
||||
{
|
||||
}
|
||||
internal new static RestCategoryChannel Create(BaseDiscordClient discord, IGuild guild, Model model)
|
||||
{
|
||||
var entity = new RestCategoryChannel(discord, guild, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Name} ({Id}, Category)";
|
||||
|
||||
// IGuildChannel
|
||||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
//IChannel
|
||||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace Discord.Rest
|
||||
internal IGuild Guild { get; }
|
||||
public string Name { get; private set; }
|
||||
public int Position { get; private set; }
|
||||
|
||||
public ulong? CategoryId { get; private set; }
|
||||
public ulong GuildId => Guild.Id;
|
||||
|
||||
internal RestGuildChannel(BaseDiscordClient discord, IGuild guild, ulong id)
|
||||
@@ -32,6 +32,8 @@ namespace Discord.Rest
|
||||
return RestTextChannel.Create(discord, guild, model);
|
||||
case ChannelType.Voice:
|
||||
return RestVoiceChannel.Create(discord, guild, model);
|
||||
case ChannelType.Category:
|
||||
return RestCategoryChannel.Create(discord, guild, model);
|
||||
default:
|
||||
// TODO: Channel categories
|
||||
return new RestGuildChannel(discord, guild, model.Id);
|
||||
@@ -61,7 +63,14 @@ namespace Discord.Rest
|
||||
}
|
||||
public Task DeleteAsync(RequestOptions options = null)
|
||||
=> ChannelHelper.DeleteAsync(this, Discord, options);
|
||||
|
||||
|
||||
public async Task<ICategoryChannel> GetCategoryAsync()
|
||||
{
|
||||
if (CategoryId.HasValue)
|
||||
return (await Guild.GetChannelAsync(CategoryId.Value).ConfigureAwait(false)) as ICategoryChannel;
|
||||
return null;
|
||||
}
|
||||
|
||||
public OverwritePermissions? GetPermissionOverwrite(IUser user)
|
||||
{
|
||||
for (int i = 0; i < _overwrites.Length; i++)
|
||||
@@ -139,20 +148,20 @@ namespace Discord.Rest
|
||||
=> await GetInvitesAsync(options).ConfigureAwait(false);
|
||||
async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
|
||||
=> await CreateInviteAsync(maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
|
||||
|
||||
OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IRole role)
|
||||
|
||||
OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IRole role)
|
||||
=> GetPermissionOverwrite(role);
|
||||
OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IUser user)
|
||||
=> GetPermissionOverwrite(user);
|
||||
async Task IGuildChannel.AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options)
|
||||
async Task IGuildChannel.AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options)
|
||||
=> await AddPermissionOverwriteAsync(role, permissions, options).ConfigureAwait(false);
|
||||
async Task IGuildChannel.AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options)
|
||||
async Task IGuildChannel.AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options)
|
||||
=> await AddPermissionOverwriteAsync(user, permissions, options).ConfigureAwait(false);
|
||||
async Task IGuildChannel.RemovePermissionOverwriteAsync(IRole role, RequestOptions options)
|
||||
async Task IGuildChannel.RemovePermissionOverwriteAsync(IRole role, RequestOptions options)
|
||||
=> await RemovePermissionOverwriteAsync(role, options).ConfigureAwait(false);
|
||||
async Task IGuildChannel.RemovePermissionOverwriteAsync(IUser user, RequestOptions options)
|
||||
async Task IGuildChannel.RemovePermissionOverwriteAsync(IUser user, RequestOptions options)
|
||||
=> await RemovePermissionOverwriteAsync(user, options).ConfigureAwait(false);
|
||||
|
||||
|
||||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
|
||||
=> AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); //Overridden //Overridden in Text/Voice
|
||||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
|
||||
@@ -157,6 +157,15 @@ namespace Discord.Rest
|
||||
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
|
||||
return RestVoiceChannel.Create(client, guild, model);
|
||||
}
|
||||
public static async Task<RestCategoryChannel> CreateCategoryChannelAsync(IGuild guild, BaseDiscordClient client,
|
||||
string name, RequestOptions options)
|
||||
{
|
||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||
|
||||
var args = new CreateGuildChannelParams(name, ChannelType.Category);
|
||||
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
|
||||
return RestCategoryChannel.Create(client, guild, model);
|
||||
}
|
||||
|
||||
//Integrations
|
||||
public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client,
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Discord.Rest
|
||||
public VerificationLevel VerificationLevel { get; private set; }
|
||||
public MfaLevel MfaLevel { get; private set; }
|
||||
public DefaultMessageNotifications DefaultMessageNotifications { get; private set; }
|
||||
|
||||
|
||||
public ulong? AFKChannelId { get; private set; }
|
||||
public ulong? EmbedChannelId { get; private set; }
|
||||
public ulong? SystemChannelId { get; private set; }
|
||||
@@ -114,7 +114,7 @@ namespace Discord.Rest
|
||||
Update(model);
|
||||
}
|
||||
public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null)
|
||||
{
|
||||
{
|
||||
var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false);
|
||||
Update(model);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ namespace Discord.Rest
|
||||
public Task<IReadOnlyCollection<RestGuildChannel>> GetChannelsAsync(RequestOptions options = null)
|
||||
=> GuildHelper.GetChannelsAsync(this, Discord, options);
|
||||
public Task<RestGuildChannel> GetChannelAsync(ulong id, RequestOptions options = null)
|
||||
=> GuildHelper.GetChannelAsync(this, Discord, id, options);
|
||||
=> GuildHelper.GetChannelAsync(this, Discord, id, options);
|
||||
public async Task<RestTextChannel> GetTextChannelAsync(ulong id, RequestOptions options = null)
|
||||
{
|
||||
var channel = await GuildHelper.GetChannelAsync(this, Discord, id, options).ConfigureAwait(false);
|
||||
@@ -176,6 +176,11 @@ namespace Discord.Rest
|
||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||
return channels.Select(x => x as RestVoiceChannel).Where(x => x != null).ToImmutableArray();
|
||||
}
|
||||
public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null)
|
||||
{
|
||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||
return channels.Select(x => x as RestCategoryChannel).Where(x => x != null).ToImmutableArray();
|
||||
}
|
||||
|
||||
public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null)
|
||||
{
|
||||
@@ -199,7 +204,7 @@ namespace Discord.Rest
|
||||
public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null)
|
||||
{
|
||||
var embedId = EmbedChannelId;
|
||||
if (embedId.HasValue)
|
||||
if (embedId.HasValue)
|
||||
return await GuildHelper.GetChannelAsync(this, Discord, embedId.Value, options).ConfigureAwait(false);
|
||||
return null;
|
||||
}
|
||||
@@ -217,6 +222,8 @@ namespace Discord.Rest
|
||||
=> GuildHelper.CreateTextChannelAsync(this, Discord, name, options);
|
||||
public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, RequestOptions options = null)
|
||||
=> GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options);
|
||||
public Task<RestCategoryChannel> CreateCategoryChannelAsync(string name, RequestOptions options = null)
|
||||
=> GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options);
|
||||
|
||||
//Integrations
|
||||
public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null)
|
||||
@@ -236,7 +243,7 @@ namespace Discord.Rest
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?),
|
||||
public async Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?),
|
||||
bool isHoisted = false, RequestOptions options = null)
|
||||
{
|
||||
var role = await GuildHelper.CreateRoleAsync(this, Discord, name, permissions, color, isHoisted, options).ConfigureAwait(false);
|
||||
@@ -320,6 +327,13 @@ namespace Discord.Rest
|
||||
else
|
||||
return ImmutableArray.Create<IVoiceChannel>();
|
||||
}
|
||||
async Task<IReadOnlyCollection<ICategoryChannel>> IGuild.GetCategoriesAsync(CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
return await GetCategoryChannelsAsync(options).ConfigureAwait(false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
async Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
{
|
||||
if (mode == CacheMode.AllowDownload)
|
||||
@@ -359,6 +373,8 @@ namespace Discord.Rest
|
||||
=> await CreateTextChannelAsync(name, options).ConfigureAwait(false);
|
||||
async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, RequestOptions options)
|
||||
=> await CreateVoiceChannelAsync(name, options).ConfigureAwait(false);
|
||||
async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, RequestOptions options)
|
||||
=> await CreateCategoryChannelAsync(name, options).ConfigureAwait(false);
|
||||
|
||||
async Task<IReadOnlyCollection<IGuildIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options)
|
||||
=> await GetIntegrationsAsync(options).ConfigureAwait(false);
|
||||
@@ -368,7 +384,7 @@ namespace Discord.Rest
|
||||
async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options)
|
||||
=> await GetInvitesAsync(options).ConfigureAwait(false);
|
||||
|
||||
IRole IGuild.GetRole(ulong id)
|
||||
IRole IGuild.GetRole(ulong id)
|
||||
=> GetRole(id);
|
||||
async Task<IRole> IGuild.CreateRoleAsync(string name, GuildPermissions? permissions, Color? color, bool isHoisted, RequestOptions options)
|
||||
=> await CreateRoleAsync(name, permissions, color, isHoisted, options).ConfigureAwait(false);
|
||||
|
||||
36
src/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs
Normal file
36
src/Discord.Net.Rpc/Entities/Channels/RpcCategoryChannel.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.Rpc.Channel;
|
||||
|
||||
namespace Discord.Rpc
|
||||
{
|
||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||
public class RpcCategoryChannel : RpcGuildChannel, ICategoryChannel
|
||||
{
|
||||
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; }
|
||||
|
||||
public string Mention => MentionUtils.MentionChannel(Id);
|
||||
|
||||
internal RpcCategoryChannel(DiscordRpcClient discord, ulong id, ulong guildId)
|
||||
: base(discord, id, guildId)
|
||||
{
|
||||
}
|
||||
internal new static RpcCategoryChannel Create(DiscordRpcClient discord, Model model)
|
||||
{
|
||||
var entity = new RpcCategoryChannel(discord, model.Id, model.GuildId.Value);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal override void Update(Model model)
|
||||
{
|
||||
base.Update(model);
|
||||
CachedMessages = model.Messages.Select(x => RpcMessage.Create(Discord, Id, x)).ToImmutableArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Audio;
|
||||
using Discord.Rest;
|
||||
using Model = Discord.API.Channel;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||
public class SocketCategoryChannel : SocketGuildChannel, ICategoryChannel
|
||||
{
|
||||
public override IReadOnlyCollection<SocketGuildUser> Users
|
||||
=> Guild.Users.Where(x => x.VoiceChannel?.Id == Id).ToImmutableArray();
|
||||
|
||||
public IReadOnlyCollection<SocketGuildChannel> Channels
|
||||
=> Guild.Channels.Where(x => x.CategoryId == CategoryId).ToImmutableArray();
|
||||
|
||||
internal SocketCategoryChannel(DiscordSocketClient discord, ulong id, SocketGuild guild)
|
||||
: base(discord, id, guild)
|
||||
{
|
||||
}
|
||||
internal new static SocketCategoryChannel Create(SocketGuild guild, ClientState state, Model model)
|
||||
{
|
||||
var entity = new SocketCategoryChannel(guild.Discord, model.Id, guild);
|
||||
entity.Update(state, model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{Name} ({Id}, Category)";
|
||||
internal new SocketCategoryChannel Clone() => MemberwiseClone() as SocketCategoryChannel;
|
||||
|
||||
// IGuildChannel
|
||||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
//IChannel
|
||||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ namespace Discord.WebSocket
|
||||
public SocketGuild Guild { get; }
|
||||
public string Name { get; private set; }
|
||||
public int Position { get; private set; }
|
||||
public ulong? CategoryId { get; private set; }
|
||||
public ICategoryChannel Category
|
||||
=> CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null;
|
||||
|
||||
public IReadOnlyCollection<Overwrite> PermissionOverwrites => _overwrites;
|
||||
public new virtual IReadOnlyCollection<SocketGuildUser> Users => ImmutableArray.Create<SocketGuildUser>();
|
||||
@@ -34,6 +37,8 @@ namespace Discord.WebSocket
|
||||
return SocketTextChannel.Create(guild, state, model);
|
||||
case ChannelType.Voice:
|
||||
return SocketVoiceChannel.Create(guild, state, model);
|
||||
case ChannelType.Category:
|
||||
return SocketCategoryChannel.Create(guild, state, model);
|
||||
default:
|
||||
// TODO: Proper implementation for channel categories
|
||||
return new SocketGuildChannel(guild.Discord, model.Id, guild);
|
||||
@@ -43,6 +48,7 @@ namespace Discord.WebSocket
|
||||
{
|
||||
Name = model.Name.Value;
|
||||
Position = model.Position.Value;
|
||||
CategoryId = model.CategoryId;
|
||||
|
||||
var overwrites = model.PermissionOverwrites.Value;
|
||||
var newOverwrites = ImmutableArray.CreateBuilder<Overwrite>(overwrites.Length);
|
||||
@@ -129,6 +135,9 @@ namespace Discord.WebSocket
|
||||
IGuild IGuildChannel.Guild => Guild;
|
||||
ulong IGuildChannel.GuildId => Guild.Id;
|
||||
|
||||
Task<ICategoryChannel> IGuildChannel.GetCategoryAsync()
|
||||
=> Task.FromResult(Category);
|
||||
|
||||
async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options)
|
||||
=> await GetInvitesAsync(options).ConfigureAwait(false);
|
||||
async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Discord.WebSocket
|
||||
return id.HasValue ? GetVoiceChannel(id.Value) : null;
|
||||
}
|
||||
}
|
||||
public SocketGuildChannel EmbedChannel
|
||||
public SocketGuildChannel EmbedChannel
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -95,6 +95,8 @@ namespace Discord.WebSocket
|
||||
=> Channels.Select(x => x as SocketTextChannel).Where(x => x != null).ToImmutableArray();
|
||||
public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels
|
||||
=> Channels.Select(x => x as SocketVoiceChannel).Where(x => x != null).ToImmutableArray();
|
||||
public IReadOnlyCollection<SocketCategoryChannel> CategoryChannels
|
||||
=> Channels.Select(x => x as SocketCategoryChannel).Where(x => x != null).ToImmutableArray();
|
||||
public SocketGuildUser CurrentUser => _members.TryGetValue(Discord.CurrentUser.Id, out SocketGuildUser member) ? member : null;
|
||||
public SocketRole EveryoneRole => GetRole(Id);
|
||||
public IReadOnlyCollection<SocketGuildChannel> Channels
|
||||
@@ -317,6 +319,9 @@ namespace Discord.WebSocket
|
||||
=> GuildHelper.CreateTextChannelAsync(this, Discord, name, options);
|
||||
public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, RequestOptions options = null)
|
||||
=> GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options);
|
||||
public Task<RestCategoryChannel> CreateCategoryChannelAsync(string name, RequestOptions options = null)
|
||||
=> GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options);
|
||||
|
||||
internal SocketGuildChannel AddChannel(ClientState state, ChannelModel model)
|
||||
{
|
||||
var channel = SocketGuildChannel.Create(this, state, model);
|
||||
@@ -348,7 +353,7 @@ namespace Discord.WebSocket
|
||||
return value;
|
||||
return null;
|
||||
}
|
||||
public Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?),
|
||||
public Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?),
|
||||
bool isHoisted = false, RequestOptions options = null)
|
||||
=> GuildHelper.CreateRoleAsync(this, Discord, name, permissions, color, isHoisted, options);
|
||||
internal SocketRole AddRole(RoleModel model)
|
||||
@@ -594,7 +599,7 @@ namespace Discord.WebSocket
|
||||
try
|
||||
{
|
||||
await RepopulateAudioStreamsAsync().ConfigureAwait(false);
|
||||
await _audioClient.StartAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false);
|
||||
await _audioClient.StartAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -651,6 +656,8 @@ namespace Discord.WebSocket
|
||||
=> Task.FromResult<ITextChannel>(GetTextChannel(id));
|
||||
Task<IReadOnlyCollection<IVoiceChannel>> IGuild.GetVoiceChannelsAsync(CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IReadOnlyCollection<IVoiceChannel>>(VoiceChannels);
|
||||
Task<IReadOnlyCollection<ICategoryChannel>> IGuild.GetCategoriesAsync(CacheMode mode , RequestOptions options)
|
||||
=> Task.FromResult<IReadOnlyCollection<ICategoryChannel>>(CategoryChannels);
|
||||
Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||
=> Task.FromResult<IVoiceChannel>(GetVoiceChannel(id));
|
||||
Task<IVoiceChannel> IGuild.GetAFKChannelAsync(CacheMode mode, RequestOptions options)
|
||||
@@ -665,6 +672,8 @@ namespace Discord.WebSocket
|
||||
=> await CreateTextChannelAsync(name, options).ConfigureAwait(false);
|
||||
async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, RequestOptions options)
|
||||
=> await CreateVoiceChannelAsync(name, options).ConfigureAwait(false);
|
||||
async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, RequestOptions options)
|
||||
=> await CreateCategoryChannelAsync(name, options).ConfigureAwait(false);
|
||||
|
||||
async Task<IReadOnlyCollection<IGuildIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options)
|
||||
=> await GetIntegrationsAsync(options).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user