From df5d64d7ffc3c6c813fa9082cb8b9ad37deeda9c Mon Sep 17 00:00:00 2001 From: Gabriel Dufresne Date: Tue, 24 Mar 2026 13:19:14 -0400 Subject: [PATCH 1/8] Added sidebar expand/collapse --- .../ViewModels/MainWindowViewModel.cs | 4 + .../ViewModels/SidebarViewModel.cs | 34 +++++ src/UniGetUI.Avalonia/Views/MainWindow.axaml | 23 +++- src/UniGetUI.Avalonia/Views/SidebarView.axaml | 117 +++++++++++------- 4 files changed, 134 insertions(+), 44 deletions(-) diff --git a/src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs b/src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs index 8c66fcde4..d62cb9f25 100644 --- a/src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs +++ b/src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs @@ -5,6 +5,7 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using UniGetUI.Avalonia.Infrastructure; using UniGetUI.Avalonia.ViewModels.Pages; using UniGetUI.Avalonia.Views; @@ -120,6 +121,9 @@ private void OnPageViewModelPropertyChanged(object? sender, System.ComponentMode private bool _telemetryWarnerVisible; // ─── Constructor ───────────────────────────────────────────────────────── + [RelayCommand] + private void ToggleSidebar() => Sidebar.IsPaneOpen = !Sidebar.IsPaneOpen; + public MainWindowViewModel() { DiscoverPage = new DiscoverSoftwarePage(); diff --git a/src/UniGetUI.Avalonia/ViewModels/SidebarViewModel.cs b/src/UniGetUI.Avalonia/ViewModels/SidebarViewModel.cs index 57c0b37d4..11761d567 100644 --- a/src/UniGetUI.Avalonia/ViewModels/SidebarViewModel.cs +++ b/src/UniGetUI.Avalonia/ViewModels/SidebarViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using UniGetUI.Avalonia.Views; +using UniGetUI.Core.SettingsEngine; namespace UniGetUI.Avalonia.ViewModels; @@ -19,6 +20,18 @@ public partial class SidebarViewModel : ViewModelBase partial void OnUpdatesBadgeCountChanged(int value) => UpdatesBadgeVisible = value > 0; + partial void OnUpdatesBadgeVisibleChanged(bool _) + { + OnPropertyChanged(nameof(UpdatesBadgeExpandedVisible)); + OnPropertyChanged(nameof(UpdatesBadgeCompactVisible)); + } + + partial void OnBundlesBadgeVisibleChanged(bool _) + { + OnPropertyChanged(nameof(BundlesBadgeExpandedVisible)); + OnPropertyChanged(nameof(BundlesBadgeCompactVisible)); + } + // ─── Loading indicators ─────────────────────────────────────────────────── [ObservableProperty] private bool _discoverIsLoading; @@ -29,6 +42,27 @@ partial void OnUpdatesBadgeCountChanged(int value) => [ObservableProperty] private bool _installedIsLoading; + // ─── Pane open/closed ───────────────────────────────────────────────────── + [ObservableProperty] + private bool _isPaneOpen = false; + + partial void OnIsPaneOpenChanged(bool value) + { + Settings.Set(Settings.K.CollapseNavMenuOnWideScreen, value); + OnPropertyChanged(nameof(PaneWidth)); + OnPropertyChanged(nameof(UpdatesBadgeExpandedVisible)); + OnPropertyChanged(nameof(UpdatesBadgeCompactVisible)); + OnPropertyChanged(nameof(BundlesBadgeExpandedVisible)); + OnPropertyChanged(nameof(BundlesBadgeCompactVisible)); + } + + public double PaneWidth => IsPaneOpen ? 250 : 72; + + public bool UpdatesBadgeExpandedVisible => UpdatesBadgeVisible && IsPaneOpen; + public bool UpdatesBadgeCompactVisible => UpdatesBadgeVisible && !IsPaneOpen; + public bool BundlesBadgeExpandedVisible => BundlesBadgeVisible && IsPaneOpen; + public bool BundlesBadgeCompactVisible => BundlesBadgeVisible && !IsPaneOpen; + // ─── Selected page ──────────────────────────────────────────────────────── [ObservableProperty] private PageType _selectedPageType = PageType.Null; diff --git a/src/UniGetUI.Avalonia/Views/MainWindow.axaml b/src/UniGetUI.Avalonia/Views/MainWindow.axaml index a5ad9038d..5b6453906 100644 --- a/src/UniGetUI.Avalonia/Views/MainWindow.axaml +++ b/src/UniGetUI.Avalonia/Views/MainWindow.axaml @@ -25,7 +25,7 @@ @@ -152,6 +152,27 @@ + + + + + + MinWidth="72"> - - - - - - - + + Padding="8,10,8,0"> - + - + + VerticalAlignment="Center" + IsVisible="{Binding IsPaneOpen}"/> - + - + - + VerticalAlignment="Center" + IsVisible="{Binding IsPaneOpen}"/> + + + + + - + - + + VerticalAlignment="Center" + IsVisible="{Binding IsPaneOpen}"/> - + - + - + VerticalAlignment="Center" + IsVisible="{Binding IsPaneOpen}"/> + + + - + @@ -147,10 +174,12 @@ Background="Transparent" BorderThickness="0" Padding="12,8" - CornerRadius="6"> + CornerRadius="6" + ToolTip.Tip="Package Managers"> - - + + @@ -159,10 +188,12 @@ Background="Transparent" BorderThickness="0" Padding="12,8" - CornerRadius="6"> + CornerRadius="6" + ToolTip.Tip="More"> - - + + From 08e71d742caed08c42e4264d3723a2ed3474c883 Mon Sep 17 00:00:00 2001 From: Gabriel Dufresne Date: Tue, 24 Mar 2026 14:15:43 -0400 Subject: [PATCH 2/8] Fixed some bug in AbstractPackagesPage --- .../Models/PackageCollections.cs | 4 +-- .../SoftwarePages/PackagesPageViewModel.cs | 19 +++++++++- .../ManageIgnoredUpdatesWindow.axaml | 36 ++++++++++++++----- .../ManageIgnoredUpdatesWindow.axaml.cs | 10 ++++++ .../SoftwarePages/AbstractPackagesPage.axaml | 31 ++++++---------- .../AbstractPackagesPage.axaml.cs | 16 --------- 6 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/UniGetUI.Avalonia/Models/PackageCollections.cs b/src/UniGetUI.Avalonia/Models/PackageCollections.cs index d5c0f7c28..83258b1d4 100644 --- a/src/UniGetUI.Avalonia/Models/PackageCollections.cs +++ b/src/UniGetUI.Avalonia/Models/PackageCollections.cs @@ -58,9 +58,7 @@ public PackageWrapper(IPackage package, PackagesPageViewModel page) { Package = package; _page = page; - VersionComboString = package.IsUpgradable - ? $"{package.VersionString} -> {package.NewVersionString}" - : package.VersionString; + VersionComboString = package.VersionString; Package.PropertyChanged += Package_PropertyChanged; UpdateDisplayState(); diff --git a/src/UniGetUI.Avalonia/ViewModels/SoftwarePages/PackagesPageViewModel.cs b/src/UniGetUI.Avalonia/ViewModels/SoftwarePages/PackagesPageViewModel.cs index 4824c7c8a..6701aab98 100644 --- a/src/UniGetUI.Avalonia/ViewModels/SoftwarePages/PackagesPageViewModel.cs +++ b/src/UniGetUI.Avalonia/ViewModels/SoftwarePages/PackagesPageViewModel.cs @@ -401,7 +401,24 @@ partial void OnInstantSearchChanged(bool value) partial void OnUpperLowerCaseChanged(bool value) => FilterPackages(); partial void OnIgnoreSpecialCharsChanged(bool value) => FilterPackages(); - partial void OnSearchModeChanged(SearchMode value) => FilterPackages(); + partial void OnSearchModeChanged(SearchMode value) + { + OnPropertyChanged(nameof(SearchMode_Both)); + OnPropertyChanged(nameof(SearchMode_Name)); + OnPropertyChanged(nameof(SearchMode_Id)); + OnPropertyChanged(nameof(SearchMode_Exact)); + OnPropertyChanged(nameof(SearchMode_Similar)); + FilterPackages(); + } + + // One bool property per mode — used for two-way RadioButton bindings. + // Mutual exclusion is enforced by the ViewModel: setting any one to true + // changes SearchMode, which notifies all five properties. + public bool SearchMode_Both { get => SearchMode == SearchMode.Both; set { if (value) SearchMode = SearchMode.Both; } } + public bool SearchMode_Name { get => SearchMode == SearchMode.Name; set { if (value) SearchMode = SearchMode.Name; } } + public bool SearchMode_Id { get => SearchMode == SearchMode.Id; set { if (value) SearchMode = SearchMode.Id; } } + public bool SearchMode_Exact { get => SearchMode == SearchMode.Exact; set { if (value) SearchMode = SearchMode.Exact; } } + public bool SearchMode_Similar { get => SearchMode == SearchMode.Similar; set { if (value) SearchMode = SearchMode.Similar; } } partial void OnAllPackagesCheckedChanged(bool? value) { diff --git a/src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml b/src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml index fdc928c2e..3e3856e24 100644 --- a/src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml +++ b/src/UniGetUI.Avalonia/Views/DialogPages/ManageIgnoredUpdatesWindow.axaml @@ -21,22 +21,38 @@ - + + + - + + Opacity="0.75"/> - + + + + + + + + + @@ -148,7 +175,7 @@ Grid.Row="1" ColumnDefinitions="Auto,Auto,*" ColumnSpacing="4" - Margin="0,0,0,8"> + Margin="0"> @@ -229,7 +254,8 @@ HorizontalContentAlignment="Stretch" IsExpanded="True" CornerRadius="8" - Padding="4,4,4,8"> + Padding="4,4,4,8" + Background="{DynamicResource SettingsCardBackground}"> @@ -295,7 +321,8 @@ HorizontalContentAlignment="Stretch" IsExpanded="False" CornerRadius="8" - Padding="16,8,16,8"> + Padding="16,8,16,8" + Background="{DynamicResource SettingsCardBackground}"> @@ -323,7 +350,8 @@ HorizontalContentAlignment="Stretch" IsExpanded="True" CornerRadius="8" - Padding="16,8,16,8"> + Padding="16,8,16,8" + Background="{DynamicResource SettingsCardBackground}"> @@ -379,10 +407,24 @@ - + BorderThickness="1" + BorderBrush="{DynamicResource AppBorderBrush}" + Background="{DynamicResource SettingsCardBackground}"> + + + + + + - +