diff --git a/NetCord/Rest/AllowedMentionsProperties.cs b/NetCord/Rest/AllowedMentionsProperties.cs index 75a4d5aa8..67bb2dcb9 100644 --- a/NetCord/Rest/AllowedMentionsProperties.cs +++ b/NetCord/Rest/AllowedMentionsProperties.cs @@ -21,7 +21,7 @@ public partial class AllowedMentionsProperties /// /// A list of mentionable role IDs. Allows all roles if set to . /// - /// /// + /// /// /// If a role's property is set to , and is not set, it will not be mentioned regardless. /// diff --git a/NetCord/Rest/JsonModels/JsonChannelPins.cs b/NetCord/Rest/JsonModels/JsonChannelPins.cs new file mode 100644 index 000000000..00652eee1 --- /dev/null +++ b/NetCord/Rest/JsonModels/JsonChannelPins.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +using NetCord.JsonModels; + +namespace NetCord.Rest.JsonModels; + +internal class JsonChannelPins +{ + [JsonPropertyName("items")] + public JsonMessagePin[] Items { get; set; } + + [JsonPropertyName("has_more")] + public bool HasMore { get; set; } +} diff --git a/NetCord/Rest/JsonModels/JsonMessagePin.cs b/NetCord/Rest/JsonModels/JsonMessagePin.cs new file mode 100644 index 000000000..4099daa7a --- /dev/null +++ b/NetCord/Rest/JsonModels/JsonMessagePin.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +using NetCord.JsonModels; + +namespace NetCord.Rest.JsonModels; + +public class JsonMessagePin +{ + [JsonPropertyName("pinned_at")] + public DateTimeOffset PinnedAt { get; set; } + + [JsonPropertyName("message")] + public JsonMessage Message { get; set; } +} diff --git a/NetCord/Rest/MessagePin.cs b/NetCord/Rest/MessagePin.cs new file mode 100644 index 000000000..e46633b61 --- /dev/null +++ b/NetCord/Rest/MessagePin.cs @@ -0,0 +1,19 @@ +namespace NetCord.Rest; + +/// +/// Represents a message pin in a channel, containing the pinned message and the time it was pinned. +/// +public class MessagePin(JsonModels.JsonMessagePin jsonModel, RestClient client) : IJsonModel +{ + JsonModels.JsonMessagePin IJsonModel.JsonModel => jsonModel; + + /// + /// The time the message was pinned. + /// + public DateTimeOffset PinnedAt => jsonModel.PinnedAt; + + /// + /// The pinned message. + /// + public RestMessage Message { get; } = new(jsonModel.Message, client); +} diff --git a/NetCord/Rest/RestClient.Channel.cs b/NetCord/Rest/RestClient.Channel.cs index ef8b636c5..018be8336 100644 --- a/NetCord/Rest/RestClient.Channel.cs +++ b/NetCord/Rest/RestClient.Channel.cs @@ -645,7 +645,7 @@ public Task TriggerTypingAsync(ulong channelId, RestRequestProperties? propertie => SendRequestAsync(HttpMethod.Post, $"/channels/{channelId}/typing", null, new(channelId), properties, cancellationToken: cancellationToken); /// - /// /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger. + /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger. /// /// The ID of the channel to type in. /// Optional properties to customize the typing interval, can be . @@ -660,7 +660,7 @@ public ValueTask EnterTypingScopeAsync(ulong channelId, TypingScope } /// - /// /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger. + /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger. /// /// The ID of the channel to type in. /// Optional properties to customize the typing interval, can be . @@ -674,16 +674,45 @@ public IDisposable EnterTypingScope(ulong channelId, TypingScopeProperties? scop /// /// Retrieves all pinned messages in a channel. /// + /// + /// Requires the permission. + /// If the user is missing the permission in the channel, then no pins will be returned. + /// /// The ID of the channel to get pinned messages from. - /// Optional properties to customize the request, can be . + /// Optional properties to customize result pagination, can be . + /// Optional properties to customize each request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] - public async Task> GetPinnedMessagesAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => (await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/pins", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessageArray).ConfigureAwait(false)).Select(m => new RestMessage(m, this)).ToArray(); + [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id), TypeNameOverride = "Channel")] + public IAsyncEnumerable GetChannelPinsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + { + paginationProperties = + PaginationProperties.PrepareWithDirectionValidation( + paginationProperties, + PaginationDirection.Before, + 50); + + return new OptimizedQueryPaginationAsyncEnumerable( + this, + paginationProperties, + async s => + { + var result = await s.ToObjectAsync(Serialization.Default.JsonChannelPins).ConfigureAwait(false); + return (result.Items.Select(m => new MessagePin(m, this)), result.HasMore); + }, + m => m.PinnedAt, + HttpMethod.Get, + $"/channels/{channelId}/messages/pins", + new(paginationProperties.BatchSize.GetValueOrDefault(), paginationProperties.Direction.GetValueOrDefault(), timestamp => timestamp.ToString("s")), + new(channelId), + properties); + } /// /// Pins a message in a channel. /// + /// + /// Requires the permission. Fires a event. + /// /// The ID of the channel containing the message. /// The ID of the message to pin. /// Optional properties to customize the request, can be . @@ -691,11 +720,14 @@ public async Task> GetPinnedMessagesAsync(ulong chann [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task PinMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => SendRequestAsync(HttpMethod.Put, $"/channels/{channelId}/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken); + => SendRequestAsync(HttpMethod.Put, $"/channels/{channelId}/messages/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken); /// /// Unpins a message from a channel. /// + /// + /// Requires the permission. Fires a event. + /// /// The ID of the channel containing the message. /// The ID of the message to unpin. /// Optional properties to customize the request, can be . @@ -703,7 +735,7 @@ public Task PinMessageAsync(ulong channelId, ulong messageId, RestRequestPropert [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task UnpinMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken); + => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken); /// /// Adds a recipient to a group DM channel. diff --git a/NetCord/Serialization.cs b/NetCord/Serialization.cs index f8be6b8a0..c38ec6ba9 100644 --- a/NetCord/Serialization.cs +++ b/NetCord/Serialization.cs @@ -211,6 +211,7 @@ namespace NetCord; [JsonSerializable(typeof(JsonEntitlement[]))] [JsonSerializable(typeof(JsonSku[]))] [JsonSerializable(typeof(JsonAuthorizationInformation))] +[JsonSerializable(typeof(JsonChannelPins))] [JsonSerializable(typeof(StageInstanceProperties))] [JsonSerializable(typeof(StageInstanceOptions))] [JsonSerializable(typeof(JsonSticker))]