public async Task RenderInDispatcher(AdaptiveCard card) { RenderedAdaptiveCard renderedCard = null; // Need to move the test to the UI Thread to render the card var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher; Exception dispatcherException = null; await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => { try { var renderer = new AdaptiveCardRenderer(); renderedCard = renderer.RenderAdaptiveCard(card); } catch (Exception e) { // If we throw an exception from inside the dispatcher the test infrastructure loses its // connection with the tests. Hold onto this and throw it from the main test thread so // it is reported properly as a test failure. dispatcherException = e; } }); if (dispatcherException != null) { // Rethrow any exceptions that may have happened within the dispatcher throw dispatcherException; } Assert.AreEqual(0, renderedCard.Warnings.Count); Assert.AreEqual(0, renderedCard.Errors.Count); }
public async Task <ActionResult> Details(string announcementid) { AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); if (string.IsNullOrEmpty(announcementid)) { return(HttpNotFound()); } var announcement = await Cache.Announcements.GetItemAsync(announcementid); AnnouncementDetails announcementinfo = new AnnouncementDetails(); if (announcement != null) { announcement.ShowAllDetailsButton = false; var html = announcement.GetPreviewCard(); announcement.ShowAllDetailsButton = true; RenderedAdaptiveCard renderedCard = renderer.RenderCard(html); HtmlTag cardhtml = renderedCard.Html; announcementinfo.Title = announcement.Title; announcementinfo.html = cardhtml; } return(View(announcementinfo)); }
private void RenderCard(AdaptiveCard inputCard) { try { // Convert the card to be rendered to a JSON string. JsonObject jobj = JsonObject.Parse(inputCard.ToJson().ToString()); // Render the card from the JSON object. RenderedAdaptiveCard renderedCard = _cardRendrer.RenderAdaptiveCardFromJson(jobj); // Get the FrameworkElement and attach it to our Frame element in the UI. CardFrame.Content = renderedCard.FrameworkElement; // Debugging check: Report any renderer warnings. // This includes things like an unknown element type found in the card // or the card exceeded the maximum number of supported actions, and so on. IList <IAdaptiveWarning> warnings = renderedCard.Warnings; for (int i = 0; i < warnings.Count; i++) { ResultTextBox.Text += warnings[i].Message + "\n"; } } catch (Exception ex) { // Display what went wrong. ResultTextBox.Text = ex.Message; } }
private void OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action is AdaptiveOpenUrlAction openUrlAction) { Process.Start(openUrlAction.Url.AbsoluteUri); } else if (e.Action is AdaptiveShowCardAction showCardAction) { // Action.ShowCard can be rendered inline automatically, or in "popup" mode // If the Host Config is set to Popup mode, then the app needs to show it if (Renderer.HostConfig.Actions.ShowCard.ActionMode == ShowCardActionMode.Popup) { var dialog = new ShowCardWindow(showCardAction.Title, showCardAction, Resources); dialog.Owner = this; dialog.ShowDialog(); } } else if (e.Action is AdaptiveSubmitAction submitAction) { var inputs = sender.UserInputs.AsJson(); // Merge the Action.Submit Data property with the inputs inputs.Merge(submitAction.Data); MessageBox.Show(this, JsonConvert.SerializeObject(inputs, Formatting.Indented), "SubmitAction"); } }
private void RenderCard() { cardError.Children.Clear(); cardGrid.Opacity = 0.65; try { AdaptiveCardParseResult parseResult = AdaptiveCard.FromJson(CardPayload); AdaptiveCard card = parseResult.Card; /* * // 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.Submit.positive", positiveStyle); * Renderer.Resources.Add("Adaptive.Action.Submit.other", otherStyle); */ 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); } }
public async Task ColumnFallbackAsync() { string cardStr = "{" + "\"type\": \"AdaptiveCard\"," + "\"version\": \"1.0\"," + "\"body\": [" + "{" + " \"type\": \"ColumnSet\"," + " \"columns\": [" + " {" + " \"type\": \"Column\"," + " \"items\": [" + " {" + " \"type\": \"Graph\"" + " }]," + " \"fallback\": {" + " \"type\": \"Column\"," + " \"items\": [" + " {" + " \"type\": \"TextBlock\"," + " \"text\": \"Fallback\"" + " }]" + " }" + " }]" + "}]}"; var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher; Exception testException = null; // Need to move the test to the UI Thread await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => { try { AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); RenderedAdaptiveCard renderedCard = renderer.RenderAdaptiveCardFromJsonString(cardStr); Assert.AreEqual(1, renderedCard.Warnings.Count); Assert.AreEqual("Performing fallback for element of type \"Column\" (fallback element type \"Column\")", renderedCard.Warnings[0].Message); } catch (Exception thrown) { testException = thrown; } }); if (testException != null) { throw testException; } }
public async Task OnGet() { HttpClient client = new HttpClient(); string json = await client.GetStringAsync("https://adaptivecard.azurewebsites.net/api/AppConsultAdaptiveCards?code=AzSEpdNE/P0c9OFIBjro2vSKwGIlLdBWdc53/jmR7Y9PX2l1Ks0/nQ=="); AdaptiveCardParseResult card = AdaptiveCards.AdaptiveCard.FromJson(json); AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); RenderedAdaptiveCard renderedCard = renderer.RenderCard(card.Card); // Get the output HTML AdaptiveCard = new HtmlString(renderedCard.Html.ToString()); }
private FrameworkElement Render(Cards.AdaptiveCard card, out string json) { try { RenderedAdaptiveCard rendered = renderer.RenderAdaptiveCard(Convert(card, out json)); return(rendered.FrameworkElement); } catch (Exception) { json = null; return(null); } }
private void HandleAdaptiveCardAction(RenderedAdaptiveCard renderdCard, AdaptiveActionEventArgs args) { Task.Factory.StartNew(async() => { try { if (args.Action is AdaptiveOpenUrlAction openUrlAction) { Process.Start(openUrlAction.Url.AbsoluteUri); } else if (args.Action is AdaptiveSubmitAction submitAction) { var inputs = renderdCard.UserInputs.AsJson(); var text = submitAction.Data is String data ? data : null; if (inputs.Count > 0) { //Merge the Action.Submit Data property with the inputs inputs.Merge(submitAction.Data); } object value = null; if (inputs.Count > 0) { value = inputs; } else if (text == null && submitAction.Data != null) { value = submitAction.Data; } await botService.SendMessageToBot(text, value); if (!string.IsNullOrWhiteSpace(text)) { AddMessage(listView, text, MessageType.OutgoingText); } } else { var text = args.Action.Title; await botService.SendMessageToBot(text); if (!string.IsNullOrWhiteSpace(text)) { AddMessage(listView, text, MessageType.OutgoingText); } } } catch (Exception) { } }); }
private void RenderAdaptiveCard(string jsonString) { var renderer = new AdaptiveCardRenderer(); var card = AdaptiveCard.FromJsonString(jsonString); RenderedAdaptiveCard renderedAdaptiveCard = renderer.RenderAdaptiveCard(card.AdaptiveCard); if (renderedAdaptiveCard.FrameworkElement != null) { // Get the framework element var uiCard = renderedAdaptiveCard.FrameworkElement; // Add it to your UI cardsGrid.Children.Add(uiCard); } }
private void RenderedCard_OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action is AdaptiveOpenUrlAction openUrlAction) { Process.Start(openUrlAction.Url.AbsoluteUri); } else if (e.Action is AdaptiveSubmitAction submitAction) { var inputs = sender.UserInputs.AsJson(); // Merge the Action.Submit Data property with the inputs inputs.Merge(submitAction.Data); MessageBox.Show(this, JsonConvert.SerializeObject(inputs, Formatting.Indented), "SubmitAction"); } }
public async Task <ActionResult> Duty(string code, string userEmailId) { Portal portal = new Portal(); AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); var card = await CardHelper.GetMyDetailedCard(code, userEmailId); if (card == null) { return(HttpNotFound()); } RenderedAdaptiveCard renderedCard = renderer.RenderCard(card.Content as AdaptiveCard); HtmlTag cardhtml = renderedCard.Html; portal.html = cardhtml; return(View("AdaptiveCardRenderer", portal)); }
public async Task <ActionResult> Duty(string code, string userEmailId) { Portal portal = new Portal(); AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); // var card = await CardHelper.GetMyDetailedCard(code, "10055"); // ${Debugging} var card = await CardHelper.GetMyDetailedCard(code, userEmailId, configuration); if (card == null) { return(StatusCode(404)); } RenderedAdaptiveCard renderedCard = renderer.RenderCard(card.Content as AdaptiveCard); HtmlTag cardhtml = renderedCard.Html; portal.html = cardhtml; return(View("AdaptiveCardRenderer", portal)); }
private async void RenderResult_OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action.ActionType == ActionType.OpenUrl) { _userActivity.ActivationUri = new Uri("adaptivecards://openLastPost"); _userActivity.VisualElements.DisplayText = "Windows AppConsult blog"; _userActivity.VisualElements.Content = AdaptiveCardBuilder.CreateAdaptiveCardFromJson(json); await _userActivity.SaveAsync(); _userActivitySession?.Dispose(); _userActivitySession = _userActivity.CreateSession(); var action = e.Action as AdaptiveOpenUrlAction; await Launcher.LaunchUriAsync(action.Url); } }
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); } }
private void RenderedCard_OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action is AdaptiveSubmitAction submitAction) { var viewModel = DataContext as MainViewModel; if (submitAction.Id == "Ok") { viewModel.ShowAdaptiveCard = false; return; } var inputs = sender.UserInputs.AsDictionary(); var notes = inputs["Notes"]; viewModel.UpdateNotes(notes); viewModel.ShowAdaptiveCard = false; sender.OnAction -= RenderedCard_OnAction; } }
private void RenderCard(AdaptiveCard adaptiveCard) { if (_renderedCard != null) { _renderedCard.OnAction -= OnCardAction; } if (adaptiveCard == null) { _renderedCard = null; RenderedCardContent = null; return; } _renderedCard = Renderer.RenderCard(adaptiveCard); _renderedCard.OnAction += OnCardAction; RenderedCardContent = _renderedCard.FrameworkElement; }
private async void RenderResult_OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action.Type == "Action.OpenUrl") { if (_desktopBridgeHelpers.IsRunningAsUwp()) { _userActivity.ActivationUri = new Uri("adaptivecards://openLastPost"); _userActivity.VisualElements.DisplayText = "Windows AppConsult blog"; _userActivity.VisualElements.Content = AdaptiveCardBuilder.CreateAdaptiveCardFromJson(json); await _userActivity.SaveAsync(); _userActivitySession?.Dispose(); _userActivitySession = _userActivity.CreateSession(); } var action = e.Action as AdaptiveOpenUrlAction; Process.Start(action.Url.ToString()); } }
private void OnAction(RenderedAdaptiveCard sender, AdaptiveActionEventArgs e) { if (e.Action is AdaptiveOpenUrlAction openUrlAction) { Process.Start(openUrlAction.Url); } else if (e.Action is AdaptiveShowCardAction showCardAction) { if (Renderer.HostConfig.Actions.ShowCard.ActionMode == ShowCardActionMode.Popup) { var dialog = new ShowCardWindow(showCardAction.Title, showCardAction, Resources); dialog.Owner = this; dialog.ShowDialog(); } } else if (e.Action is AdaptiveSubmitAction submitAction) { var inputs = sender.UserInputs.AsJson(); inputs.Merge(submitAction.Data); MessageBox.Show(this, JsonConvert.SerializeObject(inputs, Formatting.Indented), "SubmitAction"); } }
private void UpdateAdaptiveCard(ItemViewModel item) { _cardTitleTextBlock.Text = $"{item.Name}, expected to start at " + $"{item.DevelopmentStartDate.ToShortDateString()} and completed at " + $"{item.ExpectedCompletionDate.ToShortDateString()}."; if (_renderedCard != null) { adaptiveCardContainer.Children.Clear(); _renderedCard.OnAction -= RenderedCard_OnAction; _renderedCard = null; } try { _renderedCard = _renderer.RenderCard(_card); _renderedCard.OnAction += RenderedCard_OnAction; adaptiveCardContainer.Children.Add(_renderedCard.FrameworkElement); } catch (AdaptiveException exception) { Debug.WriteLine(exception); } }
public void OnAction(BaseActionElement element, RenderedAdaptiveCard renderedCard) { }
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)); }
public static async Task <RenderedTestResult> RenderCard(FileViewModel cardFile, FileViewModel hostConfigFile, Dictionary <string, IAdaptiveCardResourceResolver> resourceResolvers) { string error = null; string roundTrippedJsonString = null; FrameworkElement xaml = null; double cardWidth = 400; WeakReference weakRefCard = null; try { AdaptiveHostConfig hostConfig = AdaptiveHostConfig.FromJsonString(hostConfigFile.Contents).HostConfig; if (hostConfig == null) { error = "Parsing hostConfig failed"; } else { AdaptiveCard card = AdaptiveCard.FromJsonString(cardFile.Contents).AdaptiveCard; if (card == null) { error = "Parsing card failed"; } else { roundTrippedJsonString = card.ToJson().ToString(); card = AdaptiveCard.FromJsonString(roundTrippedJsonString).AdaptiveCard; AdaptiveFeatureRegistration featureRegistration = new AdaptiveFeatureRegistration(); featureRegistration.Set("acTest", "1.0"); var renderer = new AdaptiveCardRenderer() { HostConfig = hostConfig, FeatureRegistration = featureRegistration }; foreach (var resourceResolver in resourceResolvers) { renderer.ResourceResolvers.Set(resourceResolver.Key, resourceResolver.Value); } if (hostConfigFile.Name.Contains("windows-timeline")) { renderer.SetFixedDimensions(320, 180); cardWidth = 320; } else if (hostConfigFile.Name.Contains("windows-live-tile")) { renderer.SetFixedDimensions(310, 310); cardWidth = 310; } RenderedAdaptiveCard renderedCard = renderer.RenderAdaptiveCard(card); weakRefCard = new WeakReference(renderedCard); xaml = renderedCard.FrameworkElement as FrameworkElement; if (xaml == null) { error = "Rendering card failed"; } else { xaml = new Border() { Background = new SolidColorBrush(Colors.White), Child = xaml, IsHitTestVisible = false // Disable HitTest so that mouse pointer can't accidently hover over a button }; // The theme is important to set since it'll ensure buttons/inputs appear correctly if (hostConfigFile.Name.Contains("windows-notification")) { xaml.RequestedTheme = ElementTheme.Dark; } else { xaml.RequestedTheme = ElementTheme.Light; } } } } } catch (Exception ex) { error = ex.ToString(); } return(new RenderedTestResult { Error = error, RoundTrippedJSON = roundTrippedJsonString, Tree = xaml, CardWidth = cardWidth, WeakCard = weakRefCard }); }
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)); }
public async Task <IActionResult> Register([FromBody] RegistrationBindingModel registrationBindingModel) { HtmlTag htmlTag = new HtmlTag("", true); if (string.IsNullOrWhiteSpace(registrationBindingModel.EmailAddress)) { return(BadRequest(new GenericViewModel { Message = "Email Address needs to supplied." })); } if (string.IsNullOrWhiteSpace(registrationBindingModel.PhoneNumber)) { return(BadRequest(new GenericViewModel { Message = "Phone Number needs to supplied." })); } var attendee = await _context.Attendees.FirstOrDefaultAsync(x => x.EmailAddress == registrationBindingModel.EmailAddress); if (attendee != null) { var response = StatusCode((int)HttpStatusCode.Conflict, new GenericViewModel { Message = "Sorry, a user with that email address has been registered." }); return(response); } attendee = new Models.Data.Attendee { FirstName = registrationBindingModel.FirstName, LastName = registrationBindingModel.LastName, EmailAddress = registrationBindingModel.EmailAddress, RegistrationDate = DateTime.Now }; // Create a card renderer AdaptiveCardRenderer renderer = new AdaptiveCardRenderer(); // For fun, check the schema version this renderer supports AdaptiveSchemaVersion schemaVersion = renderer.SupportedSchemaVersion; // 1.0 // Build a simple card // In the real world this would probably be provided as JSON AdaptiveCard card = new AdaptiveCard() { Body = new List <AdaptiveElement>() { new AdaptiveContainer() { }, new AdaptiveContainer() { } }, Actions = new List <AdaptiveAction>() { new AdaptiveOpenUrlAction() { }, new AdaptiveOpenUrlAction() { } } }; try { // Render the card RenderedAdaptiveCard renderedCard = renderer.RenderCard(card); // Get the output HTML htmlTag = renderedCard.Html; // (Optional) Check for any renderer warnings // This includes things like an unknown element type found in the card // Or the card exceeded the maxmimum number of supported actions, etc IList <AdaptiveWarning> warnings = renderedCard.Warnings; } catch (AdaptiveException ex) { // Failed rendering } var _Attendee = _context.Attendees.Add(attendee); await _context.SaveChangesAsync(); await Services.EmailService.SendRegistrationEmail(attendee, htmlTag); return(Created($"http://events.windforcecorp.com/{_Attendee.Entity.AttendeeID.ToString()}", _Attendee)); }
private void RenderedCard_OnMediaClicked(RenderedAdaptiveCard sender, AdaptiveMediaEventArgs e) { MessageBox.Show(this, JsonConvert.SerializeObject(e.Media), "Host received Media"); }
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)); }
public void OnAction(BaseActionElement p0, RenderedAdaptiveCard p1) { Console.WriteLine("Action!!"); }
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); } }
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)) { RenderedAdaptiveCard renderResult = _renderer.RenderAdaptiveCardFromJson(jsonObject); 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(); }; } else { newErrors.Add(new ErrorViewModel() { Message = "There was an error Rendering this card", Type = ErrorViewModelType.Error }); } } 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); } }