From 236c2862785f8edca4eca4235107cd89229d2dd8 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 10 Jul 2021 23:31:12 +0200 Subject: [PATCH] Added SmartText and inheritors SmartPlainText and SmartEmbedText which will replace CREmbed in the future --- .../Common/SmartText/SmartEmbedText.cs | 96 +++++++++++++++++++ .../Common/SmartText/SmartPlainText.cs | 23 +++++ src/NadekoBot/Common/SmartText/SmartText.cs | 37 +++++++ .../Common/SmartText/SmartTextEmbedAuthor.cs | 13 +++ .../Common/SmartText/SmartTextEmbedField.cs | 9 ++ .../Common/SmartText/SmartTextEmbedFooter.cs | 12 +++ .../_Extensions/IMessageChannelExtensions.cs | 34 +++++++ 7 files changed, 224 insertions(+) create mode 100644 src/NadekoBot/Common/SmartText/SmartEmbedText.cs create mode 100644 src/NadekoBot/Common/SmartText/SmartPlainText.cs create mode 100644 src/NadekoBot/Common/SmartText/SmartText.cs create mode 100644 src/NadekoBot/Common/SmartText/SmartTextEmbedAuthor.cs create mode 100644 src/NadekoBot/Common/SmartText/SmartTextEmbedField.cs create mode 100644 src/NadekoBot/Common/SmartText/SmartTextEmbedFooter.cs diff --git a/src/NadekoBot/Common/SmartText/SmartEmbedText.cs b/src/NadekoBot/Common/SmartText/SmartEmbedText.cs new file mode 100644 index 000000000..bde21fe8b --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartEmbedText.cs @@ -0,0 +1,96 @@ +using System; +using Discord; +using NadekoBot.Extensions; +using NadekoBot.Services; + +namespace NadekoBot +{ + public sealed class SmartEmbedText : SmartText + { + public string PlainText { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public string Url { get; set; } + public string Thumbnail { get; set; } + public string Image { get; set; } + + public SmartTextEmbedAuthor Author { get; set; } + public SmartTextEmbedFooter Footer { get; set; } + public SmartTextEmbedField[] Fields { get; set; } + + public uint Color { get; set; } = 7458112; + + public bool IsValid => + !string.IsNullOrWhiteSpace(Title) || + !string.IsNullOrWhiteSpace(Description) || + !string.IsNullOrWhiteSpace(Url) || + !string.IsNullOrWhiteSpace(Thumbnail) || + !string.IsNullOrWhiteSpace(Image) || + (Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) || + (Fields != null && Fields.Length > 0); + + public EmbedBuilder GetEmbed(IEmbedBuilderService eb) + { + var embed = new EmbedBuilder() + .WithColor(Color); + + if (!string.IsNullOrWhiteSpace(Title)) + embed.WithTitle(Title); + + if (!string.IsNullOrWhiteSpace(Description)) + embed.WithDescription(Description); + + if (Url != null && Uri.IsWellFormedUriString(Url, UriKind.Absolute)) + embed.WithUrl(Url); + + if (Footer != null) + { + embed.WithFooter(efb => + { + efb.WithText(Footer.Text); + if (Uri.IsWellFormedUriString(Footer.IconUrl, UriKind.Absolute)) + efb.WithIconUrl(Footer.IconUrl); + }); + } + + if (Thumbnail != null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute)) + embed.WithThumbnailUrl(Thumbnail); + + if (Image != null && Uri.IsWellFormedUriString(Image, UriKind.Absolute)) + embed.WithImageUrl(Image); + + if (Author != null && !string.IsNullOrWhiteSpace(Author.Name)) + { + if (!Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute)) + Author.IconUrl = null; + if (!Uri.IsWellFormedUriString(Author.Url, UriKind.Absolute)) + Author.Url = null; + + embed.WithAuthor(Author.Name, Author.IconUrl, Author.Url); + } + + if (Fields != null) + { + foreach (var f in Fields) + { + if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value)) + embed.AddField(f.Name, f.Value, f.Inline); + } + } + + return embed; + } + + public void NormalizeFields() + { + if (Fields != null && Fields.Length > 0) + { + foreach (var f in Fields) + { + f.Name = f.Name.TrimTo(256); + f.Value = f.Value.TrimTo(1024); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Common/SmartText/SmartPlainText.cs b/src/NadekoBot/Common/SmartText/SmartPlainText.cs new file mode 100644 index 000000000..b110874f3 --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartPlainText.cs @@ -0,0 +1,23 @@ +namespace NadekoBot +{ + public sealed class SmartPlainText : SmartText + { + public string Text { get; set; } + + public SmartPlainText(string text) + { + Text = text; + } + + public static implicit operator SmartPlainText(string input) + => new SmartPlainText(input); + + public static implicit operator string(SmartPlainText input) + => input.Text; + + public override string ToString() + { + return Text; + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Common/SmartText/SmartText.cs b/src/NadekoBot/Common/SmartText/SmartText.cs new file mode 100644 index 000000000..70ffe1123 --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartText.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json; + +namespace NadekoBot +{ + // todo 3.3 check if saving embeds in db has IsEmbed field, to prevent rechecking and generating exceptions on every use + public abstract class SmartText + { + public bool IsEmbed => this is SmartEmbedText; + public bool IsPlainText => this is SmartPlainText; + + public static SmartText CreateFrom(string input) + { + if (string.IsNullOrWhiteSpace(input) || !input.Trim().StartsWith("{")) + { + return new SmartPlainText(input); + } + + try + { + var smartEmbedText = JsonConvert.DeserializeObject(input); + + smartEmbedText.NormalizeFields(); + + if (!smartEmbedText.IsValid) + { + return new SmartPlainText(input); + } + + return smartEmbedText; + } + catch + { + return new SmartPlainText(input); + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Common/SmartText/SmartTextEmbedAuthor.cs b/src/NadekoBot/Common/SmartText/SmartTextEmbedAuthor.cs new file mode 100644 index 000000000..c6d663580 --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartTextEmbedAuthor.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace NadekoBot +{ + public class SmartTextEmbedAuthor + { + public string Name { get; set; } + public string IconUrl { get; set; } + [JsonProperty("icon_url")] + private string Icon_Url { set => IconUrl = value; } + public string Url { get; set; } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Common/SmartText/SmartTextEmbedField.cs b/src/NadekoBot/Common/SmartText/SmartTextEmbedField.cs new file mode 100644 index 000000000..7450d90dd --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartTextEmbedField.cs @@ -0,0 +1,9 @@ +namespace NadekoBot +{ + public class SmartTextEmbedField + { + public string Name { get; set; } + public string Value { get; set; } + public bool Inline { get; set; } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Common/SmartText/SmartTextEmbedFooter.cs b/src/NadekoBot/Common/SmartText/SmartTextEmbedFooter.cs new file mode 100644 index 000000000..a93a14868 --- /dev/null +++ b/src/NadekoBot/Common/SmartText/SmartTextEmbedFooter.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace NadekoBot +{ + public class SmartTextEmbedFooter + { + public string Text { get; set; } + public string IconUrl { get; set; } + [JsonProperty("icon_url")] + private string Icon_Url { set => IconUrl = value; } + } +} \ No newline at end of file diff --git a/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs b/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs index e9fc71c97..6d5ac1a54 100644 --- a/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs +++ b/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs @@ -185,5 +185,39 @@ namespace NadekoBot.Extensions public static Task WarningAsync(this ICommandContext ctx) => ctx.Message.AddReactionAsync(new Emoji("⚠️")); + + // todo fix extensions + // public static Task EditAsync(this IUserMessage message, SmartText text) + // { + // switch (text) + // { + // case SmartEmbedText set: return message.ModifyAsync(set.PlainText ?? "", set.GetEmbed()); + // case SmartPlainText spt: return message.EditAsync(spt.Text); + // default: + // throw new ArgumentException(nameof(text)); + // } + // } + // + // public static Task SendAsync(this IUser user, SmartText text) + // { + // switch (text) + // { + // case SmartEmbedText set: return user.SendAsync(set.PlainText ?? "", set.GetEmbed()); + // case SmartPlainText spt: return user.SendAsync(spt.Text); + // default: + // throw new ArgumentException(nameof(text)); + // } + // } + // + // public static Task SendAsync(this ITextChannel channel, SmartText text) + // { + // switch (text) + // { + // case SmartEmbedText set: return channel.SendAsync(set.PlainText ?? "", embed: set.GetEmbed()); + // case SmartPlainText spt: return channel.SendAsync(spt.Text); + // default: + // throw new ArgumentException(nameof(text)); + // } + // } } }