Three causes behind the stuck indicator: - OperationStatus.End did not retire the generation, so tick work posted while the dispatcher was blocked drained afterwards and set ShowIndicator back to true on a finished operation. - The startup update check ran in Task.Run; OperationStatus writes its observable properties on the calling thread, so the final ShowIndicator=false never reached the binding. - OperationIndicator overwrote its own DataContext from the Status property, which re-targeted the call-site binding. It now scopes the DataContext to an inner panel and collapses itself when Status is null; every call site switched from DataContext= to Status=. Also gates the footer connection pill in the command body instead of CanExecute (a disabled command greyed out the ONLINE chip), and extends OperationTiming: pid per line, 4 MB rollover, fast successes dropped (failures always kept), and DetailsIsland.BindAsync now carries the selection trigger via TasksIslandViewModel.SelectFrom.
36 lines
1.3 KiB
C#
36 lines
1.3 KiB
C#
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using ClaudeDo.Ui.Services;
|
|
|
|
namespace ClaudeDo.Ui.Views.Controls;
|
|
|
|
public partial class OperationIndicator : UserControl
|
|
{
|
|
public static readonly StyledProperty<OperationStatus?> StatusProperty =
|
|
AvaloniaProperty.Register<OperationIndicator, OperationStatus?>(nameof(Status));
|
|
|
|
public OperationStatus? Status
|
|
{
|
|
get => GetValue(StatusProperty);
|
|
set => SetValue(StatusProperty, value);
|
|
}
|
|
|
|
public OperationIndicator()
|
|
{
|
|
InitializeComponent();
|
|
IsVisible = false;
|
|
}
|
|
|
|
/// A null `Status` leaves the inner panel's DataContext null, so its `IsVisible="{Binding
|
|
/// ShowIndicator}"` can't resolve and falls back to the property default — *visible*. That
|
|
/// renders a label-less spinner plus the stalled hint forever. Collapse the whole control
|
|
/// instead. Deliberately a direct set, not a binding: no call site binds `IsVisible` on the
|
|
/// indicator, and a local value would win over one anyway.
|
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
|
{
|
|
base.OnPropertyChanged(change);
|
|
if (change.Property == StatusProperty)
|
|
IsVisible = change.GetNewValue<OperationStatus?>() is not null;
|
|
}
|
|
}
|