From 5d1a1b224d5d844ead7ff62645de80540ab5342d Mon Sep 17 00:00:00 2001 From: Deyan Nenov Date: Thu, 17 Aug 2023 13:10:30 +0100 Subject: [PATCH 1/7] cherry-picking package details extension functionality - merging existing functionality for the package details extension --- .../Search/BrowserInternalElement.cs | 7 +- .../Controls/InstalledPackagesControl.xaml | 13 +- .../Properties/Resources.Designer.cs | 18 + .../Properties/Resources.en-US.resx | 8 +- src/DynamoCoreWpf/Properties/Resources.resx | 8 +- .../PackageManagerSearchViewModel.cs | 90 ++++ .../PackageManagerPackagesControl.xaml.cs | 31 +- .../Controls/PackageManagerSearchControl.xaml | 450 ++++++++++-------- .../PackageManager/PackageManagerView.xaml | 53 ++- .../PackageDetailsView.xaml | 22 + .../PackageDetailsView.xaml.cs | 11 + .../PackageDetailsViewExtension.cs | 89 +++- 12 files changed, 570 insertions(+), 230 deletions(-) diff --git a/src/DynamoCore/Search/BrowserInternalElement.cs b/src/DynamoCore/Search/BrowserInternalElement.cs index d8e90c812d3..2b2d42fdaf4 100644 --- a/src/DynamoCore/Search/BrowserInternalElement.cs +++ b/src/DynamoCore/Search/BrowserInternalElement.cs @@ -1,4 +1,4 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; namespace Dynamo.Search { @@ -29,6 +29,11 @@ public class BrowserInternalElement : BrowserItem /// public BrowserItem OldParent { get; set; } + /// + /// The framework element hosting the extension + /// + public object UIParent { get; set; } + internal void ReturnToOldParent() { if (this.OldParent == null) return; diff --git a/src/DynamoCoreWpf/Controls/InstalledPackagesControl.xaml b/src/DynamoCoreWpf/Controls/InstalledPackagesControl.xaml index b2c874a7a9b..a95cdf54732 100644 --- a/src/DynamoCoreWpf/Controls/InstalledPackagesControl.xaml +++ b/src/DynamoCoreWpf/Controls/InstalledPackagesControl.xaml @@ -28,7 +28,7 @@ - + @@ -36,8 +36,9 @@ @@ -70,9 +71,10 @@ - + diff --git a/src/DynamoCoreWpf/Properties/Resources.Designer.cs b/src/DynamoCoreWpf/Properties/Resources.Designer.cs index 3de5f72a46b..ed1cc7e1c0f 100644 --- a/src/DynamoCoreWpf/Properties/Resources.Designer.cs +++ b/src/DynamoCoreWpf/Properties/Resources.Designer.cs @@ -5537,6 +5537,15 @@ public static string PackageManagerInstall { } } + /// + /// Looks up a localized string similar to packageManagerMyPackages. + /// + public static string PackageManagerMyPackagesControlName { + get { + return ResourceManager.GetString("PackageManagerMyPackagesControlName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Deprecated. /// @@ -5564,6 +5573,15 @@ public static string PackageManagerPackageUpdated { } } + /// + /// Looks up a localized string similar to packageManagerSearchPackages. + /// + public static string PackageManagerSearchPackagesControlName { + get { + return ResourceManager.GetString("PackageManagerSearchPackagesControlName", resourceCulture); + } + } + /// /// Looks up a localized string similar to The name of the package cannot contain. /// diff --git a/src/DynamoCoreWpf/Properties/Resources.en-US.resx b/src/DynamoCoreWpf/Properties/Resources.en-US.resx index b6fb25f11b9..97b67e71ebd 100644 --- a/src/DynamoCoreWpf/Properties/Resources.en-US.resx +++ b/src/DynamoCoreWpf/Properties/Resources.en-US.resx @@ -2874,6 +2874,12 @@ This package will be unloaded after the next Dynamo restart. New Displays next to the package name in the Package Search window if the package has been added in the last 30 days. + + packageManagerSearchPackages + + + packageManagerMyPackages + DESCRIPTION Header in the PackageDetailsViewExtension. @@ -3651,4 +3657,4 @@ In certain complex graphs or host program scenarios, Automatic mode may cause in When toggled on, file names of exported images include date and time of export. - \ No newline at end of file + diff --git a/src/DynamoCoreWpf/Properties/Resources.resx b/src/DynamoCoreWpf/Properties/Resources.resx index b7e469db40e..90b591fa041 100644 --- a/src/DynamoCoreWpf/Properties/Resources.resx +++ b/src/DynamoCoreWpf/Properties/Resources.resx @@ -1259,6 +1259,12 @@ Don't worry, you'll have the option to save your work. New Displays next to the package name in the Package Search window if the package has been added in the last 30 days. + + packageManagerSearchPackages + + + packageManagerMyPackages + DESCRIPTION Header in the PackageDetailsViewExtension. @@ -3638,4 +3644,4 @@ In certain complex graphs or host program scenarios, Automatic mode may cause in When toggled on, file names of exported images include date and time of export. - \ No newline at end of file + diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index 175629e795d..29180d231f2 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Linq; using System.Threading.Tasks; +using System.Timers; using System.Windows; using System.Windows.Input; using Dynamo.Configuration; @@ -371,6 +372,25 @@ public PackageSearchState SearchState RaisePropertyChanged(nameof(this.SearchState)); RaisePropertyChanged(nameof(this.SearchBoxPrompt)); RaisePropertyChanged(nameof(this.ShowSearchText)); + + if (value == PackageSearchState.Results && !this.InitialResultsLoaded) + { + this.InitialResultsLoaded = true; + } + } + } + + private bool _initialResultsLoaded = false; + /// + /// Will only be set to true once after the initial search has been finished. + /// + public bool InitialResultsLoaded + { + get { return _initialResultsLoaded; } + set + { + _initialResultsLoaded = value; + RaisePropertyChanged(nameof(InitialResultsLoaded)); } } @@ -445,6 +465,19 @@ public IPreferences Preferences get { return PackageManagerClientViewModel.DynamoViewModel.PreferenceSettings; } } + private bool isDetailPackagesExtensionOpened; + public bool IsDetailPackagesExtensionOpened + { + get { return isDetailPackagesExtensionOpened; } + set + { + if (isDetailPackagesExtensionOpened != value) + { + isDetailPackagesExtensionOpened = value; + RaisePropertyChanged(nameof(IsDetailPackagesExtensionOpened)); + } + } + } #endregion Properties & Fields internal PackageManagerSearchViewModel() @@ -816,6 +849,8 @@ public IEnumerable RefreshAndSearch() public void RefreshAndSearchAsync() { + StartTimer(); // Times out according to MAX_LOAD_TIME + this.ClearSearchResults(); this.SearchState = PackageSearchState.Syncing; @@ -835,6 +870,7 @@ public void RefreshAndSearchAsync() this.AddToSearchResults(result); } this.SearchState = HasNoResults ? PackageSearchState.NoResults : PackageSearchState.Results; + TimedOut = false; if (!DynamoModel.IsTestMode) { @@ -852,6 +888,50 @@ public void RefreshAndSearchAsync() , TaskScheduler.FromCurrentSynchronizationContext()); // run continuation in ui thread } + #region Time Out + + // maximum loading time for packages - 30 seconds + // if exceeded will trigger `timed out` event and failure screen + internal int MAX_LOAD_TIME = 30 * 1000; + private bool _timedOut; + /// + /// Will trigger timed out event + /// + public bool TimedOut + { + get { return _timedOut; } + set + { + _timedOut = value; + RaisePropertyChanged(nameof(TimedOut)); + } + } + + private void StartTimer() + { + var aTimer = new System.Timers.Timer(); + aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); + aTimer.Interval = MAX_LOAD_TIME; + aTimer.AutoReset = false; + aTimer.Enabled = true; + } + + private void OnTimedEvent(object sender, ElapsedEventArgs e) + { + var aTimer = (System.Timers.Timer)sender; + aTimer.Dispose(); + + // If we have managed to get all the results + // Simply dispose of the timer + // Otherwise act + if (this.SearchState != PackageSearchState.Results) + { + TimedOut = true; + } + } + + #endregion + internal void RefreshInfectedPackages() { //do not call a protected route, if user is not logged in already. @@ -1319,5 +1399,15 @@ public void DisableSearchTextBox() RequestDisableTextSearch(null, null); } } + + /// + /// Clear after closing down + /// + internal void Close() + { + TimedOut = false; // reset the timedout screen + InitialResultsLoaded = false; // reset the loading screen settings + RequestShowFileDialog -= OnRequestShowFileDialog; + } } } diff --git a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerPackagesControl.xaml.cs b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerPackagesControl.xaml.cs index b30925c1f78..780e6990c79 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerPackagesControl.xaml.cs +++ b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerPackagesControl.xaml.cs @@ -1,8 +1,9 @@ -using Dynamo.PackageManager.ViewModels; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; +using Dynamo.PackageManager.ViewModels; +using Dynamo.Utilities; namespace Dynamo.PackageManager.UI { @@ -89,6 +90,34 @@ private void ViewDetailsButton_OnClick(object sender, RoutedEventArgs e) if (!(button.DataContext is PackageManagerSearchElementViewModel packageManagerSearchElementViewModel)) return; var PkgSearchVM = this.DataContext as PackageManagerSearchViewModel; + + var name = this.Name; + if (name.Equals(Dynamo.Wpf.Properties.Resources.PackageManagerSearchPackagesControlName)) + { + var parent = WpfUtilities.FindUpVisualTree(this) as PackageManagerSearchControl; + if (parent == null) return; + + packageManagerSearchElementViewModel.Model.UIParent = parent.packageDetailsGrid; + if (parent.packageDetailsGrid.Width.Value <= 1.0) + { + var width = (parent.packageDetailsGrid.Parent as Grid).ActualWidth * 0.5; + parent.packageDetailsGrid.Width = new GridLength(width, GridUnitType.Pixel); + } + } + else if (name.Equals(Dynamo.Wpf.Properties.Resources.PackageManagerMyPackagesControlName)) + { + var parent = WpfUtilities.FindUpVisualTree(this) as PackageManagerView; + if (parent == null) return; + + packageManagerSearchElementViewModel.Model.UIParent = parent.packageDetailsGrid; + if (parent.packageDetailsGrid.Width.Value <= 1.0) + { + var width = (parent.packageDetailsGrid.Parent as Grid).ActualWidth * 0.5; + parent.packageDetailsGrid.Width = new GridLength(width, GridUnitType.Pixel); + } + } + + PkgSearchVM.IsDetailPackagesExtensionOpened = true; PkgSearchVM?.ViewPackageDetailsCommand.Execute(packageManagerSearchElementViewModel.Model); } } diff --git a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml index bcf1bbecd33..87ddce50f9c 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml +++ b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml @@ -9,19 +9,14 @@ xmlns:controls="clr-namespace:Dynamo.Controls" xmlns:p="clr-namespace:Dynamo.Wpf.Properties" mc:Ignorable="d" - x:Name="packageSearchControl" + x:Name="PackageSearchControl" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance ViewModels:PackageManagerSearchElementViewModel, IsDesignTimeCreatable=False}"> - - - - - - - + + @@ -29,207 +24,246 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/DynamoCoreWpf/Views/PackageManager/PackageManagerView.xaml b/src/DynamoCoreWpf/Views/PackageManager/PackageManagerView.xaml index d12d9140e88..3fc8228e061 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/PackageManagerView.xaml +++ b/src/DynamoCoreWpf/Views/PackageManager/PackageManagerView.xaml @@ -27,12 +27,13 @@ + + - @@ -245,24 +246,56 @@ + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch"> + - - - + + + + + + + + + + + + + + + + diff --git a/src/PackageDetailsViewExtension/PackageDetailsView.xaml b/src/PackageDetailsViewExtension/PackageDetailsView.xaml index 3c979e17594..0fccf453351 100644 --- a/src/PackageDetailsViewExtension/PackageDetailsView.xaml +++ b/src/PackageDetailsViewExtension/PackageDetailsView.xaml @@ -144,7 +144,29 @@ + + + + + +