using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using AdaptiveCards.Rendering.Uwp;
using Monaco;
using Monaco.Helpers;
using Newtonsoft.Json;
// probs don't need these
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Monaco.Editor;
using Monaco.Languages;
using Newtonsoft.Json.Linq;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace Adaptive_Card_Editor_UWP
{
///
/// An empty page that can be used on its own or navigated to within a Frame.
///
public sealed partial class MainPage : Page
{
///
/// Create DispatcherTimer for handling input delay logic
///
public DispatcherTimer keyTimer = new DispatcherTimer();
///
/// timestamp in ticks (hundred nanoseconds) of last captured KeyUp event
///
public long lastKeyUp;
///
/// boolean indicating whether input has changed since last tick
///
public bool isRendered;
///
/// timer interval in ticks (hundred nanoseconds)
///
public long interval = 5000000;
///
/// list of known entities that contain templated content
///
///
/// If the data referenced in the container doesn't exist, the container shouldn't be included in the rendered output
///
public List Containers = new List
{
"ActionSet",
"Container",
"ColumnSet",
"Column",
"FactSheet",
"Fact",
"ImageSet"
};
public MainPage()
{
// set up a window timer for handling the keyup delay
TimerSetup();
this.InitializeComponent();
}
///
/// Sets up a window timer with a 500ms tick interval and starts the timer
///
public void TimerSetup()
{
// on every timer tick, run TimerTick()
keyTimer.Tick += TimerTick;
// set the timer interval to half a second
keyTimer.Interval = TimeSpan.Parse("00:00:00.05");
// start the timer
keyTimer.Start();
}
///
/// fires when txtInput sees keyboard input
///
private void txtInput_KeyDown(CodeEditor sender, WebKeyEventArgs e)
{
// last key up event = integer value of current time
lastKeyUp = DateTime.Now.Ticks;
// user is inputting text, so we're going to rerender
isRendered = false;
}
///
/// fires when txtData sees keyboard input
///
private void txtData_KeyDown(CodeEditor sender, WebKeyEventArgs args)
{
// last key up event = integer value of current time
lastKeyUp = DateTime.Now.Ticks;
// user is inputting text, so we're going to rerender
isRendered = false;
}
///
/// Fires when the timer ticks
///
void TimerTick(object sender, object args)
{
// if isRendered is true, there have been no changes to input since the last tick
if (isRendered)
{
return;
}
// otherwise, we done got input, so do the thing
else
{
if (DateTime.Now.Ticks >= lastKeyUp + interval )
{
// we done got some input! let's render it.
// we don't care what the input is; if it's not valid JSON ignore this keystroke
// render the text as a plain textbox
TextBlock txtOutput = new TextBlock();
txtOutput.TextWrapping = TextWrapping.Wrap;
txtOutput.Padding = new Thickness(10);
txtOutput.Text = txtInput.Text;
// clear the grid of existing content
grdCard.Children.Clear();
// render an adaptive card
try
{
AdaptiveCardRenderer cardRenderer = new AdaptiveCardRenderer();
AdaptiveCardParseResult parsedCard = AdaptiveCard.FromJsonString(txtInput.Text);
RenderedAdaptiveCard theCard = cardRenderer.RenderAdaptiveCard(parsedCard.AdaptiveCard);
grdCard.Children.Add(theCard.FrameworkElement);
}
catch (Exception ex)
{
// this means bad data was ingested by the adaptive card renderer
// so just display the exception details
txtOutput.Text = ex.ToString();
grdCard.Children.Add(txtOutput);
}
// render a card using template and data
try
{
string Template = txtInput.Text;
string Data = txtData.Text;
string Rendered = JsonFromTemplate(Template, Data);
// render the card from the rendered template + data
AdaptiveCardRenderer cardRenderer = new AdaptiveCardRenderer();
AdaptiveCardParseResult parsedCard = AdaptiveCard.FromJsonString(Rendered);
RenderedAdaptiveCard theCard = cardRenderer.RenderAdaptiveCard(parsedCard.AdaptiveCard);
grdTemplated.Children.Add(theCard.FrameworkElement);
}
catch (Exception ex)
{
// this means bad data was ingested by the adaptive card renderer
// so just display the exception details
txtOutput.Text = ex.ToString();
grdTemplated.Children.Add(txtOutput);
}
grdCard.UpdateLayout();
isRendered = true;
}
else
{
return;
}
}
}
///
/// Creates an adaptive card JSON payload from a template and data model. Follows the official templating language.
///
/// JSON adaptive card template
/// JSON data model
/// JSON string to be ingested by adaptive card renderer
public string JsonFromTemplate(string strTemplate, string strData)
{
string output = "";
// first create JSON objects out of the input
JObject Template = JObject.Parse(strTemplate);
JObject Data = JObject.Parse(strData);
return output;
}
}
}