diff --git a/Documentation/guides/basic-concepts/SendingMessages/Program.cs b/Documentation/guides/basic-concepts/SendingMessages/Program.cs index 463110921..2aef74e3a 100644 --- a/Documentation/guides/basic-concepts/SendingMessages/Program.cs +++ b/Documentation/guides/basic-concepts/SendingMessages/Program.cs @@ -128,6 +128,7 @@ async static Task PropertiesAsync() attachment = new QuotedPrintableAttachmentProperties("polish.txt", new MemoryStream("R=C3=B3=C5=BCowy means pink"u8.ToArray())); + // TODO: This guide is outdated for the new channels interface representation. TextChannel textChannel = null!; HttpClient httpClient = null!; diff --git a/NetCord.Services/ApplicationCommands/ApplicationCommandContexts.cs b/NetCord.Services/ApplicationCommands/ApplicationCommandContexts.cs index c908d7067..3f6242ccc 100644 --- a/NetCord.Services/ApplicationCommands/ApplicationCommandContexts.cs +++ b/NetCord.Services/ApplicationCommands/ApplicationCommandContexts.cs @@ -29,7 +29,7 @@ public class ApplicationCommandContext(ApplicationCommandInteraction interaction public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -50,7 +50,7 @@ public class HttpApplicationCommandContext(ApplicationCommandInteraction interac public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => (ITextChannel)Interaction.Channel; public User User => Interaction.User; } @@ -84,7 +84,7 @@ public class SlashCommandContext(SlashCommandInteraction interaction, GatewayCli public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -105,7 +105,7 @@ public class HttpSlashCommandContext(SlashCommandInteraction interaction, RestCl public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; } @@ -139,7 +139,7 @@ public class UserCommandContext(UserCommandInteraction interaction, GatewayClien public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -165,7 +165,7 @@ public class HttpUserCommandContext(UserCommandInteraction interaction, RestClie public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -204,7 +204,7 @@ public class MessageCommandContext(MessageCommandInteraction interaction, Gatewa public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -230,7 +230,7 @@ public class HttpMessageCommandContext(MessageCommandInteraction interaction, Re public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -269,7 +269,7 @@ public class EntryPointCommandContext(EntryPointCommandInteraction interaction, public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; @@ -290,7 +290,7 @@ public class HttpEntryPointCommandContext(EntryPointCommandInteraction interacti public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; public User User => Interaction.User; } diff --git a/NetCord.Services/ApplicationCommands/AutocompleteInteractionContexts.cs b/NetCord.Services/ApplicationCommands/AutocompleteInteractionContexts.cs index 56e8f1f0b..df732dfb9 100644 --- a/NetCord.Services/ApplicationCommands/AutocompleteInteractionContexts.cs +++ b/NetCord.Services/ApplicationCommands/AutocompleteInteractionContexts.cs @@ -28,7 +28,7 @@ public class AutocompleteInteractionContext(AutocompleteInteraction interaction, public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => (ITextChannel)Interaction.Channel; public User User => Interaction.User; @@ -49,7 +49,7 @@ public class HttpAutocompleteInteractionContext(AutocompleteInteraction interact public RestClient Client => client; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => (ITextChannel)Interaction.Channel; public User User => Interaction.User; } diff --git a/NetCord.Services/Commands/CommandContexts.cs b/NetCord.Services/Commands/CommandContexts.cs index 75afca73e..a7c1eec2c 100644 --- a/NetCord.Services/Commands/CommandContexts.cs +++ b/NetCord.Services/Commands/CommandContexts.cs @@ -28,7 +28,7 @@ public class CommandContext(Message message, GatewayClient client) public Guild? Guild => Message.Guild; /// - public TextChannel? Channel => Message.Channel; + public ITextChannel? Channel => Message.Channel; public User User => Message.Author; diff --git a/NetCord.Services/Commands/TypeReaders/Channels/ChannelTypeReader.cs b/NetCord.Services/Commands/TypeReaders/Channels/ChannelTypeReader.cs index 6077e9805..370b1ffef 100644 --- a/NetCord.Services/Commands/TypeReaders/Channels/ChannelTypeReader.cs +++ b/NetCord.Services/Commands/TypeReaders/Channels/ChannelTypeReader.cs @@ -14,12 +14,12 @@ public override ValueTask ParseAsync(ReadOnlyMemory(channel, input.Span)); } else - return new(GetGuildChannel(guild, input.Span)); + return new(GetGuildChannel(guild, input.Span)); return new(CommandTypeParserResult.Fail("The channel was not found.")); } - protected CommandTypeParserResult GetChannel(TextChannel channel, ReadOnlySpan input) + protected CommandTypeParserResult GetChannel(ITextChannel channel, ReadOnlySpan input) { if (Mention.TryParseChannel(input, out var id)) { diff --git a/NetCord.Services/Commands/TypeReaders/UserTypeReader.cs b/NetCord.Services/Commands/TypeReaders/UserTypeReader.cs index d471c8751..db3daba3e 100644 --- a/NetCord.Services/Commands/TypeReaders/UserTypeReader.cs +++ b/NetCord.Services/Commands/TypeReaders/UserTypeReader.cs @@ -20,7 +20,7 @@ public override ValueTask ParseAsync(ReadOnlyMemory input) + protected CommandTypeParserResult GetUser(IDMChannel dMChannel, ReadOnlySpan input) { var users = dMChannel.Users; diff --git a/NetCord.Services/ComponentInteractions/ComponentInteractionContexts.cs b/NetCord.Services/ComponentInteractions/ComponentInteractionContexts.cs index 29a4534c7..368fc59fb 100644 --- a/NetCord.Services/ComponentInteractions/ComponentInteractionContexts.cs +++ b/NetCord.Services/ComponentInteractions/ComponentInteractionContexts.cs @@ -32,7 +32,7 @@ public class ComponentInteractionContext(ComponentInteraction interaction, Gatew public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; ulong? IGuildContext.GuildId => Interaction.GuildId; } @@ -53,7 +53,7 @@ public class HttpComponentInteractionContext(ComponentInteraction interaction, R public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; } /// @@ -90,7 +90,7 @@ public class MessageComponentInteractionContext(MessageComponentInteraction inte public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; ulong? IGuildContext.GuildId => Interaction.GuildId; } @@ -114,7 +114,7 @@ public class HttpMessageComponentInteractionContext(MessageComponentInteraction public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; } /// @@ -151,7 +151,7 @@ public class ButtonInteractionContext(ButtonInteraction interaction, GatewayClie public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; ulong? IGuildContext.GuildId => Interaction.GuildId; } @@ -175,7 +175,7 @@ public class HttpButtonInteractionContext(ButtonInteraction interaction, RestCli public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; } /// @@ -212,7 +212,7 @@ public class StringMenuInteractionContext(StringMenuInteraction interaction, Gat public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected string values from the menu. @@ -241,7 +241,7 @@ public class HttpStringMenuInteractionContext(StringMenuInteraction interaction, public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected string values from the menu. @@ -283,7 +283,7 @@ public class EntityMenuInteractionContext(EntityMenuInteraction interaction, Gat public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected entity IDs from the menu. @@ -312,7 +312,7 @@ public class HttpEntityMenuInteractionContext(EntityMenuInteraction interaction, public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected entity IDs from the menu. @@ -354,7 +354,7 @@ public class UserMenuInteractionContext(UserMenuInteraction interaction, Gateway public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected users from the menu. @@ -383,7 +383,7 @@ public class HttpUserMenuInteractionContext(UserMenuInteraction interaction, Res public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected users from the menu. @@ -425,7 +425,7 @@ public class RoleMenuInteractionContext(RoleMenuInteraction interaction, Gateway public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected roles from the menu. @@ -454,7 +454,7 @@ public class HttpRoleMenuInteractionContext(RoleMenuInteraction interaction, Res public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected roles from the menu. @@ -496,7 +496,7 @@ public class MentionableMenuInteractionContext(MentionableMenuInteraction intera public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected mentionables (users or roles) from the menu. @@ -525,7 +525,7 @@ public class HttpMentionableMenuInteractionContext(MentionableMenuInteraction in public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The selected mentionables (users or roles) from the menu. @@ -567,12 +567,12 @@ public class ChannelMenuInteractionContext(ChannelMenuInteraction interaction, G public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => (ITextChannel)Interaction.Channel; /// /// The selected channels from the menu. /// - public IReadOnlyList SelectedValues => Interaction.Data.SelectedValues; + public IReadOnlyList SelectedValues => Interaction.Data.SelectedValues; ulong? IGuildContext.GuildId => Interaction.GuildId; } @@ -596,12 +596,12 @@ public class HttpChannelMenuInteractionContext(ChannelMenuInteraction interactio public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => (ITextChannel)Interaction.Channel; /// /// The selected channels from the menu. /// - public IReadOnlyList SelectedValues => Interaction.Data.SelectedValues; + public IReadOnlyList SelectedValues => Interaction.Data.SelectedValues; } /// @@ -635,7 +635,7 @@ public class ModalInteractionContext(ModalInteraction interaction, GatewayClient public Guild? Guild => Interaction.Guild; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The components submitted with the modal. @@ -661,7 +661,7 @@ public class HttpModalInteractionContext(ModalInteraction interaction, RestClien public User User => Interaction.User; /// - public TextChannel Channel => Interaction.Channel; + public ITextChannel Channel => Interaction.Channel; /// /// The components submitted with the modal. diff --git a/NetCord.Services/Contexts/IChannelContext.cs b/NetCord.Services/Contexts/IChannelContext.cs index 1d16066b3..7ddfca14d 100644 --- a/NetCord.Services/Contexts/IChannelContext.cs +++ b/NetCord.Services/Contexts/IChannelContext.cs @@ -9,5 +9,5 @@ public interface IChannelContext : IContext /// Channel in which the handled command or interaction was invoked. /// /// May be if the channel has not been cached. - public TextChannel? Channel { get; } + public ITextChannel? Channel { get; } } diff --git a/NetCord/ChannelMenuInteraction.cs b/NetCord/ChannelMenuInteraction.cs index 887900a89..eac5b4868 100644 --- a/NetCord/ChannelMenuInteraction.cs +++ b/NetCord/ChannelMenuInteraction.cs @@ -19,5 +19,5 @@ public unsafe ChannelMenuInteractionData(JsonModels.JsonInteractionData jsonMode SelectedValues = selectedValues; } - public new IReadOnlyList SelectedValues { get; } + public new IReadOnlyList SelectedValues { get; } } diff --git a/NetCord/Channels/Channel.cs b/NetCord/Channels/Channel.cs index a2f0e00cf..4f8fb2d73 100644 --- a/NetCord/Channels/Channel.cs +++ b/NetCord/Channels/Channel.cs @@ -3,38 +3,19 @@ namespace NetCord; -public abstract partial class Channel(JsonChannel jsonModel, RestClient client) : ClientEntity(client), IJsonModel, IInteractionChannel +internal abstract partial class Channel(JsonChannel jsonModel, RestClient client) : ClientEntity(client), IJsonModel, IInteractionChannel { JsonChannel IJsonModel.JsonModel => _jsonModel; + private protected JsonChannel _jsonModel = jsonModel; public override ulong Id => _jsonModel.Id; - public ChannelFlags Flags => _jsonModel.Flags.GetValueOrDefault(); + + public ChannelFlags? Flags => _jsonModel.Flags; Permissions IInteractionChannel.Permissions => _jsonModel.Permissions.GetValueOrDefault(); public override string ToString() => $"<#{Id}>"; public override bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) => Mention.TryFormatChannel(destination, out charsWritten, Id); - - public static Channel CreateFromJson(JsonChannel jsonChannel, RestClient client) - { - return jsonChannel.Type switch - { - ChannelType.TextGuildChannel => new TextGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.DMChannel => new DMChannel(jsonChannel, client), - ChannelType.VoiceGuildChannel => new VoiceGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.GroupDMChannel => new GroupDMChannel(jsonChannel, client), - ChannelType.CategoryChannel => new CategoryGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.AnnouncementGuildChannel => new AnnouncementGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.AnnouncementGuildThread => new AnnouncementGuildThread(jsonChannel, client), - ChannelType.PublicGuildThread => new PublicGuildThread(jsonChannel, client), - ChannelType.PrivateGuildThread => new PrivateGuildThread(jsonChannel, client), - ChannelType.StageGuildChannel => new StageGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.DirectoryGuildChannel => new DirectoryGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.ForumGuildChannel => new ForumGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.MediaForumGuildChannel => new MediaForumGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - _ => new UnknownChannel(jsonChannel, client), - }; - } } diff --git a/NetCord/Channels/ChannelFactory.cs b/NetCord/Channels/ChannelFactory.cs new file mode 100644 index 000000000..508b5f36f --- /dev/null +++ b/NetCord/Channels/ChannelFactory.cs @@ -0,0 +1,69 @@ +using NetCord.JsonModels; +using NetCord.Rest; + +namespace NetCord; + +internal static class ChannelFactory +{ + public static IGuildChannel CreateGuild( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static ITextChannel CreateText( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static IDMChannel CreateDM( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static IGroupDMChannel CreateGroupDM( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static IGuildThread CreateGuildThread( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static IPublicGuildThread CreatePublicGuildThread( + JsonChannel jsonChannel, + RestClient client) + => Require(Create(jsonChannel, client)); + + public static IChannel Create( + JsonChannel jsonChannel, + RestClient client) + { + return jsonChannel.Type switch + { + ChannelType.TextGuildChannel => new TextGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.DMChannel => new DMChannel(jsonChannel, client), + ChannelType.VoiceGuildChannel => new VoiceGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.GroupDMChannel => new GroupDMChannel(jsonChannel, client), + ChannelType.CategoryChannel => new CategoryGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.AnnouncementGuildChannel => new AnnouncementGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.AnnouncementGuildThread => new AnnouncementGuildThread(jsonChannel, client), + ChannelType.PublicGuildThread => new PublicGuildThread(jsonChannel, client), + ChannelType.PrivateGuildThread => new PrivateGuildThread(jsonChannel, client), + ChannelType.StageGuildChannel => new StageGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.DirectoryGuildChannel => new DirectoryGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.ForumGuildChannel => new ForumGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + ChannelType.MediaForumGuildChannel => new MediaForumGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), + _ => new UnknownChannel(jsonChannel, client), + }; + } + + private static TChannel Require(IChannel channel) + where TChannel : IChannel + { + if (channel is TChannel result) + return result; + + throw new InvalidOperationException(); + } +} \ No newline at end of file diff --git a/NetCord/Channels/DMChannel.cs b/NetCord/Channels/DMChannel.cs new file mode 100644 index 000000000..e54d05cba --- /dev/null +++ b/NetCord/Channels/DMChannel.cs @@ -0,0 +1,17 @@ +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a text channel for private messages between two users. +/// +internal partial class DMChannel(JsonModels.JsonChannel jsonModel, RestClient client) : TextChannelBase(jsonModel, client), IDMChannel +{ + /// + /// A list of the users present in the private channel, indexed by their IDs. + /// + public IReadOnlyDictionary Users { get; } = jsonModel.Users.ToDictionaryOrEmpty(u => u.Id, u => new User(u, client)); + + /// + public DateTimeOffset? LastPin => throw new NotImplementedException(); +} diff --git a/NetCord/Channels/TextChannels/GroupDMChannel.cs b/NetCord/Channels/GroupDMChannel.cs similarity index 87% rename from NetCord/Channels/TextChannels/GroupDMChannel.cs rename to NetCord/Channels/GroupDMChannel.cs index d0474a43d..87c2749b3 100644 --- a/NetCord/Channels/TextChannels/GroupDMChannel.cs +++ b/NetCord/Channels/GroupDMChannel.cs @@ -5,7 +5,7 @@ namespace NetCord; /// /// Represents a text channel for private messages, with up to 10 users. /// -public partial class GroupDMChannel(JsonModels.JsonChannel jsonModel, RestClient client) : DMChannel(jsonModel, client), INamedChannel +internal partial class GroupDMChannel(JsonModels.JsonChannel jsonModel, RestClient client) : DMChannel(jsonModel, client), INamedChannel { /// /// The group channel's name. diff --git a/NetCord/Channels/Guild/AnnouncementGuildChannel.cs b/NetCord/Channels/Guild/AnnouncementGuildChannel.cs new file mode 100644 index 000000000..b824026b7 --- /dev/null +++ b/NetCord/Channels/Guild/AnnouncementGuildChannel.cs @@ -0,0 +1,25 @@ +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a channel that users can follow and crosspost from into their own servers. Formerly known as news channels. +/// +internal partial class AnnouncementGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : GuildMessageChannelBase(jsonModel, guildId, client), IAnnouncementGuildChannel +{ + public string? Topic => _jsonModel.Topic; + + public bool? Nsfw => _jsonModel.Nsfw; + + public int? Slowmode => _jsonModel.Slowmode; + + public ThreadArchiveDuration? DefaultAutoArchiveDuration => _jsonModel.DefaultAutoArchiveDuration; + + public string Name => _jsonModel.Name!; + + public int Position => _jsonModel.Position.GetValueOrDefault(); + + public ulong? ParentId => _jsonModel.ParentId; + public IReadOnlyDictionary PermissionOverwrites => _jsonModel.PermissionOverwrites.ToDictionaryOrEmpty(p => p.Id, p => new PermissionOverwrite(p)); + public DateTimeOffset? LastPin => _jsonModel.LastPin; +} diff --git a/NetCord/Channels/CategoryGuildChannel.cs b/NetCord/Channels/Guild/CategoryGuildChannel.cs similarity index 74% rename from NetCord/Channels/CategoryGuildChannel.cs rename to NetCord/Channels/Guild/CategoryGuildChannel.cs index 9d30739ec..1e953d5c2 100644 --- a/NetCord/Channels/CategoryGuildChannel.cs +++ b/NetCord/Channels/Guild/CategoryGuildChannel.cs @@ -5,7 +5,7 @@ namespace NetCord; /// /// Represents a category within a guild. /// -public partial class CategoryGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : Channel(jsonModel, client), IGuildChannel +internal partial class CategoryGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : Channel(jsonModel, client), IGuildChannel { public ulong GuildId { get; } = guildId; diff --git a/NetCord/Channels/TextChannels/Guild/DirectoryGuildChannel.cs b/NetCord/Channels/Guild/DirectoryGuildChannel.cs similarity index 56% rename from NetCord/Channels/TextChannels/Guild/DirectoryGuildChannel.cs rename to NetCord/Channels/Guild/DirectoryGuildChannel.cs index 9e149d0e1..843e5409f 100644 --- a/NetCord/Channels/TextChannels/Guild/DirectoryGuildChannel.cs +++ b/NetCord/Channels/Guild/DirectoryGuildChannel.cs @@ -6,10 +6,10 @@ namespace NetCord; /// /// Represents a hub channel, with listed guilds. /// -public partial class DirectoryGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client) : TextChannel(jsonModel, client), IGuildChannel +internal partial class DirectoryGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client) : TextChannelBase(jsonModel, client), IGuildChannel { public ulong GuildId { get; } = guildId; public int? Position => _jsonModel.Position; - public IReadOnlyDictionary PermissionOverwrites { get; } = jsonModel.PermissionOverwrites.ToDictionaryOrEmpty(p => p.Id, p => new PermissionOverwrite(p)); + public IReadOnlyDictionary PermissionOverwrites => _jsonModel.PermissionOverwrites.ToDictionaryOrEmpty(p => p.Id, p => new PermissionOverwrite(p)); public string Name => _jsonModel.Name!; } diff --git a/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs b/NetCord/Channels/Guild/ForumGuildChannel.cs similarity index 97% rename from NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs rename to NetCord/Channels/Guild/ForumGuildChannel.cs index 75127fecf..82e473e6b 100644 --- a/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs +++ b/NetCord/Channels/Guild/ForumGuildChannel.cs @@ -6,7 +6,7 @@ namespace NetCord; /// /// Represents a forum channel within a guild. /// -public partial class ForumGuildChannel : Channel, IGuildChannel +internal partial class ForumGuildChannel : Channel, IGuildChannel { public ForumGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client) : base(jsonModel, client) { diff --git a/NetCord/Channels/Guild/GuildMessageChannelBase.cs b/NetCord/Channels/Guild/GuildMessageChannelBase.cs new file mode 100644 index 000000000..cde17648b --- /dev/null +++ b/NetCord/Channels/Guild/GuildMessageChannelBase.cs @@ -0,0 +1,9 @@ +using NetCord.JsonModels; +using NetCord.Rest; + +namespace NetCord; + +internal abstract partial class GuildMessageChannelBase(JsonChannel jsonModel, ulong guildId, RestClient client) : TextChannelBase(jsonModel, client), IGuildMessageChannel +{ + public ulong GuildId => guildId; +} \ No newline at end of file diff --git a/NetCord/Channels/Guild/IAnnouncementGuildChannel.cs b/NetCord/Channels/Guild/IAnnouncementGuildChannel.cs new file mode 100644 index 000000000..df27ef6c7 --- /dev/null +++ b/NetCord/Channels/Guild/IAnnouncementGuildChannel.cs @@ -0,0 +1,17 @@ +namespace NetCord; + +public partial interface IAnnouncementGuildChannel : + IGuildMessageChannel, + INamedChannel, + IPositionedGuildChannel, + IPermissionOverwriteChannel, + IPinnableChannel, + IWebhookChannel, + IInvitableGuildChannel +{ + string? Topic { get; } + bool? Nsfw { get; } + int? Slowmode { get; } + + ThreadArchiveDuration? DefaultAutoArchiveDuration { get; } +} diff --git a/NetCord/Channels/Guild/ICategoryGuildChannel.cs b/NetCord/Channels/Guild/ICategoryGuildChannel.cs new file mode 100644 index 000000000..ed46f3289 --- /dev/null +++ b/NetCord/Channels/Guild/ICategoryGuildChannel.cs @@ -0,0 +1,9 @@ +namespace NetCord; + +/// +/// Represents an organizational category that contains up to 50 channels. +/// +public partial interface ICategoryGuildChannel : + IGuildChannel, IPermissionOverwriteChannel, INamedChannel, IPositionedGuildChannel +{ +} diff --git a/NetCord/Channels/Guild/IDirectoryGuildChannel.cs b/NetCord/Channels/Guild/IDirectoryGuildChannel.cs new file mode 100644 index 000000000..e2b246e59 --- /dev/null +++ b/NetCord/Channels/Guild/IDirectoryGuildChannel.cs @@ -0,0 +1,5 @@ +namespace NetCord; + +public partial interface IDirectoryGuildChannel : IGuildChannel, IPermissionOverwriteChannel, INamedChannel, IPositionedGuildChannel +{ +} \ No newline at end of file diff --git a/NetCord/Channels/Guild/IGuildChannel.cs b/NetCord/Channels/Guild/IGuildChannel.cs new file mode 100644 index 000000000..7a447a340 --- /dev/null +++ b/NetCord/Channels/Guild/IGuildChannel.cs @@ -0,0 +1,87 @@ +namespace NetCord; + +public partial interface IGuildChannel : IChannel +{ + ulong GuildId { get; } +} + +/// +/// Represents a guild channel which directly contains Discord messages. +/// +/// +/// This includes: +/// +/// GUILD_TEXT +/// GUILD_ANNOUNCEMENT +/// GUILD_VOICE +/// GUILD_STAGE_VOICE +/// ANNOUNCEMENT_THREAD +/// PUBLIC_THREAD +/// PRIVATE_THREAD +/// +/// +public partial interface IGuildMessageChannel : ITextChannel, IGuildChannel +{ +} + +/// +/// Represents a guild channel that has a position and can have a parent category. +/// +public partial interface IPositionedGuildChannel : IGuildChannel +{ + /// + /// The channel's position within the guild channel list. + /// + /// + /// If two or more channels share a position, they are instead sorted by their ID. + /// + int Position { get; } + + /// + /// The ID of the channel's parent category, if it has one. + /// + ulong? ParentId { get; } +} + +/// +/// Represents a guild channel that has permission overwrites. +/// +public partial interface IPermissionOverwriteChannel : IGuildChannel +{ + IReadOnlyDictionary PermissionOverwrites { get; } +} + +/// +/// Represents a guild channel that can have webhooks. +/// +/// +/// This includes: +/// +/// GUILD_TEXT +/// GUILD_ANNOUNCEMENT +/// GUILD_FORUM +/// GUILD_MEDIA +/// +/// For threads, use the parent channel's webhooks. +/// +public partial interface IWebhookChannel : IGuildChannel +{ +} + +/// +/// Represents a guild channel that can be invited to. +/// +/// +/// This includes: +/// +/// GUILD_TEXT +/// GUILD_ANNOUNCEMENT +/// GUILD_VOICE +/// GUILD_STAGE_VOICE +/// GUILD_FORUM +/// GUILD_MEDIA +/// +/// +public partial interface IInvitableGuildChannel : IGuildChannel +{ +} diff --git a/NetCord/Channels/Guild/ITextGuildChannel.cs b/NetCord/Channels/Guild/ITextGuildChannel.cs new file mode 100644 index 000000000..3441a0c45 --- /dev/null +++ b/NetCord/Channels/Guild/ITextGuildChannel.cs @@ -0,0 +1,26 @@ +namespace NetCord; + +/// +/// Represents a regular text channel in a guild. +/// +/// +/// This only includes the GUILD_TEXT channel type +/// and excludes DMs and group DMs, annoucement channels, +/// voice and stage channels, and threads. +/// +public partial interface ITextGuildChannel : + IGuildMessageChannel, + INamedChannel, + IPositionedGuildChannel, + IPermissionOverwriteChannel, + IPinnableChannel, + IWebhookChannel, + IInvitableGuildChannel +{ + string? Topic { get; } + bool? Nsfw { get; } + int? Slowmode { get; } + + ThreadArchiveDuration? DefaultAutoArchiveDuration { get; } + int? DefaultThreadSlowmode { get; } +} diff --git a/NetCord/Channels/Guild/IThreadOnlyGuildChannel.cs b/NetCord/Channels/Guild/IThreadOnlyGuildChannel.cs new file mode 100644 index 000000000..62cfe1dd1 --- /dev/null +++ b/NetCord/Channels/Guild/IThreadOnlyGuildChannel.cs @@ -0,0 +1,34 @@ +namespace NetCord; + +public partial interface IThreadOnlyGuildChannel : + IGuildChannel, + INamedChannel, + IPositionedGuildChannel, + IPermissionOverwriteChannel, + IWebhookChannel, + IInvitableGuildChannel +{ + string? Topic { get; } + bool? Nsfw { get; } + + ulong? LastThreadId { get; } + + int? Slowmode { get; } + DateTimeOffset? LastPin { get; } + + ThreadArchiveDuration? DefaultAutoArchiveDuration { get; } + int? DefaultThreadSlowmode { get; } + + IReadOnlyList AvailableTags { get; } + Emoji? DefaultReactionEmoji { get; } + SortOrderType? DefaultSortOrder { get; } +} + +public partial interface IForumGuildChannel : IThreadOnlyGuildChannel +{ + ForumLayoutType DefaultForumLayout { get; } +} + +public partial interface IMediaGuildChannel : IThreadOnlyGuildChannel +{ +} diff --git a/NetCord/Channels/IUnknownGuildChannel.cs b/NetCord/Channels/Guild/IUnknownGuildChannel.cs similarity index 100% rename from NetCord/Channels/IUnknownGuildChannel.cs rename to NetCord/Channels/Guild/IUnknownGuildChannel.cs diff --git a/NetCord/Channels/VoiceChannels/Guild/IVoiceGuildChannel.cs b/NetCord/Channels/Guild/IVoiceChannel.cs similarity index 65% rename from NetCord/Channels/VoiceChannels/Guild/IVoiceGuildChannel.cs rename to NetCord/Channels/Guild/IVoiceChannel.cs index 7448d0eae..599cbd808 100644 --- a/NetCord/Channels/VoiceChannels/Guild/IVoiceGuildChannel.cs +++ b/NetCord/Channels/Guild/IVoiceChannel.cs @@ -1,13 +1,7 @@ namespace NetCord; -/// -/// Represents a generic voice channel within a guild. -/// -public partial interface IVoiceGuildChannel : IGuildChannel +public partial interface IVoiceChannel : IGuildMessageChannel { - /// - public bool Nsfw { get; } - /// /// The voice channel's bitrate (in bits per second). /// @@ -34,3 +28,21 @@ public partial interface IVoiceGuildChannel : IGuildChannel /// public VideoQualityMode VideoQualityMode { get; } } + +public partial interface IVoiceGuildChannel : + IVoiceChannel, + INamedChannel, + IPositionedGuildChannel, + IPermissionOverwriteChannel, + IInvitableGuildChannel +{ +} + +public partial interface IStageGuildChannel : + IVoiceChannel, + INamedChannel, + IPositionedGuildChannel, + IPermissionOverwriteChannel, + IInvitableGuildChannel +{ +} diff --git a/NetCord/Channels/TextChannels/Guild/MediaForumGuildChannel.cs b/NetCord/Channels/Guild/MediaForumGuildChannel.cs similarity index 55% rename from NetCord/Channels/TextChannels/Guild/MediaForumGuildChannel.cs rename to NetCord/Channels/Guild/MediaForumGuildChannel.cs index a0d5e0a9d..e7308f390 100644 --- a/NetCord/Channels/TextChannels/Guild/MediaForumGuildChannel.cs +++ b/NetCord/Channels/Guild/MediaForumGuildChannel.cs @@ -6,6 +6,6 @@ namespace NetCord; /// /// Represents a media channel, which is a specialized . /// -public partial class MediaForumGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client) : ForumGuildChannel(jsonModel, guildId, client) +internal partial class MediaForumGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client) : ForumGuildChannel(jsonModel, guildId, client) { } diff --git a/NetCord/Channels/Guild/StageGuildChannel.cs b/NetCord/Channels/Guild/StageGuildChannel.cs new file mode 100644 index 000000000..a181f6e8d --- /dev/null +++ b/NetCord/Channels/Guild/StageGuildChannel.cs @@ -0,0 +1,10 @@ +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a stage channel within a guild. +/// +internal partial class StageGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : VoiceGuildChannel(jsonModel, guildId, client) +{ +} diff --git a/NetCord/Channels/TextChannels/Guild/TextGuildChannel.cs b/NetCord/Channels/Guild/TextGuildChannel.cs similarity index 89% rename from NetCord/Channels/TextChannels/Guild/TextGuildChannel.cs rename to NetCord/Channels/Guild/TextGuildChannel.cs index 8cae67a03..f6520cf6f 100644 --- a/NetCord/Channels/TextChannels/Guild/TextGuildChannel.cs +++ b/NetCord/Channels/Guild/TextGuildChannel.cs @@ -5,10 +5,8 @@ namespace NetCord; /// /// Represents a text channel within a guild. /// -public partial class TextGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : TextChannel(jsonModel, client), IGuildChannel +internal partial class TextGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : GuildMessageChannelBase(jsonModel, guildId, client) { - public ulong GuildId { get; } = guildId; - public int? Position => _jsonModel.Position; public IReadOnlyDictionary PermissionOverwrites { get; } = jsonModel.PermissionOverwrites.ToDictionaryOrEmpty(p => p.Id, p => new PermissionOverwrite(p)); diff --git a/NetCord/Channels/TextChannels/Guild/Threads/AnnouncementGuildThread.cs b/NetCord/Channels/Guild/Threads/AnnouncementGuildThread.cs similarity index 52% rename from NetCord/Channels/TextChannels/Guild/Threads/AnnouncementGuildThread.cs rename to NetCord/Channels/Guild/Threads/AnnouncementGuildThread.cs index b82a54df7..65f1d43f5 100644 --- a/NetCord/Channels/TextChannels/Guild/Threads/AnnouncementGuildThread.cs +++ b/NetCord/Channels/Guild/Threads/AnnouncementGuildThread.cs @@ -5,6 +5,6 @@ namespace NetCord; /// /// Represents a thread within an . /// -public partial class AnnouncementGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client) +internal partial class AnnouncementGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client) { } diff --git a/NetCord/Channels/TextChannels/Guild/Threads/ForumGuildThread.cs b/NetCord/Channels/Guild/Threads/ForumGuildThread.cs similarity index 83% rename from NetCord/Channels/TextChannels/Guild/Threads/ForumGuildThread.cs rename to NetCord/Channels/Guild/Threads/ForumGuildThread.cs index a788737f2..67350682e 100644 --- a/NetCord/Channels/TextChannels/Guild/Threads/ForumGuildThread.cs +++ b/NetCord/Channels/Guild/Threads/ForumGuildThread.cs @@ -9,7 +9,7 @@ namespace NetCord; /// /// Threads within a forum are typically acquired as objects. /// -public partial class ForumGuildThread(JsonChannel jsonModel, RestClient client) : PublicGuildThread(jsonModel, client) +internal partial class ForumGuildThread(JsonChannel jsonModel, RestClient client) : PublicGuildThread(jsonModel, client) { /// /// The message embedded as the thread's starting point. diff --git a/NetCord/Channels/TextChannels/Guild/Threads/GuildThread.cs b/NetCord/Channels/Guild/Threads/GuildThread.cs similarity index 68% rename from NetCord/Channels/TextChannels/Guild/Threads/GuildThread.cs rename to NetCord/Channels/Guild/Threads/GuildThread.cs index b8b774df4..b68531fd1 100644 --- a/NetCord/Channels/TextChannels/Guild/Threads/GuildThread.cs +++ b/NetCord/Channels/Guild/Threads/GuildThread.cs @@ -5,17 +5,12 @@ namespace NetCord; /// /// Represents a thread within a guild. /// -public abstract partial class GuildThread : TextGuildChannel +internal abstract partial class GuildThread : GuildMessageChannelBase, IGuildThread { /// - /// The ID of the this thread was created in. + /// The ID of the parent channel of the thread. /// - public new ulong ParentId => base.ParentId.GetValueOrDefault(); - - /// - /// The ID of the thread's creator. - /// - public ulong OwnerId => _jsonModel.OwnerId.GetValueOrDefault(); + public ulong ParentId => _jsonModel.ParentId.GetValueOrDefault(); /// /// The number of messages within the thread, excluding the initial and deleted messages. @@ -45,6 +40,21 @@ public abstract partial class GuildThread : TextGuildChannel /// public int TotalMessageSent => _jsonModel.TotalMessageSent.GetValueOrDefault(); + /// + /// The name of the thread. + /// + public string Name => _jsonModel.Name!; + + /// + /// The timestamp of the last pinned message in the thread. + /// + public DateTimeOffset? LastPin => _jsonModel.LastPin; + + /// + /// The ID of the user who created the thread. + /// + public ulong OwnerId => _jsonModel.OwnerId.GetValueOrDefault(); + protected GuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : base(jsonModel, jsonModel.GuildId.GetValueOrDefault(), client) { Metadata = new(jsonModel.Metadata!); @@ -53,15 +63,4 @@ protected GuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : bas if (jsonCurrentUser is not null) CurrentUser = new(jsonCurrentUser); } - - public static new GuildThread CreateFromJson(JsonModels.JsonChannel jsonChannel, RestClient client) - { - return jsonChannel.Type switch - { - ChannelType.AnnouncementGuildThread => new AnnouncementGuildThread(jsonChannel, client), - ChannelType.PublicGuildThread => new PublicGuildThread(jsonChannel, client), - ChannelType.PrivateGuildThread => new PrivateGuildThread(jsonChannel, client), - _ => new UnknownGuildThread(jsonChannel, client), - }; - } } diff --git a/NetCord/Channels/TextChannels/Guild/Threads/GuildThreadMetadata.cs b/NetCord/Channels/Guild/Threads/GuildThreadMetadata.cs similarity index 100% rename from NetCord/Channels/TextChannels/Guild/Threads/GuildThreadMetadata.cs rename to NetCord/Channels/Guild/Threads/GuildThreadMetadata.cs diff --git a/NetCord/Channels/Guild/Threads/IGuildThread.cs b/NetCord/Channels/Guild/Threads/IGuildThread.cs new file mode 100644 index 000000000..2dbab8ff2 --- /dev/null +++ b/NetCord/Channels/Guild/Threads/IGuildThread.cs @@ -0,0 +1,51 @@ +using NetCord.Rest; + +namespace NetCord; + +public partial interface IGuildThread : + IGuildMessageChannel, + INamedChannel, + IPinnableChannel +{ + ulong ParentId { get; } + ulong OwnerId { get; } + int MessageCount { get; } + int UserCount { get; } + GuildThreadMetadata Metadata { get; } + ThreadCurrentUser? CurrentUser { get; } + int TotalMessageSent { get; } +} + +public partial interface IAnnouncementGuildThread : IGuildThread +{ +} + +public partial interface IUnknownGuildThread : + IUnknownGuildChannel, + IGuildThread +{ +} + +/// +/// Represents a private thread channel that is only viewale by those invited and those with the MANAGE_THREADS permission. +/// +public partial interface IPrivateGuildThread : IGuildThread +{ +} + +/// +/// Represents a public guild thread channel, which is a specialized . +/// +/// +/// This also includes threads in forum and media channels. +/// +public partial interface IPublicGuildThread : IGuildThread +{ + IReadOnlyList? AppliedTags { get; } +} + +public sealed class CreateGuildThreadResult +{ + public required IPublicGuildThread Thread { get; init; } + public required RestMessage Message { get; init; } +} diff --git a/NetCord/Channels/TextChannels/Guild/Threads/PrivateGuildThread.cs b/NetCord/Channels/Guild/Threads/PrivateGuildThread.cs similarity index 50% rename from NetCord/Channels/TextChannels/Guild/Threads/PrivateGuildThread.cs rename to NetCord/Channels/Guild/Threads/PrivateGuildThread.cs index 6fb11eddd..3166e399a 100644 --- a/NetCord/Channels/TextChannels/Guild/Threads/PrivateGuildThread.cs +++ b/NetCord/Channels/Guild/Threads/PrivateGuildThread.cs @@ -5,6 +5,6 @@ namespace NetCord; /// /// Represents a only accessible to a subset of users. /// -public partial class PrivateGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client) +internal partial class PrivateGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client), IPrivateGuildThread { } diff --git a/NetCord/Channels/TextChannels/Guild/Threads/PublicGuildThread.cs b/NetCord/Channels/Guild/Threads/PublicGuildThread.cs similarity index 75% rename from NetCord/Channels/TextChannels/Guild/Threads/PublicGuildThread.cs rename to NetCord/Channels/Guild/Threads/PublicGuildThread.cs index e14cf9079..94b94f0a8 100644 --- a/NetCord/Channels/TextChannels/Guild/Threads/PublicGuildThread.cs +++ b/NetCord/Channels/Guild/Threads/PublicGuildThread.cs @@ -5,7 +5,7 @@ namespace NetCord; /// /// Represents a accessible to all users. /// -public partial class PublicGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client) +internal partial class PublicGuildThread(JsonModels.JsonChannel jsonModel, RestClient client) : GuildThread(jsonModel, client), IPublicGuildThread { /// /// The set of tags applied to the thread. diff --git a/NetCord/Channels/TextChannels/Guild/Threads/UnknownGuildThread.cs b/NetCord/Channels/Guild/Threads/UnknownGuildThread.cs similarity index 100% rename from NetCord/Channels/TextChannels/Guild/Threads/UnknownGuildThread.cs rename to NetCord/Channels/Guild/Threads/UnknownGuildThread.cs diff --git a/NetCord/Channels/UnknownGuildChannel.cs b/NetCord/Channels/Guild/UnknownGuildChannel.cs similarity index 100% rename from NetCord/Channels/UnknownGuildChannel.cs rename to NetCord/Channels/Guild/UnknownGuildChannel.cs diff --git a/NetCord/Channels/Guild/VoiceGuildChannel.cs b/NetCord/Channels/Guild/VoiceGuildChannel.cs new file mode 100644 index 000000000..0ee684a62 --- /dev/null +++ b/NetCord/Channels/Guild/VoiceGuildChannel.cs @@ -0,0 +1,27 @@ +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a standard voice channel within a guild. +/// +internal partial class VoiceGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : GuildMessageChannelBase(jsonModel, guildId, client), IVoiceGuildChannel +{ + public int Bitrate => _jsonModel.Bitrate.GetValueOrDefault(); + + public int UserLimit => _jsonModel.UserLimit.GetValueOrDefault(); + + public string? RtcRegion => _jsonModel.RtcRegion; + + public VideoQualityMode VideoQualityMode => _jsonModel.VideoQualityMode.GetValueOrDefault(VideoQualityMode.Auto); + + public int Slowmode => throw new NotImplementedException(); + + public ulong? ParentId => throw new NotImplementedException(); + + public string Name => throw new NotImplementedException(); + + public int Position => throw new NotImplementedException(); + + public IReadOnlyDictionary PermissionOverwrites => throw new NotImplementedException(); +} diff --git a/NetCord/Channels/IChannel.cs b/NetCord/Channels/IChannel.cs new file mode 100644 index 000000000..efeed8186 --- /dev/null +++ b/NetCord/Channels/IChannel.cs @@ -0,0 +1,38 @@ +namespace NetCord; + +/// +/// Represents any channel. +/// +/// +/// This includes all text and voice channels, threads, +/// DMs, group DMs, categories and directory channels. +/// +public partial interface IChannel : IEntity, ISpanFormattable +{ + /// + /// Additional information about the channel's state. + /// + ChannelFlags? Flags { get; } + + public string ToString(); +} + +/// +/// Represents a channel that has a name. +/// +public partial interface INamedChannel : IChannel +{ + /// + /// The name of the channel. + /// + string Name { get; } +} + + +/// +/// Represents a channel representation which came with resolved interaction permissions. +/// +public partial interface IInteractionChannel : IChannel +{ + Permissions Permissions { get; } +} diff --git a/NetCord/Channels/IDMChannel.cs b/NetCord/Channels/IDMChannel.cs new file mode 100644 index 000000000..2918842b9 --- /dev/null +++ b/NetCord/Channels/IDMChannel.cs @@ -0,0 +1,6 @@ +namespace NetCord; + +public partial interface IDMChannel : ITextChannel, IPinnableChannel +{ + IReadOnlyDictionary Users { get; } +} diff --git a/NetCord/Channels/IGroupDMChannel.cs b/NetCord/Channels/IGroupDMChannel.cs new file mode 100644 index 000000000..c647cae29 --- /dev/null +++ b/NetCord/Channels/IGroupDMChannel.cs @@ -0,0 +1,27 @@ +namespace NetCord; + +public partial interface IGroupDMChannel : + ITextChannel, + IPinnableChannel, + INamedChannel +{ + /// + /// The group channel's icon hash. + /// + string? IconHash { get; } + + /// + /// The ID corresponding to the group channel's owner. + /// + ulong OwnerId { get; } + + /// + /// The ID corresponding to the application managing the group channel, if any, otherwise . + /// + ulong? ApplicationId { get; } + + /// + /// Whether the group channel is managed by an application with set. + /// + bool Managed { get; } +} diff --git a/NetCord/Channels/IGuildChannel.cs b/NetCord/Channels/IGuildChannel.cs deleted file mode 100644 index ae016567b..000000000 --- a/NetCord/Channels/IGuildChannel.cs +++ /dev/null @@ -1,44 +0,0 @@ -using NetCord.JsonModels; -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a channel within a guild. -/// -public partial interface IGuildChannel : INamedChannel -{ - /// - /// The ID corresponding to the channel's parent guild. - /// - public ulong GuildId { get; } - - /// - /// The channel's position within the guild channel list. - /// - /// - /// If two or more channels share a position, they are instead sorted by their ID. - /// - public int? Position { get; } - - /// - /// A list of explicit permission overwrites for specified members and roles. - /// - public IReadOnlyDictionary PermissionOverwrites { get; } - - public static IGuildChannel CreateFromJson(JsonChannel jsonChannel, ulong guildId, RestClient client) - { - return jsonChannel.Type switch - { - ChannelType.TextGuildChannel => new TextGuildChannel(jsonChannel, guildId, client), - ChannelType.VoiceGuildChannel => new VoiceGuildChannel(jsonChannel, guildId, client), - ChannelType.CategoryChannel => new CategoryGuildChannel(jsonChannel, guildId, client), - ChannelType.AnnouncementGuildChannel => new AnnouncementGuildChannel(jsonChannel, guildId, client), - ChannelType.StageGuildChannel => new StageGuildChannel(jsonChannel, guildId, client), - ChannelType.DirectoryGuildChannel => new DirectoryGuildChannel(jsonChannel, guildId, client), - ChannelType.ForumGuildChannel => new ForumGuildChannel(jsonChannel, guildId, client), - ChannelType.MediaForumGuildChannel => new MediaForumGuildChannel(jsonChannel, guildId, client), - _ => new UnknownGuildChannel(jsonChannel, guildId, client), - }; - } -} diff --git a/NetCord/Channels/IInteractionChannel.cs b/NetCord/Channels/IInteractionChannel.cs deleted file mode 100644 index f91658736..000000000 --- a/NetCord/Channels/IInteractionChannel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace NetCord; - -/// -/// An optional interface for acquiring channel permissions. -/// -public interface IInteractionChannel : IEntity, ISpanFormattable -{ - public Permissions Permissions { get; } - - public string ToString(); -} diff --git a/NetCord/Channels/IInviteChannel.cs b/NetCord/Channels/IInviteChannel.cs new file mode 100644 index 000000000..420c79723 --- /dev/null +++ b/NetCord/Channels/IInviteChannel.cs @@ -0,0 +1,8 @@ +namespace NetCord; + +public partial interface IInviteChannel : IChannel +{ + string? Name { get; } + string? Icon { get; } + IReadOnlyList? RecipientUsernames { get; } +} diff --git a/NetCord/Channels/INamedChannel.cs b/NetCord/Channels/INamedChannel.cs deleted file mode 100644 index 35ec24ba4..000000000 --- a/NetCord/Channels/INamedChannel.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace NetCord; - -/// -/// Represents a named channel. -/// -public interface INamedChannel : IEntity, ISpanFormattable -{ - /// - /// The name of the channel object, between 1 and 100 characters. - /// - public string Name { get; } - - public string ToString(); -} diff --git a/NetCord/Channels/ITextChannel.cs b/NetCord/Channels/ITextChannel.cs new file mode 100644 index 000000000..bdc177a0e --- /dev/null +++ b/NetCord/Channels/ITextChannel.cs @@ -0,0 +1,32 @@ +namespace NetCord; + +public partial interface ITextChannel : IChannel +{ + /// + /// The ID corresponding to the last message sent within the channel. Can be if the channel is empty. + /// + ulong? LastMessageId { get; } +} + +/// +/// Represents a text channel that can have pins. +/// +/// +/// This includes: +/// +/// GUILD_TEXT +/// GUILD_ANNOUNCEMENT +/// ANNOUNCEMENT_THREAD +/// PUBLIC_THREAD +/// PRIVATE_THREAD +/// DM +/// GROUP_DM +/// +/// +public partial interface IPinnableChannel : ITextChannel +{ + /// + /// The timestamp of the last pinned message, if any, otherwise . + /// + DateTimeOffset? LastPin { get; } +} \ No newline at end of file diff --git a/NetCord/Channels/IUnknownChannel.cs b/NetCord/Channels/IUnknownChannel.cs index 98b7f1045..275838128 100644 --- a/NetCord/Channels/IUnknownChannel.cs +++ b/NetCord/Channels/IUnknownChannel.cs @@ -3,10 +3,10 @@ namespace NetCord; /// /// Represents a channel of an unresolved type. /// -public interface IUnknownChannel : IEntity, ISpanFormattable +public partial interface IUnknownChannel : IChannel { /// /// The unresolved channel's type. /// - public ChannelType Type { get; } + ChannelType Type { get; } } diff --git a/NetCord/Channels/TextChannels/IUnknownDMChannel.cs b/NetCord/Channels/IUnknownDMChannel.cs similarity index 65% rename from NetCord/Channels/TextChannels/IUnknownDMChannel.cs rename to NetCord/Channels/IUnknownDMChannel.cs index 60e5821cf..3d2dbc770 100644 --- a/NetCord/Channels/TextChannels/IUnknownDMChannel.cs +++ b/NetCord/Channels/IUnknownDMChannel.cs @@ -3,6 +3,6 @@ namespace NetCord; /// /// Represents a channel for private messages of an unresolved type. /// -public interface IUnknownDMChannel : IUnknownTextChannel +public partial interface IUnknownDMChannel : IUnknownTextChannel { } diff --git a/NetCord/Channels/TextChannels/IUnknownTextChannel.cs b/NetCord/Channels/IUnknownTextChannel.cs similarity index 62% rename from NetCord/Channels/TextChannels/IUnknownTextChannel.cs rename to NetCord/Channels/IUnknownTextChannel.cs index f96d5f338..f225f9070 100644 --- a/NetCord/Channels/TextChannels/IUnknownTextChannel.cs +++ b/NetCord/Channels/IUnknownTextChannel.cs @@ -3,6 +3,6 @@ namespace NetCord; /// /// Represents a text channel of an unresolved type. /// -public interface IUnknownTextChannel : IUnknownChannel +public partial interface IUnknownTextChannel : IUnknownChannel { } diff --git a/NetCord/Channels/TextChannel.cs b/NetCord/Channels/TextChannel.cs new file mode 100644 index 000000000..04e6aa5b6 --- /dev/null +++ b/NetCord/Channels/TextChannel.cs @@ -0,0 +1,13 @@ +using NetCord.JsonModels; +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a text channel. +/// +internal abstract partial class TextChannel(JsonChannel jsonModel, RestClient client) : TextChannelBase(jsonModel, client), IPinnableChannel +{ + /// + public DateTimeOffset? LastPin => _jsonModel.LastPin; +} diff --git a/NetCord/Channels/TextChannelBase.cs b/NetCord/Channels/TextChannelBase.cs new file mode 100644 index 000000000..6badfcb54 --- /dev/null +++ b/NetCord/Channels/TextChannelBase.cs @@ -0,0 +1,10 @@ +using NetCord.JsonModels; +using NetCord.Rest; + +namespace NetCord; + +internal abstract partial class TextChannelBase(JsonChannel jsonModel, RestClient client) : Channel(jsonModel, client), ITextChannel +{ + /// + public ulong? LastMessageId => throw new NotImplementedException(); +} \ No newline at end of file diff --git a/NetCord/Channels/TextChannels/DMChannel.cs b/NetCord/Channels/TextChannels/DMChannel.cs deleted file mode 100644 index b759480e7..000000000 --- a/NetCord/Channels/TextChannels/DMChannel.cs +++ /dev/null @@ -1,24 +0,0 @@ -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a text channel for private messages between two users. -/// -public partial class DMChannel(JsonModels.JsonChannel jsonModel, RestClient client) : TextChannel(jsonModel, client) -{ - /// - /// A list of the users present in the private channel, indexed by their IDs. - /// - public IReadOnlyDictionary Users { get; } = jsonModel.Users.ToDictionaryOrEmpty(u => u.Id, u => new User(u, client)); - - public static new DMChannel CreateFromJson(JsonModels.JsonChannel jsonModel, RestClient client) - { - return jsonModel.Type switch - { - ChannelType.DMChannel => new DMChannel(jsonModel, client), - ChannelType.GroupDMChannel => new GroupDMChannel(jsonModel, client), - _ => new UnknownDMChannel(jsonModel, client), - }; - } -} diff --git a/NetCord/Channels/TextChannels/Guild/AnnouncementGuildChannel.cs b/NetCord/Channels/TextChannels/Guild/AnnouncementGuildChannel.cs deleted file mode 100644 index 7bfd915fa..000000000 --- a/NetCord/Channels/TextChannels/Guild/AnnouncementGuildChannel.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a channel that users can follow and crosspost from into their own servers. Formerly known as news channels. -/// -public partial class AnnouncementGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : TextGuildChannel(jsonModel, guildId, client) -{ -} diff --git a/NetCord/Channels/TextChannels/Guild/Threads/IUnknownGuildThread.cs b/NetCord/Channels/TextChannels/Guild/Threads/IUnknownGuildThread.cs deleted file mode 100644 index 800b264be..000000000 --- a/NetCord/Channels/TextChannels/Guild/Threads/IUnknownGuildThread.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace NetCord; - -/// -/// Represents a guild thread of an unresolved type. -/// -public partial interface IUnknownGuildThread : IUnknownGuildChannel -{ -} diff --git a/NetCord/Channels/TextChannels/TextChannel.cs b/NetCord/Channels/TextChannels/TextChannel.cs deleted file mode 100644 index 750825000..000000000 --- a/NetCord/Channels/TextChannels/TextChannel.cs +++ /dev/null @@ -1,38 +0,0 @@ -using NetCord.JsonModels; -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a generic text channel. -/// -public abstract partial class TextChannel(JsonChannel jsonModel, RestClient client) : Channel(jsonModel, client) -{ - /// - /// The ID corresponding to the last message sent within the channel. Can be if the channel is empty. - /// - public ulong? LastMessageId => _jsonModel.LastMessageId; - - /// - /// The timestamp of the last pinned message, if any, otherwise . - /// - public DateTimeOffset? LastPin => _jsonModel.LastPin; - - public static new TextChannel CreateFromJson(JsonChannel jsonChannel, RestClient client) - { - return jsonChannel.Type switch - { - ChannelType.TextGuildChannel => new TextGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.DMChannel => new DMChannel(jsonChannel, client), - ChannelType.VoiceGuildChannel => new VoiceGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.GroupDMChannel => new GroupDMChannel(jsonChannel, client), - ChannelType.AnnouncementGuildChannel => new AnnouncementGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.AnnouncementGuildThread => new AnnouncementGuildThread(jsonChannel, client), - ChannelType.PublicGuildThread => new PublicGuildThread(jsonChannel, client), - ChannelType.PrivateGuildThread => new PrivateGuildThread(jsonChannel, client), - ChannelType.StageGuildChannel => new StageGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - ChannelType.DirectoryGuildChannel => new DirectoryGuildChannel(jsonChannel, jsonChannel.GuildId.GetValueOrDefault(), client), - _ => new UnknownTextChannel(jsonChannel, client), - }; - } -} diff --git a/NetCord/Channels/TextChannels/UnknownDMChannel.cs b/NetCord/Channels/UnknownDMChannel.cs similarity index 100% rename from NetCord/Channels/TextChannels/UnknownDMChannel.cs rename to NetCord/Channels/UnknownDMChannel.cs diff --git a/NetCord/Channels/TextChannels/UnknownTextChannel.cs b/NetCord/Channels/UnknownTextChannel.cs similarity index 70% rename from NetCord/Channels/TextChannels/UnknownTextChannel.cs rename to NetCord/Channels/UnknownTextChannel.cs index 6eb5744b4..3a15b4d00 100644 --- a/NetCord/Channels/TextChannels/UnknownTextChannel.cs +++ b/NetCord/Channels/UnknownTextChannel.cs @@ -3,7 +3,7 @@ namespace NetCord; -internal partial class UnknownTextChannel(JsonChannel jsonModel, RestClient client) : TextChannel(jsonModel, client), IUnknownTextChannel +internal partial class UnknownTextChannel(JsonChannel jsonModel, RestClient client) : TextChannelBase(jsonModel, client), IUnknownTextChannel { public ChannelType Type => _jsonModel.Type; } diff --git a/NetCord/Channels/VoiceChannels/Guild/StageGuildChannel.cs b/NetCord/Channels/VoiceChannels/Guild/StageGuildChannel.cs deleted file mode 100644 index 57453aef6..000000000 --- a/NetCord/Channels/VoiceChannels/Guild/StageGuildChannel.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a stage channel within a guild. -/// -public partial class StageGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : TextGuildChannel(jsonModel, guildId, client), IVoiceGuildChannel -{ - public int Bitrate => _jsonModel.Bitrate.GetValueOrDefault(); - - public int UserLimit => _jsonModel.UserLimit.GetValueOrDefault(); - - public string? RtcRegion => _jsonModel.RtcRegion; - - public VideoQualityMode VideoQualityMode => _jsonModel.VideoQualityMode.GetValueOrDefault(VideoQualityMode.Auto); -} diff --git a/NetCord/Channels/VoiceChannels/Guild/VoiceGuildChannel.cs b/NetCord/Channels/VoiceChannels/Guild/VoiceGuildChannel.cs deleted file mode 100644 index 12412e342..000000000 --- a/NetCord/Channels/VoiceChannels/Guild/VoiceGuildChannel.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NetCord.Rest; - -namespace NetCord; - -/// -/// Represents a standard voice channel within a guild. -/// -public partial class VoiceGuildChannel(JsonModels.JsonChannel jsonModel, ulong guildId, RestClient client) : TextGuildChannel(jsonModel, guildId, client), IVoiceGuildChannel -{ - public int Bitrate => _jsonModel.Bitrate.GetValueOrDefault(); - - public int UserLimit => _jsonModel.UserLimit.GetValueOrDefault(); - - public string? RtcRegion => _jsonModel.RtcRegion; - - public VideoQualityMode VideoQualityMode => _jsonModel.VideoQualityMode.GetValueOrDefault(VideoQualityMode.Auto); -} diff --git a/NetCord/Components/ChannelMenu.cs b/NetCord/Components/ChannelMenu.cs index ed9e4f642..48bc11c38 100644 --- a/NetCord/Components/ChannelMenu.cs +++ b/NetCord/Components/ChannelMenu.cs @@ -24,5 +24,5 @@ public unsafe ChannelMenu(JsonChannelMenuComponent jsonModel, public IReadOnlyList ChannelTypes { get; } - public new IReadOnlyList? SelectedValues { get; } + public new IReadOnlyList? SelectedValues { get; } } diff --git a/NetCord/Components/EntityMenu.cs b/NetCord/Components/EntityMenu.cs index e9b739720..c56012675 100644 --- a/NetCord/Components/EntityMenu.cs +++ b/NetCord/Components/EntityMenu.cs @@ -30,7 +30,7 @@ private protected EntityMenu(JsonEntityMenuComponent jsonModel, IReadOnlyList
    GetSelectedValues(JsonEntityMenuComponent jsonModel, delegate*, InteractionResolvedData, T[]> getValues, out T[] values, InteractionResolvedData? resolvedData) where T : Entity + private protected static unsafe IReadOnlyList GetSelectedValues(JsonEntityMenuComponent jsonModel, delegate*, InteractionResolvedData, T[]> getValues, out T[] values, InteractionResolvedData? resolvedData) where T : IEntity { if (resolvedData is not null) return new EntityArrayWrapper(values = getValues(jsonModel.SelectedValues!, resolvedData)); diff --git a/NetCord/Components/EntityMenuHelper.cs b/NetCord/Components/EntityMenuHelper.cs index 598592812..ca91aceea 100644 --- a/NetCord/Components/EntityMenuHelper.cs +++ b/NetCord/Components/EntityMenuHelper.cs @@ -30,7 +30,7 @@ public static Mentionable[] GetMentionableValues(IEnumerable selectedValu }).ToArray(); } - public static Channel[] GetChannelValues(IEnumerable selectedValues, InteractionResolvedData resolvedData) + public static IChannel[] GetChannelValues(IEnumerable selectedValues, InteractionResolvedData resolvedData) { var channels = resolvedData.Channels; return selectedValues.Select(v => channels![v]).ToArray(); diff --git a/NetCord/EntityArrayWrapper.cs b/NetCord/EntityArrayWrapper.cs index 452083bf9..af7e5123d 100644 --- a/NetCord/EntityArrayWrapper.cs +++ b/NetCord/EntityArrayWrapper.cs @@ -2,7 +2,7 @@ namespace NetCord; -internal sealed class EntityArrayWrapper(T[] array) : IReadOnlyList where T : Entity +internal sealed class EntityArrayWrapper(T[] array) : IReadOnlyList where T : IEntity { public ulong this[int index] => array[index].Id; diff --git a/NetCord/EntityMenuInteraction.cs b/NetCord/EntityMenuInteraction.cs index 9c03cdb6e..00693b29d 100644 --- a/NetCord/EntityMenuInteraction.cs +++ b/NetCord/EntityMenuInteraction.cs @@ -28,7 +28,7 @@ private protected static unsafe IReadOnlyList GetSelectedValues(JsonMo RestClient client, delegate*, InteractionResolvedData, T[]> getSelectedValues, out T[] selectedValues, - out InteractionResolvedData? resolvedData) where T : Entity + out InteractionResolvedData? resolvedData) where T : IEntity { if (jsonModel.ResolvedData is { } jsonResolvedData) return new EntityArrayWrapper(selectedValues = getSelectedValues(jsonModel.SelectedValues!.Select(v => Snowflake.Parse(v)), resolvedData = new(jsonResolvedData, guildId, client))); diff --git a/NetCord/Gateway/ConcurrentGatewayClientCache.cs b/NetCord/Gateway/ConcurrentGatewayClientCache.cs index f4b8752fb..f67b4bb48 100644 --- a/NetCord/Gateway/ConcurrentGatewayClientCache.cs +++ b/NetCord/Gateway/ConcurrentGatewayClientCache.cs @@ -147,7 +147,7 @@ public IGatewayClientCache CacheGuildScheduledEvent(GuildScheduledEvent schedule return this; } - public IGatewayClientCache CacheGuildThread(GuildThread thread) + public IGatewayClientCache CacheGuildThread(IGuildThread thread) { if (_guilds.TryGetValue(thread.GuildId, out var guild)) { @@ -225,7 +225,7 @@ public IGatewayClientCache SyncGuildStickers(ulong guildId, IReadOnlyDictionary< return this; } - public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads) + public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads) { if (_guilds.TryGetValue(guildId, out var guild)) guild.ActiveThreads = threads; diff --git a/NetCord/Gateway/EventArgs/GuildThreadCreateEventArgs.cs b/NetCord/Gateway/EventArgs/GuildThreadCreateEventArgs.cs index 3ec5be775..c410b8454 100644 --- a/NetCord/Gateway/EventArgs/GuildThreadCreateEventArgs.cs +++ b/NetCord/Gateway/EventArgs/GuildThreadCreateEventArgs.cs @@ -1,8 +1,8 @@ namespace NetCord.Gateway; -public class GuildThreadCreateEventArgs(GuildThread thread, bool newlyCreated) +public class GuildThreadCreateEventArgs(IGuildThread thread, bool newlyCreated) { - public GuildThread Thread { get; } = thread; + public IGuildThread Thread { get; } = thread; public bool NewlyCreated { get; } = newlyCreated; } diff --git a/NetCord/Gateway/EventArgs/GuildThreadListSyncEventArgs.cs b/NetCord/Gateway/EventArgs/GuildThreadListSyncEventArgs.cs index 56d36ab20..f860cab0f 100644 --- a/NetCord/Gateway/EventArgs/GuildThreadListSyncEventArgs.cs +++ b/NetCord/Gateway/EventArgs/GuildThreadListSyncEventArgs.cs @@ -10,7 +10,7 @@ public class GuildThreadListSyncEventArgs(JsonModels.EventArgs.JsonGuildThreadLi public IReadOnlyList? ChannelIds => jsonModel.ChannelIds; - public IReadOnlyDictionary Threads { get; } = dictionaryProvider.CreateDictionary(jsonModel.Threads, t => t.Id, t => GuildThread.CreateFromJson(t, client)); + public IReadOnlyDictionary Threads { get; } = dictionaryProvider.CreateDictionary(jsonModel.Threads, t => t.Id, t => ChannelFactory.CreateGuildThread(t, client)); public IReadOnlyList Users { get; } = jsonModel.Users.Select(u => new ThreadUser(u, client)).ToArray(); } diff --git a/NetCord/Gateway/GatewayClient.cs b/NetCord/Gateway/GatewayClient.cs index bb645c897..6fa77657f 100644 --- a/NetCord/Gateway/GatewayClient.cs +++ b/NetCord/Gateway/GatewayClient.cs @@ -150,7 +150,7 @@ public sealed partial class GatewayClient : WebSocketClient, IEntity ///
    Required Intents: ///
    Optional Intents: None /// - public partial event Func? GuildThreadUpdate; + public partial event Func? GuildThreadUpdate; /// /// Sent when a thread relevant to the bot is deleted. @@ -1183,21 +1183,21 @@ await InvokeEventAsync(_ready, this, (Args: args, State: state, ConnectionState: case "CHANNEL_CREATE": { var json = data.ToObject(Serialization.Default.JsonChannel); - var channel = IGuildChannel.CreateFromJson(json, json.GuildId.GetValueOrDefault(), Rest); + var channel = ChannelFactory.CreateGuild(json, Rest); await InvokeEventAsync(_guildChannelCreate, this, channel, static (client, channel) => client.Cache = client.Cache.CacheGuildChannel(channel)).ConfigureAwait(false); } break; case "CHANNEL_UPDATE": { var json = data.ToObject(Serialization.Default.JsonChannel); - var channel = IGuildChannel.CreateFromJson(json, json.GuildId.GetValueOrDefault(), Rest); + var channel = ChannelFactory.CreateGuild(json, Rest); await InvokeEventAsync(_guildChannelUpdate, this, channel, static (client, channel) => client.Cache = client.Cache.CacheGuildChannel(channel)).ConfigureAwait(false); } break; case "CHANNEL_DELETE": { var json = data.ToObject(Serialization.Default.JsonChannel); - await InvokeEventAsync(_guildChannelDelete, this, (Json: json, RestClient: Rest), static data => IGuildChannel.CreateFromJson(data.Json, data.Json.GuildId.GetValueOrDefault(), data.RestClient), static (client, data) => client.Cache = client.Cache.RemoveGuildChannel(data.Json.GuildId.GetValueOrDefault(), data.Json.Id)).ConfigureAwait(false); + await InvokeEventAsync(_guildChannelDelete, this, (Json: json, RestClient: Rest), static data => ChannelFactory.CreateGuild(data.Json, data.RestClient), static (client, data) => client.Cache = client.Cache.RemoveGuildChannel(data.Json.GuildId.GetValueOrDefault(), data.Json.Id)).ConfigureAwait(false); } break; case "CHANNEL_PINS_UPDATE": @@ -1208,14 +1208,14 @@ await InvokeEventAsync(_ready, this, (Args: args, State: state, ConnectionState: case "THREAD_CREATE": { var json = data.ToObject(Serialization.Default.JsonChannel); - var thread = GuildThread.CreateFromJson(json, Rest); + var thread = ChannelFactory.CreateGuildThread(json, Rest); await InvokeEventAsync(_guildThreadCreate, this, (Json: json, Thread: thread), static data => new(data.Thread, data.Json.NewlyCreated.GetValueOrDefault()), static (client, data) => client.Cache = client.Cache.CacheGuildThread(data.Thread)).ConfigureAwait(false); } break; case "THREAD_UPDATE": { var json = data.ToObject(Serialization.Default.JsonChannel); - var thread = GuildThread.CreateFromJson(json, Rest); + var thread = ChannelFactory.CreateGuildThread(json, Rest); await InvokeEventAsync(_guildThreadUpdate, this, thread, static (client, thread) => client.Cache = client.Cache.CacheGuildThread(thread)).ConfigureAwait(false); } break; diff --git a/NetCord/Gateway/Guild.cs b/NetCord/Gateway/Guild.cs index fd09b9e1d..b8411b6f3 100644 --- a/NetCord/Gateway/Guild.cs +++ b/NetCord/Gateway/Guild.cs @@ -17,8 +17,8 @@ public Guild(JsonGuild jsonModel, ulong clientId, RestClient client, IDictionary VoiceStates = dictionaryProvider.CreateDictionary(jsonModel.VoiceStates ?? [], s => s.UserId, s => new VoiceState(s, guildId, client)); Users = dictionaryProvider.CreateDictionary(GetUsers(jsonModel.Users), u => u.User.Id, u => new GuildUser(u, guildId, client)); - Channels = dictionaryProvider.CreateDictionary(jsonModel.Channels ?? [], c => c.Id, c => IGuildChannel.CreateFromJson(c, guildId, client)); - ActiveThreads = dictionaryProvider.CreateDictionary(jsonModel.ActiveThreads ?? [], t => t.Id, t => GuildThread.CreateFromJson(t, client)); + Channels = dictionaryProvider.CreateDictionary(jsonModel.Channels ?? [], c => c.Id, c => ChannelFactory.CreateGuild(c, client)); + ActiveThreads = dictionaryProvider.CreateDictionary(jsonModel.ActiveThreads ?? [], t => t.Id, t => ChannelFactory.CreateGuildThread(t, client)); StageInstances = dictionaryProvider.CreateDictionary(jsonModel.StageInstances ?? [], i => i.Id, i => new StageInstance(i, client)); Presences = dictionaryProvider.CreateDictionary(jsonModel.Presences ?? [], p => p.User.Id, p => new Presence(p, guildId, client)); ScheduledEvents = dictionaryProvider.CreateDictionary(jsonModel.ScheduledEvents ?? [], e => e.Id, e => new GuildScheduledEvent(e, client)); @@ -125,7 +125,7 @@ private static JsonGuild Copy(JsonGuild jsonModel, Guild oldGuild) /// /// An array of objects, representing all active threads in the that current user has permission to view. /// - public IReadOnlyDictionary ActiveThreads { get; set; } + public IReadOnlyDictionary ActiveThreads { get; set; } /// /// A dictionary of objects, will only include offline users if is . diff --git a/NetCord/Gateway/IGatewayClientCache.cs b/NetCord/Gateway/IGatewayClientCache.cs index a95d3ecfb..81717ddbd 100644 --- a/NetCord/Gateway/IGatewayClientCache.cs +++ b/NetCord/Gateway/IGatewayClientCache.cs @@ -11,7 +11,7 @@ public interface IGatewayClientCache : IDictionaryProvider, IDisposable public IGatewayClientCache CachePresences(ulong guildId, IReadOnlyList presences); public IGatewayClientCache CacheRole(Role role); public IGatewayClientCache CacheGuildScheduledEvent(GuildScheduledEvent scheduledEvent); - public IGatewayClientCache CacheGuildThread(GuildThread thread); + public IGatewayClientCache CacheGuildThread(IGuildThread thread); public IGatewayClientCache CacheGuildChannel(IGuildChannel channel); public IGatewayClientCache CacheStageInstance(StageInstance stageInstance); public IGatewayClientCache CacheCurrentUser(CurrentUser user); @@ -20,7 +20,7 @@ public interface IGatewayClientCache : IDictionaryProvider, IDisposable public IGatewayClientCache SyncGuildEmojis(ulong guildId, IReadOnlyDictionary emojis); public IGatewayClientCache SyncGuildStickers(ulong guildId, IReadOnlyDictionary stickers); - public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads); + public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads); public IGatewayClientCache SyncGuilds(IReadOnlyList guildIds); public IGatewayClientCache RemoveGuild(ulong guildId); diff --git a/NetCord/Gateway/ImmutableGatewayClientCache.cs b/NetCord/Gateway/ImmutableGatewayClientCache.cs index 72fbfabc8..dbd5869c8 100644 --- a/NetCord/Gateway/ImmutableGatewayClientCache.cs +++ b/NetCord/Gateway/ImmutableGatewayClientCache.cs @@ -177,7 +177,7 @@ public IGatewayClientCache CacheGuildScheduledEvent(GuildScheduledEvent schedule return this; } - public IGatewayClientCache CacheGuildThread(GuildThread thread) + public IGatewayClientCache CacheGuildThread(IGuildThread thread) { var guildId = thread.GuildId; var guilds = _guilds; @@ -293,7 +293,7 @@ public IGatewayClientCache SyncGuildStickers(ulong guildId, IReadOnlyDictionary< return this; } - public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads) + public IGatewayClientCache SyncGuildActiveThreads(ulong guildId, IReadOnlyDictionary threads) { var guilds = _guilds; if (guilds.TryGetValue(guildId, out var guild)) diff --git a/NetCord/Gateway/Message.cs b/NetCord/Gateway/Message.cs index 1c556fe14..8fa9accf6 100644 --- a/NetCord/Gateway/Message.cs +++ b/NetCord/Gateway/Message.cs @@ -6,7 +6,7 @@ namespace NetCord.Gateway; /// /// Represents a complete object, with all required fields present. /// -public class Message(JsonMessage jsonModel, Guild? guild, TextChannel? channel, RestClient client) : RestMessage(jsonModel, client) +public class Message(JsonMessage jsonModel, Guild? guild, ITextChannel? channel, RestClient client) : RestMessage(jsonModel, client) { public static Message CreateFromJson(JsonMessage jsonModel, IGatewayClientCache cache, RestClient client) { @@ -14,10 +14,10 @@ public static Message CreateFromJson(JsonMessage jsonModel, IGatewayClientCache return new(jsonModel, guild, channel, client); } - private static (Guild?, TextChannel?) GetCacheData(JsonMessage jsonModel, IGatewayClientCache cache) + private static (Guild?, ITextChannel?) GetCacheData(JsonMessage jsonModel, IGatewayClientCache cache) { Guild? guild; - TextChannel? channel; + ITextChannel? channel; var guildId = jsonModel.GuildId; if (guildId.HasValue) { @@ -25,7 +25,7 @@ private static (Guild?, TextChannel?) GetCacheData(JsonMessage jsonModel, IGatew { var channelId = jsonModel.ChannelId; if (guild.Channels.TryGetValue(channelId, out var guildChannel)) - channel = (TextChannel)guildChannel; + channel = (ITextChannel)guildChannel; else if (guild.ActiveThreads.TryGetValue(channelId, out var thread)) channel = thread; else @@ -50,5 +50,5 @@ private static (Guild?, TextChannel?) GetCacheData(JsonMessage jsonModel, IGatew public Guild? Guild { get; } = guild; /// - public TextChannel? Channel { get; } = channel; + public ITextChannel? Channel { get; } = channel; } diff --git a/NetCord/Interaction.cs b/NetCord/Interaction.cs index 4f18c5439..1872d134a 100644 --- a/NetCord/Interaction.cs +++ b/NetCord/Interaction.cs @@ -25,7 +25,7 @@ private protected Interaction(JsonModels.JsonInteraction jsonModel, Guild? guild GuildReference = new(guildReference); Guild = guild; - Channel = TextChannel.CreateFromJson(jsonModel.Channel!, client); + Channel = (IInteractionChannel)ChannelFactory.CreateText(jsonModel.Channel!, client); Entitlements = jsonModel.Entitlements.Select(e => new Entitlement(e, client)).ToArray(); _sendResponseAsync = sendResponseAsync; @@ -41,7 +41,7 @@ private protected Interaction(JsonModels.JsonInteraction jsonModel, Guild? guild public Guild? Guild { get; } - public TextChannel Channel { get; } + public IInteractionChannel Channel { get; } public User User { get; } diff --git a/NetCord/InteractionResolvedData.cs b/NetCord/InteractionResolvedData.cs index f591957f4..3240086f3 100644 --- a/NetCord/InteractionResolvedData.cs +++ b/NetCord/InteractionResolvedData.cs @@ -21,7 +21,7 @@ public class InteractionResolvedData /// /// A list of channel objects, mapped to their IDs. /// - public IReadOnlyDictionary? Channels { get; } + public IReadOnlyDictionary? Channels { get; } /// /// A list of message objects, mapped to their IDs. @@ -75,7 +75,7 @@ public InteractionResolvedData(JsonInteractionResolvedData jsonModel, ulong? gui var channels = jsonModel.Channels; if (channels is not null) - Channels = channels.ToDictionary(c => c.Key, c => Channel.CreateFromJson(c.Value, client)); + Channels = channels.ToDictionary(c => c.Key, c => ChannelFactory.Create(c.Value, client)); var messages = jsonModel.Messages; if (messages is not null) diff --git a/NetCord/MessageComponentInteraction.cs b/NetCord/MessageComponentInteraction.cs index 1040a946f..3a7f0556c 100644 --- a/NetCord/MessageComponentInteraction.cs +++ b/NetCord/MessageComponentInteraction.cs @@ -10,7 +10,7 @@ private protected MessageComponentInteraction(JsonInteraction jsonModel, Guild? { var message = jsonModel.Message!; message.GuildId = jsonModel.GuildId; - Message = new(message, guild, Channel, client); + Message = new(message, guild, Channel as ITextChannel, client); } public Message Message { get; } diff --git a/NetCord/ModalInteraction.cs b/NetCord/ModalInteraction.cs index 7c46df669..241cc8a83 100644 --- a/NetCord/ModalInteraction.cs +++ b/NetCord/ModalInteraction.cs @@ -11,7 +11,7 @@ public ModalInteraction(JsonModels.JsonInteraction jsonModel, Guild? guild, Inte if (message is not null) { message.GuildId = jsonModel.GuildId; - Message = new(message, guild, Channel, client); + Message = new(message, guild, Channel as ITextChannel, client); } Data = new(jsonModel.Data!, jsonModel.GuildId, client); diff --git a/NetCord/PartialGuildUserExtensions.cs b/NetCord/PartialGuildUserExtensions.cs index 01ff4c388..decb1335d 100644 --- a/NetCord/PartialGuildUserExtensions.cs +++ b/NetCord/PartialGuildUserExtensions.cs @@ -42,39 +42,39 @@ public static Permissions GetPermissions(this PartialGuildUser user, RestGuild g } /// - /// Returns a -specific object belonging to the by acquiring it from the specificied . + /// Returns a -specific object belonging to the by acquiring it from the specificied . /// /// The to acquire permissions for. /// The to acquire the permissions from. - /// The to acquire the permissions for. - public static Permissions GetChannelPermissions(this PartialGuildUser user, RestGuild guild, IGuildChannel channel) + /// The to acquire the permissions for. + public static Permissions GetChannelPermissions(this PartialGuildUser user, RestGuild guild, IPermissionOverwriteChannel channel) { var guildPermissions = GetPermissions(user, guild); return user.GetChannelPermissions(guildPermissions, channel); } /// - /// Returns a -specific object belonging to the by acquiring it from the specificied . + /// Returns a -specific object belonging to the by acquiring it from the specificied . /// /// The to acquire permissions for. /// The to acquire the permissions from. - /// The ID of the to acquire the permissions for. + /// The ID of the to acquire the permissions for. public static Permissions GetChannelPermissions(this PartialGuildUser user, Guild guild, ulong channelId) { var guildPermissions = GetPermissions(user, guild); if (guildPermissions.HasFlag(Permissions.Administrator)) return (Permissions)ulong.MaxValue; - return user.GetChannelPermissionsCore(guildPermissions, guild.Channels[channelId]); + return user.GetChannelPermissionsCore(guildPermissions, guild.Channels[channelId] as IPermissionOverwriteChannel ?? throw new InvalidOperationException("The channel does not support permission overwrites.")); } /// - /// Returns a -specific object belonging to the by acquiring it from the specificied . + /// Returns a -specific object belonging to the by acquiring it from the specificied . /// /// The to acquire permissions for. /// The object to acquire permissions from. - /// The to acquire the permissions for. - public static Permissions GetChannelPermissions(this PartialGuildUser user, Permissions guildPermissions, IGuildChannel channel) + /// The to acquire the permissions for. + public static Permissions GetChannelPermissions(this PartialGuildUser user, Permissions guildPermissions, IPermissionOverwriteChannel channel) { if (guildPermissions.HasFlag(Permissions.Administrator)) return (Permissions)ulong.MaxValue; @@ -82,7 +82,7 @@ public static Permissions GetChannelPermissions(this PartialGuildUser user, Perm return user.GetChannelPermissionsCore(guildPermissions, channel); } - private static Permissions GetChannelPermissionsCore(this PartialGuildUser user, Permissions guildPermissions, IGuildChannel channel) + private static Permissions GetChannelPermissionsCore(this PartialGuildUser user, Permissions guildPermissions, IPermissionOverwriteChannel channel) { var permissions = guildPermissions; diff --git a/NetCord/Rest/GuildMessageSearchResult.cs b/NetCord/Rest/GuildMessageSearchResult.cs index 9aa5d2c1c..9cc4c9fe3 100644 --- a/NetCord/Rest/GuildMessageSearchResult.cs +++ b/NetCord/Rest/GuildMessageSearchResult.cs @@ -64,7 +64,7 @@ public class GuildMessagesSearchResultData(JsonGuildMessagesSearchResult jsonMod /// /// The threads associated with the search results. /// - public IReadOnlyList Threads { get; } = jsonModel.Threads.SelectOrEmpty(t => GuildThread.CreateFromJson(t, client)).ToArray(); + public IReadOnlyList Threads { get; } = jsonModel.Threads.SelectOrEmpty(t => ChannelFactory.CreateGuildThread(t, client)).ToArray(); /// /// The thread users associated with the search results. diff --git a/NetCord/Rest/GuildTemplatePreview.cs b/NetCord/Rest/GuildTemplatePreview.cs index 0db44d947..48f83b1b7 100644 --- a/NetCord/Rest/GuildTemplatePreview.cs +++ b/NetCord/Rest/GuildTemplatePreview.cs @@ -18,5 +18,5 @@ public class GuildTemplatePreview(JsonGuild jsonModel, RestClient client) : IJso public ulong? SystemChannelId => jsonModel.SystemChannelId; public SystemChannelFlags SystemChannelFlags => jsonModel.SystemChannelFlags; public IReadOnlyDictionary Roles { get; } = jsonModel.Roles.ToDictionaryOrEmpty(r => r.Id, r => new Role(r, 0, client)); - public IReadOnlyDictionary Channels { get; } = jsonModel.Channels.ToDictionaryOrEmpty(c => c.Id, c => IGuildChannel.CreateFromJson(c, 0, client)); + public IReadOnlyDictionary Channels { get; } = jsonModel.Channels.ToDictionaryOrEmpty(c => c.Id, c => ChannelFactory.CreateGuild(c, client)); } diff --git a/NetCord/Rest/GuildThreadGenerator.cs b/NetCord/Rest/GuildThreadGenerator.cs index d176c339a..b99f92eed 100644 --- a/NetCord/Rest/GuildThreadGenerator.cs +++ b/NetCord/Rest/GuildThreadGenerator.cs @@ -2,7 +2,7 @@ namespace NetCord.Rest; internal static class GuildThreadGenerator { - public static IEnumerable CreateThreads(JsonModels.JsonRestGuildThreadResult jsonThreads, RestClient client) + public static IEnumerable CreateThreads(JsonModels.JsonRestGuildThreadResult jsonThreads, RestClient client) { var users = jsonThreads.Users.ToDictionary(u => u.ThreadId); return jsonThreads.Threads.Select(t => @@ -10,7 +10,7 @@ public static IEnumerable CreateThreads(JsonModels.JsonRestGuildThr if (users.TryGetValue(t.Id, out var user)) t.CurrentUser = user; - return GuildThread.CreateFromJson(t, client); + return ChannelFactory.CreateGuildThread(t, client); }); } } diff --git a/NetCord/Rest/RestAuditLogEntryData.cs b/NetCord/Rest/RestAuditLogEntryData.cs index 2b7bb001a..c5115b219 100644 --- a/NetCord/Rest/RestAuditLogEntryData.cs +++ b/NetCord/Rest/RestAuditLogEntryData.cs @@ -25,7 +25,7 @@ public class RestAuditLogEntryData(JsonModels.JsonAuditLog jsonModel, RestClient /// /// List of threads referenced in the audit log /// - public IReadOnlyDictionary Threads { get; } = jsonModel.Threads.ToDictionary(c => c.Id, t => GuildThread.CreateFromJson(t, client)); + public IReadOnlyDictionary Threads { get; } = jsonModel.Threads.ToDictionary(c => c.Id, t => ChannelFactory.CreateGuildThread(t, client)); /// /// List of users referenced in the audit log. diff --git a/NetCord/Rest/RestClient.Channel.cs b/NetCord/Rest/RestClient.Channel.cs index ef8b636c5..f082f64ce 100644 --- a/NetCord/Rest/RestClient.Channel.cs +++ b/NetCord/Rest/RestClient.Channel.cs @@ -15,9 +15,9 @@ public partial class RestClient /// The ID of the channel to retrieve. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(Channel)], nameof(Channel.Id), Cast = true)] - public async Task GetChannelAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => Channel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + [GenerateAlias([typeof(IChannel)], nameof(IChannel.Id), Cast = true)] + public async Task GetChannelAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + => ChannelFactory.Create(await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); /// /// Modifies a group DM channel's properties. @@ -26,13 +26,13 @@ public async Task GetChannelAsync(ulong channelId, RestRequestPropertie /// An action delegate used to configure the channel's updated properties. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GroupDMChannel)], nameof(GroupDMChannel.Id), Cast = true)] - public async Task ModifyGroupDMChannelAsync(ulong channelId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + [GenerateAlias([typeof(IGroupDMChannel)], nameof(IGroupDMChannel.Id), Cast = true)] + public async Task ModifyGroupDMChannelAsync(ulong channelId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { GroupDMChannelOptions groupDMChannelOptions = new(); action(groupDMChannelOptions); using (HttpContent content = new JsonContent(groupDMChannelOptions, Serialization.Default.GroupDMChannelOptions)) - return Channel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Patch, content, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateGroupDM(await (await SendRequestAsync(HttpMethod.Patch, content, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } /// @@ -43,12 +43,12 @@ public async Task ModifyGroupDMChannelAsync(ulong channelId, ActionOptional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. [GenerateAlias([typeof(IGuildChannel)], nameof(IGuildChannel.Id), Cast = true)] - public async Task ModifyGuildChannelAsync(ulong channelId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + public async Task ModifyGuildChannelAsync(ulong channelId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { GuildChannelOptions guildChannelOptions = new(); action(guildChannelOptions); using (HttpContent content = new JsonContent(guildChannelOptions, Serialization.Default.GuildChannelOptions)) - return Channel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Patch, content, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateGuild(await (await SendRequestAsync(HttpMethod.Patch, content, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } /// @@ -58,7 +58,7 @@ public async Task ModifyGuildChannelAsync(ulong channelId, ActionThe status to apply to the channel. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(VoiceGuildChannel)], nameof(VoiceGuildChannel.Id))] + [GenerateAlias([typeof(IVoiceGuildChannel)], nameof(IVoiceGuildChannel.Id))] public async Task SetVoiceGuildChannelStatusAsync(ulong channelId, VoiceGuildChannelStatusProperties statusProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(statusProperties, Serialization.Default.VoiceGuildChannelStatusProperties)) @@ -71,9 +71,9 @@ public async Task SetVoiceGuildChannelStatusAsync(ulong channelId, VoiceGuildCha /// The ID of the channel to delete. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(Channel)], nameof(Channel.Id), Cast = true)] - public async Task DeleteChannelAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => Channel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + [GenerateAlias([typeof(IChannel)], nameof(IChannel.Id), Cast = true)] + public async Task DeleteChannelAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + => ChannelFactory.Create(await (await SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); /// /// Retrieves an , representing the messages of a specific channel. @@ -81,7 +81,7 @@ public async Task DeleteChannelAsync(ulong channelId, RestRequestProper /// The ID of the channel to retrieve messages from. /// Optional properties to customize result pagination, can be . /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] public IAsyncEnumerable GetMessagesAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { paginationProperties = PaginationProperties.Prepare(paginationProperties, 0, long.MaxValue, PaginationDirection.Before, 100); @@ -111,7 +111,7 @@ public IAsyncEnumerable GetMessagesAsync(ulong channelId, Paginatio /// The maximum number of messages to retrieve, or to use the default. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] public async Task> GetMessagesAroundAsync(ulong channelId, ulong messageId, int? limit = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/messages", $"?limit={limit.GetValueOrDefault(100)}&around={messageId}", new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessageArray).ConfigureAwait(false)).Select(m => new RestMessage(m, this)).ToArray(); @@ -361,7 +361,7 @@ static string InvalidEnum(string propertyName) /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. /// - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public async Task GetMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/messages/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessage).ConfigureAwait(false), this); @@ -373,7 +373,7 @@ public async Task GetMessageAsync(ulong channelId, ulong messageId, /// The content and properties of the message to send. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), TypeNameOverride = "Message")] public async Task SendMessageAsync(ulong channelId, MessageProperties message, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -388,8 +388,7 @@ public async Task SendMessageAsync(ulong channelId, MessageProperti /// The ID of the message to crosspost. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(AnnouncementGuildChannel)], nameof(AnnouncementGuildChannel.Id))] - [GenerateAlias([typeof(AnnouncementGuildThread)], nameof(AnnouncementGuildThread.Id))] + [GenerateAlias([typeof(IAnnouncementGuildChannel)], nameof(IAnnouncementGuildChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public async Task CrosspostMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Post, $"/channels/{channelId}/messages/{messageId}/crosspost", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessage).ConfigureAwait(false), this); @@ -402,7 +401,7 @@ public async Task CrosspostMessageAsync(ulong channelId, ulong mess /// The emoji to use as the reaction. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task AddMessageReactionAsync(ulong channelId, ulong messageId, ReactionEmojiProperties emoji, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Put, $"/channels/{channelId}/messages/{messageId}/reactions/{ReactionEmojiToString(emoji)}/@me", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -415,7 +414,7 @@ public Task AddMessageReactionAsync(ulong channelId, ulong messageId, ReactionEm /// The emoji to remove as a reaction. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task DeleteCurrentUserMessageReactionAsync(ulong channelId, ulong messageId, ReactionEmojiProperties emoji, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/{messageId}/reactions/{ReactionEmojiToString(emoji)}/@me", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -429,7 +428,7 @@ public Task DeleteCurrentUserMessageReactionAsync(ulong channelId, ulong message /// The ID of the user whose reaction will be removed. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task DeleteUserMessageReactionAsync(ulong channelId, ulong messageId, ReactionEmojiProperties emoji, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/{messageId}/reactions/{ReactionEmojiToString(emoji)}/{userId}", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -442,7 +441,7 @@ public Task DeleteUserMessageReactionAsync(ulong channelId, ulong messageId, Rea /// The emoji to filter reactions by. /// Pagination options for fetching users, or to use defaults. /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public IAsyncEnumerable GetMessageReactionsAsync(ulong channelId, ulong messageId, ReactionEmojiProperties emoji, MessageReactionsPaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { @@ -469,7 +468,7 @@ public IAsyncEnumerable GetMessageReactionsAsync(ulong channelId, ulong me /// The ID of the message to clear reactions from. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task DeleteAllMessageReactionsAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/{messageId}/reactions", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -482,7 +481,7 @@ public Task DeleteAllMessageReactionsAsync(ulong channelId, ulong messageId, Res /// The emoji to remove from all users. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task DeleteAllMessageReactionsForEmojiAsync(ulong channelId, ulong messageId, ReactionEmojiProperties emoji, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/{messageId}/reactions/{ReactionEmojiToString(emoji)}", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -501,7 +500,7 @@ private static string ReactionEmojiToString(ReactionEmojiProperties emoji) /// An action that sets the new message properties. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public async Task ModifyMessageAsync(ulong channelId, ulong messageId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -518,7 +517,7 @@ public async Task ModifyMessageAsync(ulong channelId, ulong message /// The ID of the message to delete. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] public Task DeleteMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -530,7 +529,7 @@ public Task DeleteMessageAsync(ulong channelId, ulong messageId, RestRequestProp /// The list of message IDs to delete. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(IGuildMessageChannel)], nameof(IGuildMessageChannel.Id))] public async Task DeleteMessagesAsync(ulong channelId, IEnumerable messageIds, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { var ids = ArrayPool.Shared.Rent(100); @@ -574,7 +573,7 @@ private async Task BulkDeleteMessagesAsync(ulong channelId, ReadOnlyMemoryThe permission overwrite to apply. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(IGuildChannel)], nameof(IGuildChannel.Id))] + [GenerateAlias([typeof(IPermissionOverwriteChannel)], nameof(IPermissionOverwriteChannel.Id))] public async Task ModifyGuildChannelPermissionsAsync(ulong channelId, PermissionOverwriteProperties permissionOverwrite, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(permissionOverwrite, Serialization.Default.PermissionOverwriteProperties)) @@ -587,7 +586,7 @@ public async Task ModifyGuildChannelPermissionsAsync(ulong channelId, Permission /// The ID of the channel to retrieve invites for. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(IGuildChannel)], nameof(IGuildChannel.Id))] + [GenerateAlias([typeof(IInvitableGuildChannel)], nameof(IInvitableGuildChannel.Id))] public async Task> GetGuildChannelInvitesAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/invites", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRestInviteArray).ConfigureAwait(false)).Select(r => new RestInvite(r, this)).ToArray(); @@ -598,7 +597,7 @@ public async Task> GetGuildChannelInvitesAsync(ulong c /// The properties to configure the new invite. Can be for defaults. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(IGuildChannel)], nameof(IGuildChannel.Id))] + [GenerateAlias([typeof(IInvitableGuildChannel)], nameof(IInvitableGuildChannel.Id))] public async Task CreateGuildChannelInviteAsync(ulong channelId, InviteProperties? inviteProperties = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { if (inviteProperties is null) @@ -615,7 +614,7 @@ public async Task CreateGuildChannelInviteAsync(ulong channelId, Inv /// The ID of the role or user whose permission overwrite is to be deleted. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(IGuildChannel)], nameof(IGuildChannel.Id))] + [GenerateAlias([typeof(IPermissionOverwriteChannel)], nameof(IPermissionOverwriteChannel.Id))] public Task DeleteGuildChannelPermissionAsync(ulong channelId, ulong overwriteId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/permissions/{overwriteId}", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -626,8 +625,7 @@ public Task DeleteGuildChannelPermissionAsync(ulong channelId, ulong overwriteId /// The ID of the channel to receive crossposted messages. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(AnnouncementGuildChannel)], nameof(AnnouncementGuildChannel.Id))] - [GenerateAlias([typeof(AnnouncementGuildThread)], nameof(AnnouncementGuildThread.Id), TypeNameOverride = nameof(AnnouncementGuildChannel))] + [GenerateAlias([typeof(IAnnouncementGuildChannel)], nameof(IAnnouncementGuildChannel.Id))] public async Task FollowAnnouncementGuildChannelAsync(ulong channelId, ulong webhookChannelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(new(webhookChannelId), Serialization.Default.FollowAnnouncementGuildChannelProperties)) @@ -640,7 +638,7 @@ public async Task FollowAnnouncementGuildChannelAsync(ulong cha /// The ID of the channel to trigger typing in. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] public Task TriggerTypingAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Post, $"/channels/{channelId}/typing", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -651,7 +649,7 @@ public Task TriggerTypingAsync(ulong channelId, RestRequestProperties? propertie /// Optional properties to customize the typing interval, can be . /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] public ValueTask EnterTypingScopeAsync(ulong channelId, TypingScopeProperties? scopeProperties = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { AsyncTypingScope scope = new(this, channelId, scopeProperties, properties, cancellationToken); @@ -665,7 +663,7 @@ public ValueTask EnterTypingScopeAsync(ulong channelId, TypingScope /// The ID of the channel to type in. /// Optional properties to customize the typing interval, can be . /// Optional properties to customize the request, can be . - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] public IDisposable EnterTypingScope(ulong channelId, TypingScopeProperties? scopeProperties = null, RestRequestProperties? properties = null) { return new TypingScope(this, channelId, scopeProperties, properties); @@ -677,7 +675,7 @@ public IDisposable EnterTypingScope(ulong channelId, TypingScopeProperties? scop /// The ID of the channel to get pinned messages from. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(IPinnableChannel)], nameof(IPinnableChannel.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(); @@ -688,7 +686,7 @@ public async Task> GetPinnedMessagesAsync(ulong chann /// The ID of the message to pin. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(IPinnableChannel)], nameof(IPinnableChannel.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); @@ -700,7 +698,7 @@ public Task PinMessageAsync(ulong channelId, ulong messageId, RestRequestPropert /// The ID of the message to unpin. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(IPinnableChannel)], nameof(IPinnableChannel.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); @@ -713,7 +711,7 @@ public Task UnpinMessageAsync(ulong channelId, ulong messageId, RestRequestPrope /// Properties for adding the user, such as access tokens. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GroupDMChannel)], nameof(GroupDMChannel.Id))] + [GenerateAlias([typeof(IGroupDMChannel)], nameof(IGroupDMChannel.Id))] public async Task GroupDMChannelAddUserAsync(ulong channelId, ulong userId, GroupDMChannelUserAddProperties groupDMChannelUserAddProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(groupDMChannelUserAddProperties, Serialization.Default.GroupDMChannelUserAddProperties)) @@ -727,7 +725,7 @@ public async Task GroupDMChannelAddUserAsync(ulong channelId, ulong userId, Grou /// The ID of the user to remove. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GroupDMChannel)], nameof(GroupDMChannel.Id))] + [GenerateAlias([typeof(IGroupDMChannel)], nameof(IGroupDMChannel.Id))] public Task GroupDMChannelDeleteUserAsync(ulong channelId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/recipients/{userId}", null, new(channelId), properties, cancellationToken: cancellationToken); @@ -739,12 +737,13 @@ public Task GroupDMChannelDeleteUserAsync(ulong channelId, ulong userId, RestReq /// The properties of the thread to create. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] + [GenerateAlias([typeof(ITextGuildChannel)], nameof(ITextGuildChannel.Id))] + [GenerateAlias([typeof(IAnnouncementGuildChannel)], nameof(IAnnouncementGuildChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")] - public async Task CreateGuildThreadAsync(ulong channelId, ulong messageId, GuildThreadFromMessageProperties threadFromMessageProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + public async Task CreateGuildThreadAsync(ulong channelId, ulong messageId, GuildThreadFromMessageProperties threadFromMessageProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(threadFromMessageProperties, Serialization.Default.GuildThreadFromMessageProperties)) - return GuildThread.CreateFromJson(await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/messages/{messageId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateGuildThread(await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/messages/{messageId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } /// @@ -754,25 +753,35 @@ public async Task CreateGuildThreadAsync(ulong channelId, ulong mes /// The properties of the thread to create. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] - public async Task CreateGuildThreadAsync(ulong channelId, GuildThreadProperties threadProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + [GenerateAlias([typeof(ITextGuildChannel)], nameof(ITextGuildChannel.Id))] + [GenerateAlias([typeof(IAnnouncementGuildChannel)], nameof(IAnnouncementGuildChannel.Id))] + public async Task CreateGuildThreadAsync(ulong channelId, GuildThreadProperties threadProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(threadProperties, Serialization.Default.GuildThreadProperties)) - return GuildThread.CreateFromJson(await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateGuildThread(await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } /// - /// Creates a new thread in a forum channel. + /// Creates a new thread in a thread-only channel (forum and media channels). /// /// The ID of the forum channel. /// The properties of the forum thread to create. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(ForumGuildChannel)], nameof(ForumGuildChannel.Id))] - public async Task CreateForumGuildThreadAsync(ulong channelId, ForumGuildThreadProperties threadProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + [GenerateAlias([typeof(IThreadOnlyGuildChannel)], nameof(IThreadOnlyGuildChannel.Id))] + public async Task CreateForumGuildThreadAsync(ulong channelId, ForumGuildThreadProperties threadProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = threadProperties.Serialize()) - return new ForumGuildThread(await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + { + var result = await (await SendRequestAsync(HttpMethod.Post, content, $"/channels/{channelId}/threads", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false); + var message = new RestMessage(result.Message!, this); + var thread = ChannelFactory.CreatePublicGuildThread(result, this); + return new CreateGuildThreadResult + { + Thread = new PublicGuildThread(result, this), + Message = message, + }; + } } /// @@ -781,7 +790,7 @@ public async Task CreateForumGuildThreadAsync(ulong channelId, /// The ID of the thread to join. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] public Task JoinGuildThreadAsync(ulong threadId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Put, $"/channels/{threadId}/thread-members/@me", null, new(threadId), properties, cancellationToken: cancellationToken); @@ -792,7 +801,7 @@ public Task JoinGuildThreadAsync(ulong threadId, RestRequestProperties? properti /// The ID of the user to add to the thread. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] public Task AddGuildThreadUserAsync(ulong threadId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Put, $"/channels/{threadId}/thread-members/{userId}", null, new(threadId), properties, cancellationToken: cancellationToken); @@ -802,7 +811,7 @@ public Task AddGuildThreadUserAsync(ulong threadId, ulong userId, RestRequestPro /// The ID of the thread to leave. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] public Task LeaveGuildThreadAsync(ulong threadId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{threadId}/thread-members/@me", null, new(threadId), properties, cancellationToken: cancellationToken); @@ -813,7 +822,7 @@ public Task LeaveGuildThreadAsync(ulong threadId, RestRequestProperties? propert /// The ID of the user to remove from the thread. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] [GenerateAlias([typeof(GuildThreadUser)], nameof(GuildThreadUser.ThreadId), nameof(GuildThreadUser.Id))] public Task DeleteGuildThreadUserAsync(ulong threadId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/channels/{threadId}/thread-members/{userId}", null, new(threadId), properties, cancellationToken: cancellationToken); @@ -826,7 +835,7 @@ public Task DeleteGuildThreadUserAsync(ulong threadId, ulong userId, RestRequest /// Whether to include full guild member info in the response. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] public async Task GetGuildThreadUserAsync(ulong threadId, ulong userId, bool withGuildUser = false, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { var user = await (await SendRequestAsync(HttpMethod.Get, $"/channels/{threadId}/thread-members/{userId}", $"?with_member={withGuildUser}", new(threadId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonThreadUser).ConfigureAwait(false); @@ -839,7 +848,7 @@ public async Task GetGuildThreadUserAsync(ulong threadId, ulong user /// The ID of the thread. /// Pagination options for fetching users, or to use defaults. /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(GuildThread)], nameof(GuildThread.Id))] + [GenerateAlias([typeof(IGuildThread)], nameof(IGuildThread.Id))] public IAsyncEnumerable GetGuildThreadUsersAsync(ulong threadId, OptionalGuildUsersPaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { paginationProperties = PaginationProperties.PrepareWithDirectionValidation(paginationProperties, PaginationDirection.After, 100); @@ -866,12 +875,13 @@ public IAsyncEnumerable GetGuildThreadUsersAsync(ulong threadId, Opt /// The ID of the text channel. /// Pagination options for archived threads, or to use defaults. /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] - public IAsyncEnumerable GetPublicArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) + [GenerateAlias([typeof(ITextGuildChannel)], nameof(ITextGuildChannel.Id))] + [GenerateAlias([typeof(IAnnouncementGuildChannel)], nameof(IAnnouncementGuildChannel.Id))] + public IAsyncEnumerable GetPublicArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { paginationProperties = PaginationProperties.PrepareWithDirectionValidation(paginationProperties, PaginationDirection.Before, 100); - return new OptimizedQueryPaginationAsyncEnumerable( + return new OptimizedQueryPaginationAsyncEnumerable( this, paginationProperties, async s => @@ -893,12 +903,12 @@ public IAsyncEnumerable GetPublicArchivedGuildThreadsAsync(ulong ch /// The ID of the text channel. /// Pagination options for archived threads, or to use defaults. /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] - public IAsyncEnumerable GetPrivateArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) + [GenerateAlias([typeof(ITextGuildChannel)], nameof(ITextGuildChannel.Id))] + public IAsyncEnumerable GetPrivateArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { paginationProperties = PaginationProperties.PrepareWithDirectionValidation(paginationProperties, PaginationDirection.Before, 100); - return new OptimizedQueryPaginationAsyncEnumerable( + return new OptimizedQueryPaginationAsyncEnumerable( this, paginationProperties, async s => @@ -920,12 +930,12 @@ public IAsyncEnumerable GetPrivateArchivedGuildThreadsAsync(ulong c /// The ID of the text channel. /// Pagination options for archived threads, or to use defaults. /// Optional properties to customize each request, can be . - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] - public IAsyncEnumerable GetJoinedPrivateArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) + [GenerateAlias([typeof(ITextGuildChannel)], nameof(ITextGuildChannel.Id))] + public IAsyncEnumerable GetJoinedPrivateArchivedGuildThreadsAsync(ulong channelId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { paginationProperties = PaginationProperties.PrepareWithDirectionValidation(paginationProperties, PaginationDirection.Before, 100); - return new OptimizedQueryPaginationAsyncEnumerable( + return new OptimizedQueryPaginationAsyncEnumerable( this, paginationProperties, async s => diff --git a/NetCord/Rest/RestClient.Guild.cs b/NetCord/Rest/RestClient.Guild.cs index eb62e537f..84ae25c37 100644 --- a/NetCord/Rest/RestClient.Guild.cs +++ b/NetCord/Rest/RestClient.Guild.cs @@ -35,13 +35,13 @@ public Task DeleteGuildAsync(ulong guildId, RestRequestProperties? properties = [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildChannelsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) - => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannelArray).ConfigureAwait(false)).Select(c => IGuildChannel.CreateFromJson(c, guildId, this)).ToArray(); + => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannelArray).ConfigureAwait(false)).Select(c => ChannelFactory.CreateGuild(c, this)).ToArray(); [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task CreateGuildChannelAsync(ulong guildId, GuildChannelProperties channelProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(channelProperties, Serialization.Default.GuildChannelProperties)) - return IGuildChannel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), guildId, this); + return ChannelFactory.CreateGuild(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] @@ -52,7 +52,7 @@ public async Task ModifyGuildChannelPositionsAsync(ulong guildId, IEnumerable> GetActiveGuildThreadsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + public async Task> GetActiveGuildThreadsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => GuildThreadGenerator.CreateThreads(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/threads/active", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRestGuildThreadResult).ConfigureAwait(false), this).ToArray(); [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] diff --git a/NetCord/Rest/RestClient.Poll.cs b/NetCord/Rest/RestClient.Poll.cs index c5ac5ad48..8ad2e0263 100644 --- a/NetCord/Rest/RestClient.Poll.cs +++ b/NetCord/Rest/RestClient.Poll.cs @@ -4,7 +4,7 @@ namespace NetCord.Rest; public partial class RestClient { - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = nameof(Message))] public IAsyncEnumerable GetMessagePollAnswerVotersAsync(ulong channelId, ulong messageId, int answerId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { @@ -22,7 +22,7 @@ public IAsyncEnumerable GetMessagePollAnswerVotersAsync(ulong channelId, u properties); } - [GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))] + [GenerateAlias([typeof(ITextChannel)], nameof(ITextChannel.Id))] [GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = nameof(Message))] public async Task EndMessagePollAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Post, $"/channels/{channelId}/polls/{messageId}/expire", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessage).ConfigureAwait(false), this); diff --git a/NetCord/Rest/RestClient.StageInstance.cs b/NetCord/Rest/RestClient.StageInstance.cs index 27c68f95c..9b8c5de04 100644 --- a/NetCord/Rest/RestClient.StageInstance.cs +++ b/NetCord/Rest/RestClient.StageInstance.cs @@ -8,12 +8,12 @@ public async Task CreateStageInstanceAsync(StageInstancePropertie return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/stage-instances", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonStageInstance).ConfigureAwait(false), this); } - [GenerateAlias([typeof(StageGuildChannel)], nameof(StageGuildChannel.Id))] + [GenerateAlias([typeof(IStageGuildChannel)], nameof(IStageGuildChannel.Id))] [GenerateAlias([typeof(StageInstance)], nameof(StageInstance.ChannelId))] public async Task GetStageInstanceAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/stage-instances/{channelId}", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonStageInstance).ConfigureAwait(false), this); - [GenerateAlias([typeof(StageGuildChannel)], nameof(StageGuildChannel.Id))] + [GenerateAlias([typeof(IStageGuildChannel)], nameof(IStageGuildChannel.Id))] [GenerateAlias([typeof(StageInstance)], nameof(StageInstance.ChannelId))] public async Task ModifyStageInstanceAsync(ulong channelId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -23,7 +23,7 @@ public async Task ModifyStageInstanceAsync(ulong channelId, Actio return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/stage-instances/{channelId}", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonStageInstance).ConfigureAwait(false), this); } - [GenerateAlias([typeof(StageGuildChannel)], nameof(StageGuildChannel.Id))] + [GenerateAlias([typeof(IStageGuildChannel)], nameof(IStageGuildChannel.Id))] [GenerateAlias([typeof(StageInstance)], nameof(StageInstance.ChannelId))] public Task DeleteStageInstanceAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/stage-instances/{channelId}", null, null, properties, cancellationToken: cancellationToken); diff --git a/NetCord/Rest/RestClient.Undocumented.cs b/NetCord/Rest/RestClient.Undocumented.cs index d023c0d78..df0d7d9c3 100644 --- a/NetCord/Rest/RestClient.Undocumented.cs +++ b/NetCord/Rest/RestClient.Undocumented.cs @@ -8,7 +8,7 @@ public partial class RestClient public async Task GetApplicationAsync(ulong applicationId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/applications/{applicationId}/rpc", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonApplication).ConfigureAwait(false), this); - [GenerateAlias([typeof(Channel)], nameof(Channel.Id))] + [GenerateAlias([typeof(IChannel)], nameof(IChannel.Id))] public async Task> CreateGoogleCloudPlatformStorageBucketsAsync(ulong channelId, IEnumerable buckets, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(new(buckets), Serialization.Default.GoogleCloudPlatformStorageBucketsProperties)) diff --git a/NetCord/Rest/RestClient.User.cs b/NetCord/Rest/RestClient.User.cs index c5e0b5718..2d2b2d0f3 100644 --- a/NetCord/Rest/RestClient.User.cs +++ b/NetCord/Rest/RestClient.User.cs @@ -49,16 +49,16 @@ public Task LeaveGuildAsync(ulong guildId, RestRequestProperties? properties = n => SendRequestAsync(HttpMethod.Delete, $"/users/@me/guilds/{guildId}", null, null, properties, cancellationToken: cancellationToken); [GenerateAlias([typeof(User)], nameof(User.Id))] - public async Task GetDMChannelAsync(ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + public async Task GetDMChannelAsync(ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(new(userId), Serialization.Default.DMChannelProperties)) - return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/users/@me/channels", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateDM(await (await SendRequestAsync(HttpMethod.Post, content, $"/users/@me/channels", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } - public async Task CreateGroupDMChannelAsync(GroupDMChannelProperties groupDMChannelProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) + public async Task CreateGroupDMChannelAsync(GroupDMChannelProperties groupDMChannelProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(groupDMChannelProperties, Serialization.Default.GroupDMChannelProperties)) - return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/users/@me/channels", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); + return ChannelFactory.CreateGroupDM(await (await SendRequestAsync(HttpMethod.Post, content, $"/users/@me/channels", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), this); } [GenerateAlias([typeof(CurrentUser)])] diff --git a/NetCord/Rest/RestClient.Webhook.cs b/NetCord/Rest/RestClient.Webhook.cs index 96859e0e1..5b745c297 100644 --- a/NetCord/Rest/RestClient.Webhook.cs +++ b/NetCord/Rest/RestClient.Webhook.cs @@ -14,8 +14,7 @@ public partial class RestClient /// Properties to customize the webhook's appearance. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(ForumGuildChannel)], nameof(ForumGuildChannel.Id))] - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] + [GenerateAlias([typeof(IWebhookChannel)], nameof(IWebhookChannel.Id))] public async Task CreateWebhookAsync(ulong channelId, WebhookProperties webhookProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(webhookProperties, Serialization.Default.WebhookProperties)) @@ -28,8 +27,7 @@ public async Task CreateWebhookAsync(ulong channelId, WebhookPr /// The ID of the channel to retrieve webhooks for. /// Optional properties to customize the request, can be . /// A token that can be used to cancel the operation before it completes. - [GenerateAlias([typeof(ForumGuildChannel)], nameof(ForumGuildChannel.Id))] - [GenerateAlias([typeof(TextGuildChannel)], nameof(TextGuildChannel.Id))] + [GenerateAlias([typeof(IWebhookChannel)], nameof(IWebhookChannel.Id))] public async Task> GetChannelWebhooksAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/webhooks", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonWebhookArray).ConfigureAwait(false)).Select(w => Webhook.CreateFromJson(w, this)).ToArray(); diff --git a/NetCord/Rest/RestInvite.cs b/NetCord/Rest/RestInvite.cs index 18be1a36a..701a57377 100644 --- a/NetCord/Rest/RestInvite.cs +++ b/NetCord/Rest/RestInvite.cs @@ -13,7 +13,7 @@ public partial class RestInvite : IInvite, IJsonModel public RestGuild? Guild { get; } - public Channel? Channel { get; } + public IInviteChannel? Channel { get; } public User? Inviter { get; } @@ -65,7 +65,7 @@ public RestInvite(JsonModels.JsonRestInvite jsonModel, RestClient client) } if (jsonModel.Channel is { } channel) - Channel = Channel.CreateFromJson(channel, client); + Channel = (IInviteChannel)ChannelFactory.Create(channel, client); if (jsonModel.Inviter is { } inviter) Inviter = new(inviter, client); diff --git a/NetCord/Rest/RestMessage.cs b/NetCord/Rest/RestMessage.cs index 95c2d6942..c52414c04 100644 --- a/NetCord/Rest/RestMessage.cs +++ b/NetCord/Rest/RestMessage.cs @@ -70,7 +70,7 @@ public RestMessage(NetCord.JsonModels.JsonMessage jsonModel, RestClient client) var startedThread = jsonModel.StartedThread; if (startedThread is not null) - StartedThread = GuildThread.CreateFromJson(startedThread, client); + StartedThread = ChannelFactory.CreateGuildThread(startedThread, client); Components = jsonModel.Components.SelectOrEmpty(IMessageComponent.CreateFromJson).ToArray(); Stickers = jsonModel.Stickers.SelectOrEmpty(s => new MessageSticker(s, client)).ToArray(); @@ -240,7 +240,7 @@ public RestMessage(NetCord.JsonModels.JsonMessage jsonModel, RestClient client) /// /// The that was started from this message, if any. /// - public GuildThread? StartedThread { get; } + public IGuildThread? StartedThread { get; } /// /// A list of objects, contains components like s, s, or other interactive components if any are present. diff --git a/NetCord/Rest/Webhook.cs b/NetCord/Rest/Webhook.cs index b34113203..0cb669429 100644 --- a/NetCord/Rest/Webhook.cs +++ b/NetCord/Rest/Webhook.cs @@ -24,7 +24,7 @@ public Webhook(JsonWebhook jsonModel, RestClient client) : base(client) var channel = jsonModel.Channel; if (channel is not null) - Channel = Channel.CreateFromJson(channel, client); + Channel = ChannelFactory.Create(channel, client); } /// @@ -100,7 +100,7 @@ public Webhook(JsonWebhook jsonModel, RestClient client) : base(client) /// This property is if is not , /// or if the has lost access to the guild where the resides. /// - public Channel? Channel { get; } + public IChannel? Channel { get; } /// /// The URL used for executing the webhook.