diff --git a/src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs b/src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs
index 0f7f5aa62..c004cafd5 100644
--- a/src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ICategoryChannel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
index c9841cb15..6514d46cd 100644
--- a/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -9,10 +9,6 @@ namespace Discord
/// Gets the position of this channel in the guild's channel list, relative to others of the same type.
int Position { get; }
- /// Gets the parentid (category) of this channel in the guild's channel list.
- ulong? CategoryId { get; }
- /// Gets the parent channel (category) of this channel.
- Task GetCategoryAsync();
/// Gets the guild this channel is a member of.
IGuild Guild { get; }
/// Gets the id of the guild this channel is a member of.
@@ -49,4 +45,4 @@ namespace Discord
/// Gets a user in this channel with the provided id.
new Task GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
}
-}
\ No newline at end of file
+}
diff --git a/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs b/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs
new file mode 100644
index 000000000..7e9d8fbf0
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Channels/INestedChannel.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// A type of guild channel that can be nested within a category.
+ /// Contains a CategoryId that is set to the parent category, if it is set.
+ ///
+ public interface INestedChannel : IGuildChannel
+ {
+ /// Gets the parentid (category) of this channel in the guild's channel list.
+ ulong? CategoryId { get; }
+ /// Gets the parent channel (category) of this channel, if it is set. If unset, returns null.
+ Task GetCategoryAsync();
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
index 7c6ec3908..ae15ce2ba 100644
--- a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
@@ -1,11 +1,11 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace Discord
{
- public interface ITextChannel : IMessageChannel, IMentionable, IGuildChannel
+ public interface ITextChannel : IMessageChannel, IMentionable, IGuildChannel, INestedChannel
{
/// Checks if the channel is NSFW.
bool IsNsfw { get; }
@@ -28,4 +28,4 @@ namespace Discord
/// Gets the webhooks for this text channel.
Task> GetWebhooksAsync(RequestOptions options = null);
}
-}
\ No newline at end of file
+}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
index bfdf1f6c0..321f1f1d2 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
@@ -25,23 +25,6 @@ namespace Discord.Rest
private string DebuggerDisplay => $"{Name} ({Id}, Category)";
// IGuildChannel
-
- ///
- /// Throws a NotSupportedException because Channel Categories cannot be the child of another Channel Category.
- ///
- /// A NotSupportedException is always thrown because Channel Categories do not support being nested.
- ulong? IGuildChannel.CategoryId
- => throw new NotSupportedException();
- ///
- /// Throws a NotSupportedException because Channel Categories cannot be the child of another Channel Category.
- ///
- /// A NotSupportedException is always thrown because Channel Categories do not support being nested.
- Task IGuildChannel.GetCategoryAsync()
- => throw new NotSupportedException();
- IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
- => throw new NotSupportedException();
- Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
- => throw new NotSupportedException();
Task IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options)
=> throw new NotSupportedException();
Task> IGuildChannel.GetInvitesAsync(RequestOptions options)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
index 026d03cc8..8bddcff09 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@@ -16,7 +16,6 @@ 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)
@@ -64,13 +63,6 @@ namespace Discord.Rest
public Task DeleteAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);
- public async Task 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++)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
index 600b197d6..18af4939a 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
@@ -9,9 +9,10 @@ using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel
+ public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel, INestedChannel
{
public string Topic { get; private set; }
+ public ulong? CategoryId { get; private set; }
public string Mention => MentionUtils.MentionChannel(Id);
@@ -168,5 +169,13 @@ namespace Discord.Rest
else
return AsyncEnumerable.Empty>();
}
+
+ // INestedChannel
+ async Task INestedChannel.GetCategoryAsync()
+ {
+ if (CategoryId.HasValue)
+ return (await Guild.GetChannelAsync(CategoryId.Value).ConfigureAwait(false)) as ICategoryChannel;
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
index 300ebd08d..53a28eaee 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
@@ -1,4 +1,4 @@
-using Discord.Audio;
+using Discord.Audio;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -9,10 +9,11 @@ using Model = Discord.API.Channel;
namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel
+ public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel, INestedChannel
{
public int Bitrate { get; private set; }
public int? UserLimit { get; private set; }
+ public ulong? CategoryId { get; private set; }
internal RestVoiceChannel(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id)
@@ -48,5 +49,13 @@ namespace Discord.Rest
=> Task.FromResult(null);
IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty>();
+
+ // INestedChannel
+ async Task INestedChannel.GetCategoryAsync()
+ {
+ if (CategoryId.HasValue)
+ return (await Guild.GetChannelAsync(CategoryId.Value).ConfigureAwait(false)) as ICategoryChannel;
+ return null;
+ }
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
index ec7615b55..b94ded5fb 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
@@ -11,11 +11,14 @@ using Model = Discord.API.Channel;
namespace Discord.WebSocket
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessageChannel
+ public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessageChannel, INestedChannel
{
private readonly MessageCache _messages;
public string Topic { get; private set; }
+ public ulong? CategoryId { get; private set; }
+ public ICategoryChannel Category
+ => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null;
private bool _nsfw;
public bool IsNsfw => _nsfw || ChannelHelper.IsNsfw(this);
@@ -164,5 +167,9 @@ namespace Discord.WebSocket
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);
+
+ // INestedChannel
+ Task INestedChannel.GetCategoryAsync()
+ => Task.FromResult(Category);
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
index e8a669845..a8ec9457a 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
@@ -1,4 +1,4 @@
-using Discord.Audio;
+using Discord.Audio;
using Discord.Rest;
using System;
using System.Collections.Generic;
@@ -11,10 +11,13 @@ using Model = Discord.API.Channel;
namespace Discord.WebSocket
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel
+ public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel, INestedChannel
{
public int Bitrate { get; private set; }
public int? UserLimit { get; private set; }
+ public ulong? CategoryId { get; private set; }
+ public ICategoryChannel Category
+ => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null;
public override IReadOnlyCollection Users
=> Guild.Users.Where(x => x.VoiceChannel?.Id == Id).ToImmutableArray();
@@ -61,5 +64,9 @@ namespace Discord.WebSocket
=> Task.FromResult(GetUser(id));
IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create>(Users).ToAsyncEnumerable();
+
+ // INestedChannel
+ Task INestedChannel.GetCategoryAsync()
+ => Task.FromResult(Category);
}
}