Pending UI work: - My Day add/remove context actions on task rows (parent removal cascades to children) - orphan-aware grouping: a child whose parent isn't in view renders as a top-level row, not an indented draft - shell menu restructure (Worker / Repositories submenus); 'Finalize plan' action, drop 'Queue subtasks sequentially' - notes editor refinements - subtask-row hover tweak (Surface3, no transition) - bump Avalonia 12.0.0 -> 12.0.4
242 lines
11 KiB
XML
242 lines
11 KiB
XML
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels"
|
|
xmlns:islands="using:ClaudeDo.Ui.Views.Islands"
|
|
xmlns:converters="using:ClaudeDo.Ui.Converters"
|
|
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
|
x:Class="ClaudeDo.Ui.Views.MainWindow"
|
|
x:DataType="vm:IslandsShellViewModel"
|
|
Title="ClaudeDo"
|
|
Width="1280" Height="820" MinWidth="780" MinHeight="600"
|
|
Background="{DynamicResource VoidBrush}"
|
|
Icon="avares://ClaudeDo.Ui/Assets/ClaudeTask.ico"
|
|
CanResize="True"
|
|
WindowDecorations="BorderOnly"
|
|
ExtendClientAreaToDecorationsHint="True"
|
|
ExtendClientAreaTitleBarHeightHint="-1">
|
|
<Window.Resources>
|
|
<converters:WorkerLogLevelToBrushConverter x:Key="WorkerLogLevelToBrush"/>
|
|
</Window.Resources>
|
|
<Window.KeyBindings>
|
|
<KeyBinding Gesture="OemQuestion" Command="{Binding FocusSearchCommand}"/>
|
|
<KeyBinding Gesture="Shift+OemQuestion" Command="{Binding FocusSearchCommand}"/>
|
|
<KeyBinding Gesture="Ctrl+N" Command="{Binding FocusAddTaskCommand}"/>
|
|
</Window.KeyBindings>
|
|
<Grid x:Name="RootGrid" RowDefinitions="36,Auto,*,22">
|
|
<!-- Custom title bar -->
|
|
<Border Grid.Row="0"
|
|
Background="{DynamicResource DeepBrush}"
|
|
BorderBrush="{DynamicResource LineBrush}"
|
|
BorderThickness="0,0,0,1">
|
|
<Grid ColumnDefinitions="Auto,*,Auto">
|
|
|
|
<!-- Left: brand block -->
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8"
|
|
VerticalAlignment="Center" Margin="14,0,0,0">
|
|
<!-- App icon (matches taskbar) -->
|
|
<Image Source="avares://ClaudeDo.Ui/Assets/ClaudeTask.ico"
|
|
Width="16" Height="16"
|
|
VerticalAlignment="Center"
|
|
RenderOptions.BitmapInterpolationMode="HighQuality"/>
|
|
<!-- CLAUDEDO label -->
|
|
<TextBlock Classes="title-brand-name eyebrow"
|
|
Text="CLAUDEDO"
|
|
Foreground="{DynamicResource TextBrush}"
|
|
LetterSpacing="1.4"
|
|
VerticalAlignment="Center"/>
|
|
<!-- separator dot -->
|
|
<TextBlock Classes="meta"
|
|
Text="·"
|
|
VerticalAlignment="Center"/>
|
|
<!-- current list name -->
|
|
<TextBlock Classes="meta"
|
|
Text="{Binding Lists.SelectedList.Name, Converter={StaticResource UpperCase}}"
|
|
LetterSpacing="1.4"
|
|
VerticalAlignment="Center"/>
|
|
<!-- Help menu -->
|
|
<Menu Margin="12,0,0,0"
|
|
Background="Transparent"
|
|
VerticalAlignment="Center">
|
|
<MenuItem Header="{loc:Tr shell.menu.worker}"
|
|
FontSize="{StaticResource FontSizeMono}"
|
|
Foreground="{DynamicResource TextDimBrush}">
|
|
<MenuItem Header="{loc:Tr shell.menu.restartWorker}"
|
|
Command="{Binding RestartWorkerCommand}"/>
|
|
<MenuItem Header="{loc:Tr shell.menu.checkForUpdates}"
|
|
Command="{Binding CheckForUpdatesCommand}"/>
|
|
</MenuItem>
|
|
<MenuItem Header="{loc:Tr shell.menu.repositories}"
|
|
FontSize="{StaticResource FontSizeMono}"
|
|
Foreground="{DynamicResource TextDimBrush}">
|
|
<MenuItem Header="{loc:Tr shell.menu.addRepos}" Command="{Binding OpenRepoImportCommand}"/>
|
|
<MenuItem Header="{loc:Tr shell.menu.worktrees}"
|
|
Command="{Binding OpenWorktreesOverviewGlobalCommand}"/>
|
|
</MenuItem>
|
|
<MenuItem Header="{loc:Tr shell.menu.help}"
|
|
FontSize="{StaticResource FontSizeMono}"
|
|
Foreground="{DynamicResource TextDimBrush}">
|
|
<MenuItem Header="{loc:Tr shell.menu.weeklyReport}" Command="{Binding OpenWeeklyReportCommand}"/>
|
|
<MenuItem Header="{loc:Tr shell.menu.about}" Command="{Binding OpenAboutCommand}"/>
|
|
</MenuItem>
|
|
</Menu>
|
|
</StackPanel>
|
|
|
|
<!-- Middle: draggable strip -->
|
|
<Border Grid.Column="1" Background="Transparent"
|
|
PointerPressed="OnTitleBarPressed" />
|
|
|
|
<!-- Right: window controls -->
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="0"
|
|
VerticalAlignment="Center" Margin="0,0,4,0">
|
|
<Button Classes="title-ctrl" Click="OnMinimize">
|
|
<PathIcon Data="{StaticResource Icon.WinMin}" Width="10" Height="10"/>
|
|
</Button>
|
|
<Button Classes="title-ctrl" Click="OnToggleMax">
|
|
<PathIcon x:Name="MaxIcon" Data="{StaticResource Icon.WinMax}" Width="10" Height="10"/>
|
|
</Button>
|
|
<Button Classes="title-ctrl close" Click="OnClose">
|
|
<PathIcon Data="{StaticResource Icon.WinClose}" Width="10" Height="10"/>
|
|
</Button>
|
|
</StackPanel>
|
|
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Update banner -->
|
|
<Border Grid.Row="1"
|
|
Background="{DynamicResource DeepBrush}"
|
|
BorderBrush="{DynamicResource LineBrush}"
|
|
BorderThickness="0,0,0,1"
|
|
Padding="14,6"
|
|
IsVisible="{Binding IsUpdateBannerVisible}">
|
|
<Grid ColumnDefinitions="*,Auto,Auto">
|
|
<TextBlock Grid.Column="0"
|
|
Classes="body"
|
|
VerticalAlignment="Center">
|
|
<Run Text="{loc:Tr shell.update.available}"/>
|
|
<Run Text="{Binding UpdateCheck.CurrentVersion}"/>
|
|
<Run Text=" → v"/>
|
|
<Run Text="{Binding UpdateBannerLatestVersion}"/>
|
|
</TextBlock>
|
|
<Button Grid.Column="1"
|
|
Classes="btn"
|
|
Margin="0,0,8,0"
|
|
Content="{loc:Tr shell.update.updateNow}"
|
|
Command="{Binding UpdateNowCommand}"/>
|
|
<Button Grid.Column="2"
|
|
Classes="btn"
|
|
Content="{loc:Tr shell.update.dismiss}"
|
|
Command="{Binding DismissBannerCommand}"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Inline update status (appears at right of banner row when no banner) -->
|
|
<TextBlock Grid.Row="1"
|
|
Classes="meta"
|
|
HorizontalAlignment="Right"
|
|
VerticalAlignment="Center"
|
|
Margin="0,0,14,0"
|
|
Text="{Binding InlineUpdateStatus}"
|
|
IsVisible="{Binding InlineUpdateStatus, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
|
|
|
<!-- Background gradient layer -->
|
|
<Border Grid.Row="2">
|
|
<Border.Background>
|
|
<RadialGradientBrush Center="50%,50%" GradientOrigin="50%,50%" RadiusX="70%" RadiusY="70%">
|
|
<GradientStop Offset="0" Color="{StaticResource DeepColor}" />
|
|
<GradientStop Offset="1" Color="{StaticResource VoidColor}" />
|
|
</RadialGradientBrush>
|
|
</Border.Background>
|
|
</Border>
|
|
|
|
<!-- Three islands (user-resizable) -->
|
|
<Grid Grid.Row="2" Margin="7">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="260" MinWidth="200"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="*" MinWidth="320"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="460" MinWidth="280"/>
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Border Grid.Column="0" Classes="island" Margin="3">
|
|
<islands:ListsIslandView DataContext="{Binding Lists}"/>
|
|
</Border>
|
|
|
|
<GridSplitter Grid.Column="1"
|
|
Width="3"
|
|
Background="Transparent"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Stretch"
|
|
ResizeDirection="Columns"
|
|
ResizeBehavior="PreviousAndNext"/>
|
|
|
|
<Border Grid.Column="2" Classes="island" Margin="3">
|
|
<islands:TasksIslandView DataContext="{Binding Tasks}"/>
|
|
</Border>
|
|
|
|
<GridSplitter Grid.Column="3"
|
|
Width="3"
|
|
Background="Transparent"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Stretch"
|
|
ResizeDirection="Columns"
|
|
ResizeBehavior="PreviousAndNext"
|
|
IsVisible="{Binding ShowDetails}"/>
|
|
|
|
<Border Grid.Column="4" Classes="island" Margin="3"
|
|
IsVisible="{Binding ShowDetails}">
|
|
<islands:DetailsIslandView DataContext="{Binding Details}"/>
|
|
</Border>
|
|
</Grid>
|
|
|
|
<!-- Footer: connection status -->
|
|
<Border Grid.Row="3"
|
|
Background="{DynamicResource DeepBrush}"
|
|
BorderBrush="{DynamicResource LineBrush}"
|
|
BorderThickness="0,1,0,0">
|
|
<DockPanel LastChildFill="True" Margin="14,0">
|
|
<!-- Left: connection pill (click to open worker help) -->
|
|
<Button DockPanel.Dock="Left"
|
|
Command="{Binding OpenWorkerConnectionHelpCommand}"
|
|
Background="Transparent" BorderThickness="0" Padding="0"
|
|
Cursor="Hand" VerticalAlignment="Center">
|
|
<StackPanel Orientation="Horizontal" Spacing="7" VerticalAlignment="Center">
|
|
<Ellipse Width="7" Height="7" Fill="{DynamicResource StatusRunningBrush}"
|
|
IsVisible="{Binding Worker.IsConnected}"/>
|
|
<Ellipse Width="7" Height="7" Fill="{DynamicResource StatusReviewBrush}"
|
|
IsVisible="{Binding Worker.IsReconnecting}"/>
|
|
<Ellipse Width="7" Height="7" Fill="{DynamicResource StatusErrorBrush}"
|
|
IsVisible="{Binding IsOffline}"/>
|
|
<TextBlock Classes="eyebrow"
|
|
Text="{Binding ConnectionText, Converter={StaticResource UpperCase}}"
|
|
LetterSpacing="1.4"
|
|
VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<!-- Right: worker log line -->
|
|
<TextBlock DockPanel.Dock="Right"
|
|
Classes="meta"
|
|
Text="{Binding WorkerLogText}"
|
|
IsVisible="{Binding IsWorkerLogVisible}"
|
|
Foreground="{Binding WorkerLogLevel, Converter={StaticResource WorkerLogLevelToBrush}}"
|
|
LetterSpacing="1.4"
|
|
TextTrimming="CharacterEllipsis"
|
|
VerticalAlignment="Center"/>
|
|
|
|
<!-- Right: prime status notification -->
|
|
<TextBlock DockPanel.Dock="Right"
|
|
Classes="meta"
|
|
Text="{Binding PrimeStatus}"
|
|
VerticalAlignment="Center"
|
|
Margin="12,0,0,0"
|
|
IsVisible="{Binding PrimeStatus, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
|
|
<!-- Spacer between pill and log -->
|
|
<Panel/>
|
|
</DockPanel>
|
|
</Border>
|
|
</Grid>
|
|
</Window>
|