diff --git a/src/DynamoCore/Configuration/PreferenceSettings.cs b/src/DynamoCore/Configuration/PreferenceSettings.cs index b004a7937bc..bb493588e62 100644 --- a/src/DynamoCore/Configuration/PreferenceSettings.cs +++ b/src/DynamoCore/Configuration/PreferenceSettings.cs @@ -395,6 +395,21 @@ public bool IsBackgroundPreviewActive /// public bool UseHardwareAcceleration { get; set; } + /// + /// Persistence for Dynamo HomePage + /// + [XmlIgnore] + internal Dictionary HomePageSettings { get; set; } + + /// + /// A helper intermediary string to allow the serialization of the HomePageSettings dictionary + /// + public string HomePageSettingsSerialized + { + get => Newtonsoft.Json.JsonConvert.SerializeObject(HomePageSettings); + set => HomePageSettings = Newtonsoft.Json.JsonConvert.DeserializeObject>(value); + } + #endregion #region Dynamo application settings diff --git a/src/DynamoCore/PublicAPI.Unshipped.txt b/src/DynamoCore/PublicAPI.Unshipped.txt index b2d6700c3d2..2e098c9d56a 100644 --- a/src/DynamoCore/PublicAPI.Unshipped.txt +++ b/src/DynamoCore/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -abstract Dynamo.Extensions.LinterExtensionBase.Name.get -> string +abstract Dynamo.Extensions.LinterExtensionBase.Name.get -> string abstract Dynamo.Extensions.LinterExtensionBase.Shutdown() -> void abstract Dynamo.Extensions.LinterExtensionBase.UniqueId.get -> string abstract Dynamo.Graph.ModelBase.DeserializeCore(System.Xml.XmlElement nodeElement, Dynamo.Graph.SaveContext context) -> void @@ -177,6 +177,8 @@ Dynamo.Configuration.PreferenceSettings.HideAutocompleteMethodOptions.get -> boo Dynamo.Configuration.PreferenceSettings.HideAutocompleteMethodOptions.set -> void Dynamo.Configuration.PreferenceSettings.HideNodesBelowSpecificConfidenceLevel.get -> bool Dynamo.Configuration.PreferenceSettings.HideNodesBelowSpecificConfidenceLevel.set -> void +Dynamo.Configuration.PreferenceSettings.HomePageSettingsSerialized.get -> string +Dynamo.Configuration.PreferenceSettings.HomePageSettingsSerialized.set -> void Dynamo.Configuration.PreferenceSettings.IronPythonResolveTargetVersion.get -> string Dynamo.Configuration.PreferenceSettings.IronPythonResolveTargetVersion.set -> void Dynamo.Configuration.PreferenceSettings.IsADPAnalyticsReportingApproved.get -> bool @@ -3139,4 +3141,4 @@ virtual Dynamo.Search.SearchElements.NodeSearchElement.FullName.get -> string virtual Dynamo.Search.SearchElements.NodeSearchElement.GenerateInputParameters() -> System.Collections.Generic.IEnumerable> virtual Dynamo.Search.SearchElements.NodeSearchElement.GenerateOutputParameters() -> System.Collections.Generic.IEnumerable virtual Dynamo.Search.SearchElements.NodeSearchElement.OnItemProduced(Dynamo.Graph.Nodes.NodeModel obj) -> void -virtual Dynamo.Search.SearchElements.SearchElementBase.CreationName.get -> string \ No newline at end of file +virtual Dynamo.Search.SearchElements.SearchElementBase.CreationName.get -> string diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt index 7f679dae94e..c2b9dc8a7ca 100644 --- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt +++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt @@ -1574,7 +1574,8 @@ Dynamo.UI.Views.ScriptHomeObject.NewCustomNodeWorkspace() -> void Dynamo.UI.Views.ScriptHomeObject.NewWorkspace() -> void Dynamo.UI.Views.ScriptHomeObject.OpenFile(string path) -> void Dynamo.UI.Views.ScriptHomeObject.OpenWorkspace() -> void -Dynamo.UI.Views.ScriptHomeObject.ScriptHomeObject(System.Action requestOpenFile, System.Action requestNewWorkspace, System.Action requestOpenWorkspace, System.Action requestNewCustomNodeWorkspace, System.Action requestApplicationLoaded, System.Action requestShowGuidedTour, System.Action requestShowSampleFilesInFolder, System.Action requestShowBackupFilesInFolder, System.Action requestShowTemplate) -> void +Dynamo.UI.Views.ScriptHomeObject.SaveSettings(string settings) -> void +Dynamo.UI.Views.ScriptHomeObject.ScriptHomeObject(System.Action requestOpenFile, System.Action requestNewWorkspace, System.Action requestOpenWorkspace, System.Action requestNewCustomNodeWorkspace, System.Action requestApplicationLoaded, System.Action requestShowGuidedTour, System.Action requestShowSampleFilesInFolder, System.Action requestShowBackupFilesInFolder, System.Action requestShowTemplate, System.Action requestSaveSettings) -> void Dynamo.UI.Views.ScriptHomeObject.ShowBackupFilesInFolder() -> void Dynamo.UI.Views.ScriptHomeObject.ShowSampleFilesInFolder() -> void Dynamo.UI.Views.ScriptHomeObject.ShowTempalte() -> void diff --git a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs index fd772baa870..eec44259825 100644 --- a/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs +++ b/src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs @@ -53,6 +53,7 @@ public partial class HomePage : UserControl, IDisposable internal Action RequestShowSampleFilesInFolder; internal Action RequestShowBackupFilesInFolder; internal Action RequestShowTemplate; + internal Action RequestSaveSettings; internal List GuidedTourItems; @@ -83,6 +84,7 @@ public HomePage() RequestShowBackupFilesInFolder = ShowBackupFilesInFolder; RequestShowTemplate = ShowTemplate; RequestApplicationLoaded = ApplicationLoaded; + RequestSaveSettings = SaveSettings; DataContextChanged += OnDataContextChanged; @@ -193,7 +195,8 @@ private async void UserControl_Loaded(object sender, System.Windows.RoutedEventA RequestShowGuidedTour, RequestShowSampleFilesInFolder, RequestShowBackupFilesInFolder, - RequestShowTemplate)); + RequestShowTemplate, + RequestSaveSettings)); } catch (ObjectDisposedException ex) { @@ -238,25 +241,14 @@ internal bool ProcessUri(string uri) return false; } - internal async void LoadingDone() + internal void LoadingDone() { - SendGuidesData(); - if (startPage == null) { return; } + SendGuidesData(); SendSamplesData(); - - var recentFiles = startPage.RecentFiles; - if (recentFiles == null || !recentFiles.Any()) { return; } - - LoadGraphs(recentFiles); - - var userLocale = CultureInfo.CurrentCulture.Name; - - if (dynWebView?.CoreWebView2 != null) - { - await dynWebView.CoreWebView2.ExecuteScriptAsync(@$"window.setLocale('{userLocale}');"); - } + SendRecentGraphsData(); + SetLocale(); } #region FrontEnd Initialization Calls @@ -289,6 +281,37 @@ private async void SendSamplesData() } } + private async void SendRecentGraphsData() + { + // Send user preferences + if (dynWebView?.CoreWebView2 != null) + { + if (startPage.DynamoViewModel.PreferenceSettings.HomePageSettings != null) + { + var settingsJson = Newtonsoft.Json.JsonConvert.SerializeObject(startPage.DynamoViewModel.PreferenceSettings.HomePageSettings); + settingsJson = System.Web.HttpUtility.JavaScriptStringEncode(settingsJson); + + await dynWebView.CoreWebView2.ExecuteScriptAsync(@$"window.setHomePageSettings('{settingsJson}');"); + } + } + + // Load recent files + var recentFiles = startPage.RecentFiles; + if (recentFiles != null && recentFiles.Any()) + { + LoadGraphs(recentFiles); + } + } + + private async void SetLocale() + { + var userLocale = CultureInfo.CurrentCulture.Name; + + if (dynWebView?.CoreWebView2 != null) + { + await dynWebView.CoreWebView2.ExecuteScriptAsync(@$"window.setLocale('{userLocale}');"); + } + } /// /// Sends guided tour data to react app @@ -402,6 +425,34 @@ internal void StartGuidedTour(string path) ShowGuidedTour(path); } + internal void SaveSettings(string settingsJson) + { + if (!string.IsNullOrEmpty(settingsJson) && this.startPage != null) + { + var settingsDict = Newtonsoft.Json.JsonConvert.DeserializeObject>(settingsJson); + + // If the HomePageSettings have not been previously created, initialize it now + if (startPage.DynamoViewModel.PreferenceSettings.HomePageSettings == null) + { + startPage.DynamoViewModel.PreferenceSettings.HomePageSettings = new Dictionary(); + } + + // Change existing values, or add new ones + foreach (var setting in settingsDict) + { + if (startPage.DynamoViewModel.PreferenceSettings.HomePageSettings.ContainsKey(setting.Key) + && startPage.DynamoViewModel.PreferenceSettings.HomePageSettings[setting.Key] != setting.Value) + { + startPage.DynamoViewModel.PreferenceSettings.HomePageSettings[setting.Key] = setting.Value; + } + else + { + startPage.DynamoViewModel.PreferenceSettings.HomePageSettings.Add(setting.Key, setting.Value); + } + } + } + } + internal void NewWorkspace() { this.startPage?.DynamoViewModel?.NewHomeWorkspaceCommand.Execute(null); @@ -506,6 +557,7 @@ public class ScriptHomeObject readonly Action RequestShowSampleFilesInFolder; readonly Action RequestShowBackupFilesInFolder; readonly Action RequestShowTemplate; + readonly Action RequestSaveSettings; public ScriptHomeObject(Action requestOpenFile, Action requestNewWorkspace, @@ -515,7 +567,8 @@ public ScriptHomeObject(Action requestOpenFile, Action requestShowGuidedTour, Action requestShowSampleFilesInFolder, Action requestShowBackupFilesInFolder, - Action requestShowTemplate) + Action requestShowTemplate, + Action requestSaveSettings) { RequestOpenFile = requestOpenFile; RequestNewWorkspace = requestNewWorkspace; @@ -526,7 +579,7 @@ public ScriptHomeObject(Action requestOpenFile, RequestShowSampleFilesInFolder = requestShowSampleFilesInFolder; RequestShowBackupFilesInFolder = requestShowBackupFilesInFolder; RequestShowTemplate = requestShowTemplate; - + RequestSaveSettings = requestSaveSettings; } [DynamoJSInvokable] public void OpenFile(string path) @@ -574,7 +627,11 @@ public void ApplicationLoaded() { RequestApplicationLoaded(); } - + [DynamoJSInvokable] + public void SaveSettings(string settings) + { + RequestSaveSettings(settings); + } } public enum GuidedTourType diff --git a/test/DynamoCoreTests/Configuration/PreferenceSettingsTests.cs b/test/DynamoCoreTests/Configuration/PreferenceSettingsTests.cs index 9d0ae696e33..e92b1e4c408 100644 --- a/test/DynamoCoreTests/Configuration/PreferenceSettingsTests.cs +++ b/test/DynamoCoreTests/Configuration/PreferenceSettingsTests.cs @@ -479,5 +479,27 @@ public void TestSanitizeValues() Assert.IsTrue(allTheGroupStylesHaveAValidFontSize, $"All the GroupStyles have a valid Font size : {allTheGroupStylesHaveAValidFontSize}"); } + + [Test] + [Category("UnitTests")] + public void TestSerializingHomePageSettings() + { + string tempPath = System.IO.Path.GetTempPath(); + tempPath = Path.Combine(tempPath, "homePagePreference.xml"); + + PreferenceSettings settings = new PreferenceSettings(); + + // Assert defaults + Assert.AreEqual(settings.HomePageSettings, null); + Assert.AreEqual(settings.HomePageSettingsSerialized, "null"); + + settings.HomePageSettings = new Dictionary { { "greeting", "Hello World" } }; + + // Save + settings.Save(tempPath); + settings = PreferenceSettings.Load(tempPath); + + Assert.AreEqual(settings.HomePageSettings["greeting"], "Hello World"); + } } } diff --git a/test/DynamoCoreWpfTests/HomePageTests.cs b/test/DynamoCoreWpfTests/HomePageTests.cs index 079f1af90b2..072a8da8983 100644 --- a/test/DynamoCoreWpfTests/HomePageTests.cs +++ b/test/DynamoCoreWpfTests/HomePageTests.cs @@ -53,6 +53,36 @@ public void ActionDelegates_ShouldBeProperlySetAfterConstruction() Assert.IsNotNull(homePage.RequestShowBackupFilesInFolder); Assert.IsNotNull(homePage.RequestShowTemplate); } + + [Test] + public void HomePage_NewSettingsAreAddedCorrectly() + { + // Arrange + var vm = View.DataContext as DynamoViewModel; + var startPage = new StartPageViewModel(vm, true); + var preferences = startPage.DynamoViewModel.PreferenceSettings; + var homePage = new HomePage(); + + homePage.DataContext = startPage; + + Assert.IsNull(preferences.HomePageSettings); + + // Act + var pair1 = @"{""Name"": ""Alice""}"; + homePage.SaveSettings(pair1); + + // Assert + Assert.IsNotNull(preferences.HomePageSettings); + Assert.AreEqual(preferences.HomePageSettings.Count, 1); + + // Act + var pair2 = @"{""Number"": 12 }"; + homePage.SaveSettings(pair2); + + // Assert + Assert.AreEqual(preferences.HomePageSettings.Count, 2); + } + #endregion #region integration tests