| @@ -19,8 +19,12 @@ namespace Discord.API | |||
| public Optional<EmbedAuthor> Author { get; set; } | |||
| [JsonProperty("footer")] | |||
| public Optional<EmbedFooter> Footer { get; set; } | |||
| [JsonProperty("video")] | |||
| public Optional<EmbedVideo> Video { get; set; } | |||
| [JsonProperty("thumbnail")] | |||
| public Optional<EmbedThumbnail> Thumbnail { get; set; } | |||
| [JsonProperty("image")] | |||
| public Optional<EmbedImage> Image { get; set; } | |||
| [JsonProperty("provider")] | |||
| public Optional<EmbedProvider> Provider { get; set; } | |||
| [JsonProperty("fields")] | |||
| @@ -0,0 +1,17 @@ | |||
| #pragma warning disable CS1591 | |||
| using Newtonsoft.Json; | |||
| namespace Discord.API | |||
| { | |||
| public class EmbedImage | |||
| { | |||
| [JsonProperty("url")] | |||
| public string Url { get; set; } | |||
| [JsonProperty("proxy_url")] | |||
| public string ProxyUrl { get; set; } | |||
| [JsonProperty("height")] | |||
| public Optional<int> Height { get; set; } | |||
| [JsonProperty("width")] | |||
| public Optional<int> Width { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| #pragma warning disable CS1591 | |||
| using Newtonsoft.Json; | |||
| namespace Discord.API | |||
| { | |||
| public class EmbedVideo | |||
| { | |||
| [JsonProperty("url")] | |||
| public string Url { get; set; } | |||
| [JsonProperty("height")] | |||
| public Optional<int> Height { get; set; } | |||
| [JsonProperty("width")] | |||
| public Optional<int> Width { get; set; } | |||
| } | |||
| } | |||
| @@ -4,6 +4,8 @@ using Embed = Discord.API.Embed; | |||
| using Field = Discord.API.EmbedField; | |||
| using Author = Discord.API.EmbedAuthor; | |||
| using Footer = Discord.API.EmbedFooter; | |||
| using Thumbnail = Discord.API.EmbedThumbnail; | |||
| using Image = Discord.API.EmbedImage; | |||
| namespace Discord | |||
| { | |||
| @@ -14,8 +16,7 @@ namespace Discord | |||
| public EmbedBuilder() | |||
| { | |||
| _model = new Embed(); | |||
| _model.Type = "rich"; | |||
| _model = new Embed {Type = "rich"}; | |||
| _fields = new List<Field>(); | |||
| } | |||
| @@ -25,6 +26,8 @@ namespace Discord | |||
| public Color? Color { get { return _model.Color.HasValue ? new Color(_model.Color.Value) : (Color?)null; } set { _model.Color = value?.RawValue; } } | |||
| public EmbedAuthorBuilder Author { get; set; } | |||
| public EmbedFooterBuilder Footer { get; set; } | |||
| public EmbedThumbnailBuilder Thumbnail { get; set; } | |||
| public EmbedImageBuilder Image { get; set; } | |||
| public EmbedBuilder WithTitle(string title) | |||
| { | |||
| @@ -71,6 +74,30 @@ namespace Discord | |||
| Footer = footer; | |||
| return this; | |||
| } | |||
| public EmbedBuilder WithThumbnail(EmbedThumbnailBuilder thumbnail) | |||
| { | |||
| Thumbnail = thumbnail; | |||
| return this; | |||
| } | |||
| public EmbedBuilder WithThumbnail(Action<EmbedThumbnailBuilder> action) | |||
| { | |||
| var thumbnail = new EmbedThumbnailBuilder(); | |||
| action(thumbnail); | |||
| Thumbnail = thumbnail; | |||
| return this; | |||
| } | |||
| public EmbedBuilder WithImage(EmbedImageBuilder image) | |||
| { | |||
| Image = image; | |||
| return this; | |||
| } | |||
| public EmbedBuilder WithImage(Action<EmbedImageBuilder> action) | |||
| { | |||
| var image = new EmbedImageBuilder(); | |||
| action(image); | |||
| Image = image; | |||
| return this; | |||
| } | |||
| public EmbedBuilder AddField(Action<EmbedFieldBuilder> action) | |||
| { | |||
| @@ -84,6 +111,8 @@ namespace Discord | |||
| { | |||
| _model.Author = Author?.ToModel(); | |||
| _model.Footer = Footer?.ToModel(); | |||
| _model.Thumbnail = Thumbnail?.ToModel(); | |||
| _model.Image = Image?.ToModel(); | |||
| _model.Fields = _fields.ToArray(); | |||
| return _model; | |||
| } | |||
| @@ -178,4 +207,68 @@ namespace Discord | |||
| internal Footer ToModel() => _model; | |||
| } | |||
| public class EmbedThumbnailBuilder | |||
| { | |||
| private Thumbnail _model; | |||
| public string Url { get { return _model.Url; } set { _model.Url = value; } } | |||
| public Optional<int> Height { get { return _model.Height; } set { _model.Height = value; } } | |||
| public Optional<int> Width { get { return _model.Width; } set { _model.Width = value; } } | |||
| public EmbedThumbnailBuilder() | |||
| { | |||
| _model = new Thumbnail(); | |||
| } | |||
| public EmbedThumbnailBuilder WithUrl(string url) | |||
| { | |||
| Url = url; | |||
| return this; | |||
| } | |||
| public EmbedThumbnailBuilder WithHeight(int height) | |||
| { | |||
| Height = height; | |||
| return this; | |||
| } | |||
| public EmbedThumbnailBuilder WithWidth(int width) | |||
| { | |||
| Width = width; | |||
| return this; | |||
| } | |||
| internal Thumbnail ToModel() => _model; | |||
| } | |||
| public class EmbedImageBuilder | |||
| { | |||
| private Image _model; | |||
| public string Url { get { return _model.Url; } set { _model.Url = value; } } | |||
| public Optional<int> Height { get { return _model.Height; } set { _model.Height = value; } } | |||
| public Optional<int> Width { get { return _model.Width; } set { _model.Width = value; } } | |||
| public EmbedImageBuilder() | |||
| { | |||
| _model = new Image(); | |||
| } | |||
| public EmbedImageBuilder WithUrl(string url) | |||
| { | |||
| Url = url; | |||
| return this; | |||
| } | |||
| public EmbedImageBuilder WithHeight(int height) | |||
| { | |||
| Height = height; | |||
| return this; | |||
| } | |||
| public EmbedImageBuilder WithWidth(int width) | |||
| { | |||
| Width = width; | |||
| return this; | |||
| } | |||
| internal Image ToModel() => _model; | |||
| } | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| using System.Diagnostics; | |||
| using Model = Discord.API.EmbedImage; | |||
| namespace Discord | |||
| { | |||
| [DebuggerDisplay("{DebuggerDisplay,nq}")] | |||
| public struct EmbedImage | |||
| { | |||
| public string Url { get; } | |||
| public string ProxyUrl { get; } | |||
| public int? Height { get; } | |||
| public int? Width { get; } | |||
| private EmbedImage(string url, string proxyUrl, int? height, int? width) | |||
| { | |||
| Url = url; | |||
| ProxyUrl = proxyUrl; | |||
| Height = height; | |||
| Width = width; | |||
| } | |||
| internal static EmbedImage Create(Model model) | |||
| { | |||
| return new EmbedImage(model.Url, model.ProxyUrl, | |||
| model.Height.IsSpecified ? model.Height.Value : (int?)null, | |||
| model.Width.IsSpecified ? model.Width.Value : (int?)null); | |||
| } | |||
| private string DebuggerDisplay => $"{ToString()} ({Url})"; | |||
| public override string ToString() => Width != null && Height != null ? $"{Width}x{Height}" : "0x0"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| using System.Diagnostics; | |||
| using Model = Discord.API.EmbedVideo; | |||
| namespace Discord | |||
| { | |||
| [DebuggerDisplay("{DebuggerDisplay,nq}")] | |||
| public struct EmbedVideo | |||
| { | |||
| public string Url { get; } | |||
| public int? Height { get; } | |||
| public int? Width { get; } | |||
| private EmbedVideo(string url, int? height, int? width) | |||
| { | |||
| Url = url; | |||
| Height = height; | |||
| Width = width; | |||
| } | |||
| internal static EmbedVideo Create(Model model) | |||
| { | |||
| return new EmbedVideo(model.Url, | |||
| model.Height.IsSpecified ? model.Height.Value : (int?)null, | |||
| model.Width.IsSpecified ? model.Width.Value : (int?)null); | |||
| } | |||
| private string DebuggerDisplay => $"{ToString()} ({Url})"; | |||
| public override string ToString() => Width != null && Height != null ? $"{Width}x{Height}" : "0x0"; | |||
| } | |||
| } | |||
| @@ -9,6 +9,8 @@ namespace Discord | |||
| string Title { get; } | |||
| string Description { get; } | |||
| Color? Color { get; } | |||
| EmbedImage? Image { get; } | |||
| EmbedVideo? Video { get; } | |||
| EmbedAuthor? Author { get; } | |||
| EmbedFooter? Footer { get; } | |||
| EmbedProvider? Provider { get; } | |||
| @@ -14,6 +14,8 @@ namespace Discord | |||
| public string Title { get; } | |||
| public string Type { get; } | |||
| public Color? Color { get; } | |||
| public EmbedImage? Image { get; } | |||
| public EmbedVideo? Video { get; } | |||
| public EmbedAuthor? Author { get; } | |||
| public EmbedFooter? Footer { get; } | |||
| public EmbedProvider? Provider { get; } | |||
| @@ -25,6 +27,8 @@ namespace Discord | |||
| string description, | |||
| string url, | |||
| Color? color, | |||
| EmbedImage? image, | |||
| EmbedVideo? video, | |||
| EmbedAuthor? author, | |||
| EmbedFooter? footer, | |||
| EmbedProvider? provider, | |||
| @@ -36,6 +40,8 @@ namespace Discord | |||
| Description = description; | |||
| Url = url; | |||
| Color = color; | |||
| Image = image; | |||
| Video = video; | |||
| Author = author; | |||
| Footer = footer; | |||
| Provider = provider; | |||
| @@ -46,6 +52,8 @@ namespace Discord | |||
| { | |||
| return new Embed(model.Type, model.Title, model.Description, model.Url, | |||
| model.Color.HasValue ? new Color(model.Color.Value) : (Color?)null, | |||
| model.Image.IsSpecified ? EmbedImage.Create(model.Image.Value) : (EmbedImage?)null, | |||
| model.Video.IsSpecified ? EmbedVideo.Create(model.Video.Value) : (EmbedVideo?)null, | |||
| model.Author.IsSpecified ? EmbedAuthor.Create(model.Author.Value) : (EmbedAuthor?)null, | |||
| model.Footer.IsSpecified ? EmbedFooter.Create(model.Footer.Value) : (EmbedFooter?)null, | |||
| model.Provider.IsSpecified ? EmbedProvider.Create(model.Provider.Value) : (EmbedProvider?)null, | |||