fix(ui): make worktree state chips readable with on-theme tints
The state badge in the worktrees overview used bright off-palette Material colors with hardcoded near-black text (via WorktreeStateColorConverter), which was hard to read. Switch to the existing chip pattern (subtle tint background + matching border + colored text): active=blue, merged=green, kept=amber, discarded=gray. Drop the now-unused WorktreeStateColorConverter.
This commit is contained in:
@@ -54,7 +54,7 @@ Design/ — Tokens.axaml (design tokens; merged before styles) + IslandStyle
|
||||
|
||||
## Converters
|
||||
|
||||
`StatusColorConverter` (+ `ConnectionColorConverter` in the same file), `WorktreeStateColorConverter`, `WorkerLogLevelToBrushConverter`, `DotBrushConverter`, `EqStatusConverter`, `IconKeyConverter`, `CheckboxBorderConverter`, `StrikeIfTrueConverter`, `BoolToItalicConverter`, `BoolToDraftOpacityConverter`, `NotNullToBoolConverter`, `UpperCaseConverter`, `DateOnlyToDateTimeConverter`.
|
||||
`StatusColorConverter` (+ `ConnectionColorConverter` in the same file), `WorkerLogLevelToBrushConverter`, `DotBrushConverter`, `EqStatusConverter`, `IconKeyConverter`, `CheckboxBorderConverter`, `StrikeIfTrueConverter`, `BoolToItalicConverter`, `BoolToDraftOpacityConverter`, `NotNullToBoolConverter`, `UpperCaseConverter`, `DateOnlyToDateTimeConverter`.
|
||||
|
||||
## Dialog Pattern
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
using ClaudeDo.Data.Models;
|
||||
|
||||
namespace ClaudeDo.Ui.Converters;
|
||||
|
||||
public sealed class WorktreeStateColorConverter : IValueConverter
|
||||
{
|
||||
private static readonly ISolidColorBrush Active = new SolidColorBrush(Color.Parse("#42A5F5"));
|
||||
private static readonly ISolidColorBrush Merged = new SolidColorBrush(Color.Parse("#66BB6A"));
|
||||
private static readonly ISolidColorBrush Discarded = new SolidColorBrush(Color.Parse("#9E9E9E"));
|
||||
private static readonly ISolidColorBrush Kept = new SolidColorBrush(Color.Parse("#FFA726"));
|
||||
private static readonly ISolidColorBrush Default = new SolidColorBrush(Colors.Gray);
|
||||
|
||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
value is WorktreeState state
|
||||
? state switch
|
||||
{
|
||||
WorktreeState.Active => Active,
|
||||
WorktreeState.Merged => Merged,
|
||||
WorktreeState.Discarded => Discarded,
|
||||
WorktreeState.Kept => Kept,
|
||||
_ => Default,
|
||||
}
|
||||
: Default;
|
||||
|
||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
@@ -238,6 +238,43 @@
|
||||
<Setter Property="Foreground" Value="#8FB9D6" />
|
||||
</Style>
|
||||
|
||||
<!-- Worktree-state chips (worktrees overview) -->
|
||||
<!-- active → slate-blue (same hue as parked: a live worktree) -->
|
||||
<Style Selector="Border.chip.wt-active">
|
||||
<Setter Property="Background" Value="#22303A" />
|
||||
<Setter Property="BorderBrush" Value="#3A5060" />
|
||||
</Style>
|
||||
<Style Selector="Border.chip.wt-active > TextBlock">
|
||||
<Setter Property="Foreground" Value="#8FB9D6" />
|
||||
</Style>
|
||||
|
||||
<!-- merged → green -->
|
||||
<Style Selector="Border.chip.wt-merged">
|
||||
<Setter Property="Background" Value="{StaticResource DoneTintBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource DoneTintBorderBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Border.chip.wt-merged > TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource StatusDoneBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- kept → amber -->
|
||||
<Style Selector="Border.chip.wt-kept">
|
||||
<Setter Property="Background" Value="{StaticResource ReviewTintBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource ReviewTintBorderBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Border.chip.wt-kept > TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource StatusReviewBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- discarded → muted gray (same as idle) -->
|
||||
<Style Selector="Border.chip.wt-discarded">
|
||||
<Setter Property="Background" Value="{StaticResource Surface2Brush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource LineBrush}" />
|
||||
</Style>
|
||||
<Style Selector="Border.chip.wt-discarded > TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource TextMuteBrush}" />
|
||||
</Style>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- BUTTONS -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
@@ -24,7 +24,12 @@ public sealed partial class WorktreeOverviewRowViewModel : ViewModelBase
|
||||
[ObservableProperty] private string _path = "";
|
||||
[ObservableProperty] private string _branchName = "";
|
||||
[ObservableProperty] private string _baseCommit = "";
|
||||
[ObservableProperty][NotifyPropertyChangedFor(nameof(IsActive))] private WorktreeState _state;
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsActive))]
|
||||
[NotifyPropertyChangedFor(nameof(IsMerged))]
|
||||
[NotifyPropertyChangedFor(nameof(IsDiscarded))]
|
||||
[NotifyPropertyChangedFor(nameof(IsKept))]
|
||||
private WorktreeState _state;
|
||||
[ObservableProperty] private string? _diffStat;
|
||||
[ObservableProperty][NotifyPropertyChangedFor(nameof(AgeText))] private DateTime _createdAt;
|
||||
[ObservableProperty] private bool _pathExistsOnDisk;
|
||||
@@ -40,6 +45,9 @@ public sealed partial class WorktreeOverviewRowViewModel : ViewModelBase
|
||||
|
||||
public string AgeText => FormatAge(DateTime.UtcNow - CreatedAt);
|
||||
public bool IsActive => State == WorktreeState.Active;
|
||||
public bool IsMerged => State == WorktreeState.Merged;
|
||||
public bool IsDiscarded => State == WorktreeState.Discarded;
|
||||
public bool IsKept => State == WorktreeState.Kept;
|
||||
public bool IsRunning => TaskStatus == TaskStatus.Running;
|
||||
|
||||
private static string FormatAge(TimeSpan ts)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Modals"
|
||||
xmlns:converters="using:ClaudeDo.Ui.Converters"
|
||||
xmlns:ctl="using:ClaudeDo.Ui.Views.Controls"
|
||||
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
||||
x:Class="ClaudeDo.Ui.Views.Modals.WorktreesOverviewModalView"
|
||||
@@ -16,7 +15,6 @@
|
||||
ExtendClientAreaTitleBarHeightHint="-1">
|
||||
|
||||
<Window.Resources>
|
||||
<converters:WorktreeStateColorConverter x:Key="WorktreeStateColor"/>
|
||||
<DataTemplate x:Key="WorktreeRowTemplate" x:DataType="vm:WorktreeOverviewRowViewModel">
|
||||
<Border Classes="task-row"
|
||||
Classes.selected="{Binding IsSelected}"
|
||||
@@ -79,10 +77,13 @@
|
||||
<TextBlock Grid.Column="2" Classes="meta" VerticalAlignment="Center"
|
||||
Text="{Binding MergeOutcome}"
|
||||
IsVisible="{Binding HasOutcome}"/>
|
||||
<Border Grid.Column="3" CornerRadius="3" Padding="6,2" VerticalAlignment="Center"
|
||||
Background="{Binding State, Converter={StaticResource WorktreeStateColor}}">
|
||||
<TextBlock Classes="meta" Text="{Binding State}" Foreground="{DynamicResource DeepBrush}"
|
||||
HorizontalAlignment="Center"/>
|
||||
<Border Grid.Column="3" Classes="chip"
|
||||
Classes.wt-active="{Binding IsActive}"
|
||||
Classes.wt-merged="{Binding IsMerged}"
|
||||
Classes.wt-discarded="{Binding IsDiscarded}"
|
||||
Classes.wt-kept="{Binding IsKept}"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding State}"/>
|
||||
</Border>
|
||||
<TextBlock Grid.Column="4" Classes="meta" Text="{Binding DiffStat}" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="5" Classes="meta" Text="{Binding AgeText}" VerticalAlignment="Center"/>
|
||||
|
||||
Reference in New Issue
Block a user