Example #1
0
        private async void OnRenderAdaptiveCard(object sender, RoutedEventArgs e)
        {
            HttpClient client = new HttpClient();

            json = await client.GetStringAsync(new Uri("https://adaptivecard.azurewebsites.net/api/AppConsultAdaptiveCards?code=AzSEpdNE/P0c9OFIBjro2vSKwGIlLdBWdc53/jmR7Y9PX2l1Ks0/nQ=="));

            AdaptiveCardParseResult card = AdaptiveCard.FromJsonString(json);

            AdaptiveCardRenderer renderer = new AdaptiveCardRenderer();
            var renderResult = renderer.RenderAdaptiveCard(card.AdaptiveCard);

            renderResult.Action += RenderResult_OnAction;

            if (renderResult != null)
            {
                MainPanel.Children.Add(renderResult.FrameworkElement);
            }
        }
Example #2
0
        private async static Task RenderAdaptiveCard(Attachment attachment)
        {
            // This is entirely optional, just shows how to render an adaptive card which in a console app isn't really very practical!

            try
            {
                AdaptiveCardParseResult result = AdaptiveCard.FromJson(attachment.Content.ToString());

                var adaptiveCard = AdaptiveCard.FromJson(attachment.Content.ToString());
                if (adaptiveCard != null)
                {
                    // Create a host config with no interactivity
                    // (buttons in images would be deceiving)
                    AdaptiveHostConfig hostConfig = new AdaptiveHostConfig()
                    {
                        SupportsInteractivity = false
                    };

                    // Create a renderer
                    AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(hostConfig);

                    // Render the card to png
                    RenderedAdaptiveCardImage renderedCard = await renderer.RenderCardToImageAsync(adaptiveCard.Card, createStaThread : true, cancellationToken : default(CancellationToken));

                    string fileName = $"{Guid.NewGuid()}.png";
                    using (var fileStream = File.Create(fileName))
                    {
                        renderedCard.ImageStream.Seek(0, SeekOrigin.Begin);
                        renderedCard.ImageStream.CopyTo(fileStream);
                    }

                    Console.WriteLine($"Adaptive Card rendered to {fileName} for debug purposes.");
                    Process.Start(fileName);
                }

                Console.WriteLine($"Adaptive Card Speak Property: {adaptiveCard.Card.Speak}");
            }
            catch (Exception)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Adaptive card not parsed");
                Console.ForegroundColor = ConsoleColor.Gray;
            }
        }
Example #3
0
        protected async override Task OnTeamsMessagingExtensionCardButtonClickedAsync(ITurnContext <IInvokeActivity> turnContext, JObject cardData, CancellationToken cancellationToken)
        {
            //var reply = MessageFactory.Text("OnTeamsMessagingExtensionCardButtonClickedAsync Value: " + JsonConvert.SerializeObject(turnContext.Activity.Value));
            var    reply = Activity.CreateMessageActivity();
            string card  = "{\r\n    \"type\": \"AdaptiveCard\",\r\n    \"version\": \"1.0\",\r\n    \"body\": [\r\n        {\r\n            \"type\": \"Image\",\r\n            \"altText\": \"\",\r\n            \"url\": \"https://1f0bd229.ngrok.io/images/Firstresponsecolor.png\",\r\n            \"width\": \"\"\r\n        },\r\n        {\r\n            \"type\": \"ColumnSet\",\r\n            \"columns\": [\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref1.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref2.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"1\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref3.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref4.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref5.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                }\r\n            ]\r\n        }\r\n    ],\r\n    \"$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\"\r\n}";

            AdaptiveCardParseResult result = AdaptiveCard.FromJson(card);
            Attachment attachment          = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = result.Card
            };

            reply.Attachments.Add(attachment);
            await turnContext.SendActivityAsync(reply, cancellationToken);


            //return base.OnTeamsMessagingExtensionCardButtonClickedAsync(turnContext, cardData, cancellationToken);
        }
        private Attachment GetAdaptiveCardAttachment(string fileName, object cardData)
        {
            var templateJson = File.ReadAllText("./Cards/" + fileName);
            AdaptiveCardTemplate template = new AdaptiveCardTemplate(templateJson);

            string cardJson = template.Expand(cardData);
            AdaptiveCardParseResult result = AdaptiveCard.FromJson(cardJson);

            // Get card from result
            AdaptiveCard card = result.Card;

            var adaptiveCardAttachment = new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = card,
            };

            return(adaptiveCardAttachment);
        }
        private void RenderCard()
        {
            cardError.Children.Clear();
            cardGrid.Children.Clear();

            try
            {
                AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(textBox.Text);

                AdaptiveCard card = parseResult.Card;

                RenderedAdaptiveCard renderedCard = Renderer.RenderCard(card);
                // TODO: should we have an option to render fallback card instead of exception?

                // Wire up click handler
                renderedCard.OnAction += OnAction;

                renderedCard.OnMediaClicked += OnMediaClick;

                cardGrid.Children.Add(renderedCard.FrameworkElement);

                // Report any warnings
                var allWarnings = parseResult.Warnings.Union(renderedCard.Warnings);
                foreach (var warning in allWarnings)
                {
                    ShowWarning(warning.Message);
                }
            }
            catch (AdaptiveRenderException ex)
            {
                var fallbackCard = new TextBlock
                {
                    Text = ex.CardFallbackText ?? "Sorry, we couldn't render the card"
                };

                cardGrid.Children.Add(fallbackCard);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }
Example #6
0
        public AdaptiveCard CreateCard(TModel startingData, ITurnContext context, CancellationToken cancellationToken = default)
        {
            var contextJSON = JsonConvert.SerializeObject(startingData);
            //Transform our template with the data model specified
            var transformedJSON = Transformer.Transform(JSON, contextJSON);
            //And then create the card from it
            AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(transformedJSON);

            //Print any warnings
            //TODO: This should tap into app insights stream somewhere
            if (parseResult.Warnings.Any())
            {
                foreach (var warning in parseResult.Warnings)
                {
                    Console.WriteLine($"[WARN] {warning.Code} - {warning.Message}");
                }
            }

            return(parseResult.Card);
        }
Example #7
0
        public async static Task <MessagingExtensionActionResponse> ShowResponseCard(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken, string Data)
        {
            string card = "{\r\n    \"type\": \"AdaptiveCard\",\r\n    \"version\": \"1.0\",\r\n    \"body\": [\r\n        {\r\n            \"type\": \"Image\",\r\n            \"altText\": \"\",\r\n            \"url\": \"https://1f0bd229.ngrok.io/images/Firstresponsecolor.png\",\r\n            \"width\": \"\"\r\n        },\r\n        {\r\n            \"type\": \"ColumnSet\",\r\n            \"columns\": [\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref1.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref2.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"1\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref3.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref4.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                },\r\n                {\r\n                    \"type\": \"Column\",\r\n                    \"items\": [\r\n                        {\r\n                            \"type\": \"Image\",\r\n                            \"altText\": \"\",\r\n                            \"url\": \"https://1f0bd229.ngrok.io/images/ref5.png\"\r\n                        },\r\n                        {\r\n                            \"type\": \"TextBlock\",\r\n                            \"text\": \"1\"\r\n                        }\r\n                    ],\r\n                    \"width\": \"stretch\"\r\n                }\r\n            ]\r\n        }\r\n    ],\r\n    \"$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\"\r\n}";

            AdaptiveCardParseResult result = AdaptiveCard.FromJson(card);
            var attachment = new MessagingExtensionAttachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = result.Card,
            };

            return(await Task.FromResult(new MessagingExtensionActionResponse
            {
                ComposeExtension = new MessagingExtensionResult
                {
                    Type = "result",
                    AttachmentLayout = "list",
                    Attachments = new List <MessagingExtensionAttachment> {
                        attachment
                    }
                }
            }));
        }
        private async Task <Stream> ConvertAsync(Attachment attachment, CancellationToken cancellationToken)
        {
            if (attachment.ContentType == AdaptiveCard.ContentType)
            {
                // https://docs.microsoft.com/en-us/adaptive-cards/sdk/rendering-cards/net-image/render-a-card
                AdaptiveCard card = null;
                if (attachment.Content is AdaptiveCard adaptiveCard)
                {
                    card = adaptiveCard;
                }
                else if (attachment.Content is JToken jtoken)
                {
                    AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(jtoken.ToString());
                    card = parseResult.Card;
                }
                else
                {
                    throw new NotImplementedException($"{attachment.Content.GetType().Name} is not supported yet!");
                }

                // TODO don't know if it is thread safe or not
                var adaptiveRenderer = new AdaptiveCardRenderer(_adaptiveHostConfig);

                // Set any XAML resource Dictionary if you have one
                //renderer.ResourcesPath = <path-to-your-resourcedictionary.xaml>;

                // Render the card to png
                // Set createStaThread to true if running from a server
                var renderedCard = await adaptiveRenderer.RenderCardToImageAsync(card, createStaThread : true, cancellationToken : cancellationToken);

                return(renderedCard.ImageStream);
            }
            else
            {
                throw new NotSupportedException($"{attachment.ContentType} is not supported yet!");
            }
        }
