| @@ -11,36 +11,23 @@ namespace Discord | |||
| /// <summary> | |||
| /// A struct representing a forum channel tag. | |||
| /// </summary> | |||
| public struct ForumTag : ISnowflakeEntity | |||
| public struct ForumTag : ISnowflakeEntity, IForumTag | |||
| { | |||
| /// <summary> | |||
| /// Gets the Id of the tag. | |||
| /// </summary> | |||
| public ulong Id { get; } | |||
| /// <summary> | |||
| /// Gets the name of the tag. | |||
| /// </summary> | |||
| /// <inheritdoc/> | |||
| public string Name { get; } | |||
| /// <summary> | |||
| /// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If the emoji is <see cref="Emote"/> only the <see cref="Emote.Id"/> will be populated. | |||
| /// Use <see cref="IGuild.GetEmoteAsync"/> to get the emoji. | |||
| /// </remarks> | |||
| /// <inheritdoc/> | |||
| public IEmote? Emoji { get; } | |||
| /// <summary> | |||
| /// Gets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||
| /// </summary> | |||
| /// <inheritdoc/> | |||
| public bool IsModerated { get; } | |||
| /// <summary> | |||
| /// Gets when the tag was created. | |||
| /// </summary> | |||
| /// <inheritdoc/> | |||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | |||
| internal ForumTag(ulong id, string name, ulong? emojiId = null, string? emojiName = null, bool moderated = false) | |||
| @@ -56,5 +43,25 @@ namespace Discord | |||
| Name = name; | |||
| IsModerated = moderated; | |||
| } | |||
| public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); | |||
| public override bool Equals(object? obj) | |||
| => obj is ForumTag tag && Equals(tag); | |||
| /// <summary> | |||
| /// Gets whether supplied tag is equals to the current one. | |||
| /// </summary> | |||
| public bool Equals(ForumTag tag) | |||
| => Id == tag.Id && | |||
| Name == tag.Name && | |||
| (Emoji is Emoji emoji && tag.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || | |||
| Emoji is Emote emote && tag.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && | |||
| IsModerated == tag.IsModerated; | |||
| public static bool operator ==(ForumTag? left, ForumTag? right) | |||
| => left?.Equals(right) ?? right is null; | |||
| public static bool operator !=(ForumTag? left, ForumTag? right) => !(left == right); | |||
| } | |||
| } | |||
| @@ -8,12 +8,25 @@ public class ForumTagBuilder | |||
| private string? _name; | |||
| private IEmote? _emoji; | |||
| private bool _moderated; | |||
| private ulong? _id; | |||
| /// <summary> | |||
| /// Returns the maximum length of name allowed by Discord. | |||
| /// </summary> | |||
| public const int MaxNameLength = 20; | |||
| /// <summary> | |||
| /// Gets or sets the snowflake Id of the tag. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If set this will update existing tag or will create a new one otherwise. | |||
| /// </remarks> | |||
| public ulong? Id | |||
| { | |||
| get { return _id; } | |||
| set { _id = value; } | |||
| } | |||
| /// <summary> | |||
| /// Gets or sets the name of the tag. | |||
| /// </summary> | |||
| @@ -50,7 +63,7 @@ public class ForumTagBuilder | |||
| /// <summary> | |||
| /// Initializes a new <see cref="ForumTagBuilder"/> class. | |||
| /// </summary> | |||
| /// </summary> | |||
| public ForumTagBuilder() | |||
| { | |||
| @@ -59,31 +72,48 @@ public class ForumTagBuilder | |||
| /// <summary> | |||
| /// Initializes a new <see cref="ForumTagBuilder"/> class with values | |||
| /// </summary> | |||
| public ForumTagBuilder(string name) | |||
| /// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||
| /// <param name="name"> Name of the tag.</param> | |||
| /// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission. </param> | |||
| public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false) | |||
| { | |||
| Name = name; | |||
| IsModerated = false; | |||
| IsModerated = isModerated; | |||
| Id = id; | |||
| } | |||
| /// <summary> | |||
| /// Initializes a new <see cref="ForumTagBuilder"/> class with values | |||
| /// </summary> | |||
| public ForumTagBuilder(string name, IEmote? emoji = null, bool moderated = false) | |||
| /// <param name="name"> Name of the tag.</param> | |||
| /// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||
| /// <param name="emoji"> Display emoji of the tag.</param> | |||
| /// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission. </param> | |||
| public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, IEmote? emoji = null) | |||
| { | |||
| Name = name; | |||
| Emoji = emoji; | |||
| IsModerated = moderated; | |||
| IsModerated = isModerated; | |||
| Id = id; | |||
| } | |||
| /// <summary> | |||
| /// Initializes a new <see cref="ForumTagBuilder"/> class with values | |||
| /// </summary> | |||
| public ForumTagBuilder(string name, ulong? emoteId = null, bool moderated = false) | |||
| /// /// <param name="name"> Name of the tag.</param> | |||
| /// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||
| /// <param name="emoteId"> The id of custom Display emoji of the tag.</param> | |||
| /// <param name="isModerated"> Sets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission </param> | |||
| public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, ulong? emoteId = null) | |||
| { | |||
| Name = name; | |||
| if(emoteId is not null) | |||
| Emoji = new Emote(emoteId.Value, null, false); | |||
| IsModerated = moderated; | |||
| IsModerated = isModerated; | |||
| Id = id; | |||
| } | |||
| /// <summary> | |||
| @@ -108,6 +138,17 @@ public class ForumTagBuilder | |||
| return this; | |||
| } | |||
| /// <summary> | |||
| /// Sets the id of the tag. | |||
| /// </summary> | |||
| /// <param name="id"> If set existing tag will be updated or a new one will be created otherwise.</param> | |||
| /// <exception cref="ArgumentException">Name length must be less than or equal to <see cref="MaxNameLength"/>.</exception> | |||
| public ForumTagBuilder WithId(ulong? id) | |||
| { | |||
| Id = id; | |||
| return this; | |||
| } | |||
| /// <summary> | |||
| /// Sets the emoji of the tag. | |||
| /// </summary> | |||
| @@ -118,11 +159,33 @@ public class ForumTagBuilder | |||
| } | |||
| /// <summary> | |||
| /// Sets the IsModerated of the tag. | |||
| /// Sets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||
| /// </summary> | |||
| public ForumTagBuilder WithModerated(bool moderated) | |||
| { | |||
| IsModerated = moderated; | |||
| return this; | |||
| } | |||
| public override int GetHashCode() => base.GetHashCode(); | |||
| public override bool Equals(object? obj) | |||
| => obj is ForumTagBuilder builder && Equals(builder); | |||
| /// <summary> | |||
| /// Gets whether supplied tag builder is equals to the current one. | |||
| /// </summary> | |||
| public bool Equals(ForumTagBuilder? builder) | |||
| => builder is not null && | |||
| Id == builder.Id && | |||
| Name == builder.Name && | |||
| (Emoji is Emoji emoji && builder.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || | |||
| Emoji is Emote emote && builder.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && | |||
| IsModerated == builder.IsModerated; | |||
| public static bool operator ==(ForumTagBuilder? left, ForumTagBuilder? right) | |||
| => left?.Equals(right) ?? right is null ; | |||
| public static bool operator !=(ForumTagBuilder? left, ForumTagBuilder? right) => !(left == right); | |||
| } | |||
| @@ -3,9 +3,9 @@ namespace Discord; | |||
| public static class ForumTagBuilderExtensions | |||
| { | |||
| public static ForumTagBuilder ToForumTagBuilder(this ForumTag tag) | |||
| => new ForumTagBuilder(tag.Name, tag.Emoji, tag.IsModerated); | |||
| => new ForumTagBuilder(tag.Name, tag.Id, tag.IsModerated, tag.Emoji); | |||
| public static ForumTagBuilder ToForumTagBuilder(this ForumTagProperties tag) | |||
| => new ForumTagBuilder(tag.Name, tag.Emoji, tag.IsModerated); | |||
| => new ForumTagBuilder(tag.Name, tag.Id, tag.IsModerated, tag.Emoji); | |||
| } | |||
| @@ -2,22 +2,20 @@ namespace Discord; | |||
| #nullable enable | |||
| public class ForumTagProperties | |||
| public class ForumTagProperties : IForumTag | |||
| { | |||
| /// <summary> | |||
| /// Gets the name of the tag. | |||
| /// Gets the Id of the tag. | |||
| /// </summary> | |||
| public ulong Id { get; } | |||
| /// <inheritdoc/> | |||
| public string Name { get; } | |||
| /// <summary> | |||
| /// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||
| /// </summary> | |||
| /// <inheritdoc/> | |||
| public IEmote? Emoji { get; } | |||
| /// <summary> | |||
| /// Gets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||
| /// </summary> | |||
| /// <inheritdoc/> | |||
| public bool IsModerated { get; } | |||
| internal ForumTagProperties(string name, IEmote? emoji = null, bool isMmoderated = false) | |||
| @@ -26,4 +24,25 @@ public class ForumTagProperties | |||
| Emoji = emoji; | |||
| IsModerated = isMmoderated; | |||
| } | |||
| public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); | |||
| public override bool Equals(object? obj) | |||
| => obj is ForumTagProperties tag && Equals(tag); | |||
| /// <summary> | |||
| /// Gets whether supplied tag is equals to the current one. | |||
| /// </summary> | |||
| public bool Equals(ForumTagProperties? tag) | |||
| => tag is not null && | |||
| Id == tag.Id && | |||
| Name == tag.Name && | |||
| (Emoji is Emoji emoji && tag.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || | |||
| Emoji is Emote emote && tag.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && | |||
| IsModerated == tag.IsModerated; | |||
| public static bool operator ==(ForumTagProperties? left, ForumTagProperties? right) | |||
| => left?.Equals(right) ?? right is null; | |||
| public static bool operator !=(ForumTagProperties? left, ForumTagProperties? right) => !(left == right); | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| namespace Discord; | |||
| #nullable enable | |||
| /// <summary> | |||
| /// Represents a Discord forum tag | |||
| /// </summary> | |||
| public interface IForumTag | |||
| { | |||
| /// <summary> | |||
| /// Gets the name of the tag. | |||
| /// </summary> | |||
| string Name { get; } | |||
| /// <summary> | |||
| /// Gets the emoji of the tag or <see langword="null"/> if none is set. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If the emoji is <see cref="Emote"/> only the <see cref="Emote.Id"/> will be populated. | |||
| /// Use <see cref="IGuild.GetEmoteAsync"/> to get the emoji. | |||
| /// </remarks> | |||
| IEmote? Emoji { get; } | |||
| /// <summary> | |||
| /// Gets whether this tag can only be added to or removed from threads by a member | |||
| /// with the <see cref="GuildPermissions.ManageThreads"/> permission | |||
| /// </summary> | |||
| bool IsModerated { get; } | |||
| } | |||
| @@ -5,6 +5,8 @@ namespace Discord.API | |||
| [JsonObject(MemberSerialization = MemberSerialization.OptIn)] | |||
| internal class ForumTagParams | |||
| { | |||
| [JsonProperty("id")] | |||
| public Optional<ulong> Id { get; set; } | |||
| [JsonProperty("name")] | |||
| public string Name { get; set; } | |||