Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Slack.NetStandard.Tests/BlockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ public void Call()
{
Utility.AssertSubType<IMessageBlock, Call>("Blocks_Call.json");
}

[Fact]
public void Container()
{
Utility.AssertSubType<IMessageBlock, Container>("Blocks_Container.json");
}

[Fact]
public void Callout()
{
Utility.AssertSubType<IMessageBlock, Callout>("Blocks_Callout.json");
}

[Fact]
public void RadioButtons()
Expand Down
45 changes: 45 additions & 0 deletions Slack.NetStandard.Tests/Examples/Blocks_Callout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"type": "callout",
"block_id": "container-callout-1",
"background_color": "blue",
"child_blocks": [
{
"type": "rich_text",
"block_id": "container-callout-rt-1",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "This callout is nested inside a container block."
}
]
}
]
},
{
"type": "divider",
"block_id": "container-callout-div-1"
},
{
"type": "section",
"block_id": "container-callout-section-1",
"text": {
"type": "mrkdwn",
"text": "*Tip:* Callouts can hold rich text, sections, dividers, and images."
}
},
{
"type": "image",
"block_id": "container-callout-img-1",
"image_url": "https://images.pexels.com/photos/257532/pexels-photo-257532.jpeg",
"alt_text": "A sample landscape image"
},
{
"type": "contact_card",
"block_id": "container-callout-contact-1",
"contact_user_id": "U0123456789"
}
]
}
5 changes: 5 additions & 0 deletions Slack.NetStandard.Tests/Examples/Blocks_Card.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
"text": "Please enjoy each card equally.",
"verbatim": false
},
"subtext": {
"type": "mrkdwn",
"text": "This is a card footer.",
"verbatim": false
},
"actions": [
{
"type": "button",
Expand Down
37 changes: 37 additions & 0 deletions Slack.NetStandard.Tests/Examples/Blocks_Container.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"type": "container",
"block_id": "bkb_container_standard",
"title": {
"type": "plain_text",
"text": "Standard Width Container"
},
"subtitle": {
"type": "plain_text",
"text": "Best sub title ever"
},
"width": "standard",
"child_blocks": [
{
"type": "rich_text",
"block_id": "rt-simple",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "This is a simple rich text block inside a container."
}
]
}
]
}
],
"icon": {
"type": "image",
"image_url": "https://picsum.photos/36/36",
"alt_text": "Icon"
},
"is_collapsible": false,
"default_collapsed": true
}
3 changes: 2 additions & 1 deletion Slack.NetStandard.Tests/Examples/Blocks_Header.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"text": {
"type": "plain_text",
"text": "Budget Performance"
}
},
"level": 2
}
6 changes: 6 additions & 0 deletions Slack.NetStandard.Tests/Slack.NetStandard.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,12 @@
<None Update="Examples\CellsDef_Message.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Examples\Blocks_Container.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Examples\Blocks_Callout.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
2 changes: 2 additions & 0 deletions Slack.NetStandard/JsonConverters/MessageBlockConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public override IMessageBlock ReadJson(JsonReader reader, Type objectType, IMess
{nameof(Alert).ToLower(), typeof(Alert)},
{nameof(Card).ToLower(), typeof(Card)},
{nameof(Carousel).ToLower(), typeof(Carousel)},
{nameof(Container).ToLower(), typeof(Container)},
{nameof(Callout).ToLower(), typeof(Callout)},
{DataTable.MessageBlockType, typeof(DataTable) },
{DataVisualization.MessageBlockType, typeof(DataVisualization) }
};
Expand Down
48 changes: 48 additions & 0 deletions Slack.NetStandard/Messages/Blocks/Callout.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Slack.NetStandard.Messages.Blocks
{
public class Callout : IMessageBlock
{
public const string MessageBlockType = "callout";
[JsonProperty("type")] public string Type => MessageBlockType;

public Callout() { }

public Callout(CalloutColor backgroundColor, params IMessageBlock[] childBlocks)
{
BackgroundColor = backgroundColor;
ChildBlocks = childBlocks.ToList();
}

[JsonProperty("background_color", NullValueHandling = NullValueHandling.Ignore)]
public CalloutColor? BackgroundColor { get; set; }

[JsonProperty("block_id", NullValueHandling = NullValueHandling.Ignore)]
public string BlockId { get; set; }

[JsonProperty("child_blocks", NullValueHandling = NullValueHandling.Ignore)]
public List<IMessageBlock> ChildBlocks { get; set; } = new List<IMessageBlock>();

public bool ShouldSerializeChildBlocks() => ChildBlocks?.Any() ?? false;

}

[JsonConverter(typeof(StringEnumConverter))]
public enum CalloutColor
{
[EnumMember(Value = "indigo")] Indigo,
[EnumMember(Value = "blue")] Blue,
[EnumMember(Value = "jade")] Jade,
[EnumMember(Value = "pink")] Pink,
[EnumMember(Value = "gray")] Gray,
[EnumMember(Value = "purple")] Purple,
[EnumMember(Value = "orange")] Orange,
[EnumMember(Value = "brown")] Brown,
[EnumMember(Value = "green")] Green
}
}
6 changes: 6 additions & 0 deletions Slack.NetStandard/Messages/Blocks/Card.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ public Card(TextObject title)

[JsonProperty("body", NullValueHandling = NullValueHandling.Ignore)]
public TextObject Body { get; set; }

[JsonProperty("slack_icon", NullValueHandling = NullValueHandling.Ignore)]
public SlackIcon SlackIcon { get; set; }

[JsonProperty("subtext", NullValueHandling = NullValueHandling.Ignore)]
public TextObject Subtext { get; set; }