Example #9
0
        private static async Task RenderCard(string file, AdaptiveCardRenderer renderer, string outPath)
        {
            try
            {
                var watch = new Stopwatch();
                watch.Start();

                AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(File.ReadAllText(file, Encoding.UTF8));
                AdaptiveCard            card        = parseResult.Card;

                // Timeout after 30 seconds
                var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

                // Render the card to an image
                RenderedAdaptiveCardImage renderedCard = await renderer.RenderCardToImageAsync(card, true, 400, cts.Token);

                // Report any warnings
                foreach (var warning in parseResult.Warnings.Union(renderedCard.Warnings))
                {
                    Console.WriteLine($"[{Path.GetFileName(file)}] WARNING: {warning.Message}");
                }

                // Write to a png file with the same name as the json file
                var outputFile = Path.Combine(outPath,
                                              Path.ChangeExtension(Path.GetFileName(file), ".png"));

                using (var fileStream = new FileStream(outputFile, FileMode.Create))
                {
                    renderedCard.ImageStream.CopyTo(fileStream);
                    Console.WriteLine($"[{watch.ElapsedMilliseconds}ms T{Thread.CurrentThread.ManagedThreadId}]\t{Path.GetFileName(file)} => {Path.GetFileName(outputFile)}");
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"[FAILED]\t{Path.GetFileName(file)} => {ex.Message}");
            }
        }
Example #10
0
        private static async Task GetMainOptions(IMessageActivity reply)
        {
            HttpClient          client = new HttpClient();
            HttpResponseMessage response;
            AdaptiveCard        card = new AdaptiveCard();

            response = await client.GetAsync(String.Format("https://surastorage.blob.core.windows.net/cardstemplates/servicios.json"));

            var json = await response.Content.ReadAsStringAsync();

            AdaptiveCardParseResult resultString = AdaptiveCard.FromJson(json);

            card = resultString.Card;
            IList <AdaptiveWarning> warnings = resultString.Warnings;


            Attachment attachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = card
            };

            reply.Attachments.Add(attachment);
        }
Example #11
0
        public PromptOptions GeneratePersonDetailsAttachment(PersonDetails personDetails, PersonKnownFor[] knownFor)
        {
            var paths            = new[] { ".", "Cards", "personDetails.json" };
            var adaptiveCardJson = File.ReadAllText(Path.Combine(paths));

            AdaptiveCardParseResult result = AdaptiveCard.FromJson(adaptiveCardJson);
            AdaptiveCard            card   = result.Card;

            ((AdaptiveTextBlock)card.Body.First()).Text = "Person details";
            ((AdaptiveImage)((AdaptiveColumnSet)card.Body[1]).Columns.First().Items.First()).Url = new Uri($"https://image.tmdb.org/t/p/w500/{personDetails.profile_path}");

            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items.First()).Text = personDetails.name;
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[1]).Text      = $"Born: {personDetails.birthday}";
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[2]).Text      = $"Role: {personDetails.known_for_department}";
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[1]).Text      = $"Born: {personDetails.birthday}";
            ((AdaptiveTextBlock)card.Body[2]).Text = personDetails.biography;

            ((AdaptiveFactSet)card.Body[4]).Facts
            .AddRange(knownFor.Select(x => new AdaptiveFact
            {
                Title = x.Title,
                Value = $"({x.ReleaseDate.Split("-")[0]}) - {TMDBGenres.MovieGenres.Where(y => y.Value == x.GenreIds[0]).FirstOrDefault().Key}"
            }));

            ((AdaptiveOpenUrlAction)card.Actions.First()).Url = new Uri($"https://www.imdb.com/name/{personDetails.imdb_id}");


            return(new PromptOptions
            {
                Prompt = (Activity)MessageFactory.Attachment(new Attachment()
                {
                    ContentType = "application/vnd.microsoft.card.adaptive",
                    Content = JObject.FromObject(card)
                })
            });
        }
