diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index d4020c2f92..e6fcb59e62 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -3,7 +3,7 @@
enable
net8.0-windows10.0.26100.0
10.0.19041.0
- 10.0.26100.57
+ 10.0.26100.56
8.0.407
Martí Climent and the contributors
Martí Climent
diff --git a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs
index 0e61004ef3..50f011c72f 100644
--- a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs
+++ b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs
@@ -1,3 +1,4 @@
+using UniGetUI.Core.Logging;
using UniGetUI.Core.Tools;
using UniGetUI.Interface.Enums;
using UniGetUI.PackageEngine.Interfaces;
@@ -66,5 +67,46 @@ protected override Task WhenAddingPackage(IPackage package)
}
return Task.CompletedTask;
}
+
+ public (IPackage?, string?) GetPackageFromIdAndManager(string id, string managerName, string sourceName)
+ {
+ IPackageManager? manager = null;
+
+ foreach (var candidate in Managers)
+ {
+ if (candidate.Name == managerName || candidate.DisplayName == managerName)
+ {
+ manager = candidate;
+ break;
+ }
+ }
+
+ if (manager is null)
+ return (null, CoreTools.Translate("The package manager \"{0}\" was not found", managerName));
+
+ if (!manager.IsEnabled())
+ return (null, CoreTools.Translate("The package manager \"{0}\" is disabled", manager.DisplayName));
+
+ if (!manager.Status.Found)
+ return (null, CoreTools.Translate("There is an error with the configuration of the package manager \"{0}\"", manager.DisplayName));
+
+ var results = manager.FindPackages(id);
+ var candidates = results.Where(p => p.Id == id).ToArray();
+
+ if (candidates.Length == 0)
+ return (null, CoreTools.Translate("The package \"{0}\" was not found on the package manager \"{1}\"", id, manager.DisplayName));
+
+ IPackage package = candidates[0];
+
+ // Get package from best source
+ if (candidates.Length >= 1 && manager.Capabilities.SupportsCustomSources)
+ foreach (var candidate in candidates)
+ {
+ if (candidate.Source.Name == sourceName)
+ package = candidate;
+ }
+
+ return (package, null);
+ }
}
}
diff --git a/src/UniGetUI/App.xaml b/src/UniGetUI/App.xaml
index f6ce147d13..6214716716 100644
--- a/src/UniGetUI/App.xaml
+++ b/src/UniGetUI/App.xaml
@@ -22,6 +22,15 @@
+
+
/Assets/Symbols/Font/fonts/UniGetUI-Symbols.ttf#UniGetUI-Symbols
@@ -34,6 +43,625 @@
+
+
+
+
+
+
diff --git a/src/UniGetUI/App.xaml.cs b/src/UniGetUI/App.xaml.cs
index aa641b1b26..f16529aed2 100644
--- a/src/UniGetUI/App.xaml.cs
+++ b/src/UniGetUI/App.xaml.cs
@@ -18,6 +18,8 @@
using UniGetUI.Interface.Telemetry;
using UniGetUI.PackageEngine.Interfaces;
using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs;
+using UniGetUI.Pages.DialogPages;
+using UniGetUI.Interface.Enums;
namespace UniGetUI
{
@@ -227,23 +229,22 @@ private async Task LoadComponentsAsync()
BackgroundApi.OnShowSharedPackage += (_, package) => MainWindow.DispatcherQueue.TryEnqueue(() =>
{
- MainWindow?.NavigationPage?.DiscoverPage.ShowSharedPackage_ThreadSafe(package.Key, package.Value);
- MainWindow?.Activate();
+ DialogHelper.ShowSharedPackage_ThreadSafe(package.Key, package.Value);
});
BackgroundApi.OnUpgradeAll += (_, _) => MainWindow.DispatcherQueue.TryEnqueue(() =>
{
- MainWindow?.NavigationPage?.UpdatesPage.UpdateAll();
+ Operations.UpdateAll();
});
- BackgroundApi.OnUpgradeAllForManager += (_, manager) => MainWindow.DispatcherQueue.TryEnqueue(() =>
+ BackgroundApi.OnUpgradeAllForManager += (_, managerName) => MainWindow.DispatcherQueue.TryEnqueue(async () =>
{
- MainWindow?.NavigationPage?.UpdatesPage.UpdateAllPackagesForManager(manager);
+ Operations.UpdateAllForManager(managerName);
});
- BackgroundApi.OnUpgradePackage += (_, package) => MainWindow.DispatcherQueue.TryEnqueue(() =>
+ BackgroundApi.OnUpgradePackage += (_, packageId) => MainWindow.DispatcherQueue.TryEnqueue(() =>
{
- MainWindow?.NavigationPage?.UpdatesPage.UpdatePackageForId(package);
+ Operations.UpdateForId(packageId);
});
_ = BackgroundApi.Start();
diff --git a/src/UniGetUI/AppOperationHelper.cs b/src/UniGetUI/AppOperationHelper.cs
index 83643ea1dd..9b08b250fc 100644
--- a/src/UniGetUI/AppOperationHelper.cs
+++ b/src/UniGetUI/AppOperationHelper.cs
@@ -15,6 +15,8 @@
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.PackageOperations;
using UniGetUI.Pages.DialogPages;
+using UniGetUI.Interface.Enums;
+using UniGetUI.PackageEngine;
namespace UniGetUI;
@@ -163,6 +165,38 @@ public static void Update(IReadOnlyList packages, bool? elevated = nul
}
}
+ public static async void UpdateAll()
+ {
+ foreach (IPackage package in PEInterface.UpgradablePackagesLoader.Packages)
+ if (package.Tag is not PackageTag.BeingProcessed and not PackageTag.OnQueue)
+ await Update(package);
+ }
+
+ public static async void UpdateAllForManager(string managerName)
+ {
+ foreach (IPackage package in PEInterface.UpgradablePackagesLoader.Packages)
+ {
+ if (package.Tag is not PackageTag.OnQueue and not PackageTag.BeingProcessed
+ && package.Manager.Name == managerName || package.Manager.DisplayName == managerName)
+ await Update(package);
+ }
+ }
+
+ public static async void UpdateForId(string packageId)
+ {
+ foreach (IPackage package in PEInterface.UpgradablePackagesLoader.Packages)
+ {
+ if (package.Id == packageId)
+ {
+ await Update(package);
+ Logger.Info($"[WIDGETS] Updating package with id {packageId}");
+ return;
+ }
+ }
+
+ Logger.Warn($"[WIDGETS] No package with id={packageId} was found");
+ }
+
/*
* PACKAGE UNINSTALL
*/
diff --git a/src/UniGetUI/Controls/LocalIcon.cs b/src/UniGetUI/Controls/LocalIcon.cs
index f90676c063..9c784aaabc 100644
--- a/src/UniGetUI/Controls/LocalIcon.cs
+++ b/src/UniGetUI/Controls/LocalIcon.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
@@ -25,6 +26,38 @@ public LocalIcon(IconType icon) : this()
}
}
+ public static class IconBuilder
+ {
+ private static FontFamily customFont = null!;
+ private static FontFamily symbolFont = null!;
+
+ public static IconType SetIcon(this TextBlock block, IconType icon)
+ {
+ customFont ??= (FontFamily)Application.Current.Resources["SymbolFont"];
+ block.Text = $"{(char)icon}";
+ block.FontFamily = customFont;
+ return icon;
+ }
+
+ public static IconType GetIcon(this TextBlock block)
+ {
+ return IconType.Help;
+ }
+
+ public static string SetGlyph(this TextBlock block, string glyph)
+ {
+ symbolFont ??= new FontFamily("Segoe Fluent Icons");
+ block.Text = glyph;
+ block.FontFamily = symbolFont;
+ return glyph;
+ }
+
+ public static string GetGlyph(this TextBlock block)
+ {
+ return block.Text;
+ }
+ }
+
public partial class LocalIconSource : FontIconSource
{
public static FontFamily font = (FontFamily)Application.Current.Resources["SymbolFont"];
diff --git a/src/UniGetUI/Controls/MenuForPackage.cs b/src/UniGetUI/Controls/MenuForPackage.cs
index 653bad5db1..71dd72bdaf 100644
--- a/src/UniGetUI/Controls/MenuForPackage.cs
+++ b/src/UniGetUI/Controls/MenuForPackage.cs
@@ -38,4 +38,28 @@ public BetterMenuItem()
Style = menuStyle;
}
}
+
+ public partial class BetterToggleMenuItem : ToggleMenuFlyoutItem
+ {
+ private readonly Style menuStyle = (Style)Application.Current.Resources["BetterToggleMenuItem"];
+
+ public IconType IconName
+ {
+ set
+ {
+ var icon = new LocalIcon(value) { FontSize = 24 };
+ Icon = icon;
+ }
+ }
+
+ public new string Text
+ {
+ set => base.Text = CoreTools.Translate(value);
+ }
+
+ public BetterToggleMenuItem()
+ {
+ Style = menuStyle;
+ }
+ }
}
diff --git a/src/UniGetUI/Controls/ObservablePackageCollection.cs b/src/UniGetUI/Controls/ObservablePackageCollection.cs
index 99e0c5c625..41d7170571 100644
--- a/src/UniGetUI/Controls/ObservablePackageCollection.cs
+++ b/src/UniGetUI/Controls/ObservablePackageCollection.cs
@@ -1,4 +1,5 @@
using UniGetUI.Core.Classes;
+using UniGetUI.Interface;
using UniGetUI.PackageEngine.Interfaces;
namespace UniGetUI.PackageEngine.PackageClasses
@@ -17,26 +18,30 @@ public enum Sorter
NewVersion,
Source,
}
+ public Sorter CurrentSorter { get; private set; }
public ObservablePackageCollection()
{
+ CurrentSorter = Sorter.Name;
SortingSelector = x => x.Package.Name;
}
///
/// Add a package to the collection
///
- public void Add(IPackage p)
+ public void Add(IPackage p, AbstractPackagesPage page)
{
- base.Add(new PackageWrapper(p));
+ base.Add(new PackageWrapper(p, page));
}
///
/// Sets the property with which to filter the package and sorts the collection
///
/// The field with which to sort the collection
+ ///
public void SetSorter(Sorter field)
{
+ CurrentSorter = field;
switch (field)
{
case Sorter.Checked:
diff --git a/src/UniGetUI/Controls/PackageWrapper.cs b/src/UniGetUI/Controls/PackageWrapper.cs
index 65ae208abd..e105bf314e 100644
--- a/src/UniGetUI/Controls/PackageWrapper.cs
+++ b/src/UniGetUI/Controls/PackageWrapper.cs
@@ -5,6 +5,7 @@
using Microsoft.UI.Xaml.Media.Imaging;
using UniGetUI.Core.Classes;
using UniGetUI.Core.Tools;
+using UniGetUI.Interface;
using UniGetUI.Interface.Enums;
using UniGetUI.PackageEngine.Interfaces;
@@ -32,6 +33,7 @@ public bool IsChecked
public bool AlternateIdIconVisible;
public bool ShowCustomPackageIcon;
public bool ShowDefaultPackageIcon = true;
+ public string VersionComboString;
public IconType MainIconId = IconType.Id;
public IconType AlternateIconId = IconType.Id;
public ImageSource? MainIconSource;
@@ -57,13 +59,22 @@ public Uri? PackageIcon
public IPackage Package { get; private set; }
public PackageWrapper Self { get; private set; }
- public PackageWrapper(IPackage package)
+ private readonly AbstractPackagesPage _page;
+
+ public PackageWrapper(IPackage package, AbstractPackagesPage page)
{
Package = package;
Self = this;
+ _page = page;
WhenTagHasChanged();
Package.PropertyChanged += Package_PropertyChanged;
UpdatePackageIcon();
+ VersionComboString = package.IsUpgradable ? $"{package.VersionString} -> {package.NewVersionString}" : package.VersionString;
+ }
+
+ public async void RightClick()
+ {
+ await _page.ShowContextMenu(this);
}
public void Package_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@@ -167,7 +178,7 @@ public void UpdatePackageIcon()
MainIconSource = new BitmapImage
{
UriSource = icon,
- DecodePixelWidth = 24,
+ DecodePixelWidth = 64,
DecodePixelType = DecodePixelType.Logical,
};
ShowCustomPackageIcon = true;
diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs
index 143b04714a..b44429727c 100644
--- a/src/UniGetUI/MainWindow.xaml.cs
+++ b/src/UniGetUI/MainWindow.xaml.cs
@@ -265,7 +265,7 @@ public void HandleNotificationActivation(AppNotificationActivatedEventArgs args)
if (action == NotificationArguments.UpdateAllPackages)
{
- NavigationPage.UpdatesPage.UpdateAll();
+ MainApp.Operations.UpdateAll();
}
else if (action == NotificationArguments.ShowOnUpdatesTab)
{
@@ -360,11 +360,11 @@ private void HandleDeepLink(string link)
if (Id != "" && CombinedManagerName != "" && ManagerName == "" && SourceName == "")
{
Logger.Warn($"URI {link} follows old scheme");
- NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, CombinedManagerName);
+ DialogHelper.ShowSharedPackage_ThreadSafe(Id, CombinedManagerName);
}
else if (Id != "" && ManagerName != "" && SourceName != "")
{
- NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, ManagerName, SourceName);
+ DialogHelper.ShowSharedPackage_ThreadSafe(Id, ManagerName, SourceName);
}
else
{
@@ -437,8 +437,7 @@ public void ProcessCommandLineParameters()
{
// Handle potential JSON files
Logger.ImportantInfo("Begin attempt to open the package bundle " + param);
- NavigationPage.NavigateTo(PageType.Bundles);
- _ = NavigationPage.BundlesPage.OpenFromFile(param);
+ NavigationPage.LoadBundleFile(param);
}
else if (param.EndsWith("UniGetUI.exe") || param.EndsWith("UniGetUI.dll"))
{
diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs
index 280cf91cbb..5dc4b8034e 100644
--- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs
+++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs
@@ -1,13 +1,17 @@
+using System.Diagnostics.Tracing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
+using UniGetUI.Core.Logging;
using UniGetUI.Core.Tools;
using UniGetUI.Interface.Dialogs;
using UniGetUI.Interface.Telemetry;
+using UniGetUI.PackageEngine;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.PackageClasses;
using UniGetUI.PackageEngine.Serializable;
+using Windows.ApplicationModel;
namespace UniGetUI.Pages.DialogPages;
@@ -139,4 +143,56 @@ public static async Task ConfirmUninstallation(IReadOnlyList pac
return await Window.ShowDialogAsync(dialog) is ContentDialogResult.Primary;
}
+
+ public static void ShowSharedPackage_ThreadSafe(string id, string combinedSourceName)
+ {
+ var contents = combinedSourceName.Split(':');
+ string managerName = contents[0];
+ string sourceName = "";
+ if (contents.Length > 1) sourceName = contents[1];
+ GetPackageFromIdAndManager(id, managerName, sourceName, "LEGACY_COMBINEDSOURCE");
+ }
+
+ public static void ShowSharedPackage_ThreadSafe(string id, string managerName, string sourceName)
+ {
+ MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() =>
+ {
+ GetPackageFromIdAndManager(id, managerName, sourceName, "DEFAULT");
+ });
+ }
+
+ private static async void GetPackageFromIdAndManager(string id, string managerName, string sourceName, string eventSource)
+ {
+ try
+ {
+ Window.Activate();
+ ShowLoadingDialog(CoreTools.Translate("Please wait..."));
+
+ var findResult = await Task.Run(() => PEInterface.DiscoveredPackagesLoader.GetPackageFromIdAndManager(id, managerName, sourceName));
+
+ HideLoadingDialog();
+
+ if (findResult.Item1 is null) throw new KeyNotFoundException(findResult.Item2 ?? "Unknown error");
+
+ TelemetryHandler.SharedPackage(findResult.Item1, eventSource);
+ ShowPackageDetails(findResult.Item1, OperationType.Install, TEL_InstallReferral.FROM_WEB_SHARE);
+
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"An error occurred while attempting to show the package with id {id}");
+ var warningDialog = new ContentDialog
+ {
+ Title = CoreTools.Translate("Package not found"),
+ Content = CoreTools.Translate("An error occurred when attempting to show the package with Id {0}", id) + ":\n" + ex.Message,
+ CloseButtonText = CoreTools.Translate("Ok"),
+ DefaultButton = ContentDialogButton.Close,
+ XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context
+ };
+
+ HideLoadingDialog();
+ await Window.ShowDialogAsync(warningDialog);
+
+ }
+ }
}
diff --git a/src/UniGetUI/Pages/MainView.xaml.cs b/src/UniGetUI/Pages/MainView.xaml.cs
index 56e592f5c1..72efe2776a 100644
--- a/src/UniGetUI/Pages/MainView.xaml.cs
+++ b/src/UniGetUI/Pages/MainView.xaml.cs
@@ -42,10 +42,10 @@ public enum PageType
public sealed partial class MainView : UserControl
{
- public DiscoverSoftwarePage DiscoverPage;
- public SoftwareUpdatesPage UpdatesPage;
- public InstalledPackagesPage InstalledPage;
- public PackageBundlesPage BundlesPage;
+ private DiscoverSoftwarePage DiscoverPage;
+ private SoftwareUpdatesPage UpdatesPage;
+ private InstalledPackagesPage InstalledPage;
+ private PackageBundlesPage BundlesPage;
private SettingsBasePage? SettingsPage;
private SettingsBasePage? ManagersPage;
private UniGetUILogPage? UniGetUILogPage;
@@ -431,5 +431,11 @@ private void MoreNavBtn_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRout
(VersionMenuItem as MenuFlyoutItem).Text = CoreTools.Translate("WingetUI Version {0}", CoreData.VersionName);
MoreNavButtonMenu.ShowAt(sender as FrameworkElement);
}
+
+ internal void LoadBundleFile(string param)
+ {
+ NavigateTo(PageType.Bundles);
+ BundlesPage?.OpenFromFile(param);
+ }
}
}
diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs
index dbf726d1d3..81e0c5f4b4 100644
--- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs
+++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs
@@ -5,6 +5,7 @@
using UniGetUI.Core.Data;
using System.Diagnostics;
using UniGetUI.Pages.DialogPages;
+using UniGetUI.Interface.SoftwarePages;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -99,7 +100,7 @@ private void OpenBackupPath_Click(object sender, RoutedEventArgs e)
private async void DoBackup_Click(object sender, EventArgs e)
{
DialogHelper.ShowLoadingDialog(CoreTools.Translate("Performing backup, please wait..."));
- await MainApp.Instance.MainWindow.NavigationPage.InstalledPage.BackupPackages();
+ await InstalledPackagesPage.BackupPackages();
DialogHelper.HideLoadingDialog();
}
}
diff --git a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml
index 76f81ffb2e..563e91c7e2 100644
--- a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml
+++ b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml
@@ -10,9 +10,11 @@
xmlns:local="using:UniGetUI.Interface"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pkgClasses="using:UniGetUI.PackageEngine.PackageClasses"
+ xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:widgets="using:UniGetUI.Interface.Widgets"
Name="ABSTRACT_PAGE"
NavigationCacheMode="Required"
+ SizeChanged="ABSTRACT_PAGE_SizeChanged"
mc:Ignorable="d">
@@ -29,624 +31,7 @@
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -827,98 +479,143 @@
-
+
-
-
-
+
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+ Margin="0,0,4,0"
+ HorizontalAlignment="Stretch"
+ Orientation="Vertical"
+ Spacing="8">
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1309,25 +1010,58 @@
Grid.Column="10"
Grid.ColumnSpan="3"
HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
BorderThickness="0"
CornerRadius="0,4,4,0" />
-
-
-
-
-
+ TargetType="x:Int32"
+ Value="{x:Bind ViewModeSelector.SelectedIndex, Mode=OneWay}">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs
index 9337759f5f..b69bea9d85 100644
--- a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs
+++ b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs
@@ -21,7 +21,7 @@
using Microsoft.UI;
using Microsoft.UI.Xaml.Media;
using Windows.UI;
-using Windows.Graphics.Printing.PrintSupport;
+using Microsoft.UI.Xaml.Controls.Primitives;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -73,7 +73,17 @@ protected enum ReloadReason
protected IPackage? SelectedItem
{
- get => (PackageList.SelectedItem as PackageWrapper)?.Package;
+ get => (CurrentPackageList.SelectedItem as PackageWrapper)?.Package;
+ }
+
+ protected ItemsView CurrentPackageList
+ {
+ get => (ViewModeSelector.SelectedIndex switch
+ {
+ 1 => PackageList_Grid,
+ 2 => PackageList_Icons,
+ _ => PackageList_List
+ });
}
protected AbstractPackageLoader Loader;
@@ -100,8 +110,6 @@ protected IPackage? SelectedItem
protected readonly string NoPackages_SubtitleText_Base;
protected readonly string NoMatches_BackgroundText;
- private bool PaneIsAnimated;
-
protected Func FoundPackages_SubtitleText_Base = (a, b) => CoreTools.Translate("{0} packages were found, {1} of which match the specified filters.", a, b);
protected string NoPackages_SubtitleText
@@ -122,10 +130,8 @@ protected string NoMatches_SubtitleText
protected AbstractPackagesPage(PackagesPageData data)
{
- InitializeComponent();
-
- Loader = data.Loader;
-
+ // Load page attributes
+ PAGE_NAME = data.PageName;
DISABLE_AUTOMATIC_PACKAGE_LOAD_ON_START = data.DisableAutomaticPackageLoadOnStart;
DISABLE_FILTER_ON_QUERY_CHANGE = data.DisableFilterOnQueryChange;
MEGA_QUERY_BOX_ENABLED = data.MegaQueryBlockEnabled;
@@ -136,19 +142,24 @@ protected AbstractPackagesPage(PackagesPageData data)
NewVersionLabelWidth = RoleIsUpdateLike ? 125 : 0;
NewVersionIconWidth = RoleIsUpdateLike ? 24 : 0;
- Loader = data.Loader;
-
- PAGE_NAME = data.PageName;
-
- MainTitle.Text = data.PageTitle;
- HeaderIcon.Glyph = data.Glyph;
-
NoPackages_BackgroundText = data.NoPackages_BackgroundText;
NoPackages_SourcesText = data.NoPackages_SourcesText;
NoPackages_SubtitleText_Base = data.NoPackages_SubtitleText_Base;
MainSubtitle_StillLoading = data.MainSubtitle_StillLoading;
NoMatches_BackgroundText = data.NoMatches_BackgroundText;
+ Loader = data.Loader;
+
+ // Load UI
+ InitializeComponent();
+
+ // Selection of grid view mode
+ int viewMode = Settings.GetDictionaryItem("PackageListViewMode", PAGE_NAME);
+ if (viewMode < 0 || viewMode >= ViewModeSelector.Items.Count) viewMode = 0;
+ ViewModeSelector.SelectedIndex = viewMode;
+
+ MainTitle.Text = data.PageTitle;
+ HeaderIcon.Glyph = data.Glyph;
SelectAllCheckBox.IsChecked = data.PackagesAreCheckedByDefault;
QuerySimilarResultsRadio.IsEnabled = !data.DisableSuggestedResultsRadio;
@@ -301,10 +312,24 @@ protected AbstractPackagesPage(PackagesPageData data)
NewVersionHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion);
SourceHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Source);
+ OrderByName_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Name);
+ OrderById_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Id);
+ OrderByVer_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Version);
+ OrderByNewVer_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion);
+ OrderBySrc_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Source);
+
+ OrderAsc_Menu.Click += (_, _) => SortPackagesBy(ascendent: true);
+ OrderDesc_Menu.Click += (_, _) => SortPackagesBy(ascendent: false);
+
GenerateToolBar();
- PackageList.ContextFlyout = GenerateContextMenu();
+ var menu = GenerateContextMenu();
+
+ PackageList_List.ContextFlyout = menu;
+ PackageList_Grid.ContextFlyout = menu;
+ PackageList_Icons.ContextFlyout = menu;
Loaded += (_, _) => ChangeFilteringPaneLayout();
+ UpdateSortingMenu();
}
private void Loader_PackagesChanged(object? sender, EventArgs e)
@@ -333,6 +358,7 @@ private void Loader_PackagesChanged(object? sender, EventArgs e)
_ = LoadIconsForNewPackages();
}
+
private void Loader_FinishedLoading(object? sender, EventArgs e)
{
// Ensure we are in the UI thread
@@ -484,18 +510,18 @@ private void SelectAndScrollTo(int index, bool focus)
if (index < 0 || index >= FilteredPackages.Count)
return;
- PackageList.Select(index);
+ CurrentPackageList.Select(index);
- if (PackageList.ScrollView?.VerticalOffset > index * 39)
+ if (CurrentPackageList.ScrollView?.VerticalOffset > index * 39)
{
- PackageList.ScrollView.ScrollTo(0, index * 39, new ScrollingScrollOptions(
+ CurrentPackageList.ScrollView.ScrollTo(0, index * 39, new ScrollingScrollOptions(
ScrollingAnimationMode.Disabled,
ScrollingSnapPointsMode.Ignore
));
}
- else if (PackageList.ScrollView?.VerticalOffset + PackageList.ScrollView?.ViewportHeight < (index + 1) * 39)
+ else if (CurrentPackageList.ScrollView?.VerticalOffset + CurrentPackageList.ScrollView?.ViewportHeight < (index + 1) * 39)
{
- PackageList.ScrollView?.ScrollTo(0, (index + 1) * 39 - PackageList.ScrollView.ViewportHeight, new ScrollingScrollOptions(
+ CurrentPackageList.ScrollView?.ScrollTo(0, (index + 1) * 39 - CurrentPackageList.ScrollView.ViewportHeight, new ScrollingScrollOptions(
ScrollingAnimationMode.Disabled,
ScrollingSnapPointsMode.Ignore
));
@@ -514,7 +540,7 @@ private void Focus(IPackage packageToFocus, int retryCount = 0)
DispatcherQueuePriority.Low,
() =>
{
- PackageItemContainer? containerToFocus = PackageList.FindDescendant(c => c.Package?.Equals(packageToFocus) == true);
+ PackageItemContainer? containerToFocus = CurrentPackageList.FindDescendant(c => c.Package?.Equals(packageToFocus) == true);
if (containerToFocus == null)
{
Focus(packageToFocus, ++retryCount);
@@ -523,7 +549,7 @@ private void Focus(IPackage packageToFocus, int retryCount = 0)
if (!containerToFocus.IsSelected)
{
- PackageItemContainer? selectedContainer = PackageList.FindDescendant(c => c.IsSelected);
+ PackageItemContainer? selectedContainer = CurrentPackageList.FindDescendant(c => c.IsSelected);
if (selectedContainer?.Package?.Equals(packageToFocus) == true)
containerToFocus = selectedContainer;
else
@@ -629,7 +655,7 @@ public void PackageList_CharacterReceived(object sender, CharacterReceivedRouted
///
public void FilterPackages()
{
- PackageWrapper? previousSelection = PackageList.SelectedItem as PackageWrapper;
+ PackageWrapper? previousSelection = CurrentPackageList.SelectedItem as PackageWrapper;
FilteredPackages.Clear();
List VisibleSources = [];
@@ -729,7 +755,7 @@ public void FilterPackages()
{
if (VisibleSources.Contains(match.Source) || (!match.Manager.Capabilities.SupportsCustomSources && VisibleManagers.Contains(match.Manager)))
{
- FilteredPackages.Add(match);
+ FilteredPackages.Add(match, this);
}
}
FilteredPackages.BlockSorting = false;
@@ -808,9 +834,39 @@ public void UpdatePackageCount()
/// The information with which to sort the packages
public void SortPackagesBy(ObservablePackageCollection.Sorter sorter)
{
- FilteredPackages.Descending = !FilteredPackages.Descending;
+ if(sorter == FilteredPackages.CurrentSorter) FilteredPackages.Descending = !FilteredPackages.Descending;
FilteredPackages.SetSorter(sorter);
FilteredPackages.Sort();
+ UpdateSortingMenu();
+ }
+
+ public void SortPackagesBy(bool ascendent)
+ {
+ FilteredPackages.Descending = !ascendent;
+ FilteredPackages.Sort();
+ UpdateSortingMenu();
+ }
+
+ private void UpdateSortingMenu()
+ {
+ OrderByName_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Name;
+ OrderById_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Id;
+ OrderByVer_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Version;
+ OrderByNewVer_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.NewVersion;
+ OrderBySrc_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Source;
+
+ OrderAsc_Menu.IsChecked = !FilteredPackages.Descending;
+ OrderDesc_Menu.IsChecked = FilteredPackages.Descending;
+
+ OrderByButton.Content = FilteredPackages.CurrentSorter switch
+ {
+ ObservablePackageCollection.Sorter.Name => CoreTools.Translate("Name"),
+ ObservablePackageCollection.Sorter.Id => CoreTools.Translate("Id"),
+ ObservablePackageCollection.Sorter.Version => CoreTools.Translate("Version"),
+ ObservablePackageCollection.Sorter.NewVersion => CoreTools.Translate("New version"),
+ ObservablePackageCollection.Sorter.Source => CoreTools.Translate("Source"),
+ _ => throw new InvalidDataException()
+ };
}
protected void SelectAllSourcesButton_Click(object sender, RoutedEventArgs e)
@@ -873,10 +929,6 @@ protected async void ShowInstallationOptionsForPackage(IPackage? package)
private void SidepanelWidth_SizeChanged(object sender, SizeChangedEventArgs e)
{
- if (PaneIsAnimated)
- return;
-
-
if ((int)e.NewSize.Width == (int)(e.NewSize.Width / 10) || (int)e.NewSize.Width == 25)
{
return;
@@ -915,13 +967,23 @@ protected void PerformMainPackageAction(IPackage? package)
}
public void FocusPackageList()
- { PackageList.Focus(FocusState.Programmatic); }
+ { CurrentPackageList.Focus(FocusState.Programmatic); }
+
+
+ public async Task ShowContextMenu(PackageWrapper wrapper)
+ {
+ CurrentPackageList.Select(wrapper.Index);
+ await Task.Delay(20);
+ if(_lastContextMenuButtonTapped is not null)
+ (CurrentPackageList.ContextFlyout as BetterMenu)?.ShowAt(_lastContextMenuButtonTapped, new FlyoutShowOptions { Placement = FlyoutPlacementMode.RightEdgeAlignedTop });
+ WhenShowingContextMenu(wrapper.Package);
+ }
private void PackageItemContainer_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
if (sender is PackageItemContainer container && container.Package is not null)
{
- PackageList.Select(container.Wrapper.Index);
+ CurrentPackageList.Select(container.Wrapper.Index);
container.Focus(FocusState.Keyboard);
WhenShowingContextMenu(container.Package);
}
@@ -931,7 +993,7 @@ private void PackageItemContainer_DoubleTapped(object sender, DoubleTappedRouted
{
if (sender is PackageItemContainer container && container.Package is not null)
{
- PackageList.Select(container.Wrapper.Index);
+ CurrentPackageList.Select(container.Wrapper.Index);
container.Focus(FocusState.Keyboard);
TEL_InstallReferral referral = TEL_InstallReferral.ALREADY_INSTALLED;
@@ -955,11 +1017,11 @@ private void SelectAllCheckBox_ValueChanged(object sender, RoutedEventArgs e)
private async void ForceRedrawByScroll()
{
- if (PackageList is not null)
+ if (CurrentPackageList is not null)
{
- PackageList.ScrollView?.ScrollBy(0, 1);
+ CurrentPackageList.ScrollView?.ScrollBy(0, 1);
await Task.Delay(10);
- PackageList.ScrollView?.ScrollBy(0, -1);
+ CurrentPackageList.ScrollView?.ScrollBy(0, -1);
}
}
@@ -1207,5 +1269,37 @@ private void FilteringPanel_PaneClosing(SplitView sender, SplitViewPaneClosingEv
{
ToggleFiltersButton.IsChecked = false;
}
+ private void ViewModeSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ Settings.SetDictionaryItem("PackageListViewMode", PAGE_NAME, ViewModeSelector.SelectedIndex);
+ }
+
+ FrameworkElement _lastContextMenuButtonTapped = null!;
+ private void ContextMenuButton_Tapped(object sender, TappedRoutedEventArgs e)
+ {
+ if (sender is FrameworkElement el)
+ _lastContextMenuButtonTapped = el;
+ }
+
+ private bool? _pageIsWide;
+ private void ABSTRACT_PAGE_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if(ActualWidth < 700)
+ {
+ if (_pageIsWide != false)
+ {
+ SearchBoxPanel.Orientation = Orientation.Vertical;
+ _pageIsWide = false;
+ }
+ }
+ else
+ {
+ if (_pageIsWide != true)
+ {
+ SearchBoxPanel.Orientation = Orientation.Horizontal;
+ _pageIsWide = true;
+ }
+ }
+ }
}
}
diff --git a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs
index c4eaff8af2..be4b8c51cd 100644
--- a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs
+++ b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs
@@ -277,10 +277,8 @@ private void MenuDetails_Invoked(object sender, RoutedEventArgs e)
private void MenuShare_Invoked(object sender, RoutedEventArgs e)
{
- if (PackageList.SelectedItem is null)
- {
+ if (SelectedItem is null)
return;
- }
MainApp.Instance.MainWindow.SharePackage(SelectedItem);
}
@@ -300,102 +298,5 @@ private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e)
private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e)
=> ShowInstallationOptionsForPackage(SelectedItem);
- public void ShowSharedPackage_ThreadSafe(string id, string combinedSourceName)
- {
- var contents = combinedSourceName.Split(':');
- string managerName = contents[0];
- string sourceName = "";
- if (contents.Length > 1) sourceName = contents[1];
- _showSharedPackage(id, managerName, sourceName, "LEGACY_COMBINEDSOURCE");
- }
-
- public void ShowSharedPackage_ThreadSafe(string id, string managerName, string sourceName)
- {
- MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() =>
- {
- _showSharedPackage(id, managerName, sourceName, "DEFAULT");
- });
- }
-
- private async void _showSharedPackage(string id, string manager, string source, string eventSource)
- {
- IPackage? package = await GetPackageFromIdAndManager(id, manager, source);
- if (package is not null)
- {
- TelemetryHandler.SharedPackage(package, eventSource);
- ShowDetailsForPackage(package, TEL_InstallReferral.FROM_WEB_SHARE);
- }
- }
-
- private static async Task GetPackageFromIdAndManager(string id, string managerName, string sourceName)
- {
- try
- {
- Logger.Info($"Showing shared package with pId={id} and pSource={managerName}: ´{sourceName} ...");
- MainApp.Instance.MainWindow.Activate();
- DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...", id));
-
- IPackageManager? manager = null;
-
- foreach (var candidate in PEInterface.Managers)
- {
- if (candidate.Name == managerName || candidate.DisplayName == managerName)
- {
- manager = candidate;
- break;
- }
- }
-
- if (manager is null)
- {
- throw new ArgumentException(CoreTools.Translate("The package manager \"{0}\" was not found", managerName));
- }
-
- if (!manager.IsEnabled())
- throw new ArgumentException(CoreTools.Translate("The package manager \"{0}\" is disabled", manager.DisplayName));
-
- if (!manager.Status.Found)
- throw new ArgumentException(CoreTools.Translate("There is an error with the configuration of the package manager \"{0}\"", manager.DisplayName));
-
- var results = await Task.Run(() => manager.FindPackages(id));
- var candidates = results.Where(p => p.Id == id).ToArray();
-
- if (candidates.Length == 0)
- {
- throw new ArgumentException(CoreTools.Translate("The package \"{0}\" was not found on the package manager \"{1}\"", id, manager.DisplayName));
- }
-
- IPackage package = candidates[0];
-
- // Get package from best source
- if (candidates.Length >= 1 && manager.Capabilities.SupportsCustomSources)
- foreach (var candidate in candidates)
- {
- if (candidate.Source.Name == sourceName)
- package = candidate;
- }
-
- Logger.ImportantInfo($"Found package {package.Id} on manager {package.Manager.Name}, showing it...");
- DialogHelper.HideLoadingDialog();
- return package;
- }
- catch (Exception ex)
- {
- Logger.Error($"An error occurred while attempting to show the package with id {id}");
- Logger.Error(ex);
- var warningDialog = new ContentDialog
- {
- Title = CoreTools.Translate("Package not found"),
- Content = CoreTools.Translate("An error occurred when attempting to show the package with Id {0}", id) + ":\n" + ex.Message,
- CloseButtonText = CoreTools.Translate("Ok"),
- DefaultButton = ContentDialogButton.Close,
- XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context
- };
-
- DialogHelper.HideLoadingDialog();
- await MainApp.Instance.MainWindow.ShowDialogAsync(warningDialog);
- return null;
- }
- }
}
}
diff --git a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs
index 72aa083dbd..ead9b05601 100644
--- a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs
+++ b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs
@@ -17,7 +17,7 @@ namespace UniGetUI.Interface.SoftwarePages
{
public partial class InstalledPackagesPage : AbstractPackagesPage
{
- private bool HasDoneBackup;
+ private static bool HasDoneBackup;
private BetterMenuItem? MenuAsAdmin;
private BetterMenuItem? MenuInteractive;
@@ -361,14 +361,14 @@ private async void ExportSelection_Click(object sender, RoutedEventArgs e)
}
- public async Task BackupPackages()
+ public static async Task BackupPackages()
{
try
{
Logger.Debug("Starting package backup");
List packagesToExport = [];
- foreach (IPackage package in Loader.Packages)
+ foreach (IPackage package in PEInterface.InstalledPackagesLoader.Packages)
{
packagesToExport.Add(package);
}
@@ -448,10 +448,8 @@ private async void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs args
private void MenuShare_Invoked(object sender, RoutedEventArgs args)
{
- if (PackageList.SelectedItem is null)
- {
+ if (SelectedItem is null)
return;
- }
MainApp.Instance.MainWindow.SharePackage(SelectedItem);
}
diff --git a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs
index 20bb2719ad..72b0ff73bb 100644
--- a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs
+++ b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs
@@ -325,15 +325,6 @@ protected override void WhenPackageCountUpdated()
MainApp.Tooltip.AvailableUpdates = Loader.Count();
}
- public void UpdateAll()
- {
- foreach (IPackage package in Loader.Packages)
- {
- if (package.Tag is not PackageTag.BeingProcessed and not PackageTag.OnQueue)
- _ = MainApp.Operations.Update(package);
- }
- }
-
protected override void WhenPackagesLoaded(ReloadReason reason)
{
List upgradablePackages = [];
@@ -374,12 +365,14 @@ protected override void WhenPackagesLoaded(ReloadReason reason)
if(EnableAutoUpdate)
- UpdateAll();
+ {
+ MainApp.Operations.UpdateAll();
+ }
if (Settings.AreUpdatesNotificationsDisabled())
return;
- AppNotificationManager.Default.RemoveByTagAsync(CoreData.UpdatesAvailableNotificationTag.ToString());
+ _ = AppNotificationManager.Default.RemoveByTagAsync(CoreData.UpdatesAvailableNotificationTag.ToString());
AppNotification notification;
if (upgradablePackages.Count == 1)
@@ -536,29 +529,17 @@ private void MenuSkipVersion_Invoked(object sender, RoutedEventArgs e)
PEInterface.UpgradablePackagesLoader.IgnoredPackages[package.Id] = package;
}
- public void UpdatePackageForId(string id)
+
+ public void UpdateAll()
{
- foreach (IPackage package in Loader.Packages)
- {
- if (package.Id == id)
- {
- _ = MainApp.Operations.Update(package);
- Logger.Info($"[WIDGETS] Updating package with id {id}");
- break;
- }
- }
+ }
- Logger.Warn($"[WIDGETS] No package with id={id} was found");
+ public void UpdatePackageForId(string id)
+ {
}
public async void UpdateAllPackagesForManager(string manager)
{
- foreach (IPackage package in Loader.Packages)
- {
- if (package.Tag is not PackageTag.OnQueue and not PackageTag.BeingProcessed)
- if (package.Manager.Name == manager || package.Manager.DisplayName == manager)
- await MainApp.Operations.Update(package);
- }
}
}
}
diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj
index 85f8007cdf..79a2b77151 100644
--- a/src/UniGetUI/UniGetUI.csproj
+++ b/src/UniGetUI/UniGetUI.csproj
@@ -69,6 +69,7 @@
+
diff --git a/test_publish_nosign.cmd b/test_publish_nosign.cmd
new file mode 100644
index 0000000000..d503cc957c
--- /dev/null
+++ b/test_publish_nosign.cmd
@@ -0,0 +1,5 @@
+@echo off
+rmdir /q /s src\UniGetUI\bin\x64\Release\net8.0-windows10.0.26100.0\win-x64\publish\
+dotnet publish src/UniGetUI/UniGetUI.csproj /noLogo /property:Configuration=Release /property:Platform=x64 -v m
+src\UniGetUI\bin\x64\Release\net8.0-windows10.0.26100.0\win-x64\publish\UniGetUI.exe
+pause
\ No newline at end of file