[JsonProperty("actions", NullValueHandling = NullValueHandling.Ignore)]
public IList<IMessageElement> Actions { get; set; } = new List<IMessageElement>();

Expand Down
59 changes: 59 additions & 0 deletions Slack.NetStandard/Messages/Blocks/Container.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Slack.NetStandard.Messages.Blocks
{
public class Container : IMessageBlock
{
public const string MessageBlockType = "container";
[JsonProperty("type")] public string Type => MessageBlockType;

public Container() { }

public Container(string title, params IMessageBlock[] childBlocks)
{
Title = new PlainText(title);
ChildBlocks = childBlocks.ToList();
}

[JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
public PlainText Title { get; set; }

[JsonProperty("subtitle", NullValueHandling = NullValueHandling.Ignore)]
public TextObject Subtitle { get; set; }

[JsonProperty("width", NullValueHandling = NullValueHandling.Ignore)]
public SlackContainerWidth? Width { get; set; }


[JsonProperty("block_id", NullValueHandling = NullValueHandling.Ignore)]
public string BlockId { get; set; }

[JsonProperty("child_blocks", NullValueHandling = NullValueHandling.Ignore)]
public List<IMessageBlock> ChildBlocks { get; set; } = new List<IMessageBlock>();

public bool ShouldSerializeChildBlocks() => ChildBlocks?.Any() ?? false;

[JsonProperty("icon", NullValueHandling = NullValueHandling.Ignore)]
public Image Icon { get; set; }

[JsonProperty("is_collapsible", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsCollapsible { get; set; }

[JsonProperty("default_collapsed", NullValueHandling = NullValueHandling.Ignore)]
public bool? DefaultCollapsed { get; set; }

}

[JsonConverter(typeof(StringEnumConverter))]
public enum SlackContainerWidth
{
[EnumMember(Value = "narrow")] Narrow,
[EnumMember(Value = "standard")] Standard,
[EnumMember(Value = "wide")] Wide,
[EnumMember(Value = "full")] Full
}
}
3 changes: 3 additions & 0 deletions Slack.NetStandard/Messages/Blocks/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@ public Header(PlainText text)

[JsonProperty("block_id", NullValueHandling = NullValueHandling.Ignore)]
public string BlockId { get; set; }

[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
public int? Level { get; set; }
}
}
76 changes: 76 additions & 0 deletions Slack.NetStandard/Messages/Blocks/SlackIcon.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Slack.NetStandard.Messages.Blocks
{
public class SlackIcon
{
public const string SlackIconType = "slack_icon";

[JsonProperty("type")]
public string Type => SlackIconType;

[JsonProperty("icon_name")]
public SlackIconName IconName { get; set; }
}

[JsonConverter(typeof(StringEnumConverter))]
public enum SlackIconName
{
[EnumMember(Value = "archive")] Archive,
[EnumMember(Value = "book")] Book,
[EnumMember(Value = "bookmark")] Bookmark,
[EnumMember(Value = "bot")] Bot,
[EnumMember(Value = "bug")] Bug,
[EnumMember(Value = "calendar")] Calendar,
[EnumMember(Value = "call")] Call,
[EnumMember(Value = "caret-left")] CaretLeft,
[EnumMember(Value = "caret-right")] CaretRight,
[EnumMember(Value = "check")] Check,
[EnumMember(Value = "clipboard")] Clipboard,
[EnumMember(Value = "code")] Code,
[EnumMember(Value = "comment")] Comment,
[EnumMember(Value = "compass")] Compass,
[EnumMember(Value = "copy")] Copy,
[EnumMember(Value = "cube")] Cube,
[EnumMember(Value = "download")] Download,
[EnumMember(Value = "edit")] Edit,
[EnumMember(Value = "email")] Email,
[EnumMember(Value = "eye-closed")] EyeClosed,
[EnumMember(Value = "eye-open")] EyeOpen,
[EnumMember(Value = "file")] File,
[EnumMember(Value = "flag")] Flag,
[EnumMember(Value = "folder")] Folder,
[EnumMember(Value = "gear")] Gear,
[EnumMember(Value = "globe")] Globe,
[EnumMember(Value = "heart")] Heart,
[EnumMember(Value = "help")] Help,
[EnumMember(Value = "image")] Image,
[EnumMember(Value = "info")] Info,
[EnumMember(Value = "key")] Key,
[EnumMember(Value = "lightbulb")] Lightbulb,
[EnumMember(Value = "link")] Link,
[EnumMember(Value = "map")] Map,
[EnumMember(Value = "mobile")] Mobile,
[EnumMember(Value = "new-window")] NewWindow,
[EnumMember(Value = "pin")] Pin,
[EnumMember(Value = "plus")] Plus,
[EnumMember(Value = "refine")] Refine,
[EnumMember(Value = "refresh")] Refresh,
[EnumMember(Value = "rocket")] Rocket,
[EnumMember(Value = "save")] Save,
[EnumMember(Value = "screen")] Screen,
[EnumMember(Value = "share")] Share,
[EnumMember(Value = "sparkle")] Sparkle,
[EnumMember(Value = "star")] Star,
[EnumMember(Value = "star-filled")] StarFilled,
[EnumMember(Value = "tag")] Tag,
[EnumMember(Value = "thumbs-down")] ThumbsDown,
[EnumMember(Value = "thumbs-up")] ThumbsUp,
[EnumMember(Value = "trash")] Trash,
[EnumMember(Value = "upload")] Upload,
[EnumMember(Value = "user")] User,
[EnumMember(Value = "warning")] Warning
}
}