feat(ui): add usage pill to footer and mission control header

Adds the IWorkerClient/WorkerClient usage surface (GetUsageSnapshot,
GetModelUsage, GetTaskUsage, UsageUpdated event) and a shared
UsagePillViewModel hosted once in IslandsShellViewModel (footer) and
once in MissionControlViewModel (header), showing "5h X% · 7d Y%"
with warn/blocked/stale states via existing design tokens. The
OpenMonitorCommand is wired but currently a no-op, pending the usage
monitor modal.
This commit is contained in:
mika kuns
2026-08-05 13:16:29 +02:00
parent 6e2158d157
commit 7cbd4e66ae
16 changed files with 414 additions and 4 deletions
@@ -0,0 +1,25 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
x:Class="ClaudeDo.Ui.Views.Controls.UsagePill"
x:DataType="vm:UsagePillViewModel">
<Button Command="{Binding OpenMonitorCommand}"
Background="Transparent" BorderThickness="0" Padding="0"
Cursor="Hand" VerticalAlignment="Center"
ToolTip.Tip="{Binding Tooltip}">
<StackPanel Orientation="Horizontal" Spacing="7" VerticalAlignment="Center">
<Ellipse Width="7" Height="7" Fill="{DynamicResource TextDimBrush}"
IsVisible="{Binding ShowNormalDot}"/>
<Ellipse Width="7" Height="7" Fill="{DynamicResource StatusReviewBrush}"
IsVisible="{Binding ShowWarnDot}"/>
<Ellipse Width="7" Height="7" Fill="{DynamicResource StatusErrorBrush}"
IsVisible="{Binding IsBlocked}"/>
<Ellipse Width="7" Height="7" Fill="{DynamicResource TextMuteBrush}"
IsVisible="{Binding ShowStaleDot}"/>
<TextBlock Classes="eyebrow"
Text="{Binding Text, Converter={StaticResource UpperCase}}"
LetterSpacing="1.4"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
</UserControl>
@@ -0,0 +1,8 @@
using Avalonia.Controls;
namespace ClaudeDo.Ui.Views.Controls;
public partial class UsagePill : UserControl
{
public UsagePill() => InitializeComponent();
}
+7
View File
@@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
xmlns:islands="using:ClaudeDo.Ui.Views.Islands"
xmlns:controls="using:ClaudeDo.Ui.Views.Controls"
xmlns:converters="using:ClaudeDo.Ui.Converters"
xmlns:loc="using:ClaudeDo.Ui.Localization"
x:Class="ClaudeDo.Ui.Views.MainWindow"
@@ -184,6 +185,12 @@
</StackPanel>
</Button>
<!-- Left: usage pill (click opens the usage monitor, wired in a later subtask) -->
<controls:UsagePill DockPanel.Dock="Left"
DataContext="{Binding UsagePill}"
Margin="14,0,0,0"
VerticalAlignment="Center"/>
<!-- Right: worker log line — click to open the Log Visualizer overlay -->
<Button DockPanel.Dock="Right"
Command="{Binding OpenLogVisualizerCommand}"
@@ -3,6 +3,7 @@
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
xmlns:vmm="using:ClaudeDo.Ui.ViewModels.MissionControl"
xmlns:mc="using:ClaudeDo.Ui.Views.MissionControl"
xmlns:controls="using:ClaudeDo.Ui.Views.Controls"
xmlns:loc="using:ClaudeDo.Ui.Localization"
x:DataType="vm:MissionControlViewModel"
x:Class="ClaudeDo.Ui.Views.MissionControl.MissionControlView">
@@ -25,6 +26,9 @@
LetterSpacing="1.4" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8"
VerticalAlignment="Center">
<controls:UsagePill DataContext="{Binding UsagePill}"
Margin="0,0,4,0"
VerticalAlignment="Center"/>
<Button Classes="icon-btn"
Click="OnNewSessionClicked"
ToolTip.Tip="{loc:Tr missionControl.newSession}">