Example #12
0
        public PromptOptions GenerateTVDetailsAttachment(TVDetails tvDetails)
        {
            var paths            = new[] { ".", "Cards", "movieDetails.json" };
            var adaptiveCardJson = File.ReadAllText(Path.Combine(paths));

            AdaptiveCardParseResult result = AdaptiveCard.FromJson(adaptiveCardJson);
            AdaptiveCard            card   = result.Card;

            ((AdaptiveTextBlock)card.Body.First()).Text = "Movie details";
            ((AdaptiveImage)((AdaptiveColumnSet)card.Body[1]).Columns.First().Items.First()).Url = new Uri($"https://image.tmdb.org/t/p/w500/{tvDetails.PosterPath}");

            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items.First()).Text = tvDetails.Name;
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[1]).Text      = $"Released: {tvDetails.FirstAirDate}";
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[2]).Text      = $"Genres: {string.Join(", ", tvDetails.Genres.Select(x => x.Name))}";
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[3]).Text      = $"Status: {tvDetails.Status}";
            ((AdaptiveTextBlock)((AdaptiveColumnSet)card.Body[1]).Columns[1].Items[4]).Text      = $"Rating: {tvDetails.VoteAverage}";
            ((AdaptiveTextBlock)card.Body[2]).Text = tvDetails.Overview;

            card.Actions = null;

            ((AdaptiveFactSet)card.Body[3]).Facts
            .AddRange(tvDetails.Seasons.OrderBy(x => x.SeasonNumber).Select(x => new AdaptiveFact
            {
                Title = x.Name,
                Value = $"- ({x.AirDate?.Split("-")[0]}) - {x.EpisodeCount} episodes"
            }));

            return(new PromptOptions
            {
                Prompt = (Activity)MessageFactory.Attachment(new Attachment()
                {
                    ContentType = "application/vnd.microsoft.card.adaptive",
                    Content = JObject.FromObject(card)
                })
            });
        }
Example #13
0
        public async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> argument)
        {
            AdaptiveCard card = new AdaptiveCard();

            card.Body.Add(new AdaptiveTextBlock()
            {
                Text   = "Adaptive Card rendering test",
                Size   = AdaptiveTextSize.Large,
                Weight = AdaptiveTextWeight.Bolder
            });

            var choiceSet = new AdaptiveChoiceSetInput();

            choiceSet.Choices.Add(
                new AdaptiveChoice()
            {
                Title = "Zuko",
                Value = "zuko"
            });
            choiceSet.Choices.Add(new AdaptiveChoice()
            {
                Title = "Buko",
                Value = "buko"
            });
            card.Body.Add(choiceSet);

            Attachment attachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = card
            };

            var replyToConversation = context.MakeMessage();

            replyToConversation.Attachments.Add(attachment);

            //return our reply to the user
            await context.PostAsync(replyToConversation);

            string json = @"{
    ""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"",
    ""type"": ""AdaptiveCard"",
    ""version"": ""1.0"",
    ""body"": [
        {
            ""type"": ""TextBlock"",
            ""text"": ""title"",
            ""weight"": ""bolder"",
            ""size"": ""large""
        },
        {
            ""type"": ""TextBlock"",
            ""text"": ""shortText"",
            ""wrap"": ""true""
        },
        {
            ""type"": ""TextBlock"",
            ""text"": ""Date: date"",
            ""separator"": ""true"",
            ""weight"": ""bolder""
        }
    ],
    ""actions"": [
        {
            ""type"": ""Action.OpenUrl"",
            ""title"": ""More information"",
            ""url"": ""Url""
        },
        {
            ""type"": ""Action.Submit"",
            ""title"": ""Subscribe"",
            ""data"": ""subscribesentence""
        }
    ]
}";
            AdaptiveCardParseResult result = AdaptiveCard.FromJson(json);

            AdaptiveCard card2       = result.Card;
            Attachment   attachment2 = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = card2
            };

            var replyToConversation2 = context.MakeMessage();

            replyToConversation2.Attachments.Add(attachment2);
            await context.PostAsync(replyToConversation2);

            context.Wait(MessageReceivedAsync);
        }
