in CSharp/Library/Microsoft.Bot.Builder/FormFlow/IPrompt.cs [186:323]
public delegate Task<FormPrompt> PromptAsyncDelegate<T>(IDialogContext context, FormPrompt prompt, T state, IField<T> field)
where T : class;
public static partial class Extensions
{
/// <summary>
/// Generate a hero card from a FormPrompt.
/// </summary>
/// <param name="prompt">Prompt definition.</param>
/// <returns>Either an empty list if no buttons or a list with one hero card.</returns>
public static IList<Attachment> GenerateHeroCard(this FormPrompt prompt)
{
var actions = new List<CardAction>();
foreach (var button in prompt.Buttons)
{
actions.Add(new CardAction(ActionTypes.ImBack, button.Description, button.Image, button.Message ?? button.Description));
}
var attachments = new List<Attachment>();
if (actions.Count > 0)
{
var description = prompt.Description;
// Facebook requires a title https://github.com/Microsoft/BotBuilder/issues/1678
attachments.Add(new HeroCard(text: prompt.Prompt, title: description.Title ?? string.Empty, subtitle: description.SubTitle,
buttons: actions,
images: prompt.Description?.Image == null ? null : new List<CardImage>() { new CardImage() { Url = description.Image } })
.ToAttachment());
}
return attachments;
}
/// <summary>
/// Generate a list of hero cards from a prompt definition.
/// </summary>
/// <param name="prompt">Prompt definition.</param>
/// <returns>List of hero cards.</returns>
public static IList<Attachment> GenerateHeroCards(this FormPrompt prompt)
{
var attachments = new List<Attachment>();
var description = prompt.Description;
foreach (var button in prompt.Buttons)
{
string image = button.Image ?? description.Image;
attachments.Add(new HeroCard(
title: button.Title ?? description.Title ?? string.Empty,
subtitle: button.SubTitle ?? description.SubTitle,
text: prompt.Prompt,
images: (image == null ? null : (new List<CardImage>() { new CardImage() { Url = image } })),
buttons: new List<CardAction>() { new CardAction(ActionTypes.ImBack, button.Description, null, button.Message ?? button.Description) })
.ToAttachment());
}
return attachments;
}
/// <summary>
/// Given a prompt definition generate messages to send back.
/// </summary>
/// <param name="prompt">Prompt definition.</param>
/// <param name="preamble">Simple text message with all except last line of prompt to allow markdown in prompts.</param>
/// <param name="promptMessage">Message with prompt definition including cards.</param>
/// <returns>True if preamble should be sent.</returns>
public static bool GenerateMessages(this FormPrompt prompt, IMessageActivity preamble, IMessageActivity promptMessage)
{
var promptCopy = (FormPrompt) prompt.Clone();
bool hasPreamble = false;
if (promptCopy.Buttons?.Count > 0 || promptCopy.Description?.Image != null)
{
// If we are generating cards we do not support markdown so create a separate message
// for all lines except the last one.
var lines = promptCopy.Prompt.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
if (lines.Length > 1)
{
var builder = new StringBuilder();
for (var i = 0; i < lines.Length - 1; ++i)
{
if (i > 0)
{
builder.AppendLine();
}
builder.Append(lines[i]);
}
preamble.Text = builder.ToString();
promptCopy.Prompt = lines.Last();
hasPreamble = true;
}
if (promptCopy.Buttons?.Count > 0)
{
var style = promptCopy.Style;
if (style == ChoiceStyleOptions.Auto)
{
foreach (var button in promptCopy.Buttons)
{
// Images require carousel
if (button.Image != null)
{
style = ChoiceStyleOptions.Carousel;
break;
}
}
}
if (style == ChoiceStyleOptions.Carousel)
{
promptMessage.AttachmentLayout = AttachmentLayoutTypes.Carousel;
promptMessage.Attachments = promptCopy.GenerateHeroCards();
}
else
{
promptMessage.AttachmentLayout = AttachmentLayoutTypes.List;
promptMessage.Attachments = promptCopy.GenerateHeroCard();
}
}
else if (promptCopy.Description?.Image != null)
{
promptMessage.AttachmentLayout = AttachmentLayoutTypes.List;
var card = new HeroCard() { Title = promptCopy.Prompt, Images = new List<CardImage> { new CardImage(promptCopy.Description.Image) } };
promptMessage.Attachments = new List<Attachment> { card.ToAttachment() };
}
}
else
{
promptMessage.Text = promptCopy.Prompt;
}
return hasPreamble;
}
internal static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> enumerable)
{
foreach (var cur in enumerable)
{
collection.Add(cur);
}
}
internal static IList<T> Clone<T>(this IList<T> listToClone) where T : ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}