diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/App.config b/src/InvvardDev.EZLayoutDisplay.Desktop/App.config index 91b7abd6..9b76f990 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/App.config +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/App.config @@ -21,7 +21,7 @@ - https://configure.ergodox-ez.com/layouts/default/latest/0 + https://configure.ergodox-ez.com/ergodox-ez/layouts/default/latest/0 {"modifiers":[0,1,2,4],"keycode":32} diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml b/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml index a06a2aea..85070d01 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/App.xaml @@ -20,6 +20,23 @@ + + + @@ -174,6 +175,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayer.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayer.cs index d256a134..d6d64322 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayer.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayer.cs @@ -34,5 +34,10 @@ public class ErgodoxLayer /// [JsonProperty("color")] public string Color { get; set; } + + public override string ToString() + { + return $"{Title} {Position}"; + } } } \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayout.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayout.cs index e9c633f5..b565dec3 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayout.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxLayout.cs @@ -11,12 +11,24 @@ public class ErgodoxLayout [JsonProperty("hashId")] public string HashId { get; set; } + /// + /// Gets or sets the keyboard geometry. + /// + [JsonProperty("geometry")] + public string Geometry { get; set; } + /// /// Gets or sets the layout title. /// [JsonProperty("title")] public string Title { get; set; } + /// + /// Gets or sets the keyboard tags. + /// + [JsonProperty("tags", NullValueHandling = NullValueHandling.Ignore)] + public List Tags { get; set; } + /// /// Gets or sets the list of . /// diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxTag.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxTag.cs new file mode 100644 index 00000000..bda5b2b7 --- /dev/null +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/ErgodoxTag.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace InvvardDev.EZLayoutDisplay.Desktop.Model +{ + public class ErgodoxTag + { + /// + /// Gets or sets the tag name. + /// + [JsonProperty("name")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Revision.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Revision.cs index 3b72cfb1..9ebd2b67 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Revision.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Model/Revision.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Newtonsoft.Json; namespace InvvardDev.EZLayoutDisplay.Desktop.Model @@ -11,6 +12,18 @@ public class Revision [JsonProperty("hashId")] public string HashId { get; set; } + /// + /// Gets or sets the keyboard layout HEX file URL. + /// + [JsonProperty("hexUrl")] + public string HexUrl { get; set; } + + /// + /// Gets or sets the keyboard layout sources zip URL. + /// + [JsonProperty("zipUrl")] + public string SourcesUrl { get; set; } + /// /// Gets or sets the keyboard model. /// diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.Designer.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.Designer.cs index 20fee19f..d0cabd01 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.Designer.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace InvvardDev.EZLayoutDisplay.Desktop.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")] public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -25,7 +25,7 @@ public static Settings Default { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("https://configure.ergodox-ez.com/layouts/default/latest/0")] + [global::System.Configuration.DefaultSettingValueAttribute("https://configure.ergodox-ez.com/ergodox-ez/layouts/default/latest/0")] public string ErgodoxLayoutUrl { get { return ((string)(this["ErgodoxLayoutUrl"])); diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.settings b/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.settings index cea1e0ac..d45dd66c 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.settings +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Properties/Settings.settings @@ -3,7 +3,7 @@ - https://configure.ergodox-ez.com/layouts/default/latest/0 + https://configure.ergodox-ez.com/ergodox-ez/layouts/default/latest/0 {"modifiers":[0,1,2,4],"keycode":32} diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Design/LayoutService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Design/LayoutService.cs index 0e33a8db..a0c06ff3 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Design/LayoutService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Design/LayoutService.cs @@ -8,6 +8,16 @@ namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Design { public class LayoutService : ILayoutService { + public async Task GetLayoutInfo(string layoutHashId) + { + Debug.WriteLine("Layout retrieved."); + + var layoutInfo = new ErgodoxLayout(); + layoutInfo.Title = "Layout title v1.0"; + + return await new Task(() => layoutInfo); + } + /// public async Task GetErgodoxLayout(string layoutHashId) { diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs index aac4a309..4fff868e 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Implementation/LayoutService.cs @@ -15,50 +15,37 @@ namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Implementation public class LayoutService : ILayoutService { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly string GetLayoutBody = "{{\"operationName\":\"getLayout\",\"variables\":{{\"hashId\":\"{0}\"}},\"query\":\"query getLayout($hashId: String!) {{\\n Layout(hashId: $hashId) {{\\n ...LayoutData\\n }}\\n}}\\n\\nfragment LayoutData on Layout {{\\n hashId\\n title\\n revisions {{\\n hashId\\n model\\n layers {{\\n hashId\\n keys\\n position\\n title\\n color\\n }}\\n}}\\n}}\\n\"}}"; + private readonly string GetLayoutInfoRequestBody = + "{{\"operationName\":\"getLayout\",\"variables\":{{\"hashId\":\"{0}\"}},\"query\":\"query getLayout($hashId: String!) {{\\n Layout(hashId: $hashId) {{\\n ...LayoutData\\n __typename\\n }}\\n}}\\n\\nfragment LayoutData on Layout {{\\n geometry\\n hashId\\n title\\n tags {{\\n id\\n hashId\\n name\\n }}\\n revisions {{\\n hexUrl\\n model\\n zipUrl\\n layers {{\\n position\\n title\\n }}\\n }}\\n __typename\\n}}\\n\"}}"; + private const string GetLayoutRequestUri = "https://oryx.ergodox-ez.com/graphql"; #region ILayoutService implementation /// - public async Task GetErgodoxLayout(string layoutHashId) + public async Task GetLayoutInfo(string layoutHashId) { Logger.TraceMethod(); Logger.DebugInputParam(nameof(layoutHashId), layoutHashId); - if (string.IsNullOrWhiteSpace(layoutHashId)) - { - Logger.Error("Layout {0} was not found", layoutHashId); - // ReSharper disable once LocalizableElement - throw new ArgumentNullException(nameof(layoutHashId), $"Layout hash ID '{layoutHashId}' was not found."); - } - - DataRoot layout; - - using (HttpClient client = new HttpClient()) - { - var body = string.Format(GetLayoutBody, layoutHashId); - Logger.Debug("Request body : {@body}", body); - - var response = await client.PostAsync(GetLayoutRequestUri, new StringContent(body, Encoding.UTF8, "application/json")); - Logger.Debug("Response : {@response}", response); - - var result = await response.Content.ReadAsStringAsync(); - Logger.Debug("Content result : {@result}", result); + var info = await QueryData(layoutHashId, GetLayoutInfoRequestBody); + + return info; + } - layout = JsonConvert.DeserializeObject(result); - Logger.Debug("Deserialized layout : {@layout}", layout); + /// + public async Task GetErgodoxLayout(string layoutHashId) + { + Logger.TraceMethod(); + Logger.DebugInputParam(nameof(layoutHashId), layoutHashId); - if (layout?.LayoutRoot?.Layout == null) - { - Logger.Error("Layout {0} does not exist", layoutHashId); - throw new ArgumentException(layoutHashId, $"Hash ID \"{layoutHashId}\" does not exist"); - } - } + var layout = await QueryData(layoutHashId, GetLayoutBody); - return layout.LayoutRoot.Layout; + return layout; } /// @@ -80,11 +67,60 @@ public async Task> GetLayoutTemplate() IEnumerable layoutTemplate = await ReadLayoutDefinition(); return layoutTemplate; + } + + #endregion + + #region Private methods + + private async Task QueryData(string layoutHashId, string graphQlQuery) + { + ValidateLayoutHashId(layoutHashId); + + var requestBody = string.Format(graphQlQuery, layoutHashId); + + var layout = await HttpClientCall(requestBody); + + if (layout?.LayoutRoot?.Layout == null) + { + Logger.Error("Layout {0} does not exist", layoutHashId); + + throw new ArgumentException(layoutHashId, $"Hash ID \"{layoutHashId}\" does not exist"); + } + + return layout.LayoutRoot.Layout; } - #endregion + private static void ValidateLayoutHashId(string layoutHashId) + { + if (!string.IsNullOrWhiteSpace(layoutHashId)) return; - #region Private methods + Logger.Error("Layout {0} was not found", layoutHashId); + + // ReSharper disable once LocalizableElement + throw new ArgumentNullException(nameof(layoutHashId), $"Layout hash ID '{layoutHashId}' was not found."); + } + + private async Task HttpClientCall(string requestBody) + { + DataRoot layout; + + using (HttpClient client = new HttpClient()) + { + Logger.Debug("Request body : {@body}", requestBody); + + var response = await client.PostAsync(GetLayoutRequestUri, new StringContent(requestBody, Encoding.UTF8, "application/json")); + Logger.Debug("Response : {@response}", response); + + var result = await response.Content.ReadAsStringAsync(); + Logger.Debug("Content result : {@result}", result); + + layout = JsonConvert.DeserializeObject(result); + Logger.Debug("Deserialized layout : {@layout}", layout); + } + + return layout; + } private async Task> ReadLayoutDefinition() { @@ -93,16 +129,17 @@ private async Task> ReadLayoutDefinition() if (Resources.layoutDefinition.Length <= 0) { Logger.Warn("Layout definition is empty"); + return new List(); } var layoutTemplate = await Task.Run(() => { - var json = Encoding.Default.GetString(Resources.layoutDefinition); + var json = Encoding.Default.GetString(Resources.layoutDefinition); - var layoutDefinition = JsonConvert.DeserializeObject>(json); + var layoutDefinition = JsonConvert.DeserializeObject>(json); - return layoutDefinition; - }); + return layoutDefinition; + }); Logger.DebugOutputParam(nameof(layoutTemplate), layoutTemplate); diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILayoutService.cs b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILayoutService.cs index 3e413026..da07a72f 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILayoutService.cs +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Service/Interface/ILayoutService.cs @@ -6,6 +6,13 @@ namespace InvvardDev.EZLayoutDisplay.Desktop.Service.Interface { public interface ILayoutService { + /// + /// Gets the basic info. + /// + /// The layout hash ID to get. + /// The . + Task GetLayoutInfo(string layoutHashId); + /// /// Gets the . /// diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/AboutSkin.xaml b/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/AboutSkin.xaml index 1b48b310..1620afc6 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/AboutSkin.xaml +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/AboutSkin.xaml @@ -29,21 +29,4 @@ - - \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/SettingsSkin.xaml b/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/SettingsSkin.xaml new file mode 100644 index 00000000..f7213c86 --- /dev/null +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/Skins/SettingsSkin.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/InvvardDev.EZLayoutDisplay.Desktop/View/SettingsWindow.xaml b/src/InvvardDev.EZLayoutDisplay.Desktop/View/SettingsWindow.xaml index 4fd469f1..7b168a07 100644 --- a/src/InvvardDev.EZLayoutDisplay.Desktop/View/SettingsWindow.xaml +++ b/src/InvvardDev.EZLayoutDisplay.Desktop/View/SettingsWindow.xaml @@ -3,37 +3,93 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:model="clr-namespace:InvvardDev.EZLayoutDisplay.Desktop.Model" mc:Ignorable="d" Background="{StaticResource WindowBackgroundBrush}" Title="{Binding WindowTitle}" Icon="{StaticResource WindowIcon}" - Width="600" Height="100" MinWidth="500" MinHeight="100" - WindowStartupLocation="CenterScreen" ResizeMode="NoResize" + Width="630" Height="340" MinWidth="630" MinHeight="300" + WindowStartupLocation="CenterScreen" DataContext="{Binding Settings, Source={StaticResource Locator}}"> + + + + + - + +