Browse Source

Add support for channel categories (as its own channel type)

pull/821/head
pegasy 7 years ago
parent
commit
e18bd8c799
18 changed files with 243 additions and 33 deletions
  1. +12
    -0
      src/Discord.Net.Core/Entities/Channels/GuildChannelCategoryProperties.cs
  2. +4
    -0
      src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs
  3. +5
    -1
      src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs
  4. +14
    -0
      src/Discord.Net.Core/Entities/Channels/IGuildChannelCategory.cs
  5. +1
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  6. +2
    -0
      src/Discord.Net.Rest/API/Common/Channel.cs
  7. +14
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildChannelCategoryParams.cs
  8. +2
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildChannelParams.cs
  9. +17
    -14
      src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
  10. +2
    -1
      src/Discord.Net.Rest/Entities/Channels/ChannelType.cs
  11. +10
    -8
      src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
  12. +38
    -0
      src/Discord.Net.Rest/Entities/Channels/RestGuildChannelCategory.cs
  13. +18
    -6
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  14. +38
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcChannelCategory.cs
  15. +7
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
  16. +6
    -0
      src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
  17. +46
    -0
      src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannelCategory.cs
  18. +7
    -3
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 12
- 0
src/Discord.Net.Core/Entities/Channels/GuildChannelCategoryProperties.cs View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
//public class GuildChannelCategoryProperties : GuildChannelProperties
//{
//}
}

+ 4
- 0
src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs View File

@@ -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?> ParentId { get; set; }
}
}

+ 5
- 1
src/Discord.Net.Core/Entities/Channels/IGuildChannel.cs View File

@@ -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? ParentId { get; }
/// <summary> Gets the parent channel (category) of this channel. </summary>
Task<IGuildChannel> GetParentChannelAsync();
/// <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 = 1800, 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);



+ 14
- 0
src/Discord.Net.Core/Entities/Channels/IGuildChannelCategory.cs View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
public interface IGuildChannelCategory : IGuildChannel
{
///// <summary> Modifies this text channel. </summary>
//Task ModifyAsync(Action<GuildChannelCategoryProperties> func, RequestOptions options = null);
}
}

+ 1
- 0
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -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<IGuildChannelCategory>> GetChannelCategoriesAsync(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);


+ 2
- 0
src/Discord.Net.Rest/API/Common/Channel.cs View File

@@ -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? ParentId { get; set; }

//TextChannel
[JsonProperty("topic")]


+ 14
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildChannelCategoryParams.cs View File

@@ -0,0 +1,14 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rest
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
internal class ModifyGuildChannelCategoryParams
{
[JsonProperty("name")]
public Optional<string> Name { get; set; }
[JsonProperty("position")]
public Optional<int> Position { get; set; }
}
}

+ 2
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildChannelParams.cs View File

@@ -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?> ParentId { get; set; }
}
}

+ 17
- 14
src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs View File

@@ -13,13 +13,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();
@@ -27,12 +27,13 @@ namespace Discord.Rest
var apiArgs = new API.Rest.ModifyGuildChannelParams
{
Name = args.Name,
Position = args.Position
Position = args.Position,
ParentId = args.ParentId
};
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();
@@ -41,13 +42,14 @@ namespace Discord.Rest
{
Name = args.Name,
Position = args.Position,
ParentId = args.ParentId,
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();
@@ -57,6 +59,7 @@ namespace Discord.Rest
Bitrate = args.Bitrate,
Name = args.Name,
Position = args.Position,
ParentId = args.ParentId,
UserLimit = args.UserLimit.IsSpecified ? (args.UserLimit.Value ?? 0) : Optional.Create<int>()
};
return await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
@@ -86,7 +89,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;
@@ -97,7 +100,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)
@@ -123,7 +126,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();
},
@@ -179,7 +182,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(IMessageChannel channel, BaseDiscordClient client,
IEnumerable<ulong> messageIds, RequestOptions options)
@@ -276,7 +279,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);



+ 2
- 1
src/Discord.Net.Rest/Entities/Channels/ChannelType.cs View File

@@ -5,6 +5,7 @@
Text = 0,
DM = 1,
Voice = 2,
Group = 3
Group = 3,
Category = 4
}
}

+ 10
- 8
src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs View File

@@ -16,6 +16,8 @@ namespace Discord.Rest
internal IGuild Guild { get; }
public string Name { get; private set; }
public int Position { get; private set; }
public ulong? ParentId { get; private set; }
public Task<IGuildChannel> GetParentChannelAsync() => ParentId == null ? null : Guild.GetChannelAsync(ParentId.Value);

public ulong GuildId => Guild.Id;

@@ -61,7 +63,7 @@ namespace Discord.Rest
}
public Task DeleteAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);
public OverwritePermissions? GetPermissionOverwrite(IUser user)
{
for (int i = 0; i < _overwrites.Length; i++)
@@ -139,20 +141,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>>(); //Overriden //Overriden in Text/Voice
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)


+ 38
- 0
src/Discord.Net.Rest/Entities/Channels/RestGuildChannelCategory.cs View File

@@ -0,0 +1,38 @@
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 RestGuildChannelCategory : RestGuildChannel, IGuildChannelCategory
{
public string Mention => MentionUtils.MentionChannel(Id);

internal RestGuildChannelCategory(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id)
{
}
internal new static RestGuildChannelCategory Create(BaseDiscordClient discord, IGuild guild, Model model)
{
var entity = new RestGuildChannelCategory(discord, guild, model.Id);
entity.Update(model);
return entity;
}
internal override void Update(Model model)
{
base.Update(model);
}

public Task<RestGuildUser> GetUserAsync(ulong id, RequestOptions options = null)
=> ChannelHelper.GetUserAsync(this, Guild, Discord, id, options);
public IAsyncEnumerable<IReadOnlyCollection<RestGuildUser>> GetUsersAsync(RequestOptions options = null)
=> ChannelHelper.GetUsersAsync(this, Guild, Discord, null, null, options);

private string DebuggerDisplay => $"{Name} ({Id}, Text)";
}
}

+ 18
- 6
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -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<RestGuildChannelCategory>> GetChannelCategoriesAsync(RequestOptions options = null)
{
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
return channels.Select(x => x as RestGuildChannelCategory).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;
}
@@ -236,7 +241,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);
@@ -304,6 +309,13 @@ namespace Discord.Rest
else
return ImmutableArray.Create<IVoiceChannel>();
}
async Task<IReadOnlyCollection<IGuildChannelCategory>> IGuild.GetChannelCategoriesAsync(CacheMode mode , RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetChannelCategoriesAsync(options).ConfigureAwait(false);
else
return null;
}
async Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
@@ -352,7 +364,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);


+ 38
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcChannelCategory.cs View File

@@ -0,0 +1,38 @@
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 RpcChannelCategory : RpcGuildChannel
{
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; }

public string Mention => MentionUtils.MentionChannel(Id);
// TODO: Check if RPC includes the 'nsfw' field on Channel models
public bool IsNsfw => ChannelHelper.IsNsfw(this);

internal RpcChannelCategory(DiscordRpcClient discord, ulong id, ulong guildId)
: base(discord, id, guildId)
{
}
internal new static RpcChannelCategory Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcChannelCategory(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();
}
}
}

+ 7
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs View File

@@ -10,6 +10,7 @@ namespace Discord.Rpc
{
public ulong GuildId { get; }
public int Position { get; private set; }
public ulong? ParentId { get; private set; }

internal RpcGuildChannel(DiscordRpcClient discord, ulong id, ulong guildId)
: base(discord, id)
@@ -57,6 +58,12 @@ namespace Discord.Rpc
public override string ToString() => Name;

//IGuildChannel
public Task<IGuildChannel> GetParentChannelAsync()
{
//Always fails
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
}

IGuild IGuildChannel.Guild
{
get


+ 6
- 0
src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs View File

@@ -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? ParentId { get; private set; }
public IGuildChannel ParentChannel => ParentId == null ? null : Guild.GetChannel(ParentId.Value);
public Task<IGuildChannel> GetParentChannelAsync() => Task.FromResult(ParentChannel);

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 SocketGuildChannelCategory.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;
ParentId = model.ParentId;

var overwrites = model.PermissionOverwrites.Value;
var newOverwrites = ImmutableArray.CreateBuilder<Overwrite>(overwrites.Length);


+ 46
- 0
src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannelCategory.cs View File

@@ -0,0 +1,46 @@
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 SocketGuildChannelCategory : SocketGuildChannel, IGuildChannelCategory
{
public override IReadOnlyCollection<SocketGuildUser> Users
=> Guild.Users.Where(x => x.VoiceChannel?.Id == Id).ToImmutableArray();

internal SocketGuildChannelCategory(DiscordSocketClient discord, ulong id, SocketGuild guild)
: base(discord, id, guild)
{
}
internal new static SocketGuildChannelCategory Create(SocketGuild guild, ClientState state, Model model)
{
var entity = new SocketGuildChannelCategory(guild.Discord, model.Id, guild);
entity.Update(state, model);
return entity;
}
internal override void Update(ClientState state, Model model)
{
base.Update(state, model);
}

public override SocketGuildUser GetUser(ulong id)
{
var user = Guild.GetUser(id);
if (user?.VoiceChannel?.Id == Id)
return user;
return null;
}

private string DebuggerDisplay => $"{Name} ({Id}, Category)";
internal new SocketGuildChannelCategory Clone() => MemberwiseClone() as SocketGuildChannelCategory;
}
}

+ 7
- 3
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -74,7 +74,7 @@ namespace Discord.WebSocket
return id.HasValue ? GetVoiceChannel(id.Value) : null;
}
}
public SocketGuildChannel EmbedChannel
public SocketGuildChannel EmbedChannel
{
get
{
@@ -94,6 +94,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<SocketGuildChannelCategory> ChannelCategories
=> Channels.Select(x => x as SocketGuildChannelCategory).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
@@ -347,7 +349,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)
@@ -577,7 +579,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)
{
@@ -634,6 +636,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<IGuildChannelCategory>> IGuild.GetChannelCategoriesAsync(CacheMode mode , RequestOptions options)
=> Task.FromResult<IReadOnlyCollection<IGuildChannelCategory>>(ChannelCategories);
Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IVoiceChannel>(GetVoiceChannel(id));
Task<IVoiceChannel> IGuild.GetAFKChannelAsync(CacheMode mode, RequestOptions options)


Loading…
Cancel
Save