Example #14
0
        protected override async void LoadPayload(string payload)
        {
            var newErrors = await PayloadValidator.ValidateAsync(payload);

            if (newErrors.Any(i => i.Type == ErrorViewModelType.Error))
            {
                MakeErrorsLike(newErrors);
                return;
            }

            try
            {
                if (_renderer == null)
                {
                    InitializeRenderer(MainPageViewModel.HostConfigEditor.HostConfig);
                }
            }
            catch (Exception ex)
            {
                newErrors.Add(new ErrorViewModel()
                {
                    Message = "Initializing renderer error: " + ex.ToString(),
                    Type    = ErrorViewModelType.Error
                });
                MakeErrorsLike(newErrors);
                return;
            }

            try
            {
                JsonObject jsonObject;
                if (JsonObject.TryParse(payload, out jsonObject))
                {
                    AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(jsonObject);

                    RenderedAdaptiveCard renderResult = _renderer.RenderAdaptiveCard(parseResult.AdaptiveCard);
                    if (renderResult.FrameworkElement != null)
                    {
                        RenderedCard         = renderResult.FrameworkElement;
                        renderResult.Action += async(sender, e) =>
                        {
                            var m_actionDialog = new ContentDialog();

                            if (e.Action.ActionType == ActionType.ShowCard)
                            {
                                AdaptiveShowCardAction showCardAction   = (AdaptiveShowCardAction)e.Action;
                                RenderedAdaptiveCard   renderedShowCard = _renderer.RenderAdaptiveCard(showCardAction.Card);
                                if (renderedShowCard.FrameworkElement != null)
                                {
                                    m_actionDialog.Content = renderedShowCard.FrameworkElement;
                                }
                            }
                            else
                            {
                                m_actionDialog.Content = SerializeActionEventArgsToString(e);
                            }

                            m_actionDialog.PrimaryButtonText = "Close";

                            await m_actionDialog.ShowAsync();
                        };

                        if (!MainPageViewModel.HostConfigEditor.HostConfig.Media.AllowInlinePlayback)
                        {
                            renderResult.MediaPlay += async(sender, e) =>
                            {
                                var onPlayDialog = new ContentDialog();
                                onPlayDialog.Content = "MediaPlayEvent:";

                                foreach (var source in e.Media.Sources)
                                {
                                    onPlayDialog.Content += "\n" + source.Url + " (" + source.MimeType + ")";
                                }

                                onPlayDialog.PrimaryButtonText = "Close";

                                await onPlayDialog.ShowAsync();
                            };
                        }
                        else
                        {
                            renderResult.MediaEnded += async(sender, e) =>
                            {
                                var mediaEndedDialog = new ContentDialog();
                                mediaEndedDialog.Content = "Media Ended Event:";

                                foreach (var source in e.Media.Sources)
                                {
                                    mediaEndedDialog.Content += "\n" + source.Url + " (" + source.MimeType + ")";
                                }

                                mediaEndedDialog.PrimaryButtonText = "Close";

                                await mediaEndedDialog.ShowAsync();
                            };
                        }
                    }
                    else
                    {
                        newErrors.Add(new ErrorViewModel()
                        {
                            Message = "There was an error Rendering this card",
                            Type    = ErrorViewModelType.Error
                        });
                    }
                    foreach (var error in parseResult.Errors)
                    {
                        newErrors.Add(new ErrorViewModel()
                        {
                            Message = error.Message,
                            Type    = ErrorViewModelType.Error
                        });
                    }
                    foreach (var error in renderResult.Errors)
                    {
                        newErrors.Add(new ErrorViewModel()
                        {
                            Message = error.Message,
                            Type    = ErrorViewModelType.Error
                        });
                    }
                    foreach (var error in parseResult.Warnings)
                    {
                        newErrors.Add(new ErrorViewModel()
                        {
                            Message = error.Message,
                            Type    = ErrorViewModelType.Warning
                        });
                    }

                    foreach (var error in renderResult.Warnings)
                    {
                        newErrors.Add(new ErrorViewModel()
                        {
                            Message = error.Message,
                            Type    = ErrorViewModelType.Warning
                        });
                    }
                }
                else
                {
                    newErrors.Add(new ErrorViewModel()
                    {
                        Message = "There was an error creating a JsonObject from the card",
                        Type    = ErrorViewModelType.Error
                    });
                }

                if (RenderedCard is FrameworkElement)
                {
                    (RenderedCard as FrameworkElement).VerticalAlignment = VerticalAlignment.Top;
                }
                MakeErrorsLike(newErrors);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                newErrors.Add(new ErrorViewModel()
                {
                    Message = "Rendering failed",
                    Type    = ErrorViewModelType.Error
                });
                MakeErrorsLike(newErrors);
            }
        }
Example #15
0
        static void Main(string[] args)
        {
            bool supportsInteractivity = false;

            const string supportsInteractivityFlag = "/supportsInteractivity";

            if (args.Contains(supportsInteractivityFlag))
            {
                supportsInteractivity = true;
                args = args.Except(new string[] { supportsInteractivityFlag }).ToArray();
            }

            Console.WriteLine(@"<html><head>");
            Console.WriteLine(@"<style>");
            Console.WriteLine(@".cardcontainer { ");
            Console.WriteLine(@"  width: 400px;");
            Console.WriteLine(@"  border-width: 1px;");
            Console.WriteLine(@"  border-color: #808080;");
            Console.WriteLine(@"  border-style: solid;");
            Console.WriteLine(@"  padding: 8px;");
            Console.WriteLine(@"}");
            Console.WriteLine(@"</style>");
            Console.WriteLine(@"</head>");
            Console.WriteLine(@"<body>");
            List <string> files = new List <string>();

            if (File.Exists(args[0]))
            {
                files.Add(args[0]);
            }
            else
            {
                files = Directory.GetFiles(args[0]).ToList();
            }

            foreach (var file in files)
            {
                try
                {
                    Console.WriteLine("<hr/>");
                    Console.WriteLine($"<h1>{file}</h1>");

                    AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(File.ReadAllText(file));
                    if (parseResult.Card != null)
                    {
                        AdaptiveCard card = parseResult.Card;

                        AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(new HostConfig()
                        {
                            SupportsInteractivity = supportsInteractivity
                        });

                        Console.WriteLine($"<h3>Renderer schema version: {renderer.SupportedSchemaVersion}</h3>");

                        RenderedAdaptiveCard renderedCard = renderer.RenderCard(card);

                        if (renderedCard.HtmlTag != null)
                        {
                            Console.WriteLine($"<div class='cardcontainer'>{renderedCard.HtmlTag.ToString()}</div>");
                        }
                        else
                        {
                            Console.WriteLine($"<p>Rendering failed</p>");
                        }
                    }
                }
                catch (Exception err)
                {
                    Console.WriteLine($"{file} failed: {err.Message}<br/>");
                }
            }

#if DEBUG
            // Leave the console up while debugging
            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.ReadLine();
            }
