diff --git a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs index af4e5ec6a..f5605d84c 100644 --- a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs @@ -160,5 +160,15 @@ namespace Discord /// Task CreateThreadAsync(string name, ThreadType type = ThreadType.PublicThread, ThreadArchiveDuration autoArchiveDuration = ThreadArchiveDuration.OneDay, IMessage message = null, bool? invitable = null, int? slowmode = null, RequestOptions options = null); + + /// + /// Gets a collection of active threads within this channel. + /// + /// The options to be used when sending the request. + /// + /// A task that represents an asynchronous get operation for retrieving the threads. The task result contains + /// a collection of active threads. + /// + Task> GetActiveThreadsAsync(RequestOptions options = null); } } diff --git a/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs index 5ec81a7fc..a2eef3d2d 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs @@ -134,9 +134,9 @@ namespace Discord.Rest MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None, ForumTag[] tags = null) => ThreadHelper.CreatePostAsync(this, Discord, title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags, tags?.Select(tag => tag.Id).ToArray()); - /// + /// public Task> GetActiveThreadsAsync(RequestOptions options = null) - => ThreadHelper.GetActiveThreadsAsync(Guild, Discord, options); + => ThreadHelper.GetActiveThreadsAsync(Guild, Id, Discord, options); /// public Task> GetJoinedPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null) diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs index 81f21bcd7..f0669534e 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -288,6 +288,10 @@ namespace Discord.Rest /// public Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); + + /// + public virtual Task> GetActiveThreadsAsync(RequestOptions options = null) + => ThreadHelper.GetActiveThreadsAsync(Guild, Id, Discord, options); #endregion #region Invites @@ -321,6 +325,10 @@ namespace Discord.Rest async Task ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, bool? invitable, int? slowmode, RequestOptions options) => await CreateThreadAsync(name, type, autoArchiveDuration, message, invitable, slowmode, options); + + /// + async Task> ITextChannel.GetActiveThreadsAsync(RequestOptions options) + => await GetActiveThreadsAsync(options); #endregion #region IMessageChannel diff --git a/src/Discord.Net.Rest/Entities/Channels/RestThreadChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestThreadChannel.cs index c1be5182e..86e65d7b6 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestThreadChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestThreadChannel.cs @@ -241,5 +241,9 @@ namespace Discord.Rest /// public Task RemoveUserAsync(IGuildUser user, RequestOptions options = null) => Discord.ApiClient.RemoveThreadMemberAsync(Id, user.Id, options); + + /// This method is not supported in threads. + public override Task> GetActiveThreadsAsync(RequestOptions options = null) + => throw new NotSupportedException("This method is not supported in threads."); } } diff --git a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs index 3c9869c4c..01db33ffb 100644 --- a/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs +++ b/src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs @@ -234,6 +234,10 @@ namespace Discord.Rest return base.TriggerTypingAsync(options); } + /// Threads are not supported in voice channels + public override Task> GetActiveThreadsAsync(RequestOptions options = null) + => throw new NotSupportedException("Threads are not supported in voice channels"); + #endregion diff --git a/src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs index 52cba0657..0cdc92bcb 100644 --- a/src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs +++ b/src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs @@ -68,10 +68,10 @@ namespace Discord.Rest return await client.ApiClient.ModifyThreadAsync(channel.Id, apiArgs, options).ConfigureAwait(false); } - public static async Task> GetActiveThreadsAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) + public static async Task> GetActiveThreadsAsync(IGuild guild, ulong channelId, BaseDiscordClient client, RequestOptions options) { var result = await client.ApiClient.GetActiveThreadsAsync(guild.Id, options).ConfigureAwait(false); - return result.Threads.Select(x => RestThreadChannel.Create(client, guild, x)).ToImmutableArray(); + return result.Threads.Where(x => x.CategoryId == channelId).Select(x => RestThreadChannel.Create(client, guild, x)).ToImmutableArray(); } public static async Task> GetPublicArchivedThreadsAsync(IGuildChannel channel, BaseDiscordClient client, int? limit = null, diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs index 9d46bc2aa..8929a46f9 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs @@ -135,9 +135,9 @@ namespace Discord.WebSocket MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None, ForumTag[] tags = null) => ThreadHelper.CreatePostAsync(this, Discord, title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags, tags?.Select(tag => tag.Id).ToArray()); - /// + /// public Task> GetActiveThreadsAsync(RequestOptions options = null) - => ThreadHelper.GetActiveThreadsAsync(Guild, Discord, options); + => ThreadHelper.GetActiveThreadsAsync(Guild, Id, Discord, options); /// public Task> GetJoinedPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index 2d8aeeae7..48da69e09 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -130,7 +130,12 @@ namespace Discord.WebSocket return thread; } -#endregion + + /// + public virtual Task> GetActiveThreadsAsync(RequestOptions options = null) + => ThreadHelper.GetActiveThreadsAsync(Guild, Id, Discord, options); + + #endregion #region Messages /// @@ -378,6 +383,9 @@ namespace Discord.WebSocket /// async Task ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, bool? invitable, int? slowmode, RequestOptions options) => await CreateThreadAsync(name, type, autoArchiveDuration, message, invitable, slowmode, options); + /// + async Task> ITextChannel.GetActiveThreadsAsync(RequestOptions options) + => await GetActiveThreadsAsync(options); #endregion #region IGuildChannel diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs index d9d54f91e..423e5504f 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs @@ -374,6 +374,10 @@ namespace Discord.WebSocket public override Task SyncPermissionsAsync(RequestOptions options = null) => throw new NotSupportedException("This method is not supported in threads."); + /// This method is not supported in threads. + public override Task> GetActiveThreadsAsync(RequestOptions options = null) + => throw new NotSupportedException("This method is not supported in threads."); + string IChannel.Name => Name; } } diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs index 9036659fe..f2bb5d6d3 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs @@ -296,6 +296,10 @@ namespace Discord.WebSocket return base.TriggerTypingAsync(options); } + /// Threads are not supported in voice channels + public override Task> GetActiveThreadsAsync(RequestOptions options = null) + => throw new NotSupportedException("Threads are not supported in voice channels"); + #endregion private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; diff --git a/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs b/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs index 8913c127d..11737fb81 100644 --- a/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs +++ b/test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs @@ -214,11 +214,12 @@ namespace Discord { throw new NotImplementedException(); } - + public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); public Task CreateThreadAsync(string name, ThreadType type = ThreadType.PublicThread, ThreadArchiveDuration autoArchiveDuration = ThreadArchiveDuration.OneDay, IMessage message = null, bool? invitable = null, int? slowmode = null, RequestOptions options = null, MessageFlags flags = MessageFlags.None) => throw new NotImplementedException(); public Task CreateInviteToApplicationAsync(DefaultApplications application, int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => throw new NotImplementedException(); public Task CreateThreadAsync(string name, ThreadType type = ThreadType.PublicThread, ThreadArchiveDuration autoArchiveDuration = ThreadArchiveDuration.OneDay, IMessage message = null, bool? invitable = null, int? slowmode = null, RequestOptions options = null) => throw new NotImplementedException(); + public Task> GetActiveThreadsAsync(RequestOptions options = null) => throw new NotImplementedException(); } }