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