#endif
        }
        private void RenderCard()
        {
            cardError.Children.Clear();
            cardGrid.Opacity = 0.65;

            if (templateData != null && templateData.Length == 0)
            {
                templateData = null;
            }

            string expandedPayload = "";

            try
            {
                // don't throw error, but should affect work flow and performance.
                // transformer -> has to have errors
                var template = new AdaptiveCardTemplate(CardPayload);
                var context  = new EvaluationContext
                {
                    Root = templateData
                };

                // Create a data binding context, and set its $root property to the
                // data object to bind the template to
                // var context = new ACData.EvaluationContext();
                // context.$root = {
                //     "name": "Mickey Mouse"
                // };

                expandedPayload = template.Expand(context);
            }

            catch (Exception e)
            {
                // if an exception thrown, we parse and render cards as it is
                ShowError(e);
                expandedPayload = CardPayload;
            }

            try
            {
                AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(expandedPayload);

                AdaptiveCard card = parseResult.Card;

                /*
                 * if (!_stylesAdded)
                 * {
                 *  // Example on how to override the Action Positive and Destructive styles
                 *  Style positiveStyle = new Style(typeof(Button));
                 *  positiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.Green));
                 *  Style otherStyle = new Style(typeof(Button));
                 *  otherStyle.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.Yellow));
                 *  otherStyle.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.Red));
                 *
                 *  Renderer.Resources.Add("Adaptive.Action.positive", positiveStyle);
                 *  Renderer.Resources.Add("Adaptive.Action.other", otherStyle);
                 *
                 *  _stylesAdded = true;
                 * }
                 */

                RenderedAdaptiveCard renderedCard = Renderer.RenderCard(card);
                // TODO: should we have an option to render fallback card instead of exception?

                // Wire up click handler
                renderedCard.OnAction += OnAction;

                renderedCard.OnMediaClicked += OnMediaClick;

                cardGrid.Opacity = 1;
                cardGrid.Children.Clear();
                cardGrid.Children.Add(renderedCard.FrameworkElement);

                // Report any warnings
                var allWarnings = parseResult.Warnings.Union(renderedCard.Warnings);
                foreach (var warning in allWarnings)
                {
                    ShowWarning(warning.Message);
                }
            }
            catch (AdaptiveRenderException ex)
            {
                var fallbackCard = new TextBlock
                {
                    Text = ex.CardFallbackText ?? "Sorry, we couldn't render the card"
                };

                cardGrid.Children.Add(fallbackCard);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }
Example #17
0
    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <object> result)
    {
        var activity = await result as Activity;

        if (activity.Value != null)
        {
            JToken valueToken  = JObject.Parse(activity.Value.ToString());
            string actionValue = valueToken.SelectToken("property") != null?valueToken.SelectToken("property").ToString() : string.Empty;

            var    reply = context.MakeMessage();
            string json  = "";

            switch (actionValue)
            {
            case "1":
                json = await GetCardText("card1");

                break;

            case "2":
                json = await GetCardText("card2");

                break;

            case "3":
                json = await GetCardText("card3");

                break;

            default:
                break;
            }

            AdaptiveCardParseResult cardParseResult = AdaptiveCard.FromJson(json);

            reply.Attachments.Add(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = cardParseResult.Card
            });

            await context.PostAsync(reply);
        }
        else
        {
            if (activity.Text.ToLower().Contains("card"))
            {
                var replyMessage = context.MakeMessage();

                var json = await GetCardText("maincard");

                AdaptiveCardParseResult cardParseResult = AdaptiveCard.FromJson(json);

                replyMessage.Attachments.Add(new Attachment()
                {
                    Content     = cardParseResult.Card,
                    ContentType = AdaptiveCard.ContentType,
                    Name        = "Card"
                });

                await context.PostAsync(replyMessage);
            }
            else
            {
                await context.PostAsync($"You sent {activity.Text}");
            }
        }

        context.Wait(MessageReceivedAsync);
    }
