feat(ui): richer diff viewer + surface child roadblocks on parents
- UnifiedDiffParser detects added/deleted/renamed/binary files; diff modal shows a file list, binary/empty placeholders, and can diff a merged task by commit range after its worktree is gone - DetailsIslandViewModel flags children needing attention (failed, cancelled, awaiting review, or with roadblocks) on the parent - GitService gains worktree head-commit/range support; planning chain, merge orchestration, and session manager tweaks with updated tests - refresh app/installer/worker icons Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,51 +26,100 @@
|
||||
</StackPanel>
|
||||
</ctl:ModalShell.Footer>
|
||||
|
||||
<!-- Body: sidebar + diff content -->
|
||||
<Grid ColumnDefinitions="240,*">
|
||||
<!-- Body: two islands — file list | diff content -->
|
||||
<Grid ColumnDefinitions="280,12,*" Margin="16">
|
||||
|
||||
<!-- File sidebar -->
|
||||
<Border Grid.Column="0"
|
||||
Classes="sidebar-pane">
|
||||
<ListBox ItemsSource="{Binding Files}"
|
||||
SelectedItem="{Binding SelectedFile, Mode=TwoWay}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:DiffFileViewModel">
|
||||
<Border Padding="10,8" Background="Transparent">
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Classes="path-mono" Text="{Binding Path}"
|
||||
TextTrimming="PrefixCharacterEllipsis"/>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<Border Classes="chip" Padding="5,2">
|
||||
<TextBlock Foreground="{DynamicResource MossBrightBrush}"
|
||||
Text="{Binding Additions, StringFormat='+{0}'}"/>
|
||||
</Border>
|
||||
<Border Classes="chip" Padding="5,2">
|
||||
<TextBlock Foreground="{DynamicResource BloodBrush}"
|
||||
Text="{Binding Deletions, StringFormat='−{0}'}"/>
|
||||
</Border>
|
||||
<!-- Files island -->
|
||||
<Border Grid.Column="0" Classes="island">
|
||||
<DockPanel>
|
||||
<Border DockPanel.Dock="Top" Classes="island-header">
|
||||
<TextBlock Classes="eyebrow" Text="{loc:Tr modals.diff.filesHeader}"/>
|
||||
</Border>
|
||||
<ListBox ItemsSource="{Binding Files}"
|
||||
SelectedItem="{Binding SelectedFile, Mode=TwoWay}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:DiffFileViewModel">
|
||||
<Border Padding="10,8" Background="Transparent">
|
||||
<StackPanel Spacing="4">
|
||||
<Grid ColumnDefinitions="Auto,*">
|
||||
<Border Grid.Column="0" Tag="{Binding StatusCode}"
|
||||
CornerRadius="3" Padding="4,0" Margin="0,0,8,0"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding StatusCode}"
|
||||
FontFamily="{DynamicResource MonoFont}"
|
||||
FontSize="{StaticResource FontSizeEyebrow}"
|
||||
Foreground="{DynamicResource TextBrush}"/>
|
||||
</Border>
|
||||
<TextBlock Grid.Column="1" Classes="path-mono" Text="{Binding Path}"
|
||||
VerticalAlignment="Center"
|
||||
TextTrimming="PrefixCharacterEllipsis"/>
|
||||
</Grid>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6"
|
||||
IsVisible="{Binding !IsBinary}">
|
||||
<Border Classes="chip" Padding="5,2">
|
||||
<TextBlock Foreground="{DynamicResource MossBrightBrush}"
|
||||
Text="{Binding Additions, StringFormat='+{0}'}"/>
|
||||
</Border>
|
||||
<Border Classes="chip" Padding="5,2">
|
||||
<TextBlock Foreground="{DynamicResource BloodBrush}"
|
||||
Text="{Binding Deletions, StringFormat='−{0}'}"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Diff content -->
|
||||
<Grid Grid.Column="1" Background="{DynamicResource VoidBrush}">
|
||||
<TextBlock Classes="body" Text="{Binding StatusMessage}"
|
||||
IsVisible="{Binding StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<ctl:DiffLinesView Lines="{Binding SelectedFile.Lines}"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
<!-- Diff content island -->
|
||||
<Border Grid.Column="2" Classes="island">
|
||||
<DockPanel>
|
||||
<Border DockPanel.Dock="Top" Classes="island-header"
|
||||
IsVisible="{Binding SelectedFile, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
<Grid ColumnDefinitions="Auto,*">
|
||||
<Border Grid.Column="0" Tag="{Binding SelectedFile.StatusCode}"
|
||||
CornerRadius="3" Padding="4,0" Margin="0,0,8,0"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding SelectedFile.StatusCode}"
|
||||
FontFamily="{DynamicResource MonoFont}"
|
||||
FontSize="{StaticResource FontSizeEyebrow}"
|
||||
Foreground="{DynamicResource TextBrush}"/>
|
||||
</Border>
|
||||
<TextBlock Grid.Column="1" Classes="path-mono" Text="{Binding SelectedFile.Path}"
|
||||
VerticalAlignment="Center"
|
||||
TextTrimming="PrefixCharacterEllipsis"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid Background="{DynamicResource VoidBrush}">
|
||||
<!-- Load / no-changes message -->
|
||||
<TextBlock Classes="body" Text="{Binding StatusMessage}"
|
||||
IsVisible="{Binding StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<!-- Binary file -->
|
||||
<TextBlock Classes="body" Text="{loc:Tr modals.diff.binary}"
|
||||
Foreground="{DynamicResource TextMuteBrush}"
|
||||
IsVisible="{Binding SelectedFile.IsBinary}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<!-- Empty / no-content file -->
|
||||
<TextBlock Classes="body" Text="{loc:Tr modals.diff.empty}"
|
||||
Foreground="{DynamicResource TextMuteBrush}"
|
||||
IsVisible="{Binding SelectedFile.IsEmptyContent}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<!-- Diff content -->
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
IsVisible="{Binding SelectedFile.HasLines}">
|
||||
<ctl:DiffLinesView Lines="{Binding SelectedFile.Lines}"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ctl:ModalShell>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user