Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShowFailedOperationBadge))]
[NotifyPropertyChangedFor(nameof(OperationsSplitterVisible))]
private bool _operationsPanelVisible;

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShowFailedOperationBadge))]
[NotifyPropertyChangedFor(nameof(OperationsSplitterVisible))]
private bool _operationsPanelExpanded = true;

public bool OperationsSplitterVisible => OperationsPanelVisible && OperationsPanelExpanded;

private readonly List<AbstractOperation> _operationBatch = new();
private bool _batchSummaryShown;

Expand Down Expand Up @@ -156,16 +160,16 @@
private void ToggleOperationsPanel() => OperationsPanelExpanded = !OperationsPanelExpanded;

[RelayCommand]
private void RetryFailedOperations() => AvaloniaOperationRegistry.RetryFailed();

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (NativeAOT)

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (Avalonia)

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (NativeAOT)

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 163 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'RetryFailedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

[RelayCommand]
private void ClearSuccessfulOperations() => AvaloniaOperationRegistry.ClearSuccessful();

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (NativeAOT)

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (Avalonia)

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (NativeAOT)

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 166 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearSuccessfulOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

[RelayCommand]
private void ClearFinishedOperations() => AvaloniaOperationRegistry.ClearFinished();

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (NativeAOT)

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (Avalonia)

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (NativeAOT)

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 169 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'ClearFinishedOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

[RelayCommand]
private void CancelAllOperations() => AvaloniaOperationRegistry.CancelAll();

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (NativeAOT)

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Linux (Avalonia)

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (Avalonia)

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Windows (NativeAOT)

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

Check warning on line 172 in src/UniGetUI.Avalonia/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / test-codebase

Member 'CancelAllOperations' does not access instance data and can be marked as static (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1822)

// ─── Sidebar ─────────────────────────────────────────────────────────────
public SidebarViewModel Sidebar { get; } = new();
Expand Down
5 changes: 3 additions & 2 deletions src/UniGetUI.Avalonia/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,11 @@
</TransitioningContentControl>

<!-- ── GridSplitter (only visible when operations are present) ── -->
<GridSplitter Grid.Row="1"
<GridSplitter x:Name="OperationsSplitter"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding OperationsPanelVisible}"
IsVisible="{Binding OperationsSplitterVisible}"
automation:AutomationProperties.AccessibilityView="Raw"
Background="{DynamicResource AppSplitterBackground}"
Opacity="0.8"/>
Expand Down
87 changes: 80 additions & 7 deletions src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia;
Expand Down Expand Up @@ -103,6 +105,8 @@ public partial class MainWindow : Window

// Last user-chosen height (px) of the operations panel; restored when re-expanded.
private double _operationsPanelHeight = 240;
private bool _userResizedPanel;
private readonly HashSet<OperationViewModel> _badgeSubscriptions = new();

public enum RuntimeNotificationLevel
{
Expand Down Expand Up @@ -132,6 +136,9 @@ public MainWindow()
// Title-bar back button: visible whenever there's somewhere to go back to (mirrors WinUI's TitleBar.IsBackButtonVisible).
ViewModel.CanGoBackChanged += (_, canGoBack) => BackButton.IsVisible = canGoBack;
ViewModel.PropertyChanged += OnViewModelPropertyChanged;
ViewModel.Operations.CollectionChanged += OnOperationsCollectionChanged;
OperationsSplitter.DragCompleted += OnOperationsSplitterDragCompleted;
SyncBadgeSubscriptions();
UpdateOperationsPanelRow();

Resized += (_, _) => _ = SaveGeometryAsync();
Expand Down Expand Up @@ -292,7 +299,10 @@ private void OnViewModelPropertyChanged(object? sender, System.ComponentModel.Pr
{
if (e.PropertyName is nameof(MainWindowViewModel.OperationsPanelExpanded)
or nameof(MainWindowViewModel.OperationsPanelVisible))
{
UpdateOperationsPanelRow();
ScheduleOperationsAutoSize();
}

// Expanding the panel while an operation has failed jumps to that op (the failure
// badge on the chevron is what drew the user here).
Expand All @@ -314,10 +324,6 @@ private void ScrollToFirstFailedOperation()
}, DispatcherPriority.Background);
}

// Drive the operations-panel grid row: a resizable pixel height while the panel is
// open, Auto otherwise so it collapses to just the toolbar (or vanishes when empty).
// The GridSplitter writes the row height directly, so we read it back to preserve the
// user's chosen size across collapse/expand.
private void UpdateOperationsPanelRow()
{
if (ContentRoot.RowDefinitions.Count < 3)
Expand All @@ -326,18 +332,85 @@ private void UpdateOperationsPanelRow()
RowDefinition row = ContentRoot.RowDefinitions[2];
if (ViewModel.OperationsPanelVisible && ViewModel.OperationsPanelExpanded)
{
row.MinHeight = 80;
row.Height = new GridLength(_operationsPanelHeight, GridUnitType.Pixel);
row.MinHeight = 48;
double height = _userResizedPanel ? _operationsPanelHeight : ComputeOperationsAutoHeight();
if (height <= 0)
height = _operationsPanelHeight;
row.Height = new GridLength(height, GridUnitType.Pixel);
}
else
{
if (row.Height.IsAbsolute && row.Height.Value > 0)
if (_userResizedPanel && row.Height.IsAbsolute && row.Height.Value > 0)
_operationsPanelHeight = row.Height.Value;
row.MinHeight = 0;
row.Height = GridLength.Auto;
}
}

private double ComputeOperationsAutoHeight()
{
int count = ViewModel.Operations.Count;
if (count == 0)
return 0;

const double chrome = 42;
const double fallbackRow = 68;

double rows = 0;
int visible = Math.Min(count, 3);
for (int i = 0; i < visible; i++)
rows += (OperationsList.ContainerFromIndex(i) as Control)?.Bounds.Height ?? fallbackRow;

return chrome + rows;
}

private void ScheduleOperationsAutoSize()
{
if (_userResizedPanel)
return;
Dispatcher.UIThread.Post(UpdateOperationsPanelRow, DispatcherPriority.Loaded);
}

private void OnOperationsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (ViewModel.Operations.Count == 0)
_userResizedPanel = false;
SyncBadgeSubscriptions();
ScheduleOperationsAutoSize();
Comment thread
GabrielDuf marked this conversation as resolved.
}

private void SyncBadgeSubscriptions()
{
_badgeSubscriptions.RemoveWhere(vm =>
{
if (ViewModel.Operations.Contains(vm))
return false;
vm.Badges.CollectionChanged -= OnOperationBadgesChanged;
return true;
});

foreach (OperationViewModel vm in ViewModel.Operations)
if (_badgeSubscriptions.Add(vm))
vm.Badges.CollectionChanged += OnOperationBadgesChanged;
}

private void OnOperationBadgesChanged(object? sender, NotifyCollectionChangedEventArgs e)
=> ScheduleOperationsAutoSize();

private void OnOperationsSplitterDragCompleted(object? sender, VectorEventArgs e)
{
if (!ViewModel.OperationsPanelVisible || !ViewModel.OperationsPanelExpanded)
return;

if (ContentRoot.RowDefinitions.Count >= 3)
{
RowDefinition row = ContentRoot.RowDefinitions[2];
if (row.Height.IsAbsolute && row.Height.Value > 0)
_operationsPanelHeight = row.Height.Value;
}
_userResizedPanel = true;
}

// ─── Navigation rail / docked pane (responsive) ────────────────────────────
// Feed the live window width to the sidebar, which resolves the layout mode and drives
// the NavRail / NavDock / overlay visibility bindings.
Expand Down
Loading