diff --git a/src/Discord.Net.Core/Discord.Net.Core.xml b/src/Discord.Net.Core/Discord.Net.Core.xml index bce491f0f..076aa6db5 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.xml +++ b/src/Discord.Net.Core/Discord.Net.Core.xml @@ -1987,6 +1987,11 @@ Represents a thread channel inside of a guild. + + + if the current user has joined this thread, otherwise . + + if the current thread is archived, otherwise . @@ -2017,6 +2022,18 @@ An approximate count of messages in a thread, stops counting at 50. + + + Joins the current thread. + + + + + + Leaves the current thread. + + + Represents a generic voice channel in a guild. @@ -4107,6 +4124,11 @@ A or . + + + A . + + Provides properties that are used to modify a with the specified changes. @@ -4502,7 +4524,8 @@ - Adds a button to the specified row. + Adds a with specified parameters to the at the specific row. + If the row cannot accept the component then it will add it to a row that can. The label text for the newly added button. The style of this newly added button. @@ -4627,44 +4650,49 @@ Creates a new instance of a from instance of a . - + Creates a button with the style. - The label to use on the newly created link button. + The label for this link button. The url for this link button to go to. + The emote for this link button A builder with the newly created button. - + Creates a button with the style. The label for this danger button. The custom id for this danger button. + The emote for this danger button A builder with the newly created button. - + Creates a button with the style. The label for this primary button. The custom id for this primary button. + The emote for this primary button A builder with the newly created button. - + Creates a button with the style. The label for this secondary button. The custom id for this secondary button. + The emote for this secondary button A builder with the newly created button. - + Creates a button with the style. The label for this success button. The custom id for this success button. + The emote for this success button A builder with the newly created button. diff --git a/src/Discord.Net.Core/Entities/Channels/IThreadChannel.cs b/src/Discord.Net.Core/Entities/Channels/IThreadChannel.cs index 1459c954c..f801d3fd8 100644 --- a/src/Discord.Net.Core/Entities/Channels/IThreadChannel.cs +++ b/src/Discord.Net.Core/Entities/Channels/IThreadChannel.cs @@ -11,6 +11,11 @@ namespace Discord /// public interface IThreadChannel : ITextChannel, IGuildChannel { + /// + /// if the current user has joined this thread, otherwise . + /// + bool Joined { get; } + /// /// if the current thread is archived, otherwise . /// @@ -40,5 +45,17 @@ namespace Discord /// An approximate count of messages in a thread, stops counting at 50. /// int MessageCount { get; } + + /// + /// Joins the current thread. + /// + /// + Task JoinAsync(); + + /// + /// Leaves the current thread. + /// + /// + Task LeaveAsync(); } } diff --git a/src/Discord.Net.WebSocket/API/Gateway/ThreadMembersUpdate.cs b/src/Discord.Net.WebSocket/API/Gateway/ThreadMembersUpdate.cs new file mode 100644 index 000000000..b6acba6ae --- /dev/null +++ b/src/Discord.Net.WebSocket/API/Gateway/ThreadMembersUpdate.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord.API.Gateway +{ + internal class ThreadMembersUpdated + { + [JsonProperty("id")] + public ulong Id { get; set; } + + [JsonProperty("guild_id")] + public ulong GuildId { get; set; } + + [JsonProperty("member_count")] + public int MemberCount { get; set; } + + [JsonProperty("added_members")] + public Optional AddedMembers { get; set; } + + [JsonProperty("removed_member_ids")] + public Optional RemovedMemberIds { get; set; } + } +} diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml index 00f22c0e8..8db8a1340 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml @@ -756,6 +756,21 @@ + + + Fired when a thread is created within a guild. + + + + + Fired when a thread is updated within a guild. + + + + + Fired when a thread is deleted. + + @@ -2154,6 +2169,11 @@ + + + Gets a collection of threads within this text channel. + + @@ -2360,9 +2380,19 @@ Represents a thread channel inside of a guild. - + + + + if this thread is private, otherwise + + + + + Gets the parent channel this thread resides in. + + @@ -2848,6 +2878,14 @@ A read-only collection of category channels found within this guild. + + + Gets a collection of all thread channels in this guild. + + + A read-only collection of thread channels found within this guild. + + Gets the current logged-in user. @@ -3431,10 +3469,11 @@ - Updates the original message of the component on which the interaction was received on. + Updates the message which this component resides in with the type A delegate containing the properties to modify the message with. The request options for this async request. + A task that represents the asynchronous operation of updating the message. @@ -3689,6 +3728,14 @@ The request options for this async request. A that represents the initial response. + + + Acknowledges this interaction. + + + A task that represents the asynchronous operation of acknowledging the interaction. + + Acknowledges this interaction. @@ -4488,6 +4535,156 @@ + + + Gets the this user is in. + + + + + Gets the timestamp for when this user joined this thread. + + + + + Gets the guild this user is in. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gets the guild user of this thread user. + + + Represents a WebSocket-based user that is yet to be recognized by the client. diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index c05ff3878..c52675d66 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -1975,48 +1975,62 @@ namespace Discord.WebSocket // Threads case "THREAD_CREATE": { - await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_CREATE)").ConfigureAwait(false); + try + { + await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_CREATE)").ConfigureAwait(false); - var data = (payload as JToken).ToObject(_serializer); + var data = (payload as JToken).ToObject(_serializer); - var guild = State.GetGuild(data.GuildId.Value); + var guild = State.GetGuild(data.GuildId.Value); - if(guild == null) - { - await UnknownGuildAsync(type, data.GuildId.Value); - return; - } + if (guild == null) + { + await UnknownGuildAsync(type, data.GuildId.Value); + return; + } + + var threadChannel = (SocketThreadChannel)guild.AddChannel(this.State, data); - var threadChannel = (SocketThreadChannel)guild.AddChannel(this.State, data); + await TimedInvokeAsync(_threadCreated, nameof(ThreadCreated), threadChannel).ConfigureAwait(false); + } + catch(Exception x) + { - await TimedInvokeAsync(_threadCreated, nameof(ThreadCreated), threadChannel).ConfigureAwait(false); + } } break; case "THREAD_UPDATE": { - await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_UPDATE)").ConfigureAwait(false); - - var data = (payload as JToken).ToObject(_serializer); - var guild = State.GetGuild(data.GuildId.Value); - if (guild == null) + try { - await UnknownGuildAsync(type, data.GuildId.Value); - return; - } + await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_UPDATE)").ConfigureAwait(false); - var channel = (SocketThreadChannel)guild.GetChannel(data.Id); + var data = (payload as JToken).ToObject(_serializer); + var guild = State.GetGuild(data.GuildId.Value); + if (guild == null) + { + await UnknownGuildAsync(type, data.GuildId.Value); + return; + } - var before = channel.Clone(); - channel.Update(State, data); + var channel = (SocketThreadChannel)guild.GetChannel(data.Id); - if (!(guild?.IsSynced ?? true)) - { - await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false); - return; + var before = channel.Clone(); + channel.Update(State, data); + + if (!(guild?.IsSynced ?? true)) + { + await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false); + return; + } + + await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, channel).ConfigureAwait(false); } + catch(Exception x) + { - await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, channel).ConfigureAwait(false); + } } break; @@ -2071,8 +2085,20 @@ namespace Discord.WebSocket } break; case "THREAD_MEMBER_UPDATE": + { + await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_MEMBER_UPDATE)").ConfigureAwait(false); + var p = payload; + } + break; case "THREAD_MEMBERS_UPDATE": // based on intents + { + await _gatewayLogger.DebugAsync("Received Dispatch (THREAD_MEMBERS_UPDATE)").ConfigureAwait(false); + + var data = (payload as JToken).ToObject(_serializer); + + } + break; //Ignored (User only) diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs index 9f63ad7b4..7187c9771 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs @@ -66,9 +66,9 @@ namespace Discord.WebSocket internal override void Update(ClientState state, Model model) { Name = model.Name.Value; - Position = model.Position.Value; + Position = model.Position.GetValueOrDefault(0); - var overwrites = model.PermissionOverwrites.Value; + var overwrites = model.PermissionOverwrites.GetValueOrDefault(new API.Overwrite[0]); var newOverwrites = ImmutableArray.CreateBuilder(overwrites.Length); for (int i = 0; i < overwrites.Length; i++) newOverwrites.Add(overwrites[i].ToEntity()); diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs index d9583d1ea..4072276cb 100644 --- a/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs +++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketThreadChannel.cs @@ -2,19 +2,26 @@ using Discord.Rest; using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Model = Discord.API.Channel; +using ThreadMember = Discord.API.ThreadMember; namespace Discord.WebSocket { /// /// Represents a thread channel inside of a guild. /// + [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class SocketThreadChannel : SocketGuildChannel, IThreadChannel, ISocketMessageChannel { + + /// + public bool Joined { get; private set; } + /// /// if this thread is private, otherwise /// @@ -65,6 +72,8 @@ namespace Discord.WebSocket private readonly MessageCache _messages; + private string DebuggerDisplay => $"{Name} ({Id}, Thread)"; + internal SocketThreadChannel(DiscordSocketClient discord, SocketGuild guild, ulong id, SocketTextChannel parent) : base(discord, id, guild) { @@ -97,6 +106,11 @@ namespace Discord.WebSocket } } + internal void Update(ClientState state, ThreadMember self) + { + + } + /// public virtual Task SyncPermissionsAsync(RequestOptions options = null) => ChannelHelper.SyncPermissionsAsync(this, Discord, options); @@ -253,10 +267,10 @@ namespace Discord.WebSocket public Task GetUsersAsync() { - + return Task.CompletedTask; } - private string DebuggerDisplay => $"{Name} ({Id}, Thread)"; + internal new SocketThreadChannel Clone() => MemberwiseClone() as SocketThreadChannel; //ITextChannel @@ -325,22 +339,22 @@ namespace Discord.WebSocket public Task JoinAsync() { - + return Task.CompletedTask; } public Task LeaveAsync() { - + return Task.CompletedTask; } public Task AddThreadMember(IGuildUser user) { - + return Task.CompletedTask; } public Task RemoveThreadMember(IGuildUser user) { - + return Task.CompletedTask; }