Example #18
0
        static int Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            var app = new CommandLineApplication();

            app.HelpOption("-h|--help");

            var pathArg       = app.Argument("path", "The path that contains JSON card payloads");
            var optionRecurse = app.Option("-r|--recursive", "Recurse the directory for all JSON files", CommandOptionType.NoValue);
            var optionOutput  = app.Option("-o|--out", "The file to output the HTML to", CommandOptionType.SingleValue);
            var optionSupportsInteracitivty = app.Option("-i|--supports-interactivity", "Include actions and inputs in the output", CommandOptionType.NoValue);
            var hostConfigOption            = app.Option("--host-config", "Specify a host config file", CommandOptionType.SingleValue);

            app.OnExecute(() =>
            {
                FileStream outputFile = null;
                var writer            = Console.Out;

                // Output to file instead of console
                if (optionOutput.HasValue())
                {
                    outputFile = File.Open(optionOutput.Value(), FileMode.Create);
                    writer     = new StreamWriter(outputFile);
                }

                // Get payload search path
                var payloadPath = pathArg.Value ?? "..\\..\\..\\..\\samples\\v1.0\\Scenarios";
                if (pathArg.Value == null)
                {
                    Console.WriteLine($"No path argument specified, trying {payloadPath}...");
                }

                var files = new List <string>();

                if (File.Exists(payloadPath))
                {
                    files.Add(payloadPath);
                }
                else if (Directory.Exists(payloadPath))
                {
                    var recurse = optionRecurse.HasValue()
                        ? SearchOption.AllDirectories
                        : SearchOption.TopDirectoryOnly;

                    files = Directory.GetFiles(payloadPath, "*.json", recurse).ToList();
                    Console.WriteLine($"Found {files.Count} card payloads...");
                }
                else
                {
                    Console.WriteLine($"{payloadPath} does not contain any JSON files. Nothing to do.");
                    return;
                }

                writer.WriteLine(@"<!DOCTYPE html>
<html>
<head>
    <title>Adaptive Cards HTML Renderer Test Bed</title>
    <meta charset=""UTF-8"">
    <style type""text/css"">
                
        * {
            box-sizing: border-box;
            font-family: 'Segoe UI'
        }

        .cardcontainer {
            width: 400px;
            border-width: 1px;
            border-color: #808080;
            border-style: solid;
        }

        .error {
            border: solid 1px maroon;
            color: white;
            background: maroon;
            padding: 5px;
            width: 400px;
        }

        .warning {
            border: solid 1px orange;
            color: white;
            background: orange;
            padding: 5px;
            width: 400px;
        }
    </style>
</head>
<body>");


                AdaptiveHostConfig hostConfig = new AdaptiveHostConfig()
                {
                    SupportsInteractivity = optionSupportsInteracitivty.HasValue()
                };

                if (hostConfigOption.HasValue())
                {
                    hostConfig = AdaptiveHostConfig.FromJson(File.ReadAllText(hostConfigOption.Value()));
                }

                AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(hostConfig);


                writer.WriteLine($"<h3>Renderer schema version: {renderer.SupportedSchemaVersion}</h3>");
                writer.WriteLine($"<h4>Interactivty Enabled: {hostConfig.SupportsInteractivity}</h4>");
                writer.WriteLine($"<h4>Generated at: {DateTime.Now:G}</h4>");

                foreach (var file in files)
                {
                    try
                    {
                        writer.WriteLine("<hr/>");
                        writer.WriteLine($"<h2>{Path.GetFileName(file)}</h2>");

                        AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(File.ReadAllText(file, Encoding.UTF8));

                        AdaptiveCard card = parseResult.Card;

                        RenderedAdaptiveCard renderedCard = renderer.RenderCard(card);

                        // Report any warnings
                        foreach (var warning in parseResult.Warnings.Union(renderedCard.Warnings))
                        {
                            writer.WriteLine($"<p class='warning'>WARNING: {warning.Message}</p>");
                        }

                        writer.WriteLine($"<div class='cardcontainer'>{renderedCard.Html}</div>");
                    }
                    catch (Exception err)
                    {
                        Debugger.Break();
                        writer.WriteLine($"<p class='error'>ERROR: {err.Message}</p>");
                    }
                }

                bool allowInlinePlayback = hostConfig.Media.AllowInlinePlayback;

                // Convert to JavaScript boolean values (False -> false, True -> true)
                string jsAllowInlinePlayback = allowInlinePlayback.ToString().ToLower();

                writer.WriteLine("</body>");
                writer.WriteLine($@"
    <script>
        // Sample JavaScript code to make media elements work
        const mediaPosterButtons = document.getElementsByClassName('ac-media-poster');
        const allowInlinePlayback = false;
        for (var i = 0; i < mediaPosterButtons.length; i++)
        {{
            const button = mediaPosterButtons[i];
            button.addEventListener('click', function() {{
                if ({jsAllowInlinePlayback}) {{
                    const mediaId = button.dataset.acMediaid;
                    const mediaPlayerContainer = document.getElementById(mediaId);

                    if (mediaPlayerContainer)
                    {{
                        // Hide the poster
                        button.style.display = 'none';

                        // Show the media player container
                        mediaPlayerContainer.style.display = '';

                        // Play the media
                        const mediaPlayer = document.getElementById(`${{mediaId}}-player`);
                        mediaPlayer.play();
                    }}
                }} else {{
                    const mediaSources = button.dataset.acMediaSources;
                    alert(mediaSources);
                }}
            }});
        }}
    </script>");
                writer.WriteLine("</html>");

                if (outputFile != null)
                {
                    writer.Flush();
                    outputFile.Flush();
                    outputFile.Dispose();

                    Console.WriteLine($"All cards were written to {outputFile.Name}");
                }


                // if output, launch the file
                if (Debugger.IsAttached)
                {
                    Console.ReadLine();
                }
            });

            return(app.Execute(args));
        }
Example #19
0
        static int Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            var app = new CommandLineApplication();

            app.HelpOption("-h|--help");

            var pathArg       = app.Argument("path", "The path that contains JSON card payloads");
            var optionRecurse = app.Option("-r|--recursive", "Recurse the directory for all JSON files", CommandOptionType.NoValue);
            var optionOutput  = app.Option("-o|--out", "The file to output the HTML to", CommandOptionType.SingleValue);
            var optionSupportsInteracitivty = app.Option("-i|--supports-interactivity", "Include actions and inputs in the output", CommandOptionType.NoValue);
            var hostConfigOption            = app.Option("--host-config", "Specify a host config file", CommandOptionType.SingleValue);

            app.OnExecute(() =>
            {
                FileStream outputFile = null;
                var writer            = Console.Out;

                // Output to file instead of console
                if (optionOutput.HasValue())
                {
                    outputFile = File.Open(optionOutput.Value(), FileMode.Create);
                    writer     = new StreamWriter(outputFile);
                }

                // Get payload search path
                var payloadPath = pathArg.Value ?? "..\\..\\..\\..\\samples\\v1.0\\Scenarios";
                if (pathArg.Value == null)
                {
                    Console.WriteLine($"No path argument specified, trying {payloadPath}...");
                }

                var files = new List <string>();

                if (File.Exists(payloadPath))
                {
                    files.Add(payloadPath);
                }
                else if (Directory.Exists(payloadPath))
                {
                    var recurse = optionRecurse.HasValue()
                        ? SearchOption.AllDirectories
                        : SearchOption.TopDirectoryOnly;

                    files = Directory.GetFiles(payloadPath, "*.json", recurse).ToList();
                    Console.WriteLine($"Found {files.Count} card payloads...");
                }
                else
                {
                    Console.WriteLine($"{payloadPath} does not contain any JSON files. Nothing to do.");
                    return;
                }

                writer.WriteLine(@"<!DOCTYPE html>
<html>
<head>
    <title>Adaptive Cards HTML Renderer Test Bed</title>
    <meta charset=""UTF-8"">
    <style type""text/css"">

        * {
            box-sizing: border-box;
            font-family: 'Segoe UI'
        }

        .cardcontainer {
            width: 400px;
            border-width: 1px;
            border-color: #808080;
            border-style: solid;
        }

        .error {
            border: solid 1px maroon;
            color: white;
            background: maroon;
            padding: 5px;
            width: 400px;
        }

        .warning {
            border: solid 1px orange;
            color: white;
            background: orange;
            padding: 5px;
            width: 400px;
        }

    </style>
</head>
<body>");


                AdaptiveHostConfig hostConfig = new AdaptiveHostConfig()
                {
                    SupportsInteractivity = optionSupportsInteracitivty.HasValue()
                };

                if (hostConfigOption.HasValue())
                {
                    hostConfig = AdaptiveHostConfig.FromJson(File.ReadAllText(hostConfigOption.Value()));
                }

                AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(hostConfig);


                writer.WriteLine($"<h3>Renderer schema version: {renderer.SupportedSchemaVersion}</h3>");
                writer.WriteLine($"<h4>Interactivty Enabled: {hostConfig.SupportsInteractivity}</h4>");
                writer.WriteLine($"<h4>Generated at: {DateTime.Now:G}</h4>");

                foreach (var file in files)
                {
                    try
                    {
                        writer.WriteLine("<hr/>");
                        writer.WriteLine($"<h2>{Path.GetFileName(file)}</h2>");

                        AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(File.ReadAllText(file, Encoding.UTF8));

                        AdaptiveCard card = parseResult.Card;

                        RenderedAdaptiveCard renderedCard = renderer.RenderCard(card);

                        // Report any warnings
                        foreach (var warning in parseResult.Warnings.Union(renderedCard.Warnings))
                        {
                            writer.WriteLine($"<p class='warning'>WARNING: {warning.Message}</p>");
                        }

                        writer.WriteLine($"<div class='cardcontainer'>{renderedCard.Html}</div>");
                    }
                    catch (Exception err)
                    {
                        Debugger.Break();
                        writer.WriteLine($"<p class='error'>ERROR: {err.Message}</p>");
                    }
                }

                bool allowInlinePlayback = hostConfig.Media.AllowInlinePlayback;

                // Convert to JavaScript boolean values (False -> false, True -> true)
                string jsAllowInlinePlayback = allowInlinePlayback.ToString().ToLower();

                writer.WriteLine("</body>");
                writer.WriteLine($@"
    <script>
        // Sample JavaScript code to make media elements work
        const mediaPosterButtons = document.getElementsByClassName('ac-media-poster');
        const allowInlinePlayback = false;

        function activateMedia(button) {{
            const mediaId = button.dataset.acMediaid;
            const mediaPlayerContainer = document.getElementById(mediaId);

            if (mediaPlayerContainer)
            {{
                // Hide the poster
                button.style.display = 'none';

                // Show the media player container
                mediaPlayerContainer.style.display = '';

                // Play the media
                const mediaPlayer = document.getElementById(`${{mediaId}}-player`);
                mediaPlayer.play();
            }}
        }}

        for (var i = 0; i < mediaPosterButtons.length; i++)
        {{
            const button = mediaPosterButtons[i];
            button.addEventListener('click', function() {{
                if ({jsAllowInlinePlayback}) {{
                    activateMedia(button);
                }} else {{
                    const mediaSources = button.dataset.acMediaSources;
                    alert(mediaSources);
                }}
            }});
            button.addEventListener('keydown', function(e) {{
                if (e.key == "" "") {{
                    if ({jsAllowInlinePlayback}) {{
                        activateMedia(button);
                    }} else {{
                        const mediaSources = button.dataset.acMediaSources;
                        alert(mediaSources);
                    }}
                }}
            }});
        }}

        // Sample JavaScript code to test showCard action
        const showCardActions = document.getElementsByClassName('ac-action-showCard');
        for (var i = 0; i < showCardActions.length; i++)
        {{
            const showCardAction = showCardActions[i];
            showCardAction.addEventListener('click', function() {{
                if (true) {{
                    const showCardId = showCardAction.dataset.acShowcardid;
                    const showCard = document.getElementById(showCardId);

                    if(showCard.style.display == 'none') {{
                        showCard.style.display = 'inline';
                    }}
                    else {{
                        showCard.style.display = 'none'
                    }}
                }} else {{
                    const showCardId = showCardAction.dataset.acShowCardId;
                    alert(showCardId);
                }}
            }});
        }}

        // Sample JavaScript code to test inlienaction's keyboard event handler
        const textinputWithInlineAction = document.getElementsByClassName('ac-textinput-inlineaction');
        for (var i = 0; i < textinputWithInlineAction.length; i++)
        {{
            const container = textinputWithInlineAction[i];
            const textinputId = container.dataset.acTextinputId;
            const textinput = document.getElementById(textinputId);
            textinput.addEventListener('keydown', function (e) {{
                if (e.key == ""Enter"") {{
                    const inlineactionId = container.dataset.acInlineactionId;
                    const inlineaction = document.getElementById(inlineactionId);

                    if (inlineaction) {{
                        var actionAttribute = inlineaction.getAttribute('data-ac-url');
                        if (actionAttribute != null) {{
                            window.open(actionAttribute);
                        }}
                        else {{
                            actionAttribute = inlineaction.getAttribute('data-ac-submitData')
                            if (actionAttribute != null) {{
                                alert(textinput.value);
                            }}
                        }}
                    }}
                }}
            }});
        }}

        // Sample JavaScript code to test toggleVisibility action
        const toggleVisibilityActions = document.getElementsByClassName('ac-action-toggleVisibility');
        for (var i = 0; i < toggleVisibilityActions.length; i++) {{
            const toggleVisibilityAction = toggleVisibilityActions[i];

            toggleVisibilityAction.addEventListener('click', function() {{
                if ({jsAllowInlinePlayback}) {{
                    // Read list of targets with defined behaviour
                    // List will be in format id-targets='id1:True,id2:Toggle,id3:False'
                    const targetElementsString = toggleVisibilityAction.dataset.acTargetelements;
                    var targetElements = targetElementsString.split(',');

                    // For each target in list of targets
                    for(var j = 0; j < targetElements.length; j++) {{
                        /// Do a split for commas and for each element, find the : to divide both strings
                        const targetElementIdWithAction = targetElements[j].split(':');
                        const targetElementId = targetElementIdWithAction[0];
                        const targetElementAction = targetElementIdWithAction[1];

                        var targetElementsInDocument = document.getElementsByName(targetElementId);
                        // There is no singular version of getElementByName so just take the first element
                        var targetElement = targetElementsInDocument[0];
                        // The way to discern between checkbox elements and inline-actions is that inline-actions contain a textinput
                        var isCheckBoxElement = ((targetElementsInDocument.length > 1) && !(targetElement.className.includes('ac-textinput')));

                        const targetSeparatorId = targetElement.dataset.acSeparatorid;						
                        const separator = document.getElementById(targetSeparatorId);

                        if(targetElementAction == 'True' || (targetElementAction == 'Toggle' && targetElement.style.display == 'none')) {{
                            if( isCheckBoxElement ) {{
                                targetElement.style.display = 'inline-block';
                            }}
                            else {{
                                targetElement.style.display = 'flex';
                            }}

                            if(targetElement.className.includes('ac-container')){{
                                targetElement.style.display = 'block';
                            }}

                            if(separator != null) {{
                                separator.style.display = 'block';
                            }}
                        }}
                        else if(targetElementAction == 'False' || (targetElementAction == 'Toggle' && targetElement.style.display != 'none')) {{
                            targetElement.style.display = 'none';

                            if(separator != null) {{
                                separator.style.display = 'none';
                            }}
                        }}

                        const parent = targetElement.parentNode;
						var isFirstElement = true;
						for(var k = 0; k < parent.childNodes.length; k++){{

                            var child = parent.childNodes[k];
							
							<!-- if element is separator -> skip (As we don't care of this one) -->
							if(child.className.includes('ac-separator') || child.className.includes('ac-columnseparator')){{
								continue;
							}}
							
							<!-- if element is not visible -> skip (The separator was hidden in the previous step) -->
							if(child.style.display == 'none'){{
								continue;	
							}}
							
							const childSeparatorId = child.dataset.acSeparatorid;		
							var childSeparator = document.getElementById(childSeparatorId);
							
							if(isFirstElement){{
								<!-- if element is visible -> hide separator -->
								if(childSeparator != null){{
									childSeparator.style.display = 'none';
								}}
								isFirstElement = false;
							}}
							else{{
								<!-- if element is visible -> show separator -->
								if(childSeparator != null){{
									childSeparator.style.display = 'block';
								}}
							}}
							
						}}

                    }}

                }} else {{
                    const targetElementsString = toggleVisibilityAction.dataset.acTargetelements;
                    alert(targetElementsString);
                }}
            }});
        }}

    </script>");
                writer.WriteLine("</html>");

                if (outputFile != null)
                {
                    writer.Flush();
                    outputFile.Flush();
                    outputFile.Dispose();

                    Console.WriteLine($"All cards were written to {outputFile.Name}");
                }


                // if output, launch the file
                if (Debugger.IsAttached)
                {
                    Console.ReadLine();
                }
            });

            return(app.Execute(args));
        }
        private void TestParsingInvalidCard(string cardPayload)
        {
            AdaptiveCardParseResult result = AdaptiveCard.FromJson(cardPayload);

            Assert.IsNull(result.Card);
        }
Example #21
0
        static int Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            var app = new CommandLineApplication();

            app.HelpOption("-h|--help");

            var pathArg       = app.Argument("path", "The path that contains JSON card payloads");
            var optionRecurse = app.Option("-r|--recursive", "Recurse the directory for all JSON files", CommandOptionType.NoValue);
            var optionOutput  = app.Option("-o|--out", "The file to output the HTML to", CommandOptionType.SingleValue);
            var optionSupportsInteracitivty = app.Option("-i|--supports-interactivity", "Include actions and inputs in the output", CommandOptionType.NoValue);
            var hostConfigOption            = app.Option("--host-config", "Specify a host config file", CommandOptionType.SingleValue);

            app.OnExecute(() =>
            {
                FileStream outputFile = null;
                var writer            = Console.Out;

                // Output to file instead of console
                if (optionOutput.HasValue())
                {
                    outputFile = File.Open(optionOutput.Value(), FileMode.Create);
                    writer     = new StreamWriter(outputFile);
                }

                // Get payload search path
                var payloadPath = pathArg.Value ?? "..\\..\\..\\..\\samples\\v1.0\\Scenarios";
                if (pathArg.Value == null)
                {
                    Console.WriteLine($"No path argument specified, trying {payloadPath}...");
                }

                var files = new List <string>();

                if (File.Exists(payloadPath))
                {
                    files.Add(payloadPath);
                }
                else if (Directory.Exists(payloadPath))
                {
                    var recurse = optionRecurse.HasValue()
                        ? SearchOption.AllDirectories
                        : SearchOption.TopDirectoryOnly;

                    files = Directory.GetFiles(payloadPath, "*.json", recurse).ToList();
                    Console.WriteLine($"Found {files.Count} card payloads...");
                }
                else
                {
                    Console.WriteLine($"{payloadPath} does not contain any JSON files/. Nothing to do.");
                    return;
                }


                writer.WriteLine(@"<!DOCTYPE html>");
                writer.WriteLine(@"<html>");
                writer.WriteLine(@"<head>");
                writer.WriteLine(@"  <title>Adaptive Cards HTML Renderer Test Bed</title>");
                writer.WriteLine(@"  <meta charset=""UTF-8"">");
                writer.WriteLine(@"  <link rel='stylesheet' type='text/css' href='AdaptiveCards.css' />");
                writer.WriteLine(@"</head>");
                writer.WriteLine(@"<body>");


                AdaptiveHostConfig hostConfig = new AdaptiveHostConfig()
                {
                    SupportsInteractivity = optionSupportsInteracitivty.HasValue()
                };

                if (hostConfigOption.HasValue())
                {
                    hostConfig = AdaptiveHostConfig.FromJson(File.ReadAllText(hostConfigOption.Value()));
                }

                AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(hostConfig);


                writer.WriteLine($"<h3>Renderer schema version: {renderer.SupportedSchemaVersion}</h3>");
                writer.WriteLine($"<h4>Interactivty Enabled: {hostConfig.SupportsInteractivity}</h4>");
                writer.WriteLine($"<h4>Generated at: {DateTime.Now:G}</h4>");

                foreach (var file in files)
                {
                    try
                    {
                        writer.WriteLine("<hr/>");
                        writer.WriteLine($"<h2>{Path.GetFileName(file)}</h2>");

                        AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(File.ReadAllText(file, Encoding.UTF8));

                        AdaptiveCard card = parseResult.Card;

                        RenderedAdaptiveCard renderedCard = renderer.RenderCard(card);

                        // Report any warnings
                        foreach (var warning in parseResult.Warnings.Union(renderedCard.Warnings))
                        {
                            writer.WriteLine($"<p class='warning'>WARNING: {warning.Message}</p>");
                        }

                        writer.WriteLine($"<div class='cardcontainer'>{renderedCard.Html}</div>");
                    }
                    catch (Exception err)
                    {
                        Debugger.Break();
                        writer.WriteLine($"<p class='error'>ERROR: {err.Message}</p>");
                    }
                }

                writer.WriteLine("</body>");
                writer.WriteLine("</html>");

                if (outputFile != null)
                {
                    writer.Flush();
                    outputFile.Flush();
                    outputFile.Dispose();

                    Console.WriteLine($"All cards were written to {outputFile.Name}");
                }


                // if output, launch the file
                if (Debugger.IsAttached)
                {
                    Console.ReadLine();
                }
            });

            return(app.Execute(args));
        }
Example #22
0
        private void RenderCard()
        {
            cardError.Children.Clear();
            cardGrid.Opacity = 0.65;

            try
            {
                AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(CardPayload);

                AdaptiveCard card = parseResult.Card;

                /*
                 * if (!_stylesAdded)
                 * {
                 *  // Example on how to override the Action Positive and Destructive styles
                 *  Style positiveStyle = new Style(typeof(Button));
                 *  positiveStyle.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.Green));
                 *  Style otherStyle = new Style(typeof(Button));
                 *  otherStyle.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.Yellow));
                 *  otherStyle.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.Red));
                 *
                 *  Renderer.Resources.Add("Adaptive.Action.positive", positiveStyle);
                 *  Renderer.Resources.Add("Adaptive.Action.other", otherStyle);
                 *
                 *  _stylesAdded = true;
                 * }
                 */

                RenderedAdaptiveCard renderedCard = Renderer.RenderCard(card);
                // TODO: should we have an option to render fallback card instead of exception?

                // Wire up click handler
                renderedCard.OnAction += OnAction;

                renderedCard.OnMediaClicked += OnMediaClick;

                cardGrid.Opacity = 1;
                cardGrid.Children.Clear();
                cardGrid.Children.Add(renderedCard.FrameworkElement);

                // Report any warnings
                var allWarnings = parseResult.Warnings.Union(renderedCard.Warnings);
                foreach (var warning in allWarnings)
                {
                    ShowWarning(warning.Message);
                }
            }
            catch (AdaptiveRenderException ex)
            {
                var fallbackCard = new TextBlock
                {
                    Text = ex.CardFallbackText ?? "Sorry, we couldn't render the card"
                };

                cardGrid.Children.Add(fallbackCard);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }