From 9084c4214eecb8c41849760a6edd1a7f6db9ba79 Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Sat, 4 May 2019 14:07:31 -0700 Subject: [PATCH] feature: Fix #1280 Add NewsChannel Types (#1293) * add News channel type * remove (very outdated) todo * add [Socket/Rest]NewsChannel types * update TextChannel properties to include a Type optional parameter with validation as of writing, this feature is still only available to verified guilds, which makes it impossible for testing. * actually create the news channels when given the type * throw NotSupportedException in News channel throw a NotSupportedException whenever trying to use SlowModeInterval or anything related to overwrite permissions * make RestNewsChannel throw NotSupportedException also * remove the (untested) ability to change channel types --- .../Entities/Channels/ChannelType.cs | 4 +- .../Entities/Channels/RestChannel.cs | 1 + .../Entities/Channels/RestGuildChannel.cs | 16 +++--- .../Entities/Channels/RestNewsChannel.cs | 53 +++++++++++++++++++ .../Entities/Channels/RestTextChannel.cs | 2 +- .../Entities/Channels/SocketGuildChannel.cs | 17 +++--- .../Entities/Channels/SocketNewsChannel.cs | 52 ++++++++++++++++++ .../Entities/Channels/SocketTextChannel.cs | 4 +- 8 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 src/Discord.Net.Rest/Entities/Channels/RestNewsChannel.cs create mode 100644 src/Discord.Net.WebSocket/Entities/Channels/SocketNewsChannel.cs diff --git a/src/Discord.Net.Core/Entities/Channels/ChannelType.cs b/src/Discord.Net.Core/Entities/Channels/ChannelType.cs index 7759622c2..6dd910ba6 100644 --- a/src/Discord.Net.Core/Entities/Channels/ChannelType.cs +++ b/src/Discord.Net.Core/Entities/Channels/ChannelType.cs @@ -12,6 +12,8 @@ namespace Discord /// The channel is a group channel. Group = 3, /// The channel is a category channel. - Category = 4 + Category = 4, + /// The channel is a news channel. + News = 5 } } diff --git a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs index dd190199f..6f6a1f0d3 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestChannel.cs @@ -23,6 +23,7 @@ namespace Discord.Rest { switch (model.Type) { + case ChannelType.News: case ChannelType.Text: case ChannelType.Voice: return RestGuildChannel.Create(discord, new RestGuild(discord, model.GuildId.Value), model); diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs index 5f4db2eea..fdfee39ea 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs @@ -15,7 +15,7 @@ namespace Discord.Rest private ImmutableArray _overwrites; /// - public IReadOnlyCollection PermissionOverwrites => _overwrites; + public virtual IReadOnlyCollection PermissionOverwrites => _overwrites; internal IGuild Guild { get; } /// @@ -34,6 +34,8 @@ namespace Discord.Rest { switch (model.Type) { + case ChannelType.News: + return RestNewsChannel.Create(discord, guild, model); case ChannelType.Text: return RestTextChannel.Create(discord, guild, model); case ChannelType.Voice: @@ -79,7 +81,7 @@ namespace Discord.Rest /// /// An overwrite object for the targeted user; null if none is set. /// - public OverwritePermissions? GetPermissionOverwrite(IUser user) + public virtual OverwritePermissions? GetPermissionOverwrite(IUser user) { for (int i = 0; i < _overwrites.Length; i++) { @@ -96,7 +98,7 @@ namespace Discord.Rest /// /// An overwrite object for the targeted role; null if none is set. /// - public OverwritePermissions? GetPermissionOverwrite(IRole role) + public virtual OverwritePermissions? GetPermissionOverwrite(IRole role) { for (int i = 0; i < _overwrites.Length; i++) { @@ -115,7 +117,7 @@ namespace Discord.Rest /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// - public async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + public virtual async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, user, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(user.Id, PermissionTarget.User, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); @@ -129,7 +131,7 @@ namespace Discord.Rest /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// - public async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + public virtual async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, role, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(role.Id, PermissionTarget.Role, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); @@ -143,7 +145,7 @@ namespace Discord.Rest /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// - public async Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + public virtual async Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, user, options).ConfigureAwait(false); @@ -164,7 +166,7 @@ namespace Discord.Rest /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// - public async Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + public virtual async Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, role, options).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/Entities/Channels/RestNewsChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestNewsChannel.cs new file mode 100644 index 000000000..f4984a0d2 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/Channels/RestNewsChannel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Model = Discord.API.Channel; + +namespace Discord.Rest +{ + /// + /// Represents a REST-based news channel in a guild that has the same properties as a . + /// + [DebuggerDisplay(@"{DebuggerDisplay,nq}")] + public class RestNewsChannel : RestTextChannel + { + internal RestNewsChannel(BaseDiscordClient discord, IGuild guild, ulong id) + :base(discord, guild, id) + { + } + internal new static RestNewsChannel Create(BaseDiscordClient discord, IGuild guild, Model model) + { + var entity = new RestNewsChannel(discord, guild, model.Id); + entity.Update(model); + return entity; + } + public override int SlowModeInterval => throw new NotSupportedException("News channels do not support Slow Mode."); + public override Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override OverwritePermissions? GetPermissionOverwrite(IRole role) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override OverwritePermissions? GetPermissionOverwrite(IUser user) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + } +} diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index e95b6e877..78bc7393f 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -17,7 +17,7 @@ namespace Discord.Rest /// public string Topic { get; private set; } /// - public int SlowModeInterval { get; private set; } + public virtual int SlowModeInterval { get; private set; } /// public ulong? CategoryId { get; private set; } diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs index 18401c593..c65f3be05 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs @@ -30,7 +30,7 @@ namespace Discord.WebSocket public int Position { get; private set; } /// - public IReadOnlyCollection PermissionOverwrites => _overwrites; + public virtual IReadOnlyCollection PermissionOverwrites => _overwrites; /// /// Gets a collection of users that are able to view the channel. /// @@ -48,6 +48,8 @@ namespace Discord.WebSocket { switch (model.Type) { + case ChannelType.News: + return SocketNewsChannel.Create(guild, state, model); case ChannelType.Text: return SocketTextChannel.Create(guild, state, model); case ChannelType.Voice: @@ -55,7 +57,6 @@ namespace Discord.WebSocket case ChannelType.Category: return SocketCategoryChannel.Create(guild, state, model); default: - // TODO: Proper implementation for channel categories return new SocketGuildChannel(guild.Discord, model.Id, guild); } } @@ -86,7 +87,7 @@ namespace Discord.WebSocket /// /// An overwrite object for the targeted user; null if none is set. /// - public OverwritePermissions? GetPermissionOverwrite(IUser user) + public virtual OverwritePermissions? GetPermissionOverwrite(IUser user) { for (int i = 0; i < _overwrites.Length; i++) { @@ -102,7 +103,7 @@ namespace Discord.WebSocket /// /// An overwrite object for the targeted role; null if none is set. /// - public OverwritePermissions? GetPermissionOverwrite(IRole role) + public virtual OverwritePermissions? GetPermissionOverwrite(IRole role) { for (int i = 0; i < _overwrites.Length; i++) { @@ -121,7 +122,7 @@ namespace Discord.WebSocket /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// - public async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + public virtual async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, user, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(user.Id, PermissionTarget.User, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); @@ -136,7 +137,7 @@ namespace Discord.WebSocket /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// - public async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + public virtual async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, role, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(role.Id, PermissionTarget.Role, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); @@ -149,7 +150,7 @@ namespace Discord.WebSocket /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// - public async Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + public virtual async Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, user, options).ConfigureAwait(false); @@ -170,7 +171,7 @@ namespace Discord.WebSocket /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// - public async Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + public virtual async Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, role, options).ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketNewsChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketNewsChannel.cs new file mode 100644 index 000000000..53fea150f --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketNewsChannel.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using Model = Discord.API.Channel; + +namespace Discord.WebSocket +{ + /// + /// Represents a WebSocket-based news channel in a guild that has the same properties as a . + /// + [DebuggerDisplay(@"{DebuggerDisplay,nq}")] + public class SocketNewsChannel : SocketTextChannel + { + internal SocketNewsChannel(DiscordSocketClient discord, ulong id, SocketGuild guild) + :base(discord, id, guild) + { + } + internal new static SocketNewsChannel Create(SocketGuild guild, ClientState state, Model model) + { + var entity = new SocketNewsChannel(guild.Discord, model.Id, guild); + entity.Update(state, model); + return entity; + } + public override int SlowModeInterval + { + get { throw new NotSupportedException("News channels do not support Slow Mode."); } + } + public override Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override IReadOnlyCollection PermissionOverwrites + => throw new NotSupportedException("News channels do not support Overwrite Permissions."); + public override Task SyncPermissionsAsync(RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + public override Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) + { + throw new NotSupportedException("News channels do not support Overwrite Permissions."); + } + } +} diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index 496b96d30..239d39eab 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -21,7 +21,7 @@ namespace Discord.WebSocket /// public string Topic { get; private set; } /// - public int SlowModeInterval { get; private set; } + public virtual int SlowModeInterval { get; private set; } /// public ulong? CategoryId { get; private set; } /// @@ -33,7 +33,7 @@ namespace Discord.WebSocket public ICategoryChannel Category => CategoryId.HasValue ? Guild.GetChannel(CategoryId.Value) as ICategoryChannel : null; /// - public Task SyncPermissionsAsync(RequestOptions options = null) + public virtual Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); private bool _nsfw;