Files
ClaudeDo/src/ClaudeDo.Ui/Views/Modals/DiffViewerView.axaml
T

179 lines
9.5 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Modals"
xmlns:ctl="using:ClaudeDo.Ui.Views.Controls"
xmlns:loc="using:ClaudeDo.Ui.Localization"
x:Class="ClaudeDo.Ui.Views.Modals.DiffViewerView"
x:DataType="vm:DiffViewerViewModel"
Title="{loc:Tr modals.diff.windowTitle}"
Width="1200" Height="800" MinWidth="700" MinHeight="450"
CanResize="True"
WindowDecorations="BorderOnly"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaTitleBarHeightHint="-1"
WindowStartupLocation="CenterOwner"
Background="{DynamicResource SurfaceBrush}">
<Window.KeyBindings>
<KeyBinding Gesture="Escape" Command="{Binding CloseCommand}"/>
</Window.KeyBindings>
<ctl:ModalShell Title="{loc:Tr modals.diff.title}" CloseCommand="{Binding CloseCommand}">
<ctl:ModalShell.Footer>
<StackPanel Orientation="Horizontal" Spacing="8"
HorizontalAlignment="Right" VerticalAlignment="Center">
<Button Classes="btn" Content="{loc:Tr modals.diff.merge}"
Command="{Binding MergeCommand}"
IsVisible="{Binding ShowMerge}"/>
</StackPanel>
</ctl:ModalShell.Footer>
<DockPanel>
<!-- View toolbar: layout + wrap, both persisted -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="8" Margin="16,8,16,0">
<ToggleButton Content="{loc:Tr modals.diff.splitView}" IsChecked="{Binding IsSplitView}"/>
<ToggleButton Content="{loc:Tr modals.diff.wrapLines}" IsChecked="{Binding WrapLines}"/>
</StackPanel>
<!-- Planning toolbar: combined-mode toggle + warning/loading -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="8" Margin="16,8,16,0"
IsVisible="{Binding IsPlanning}">
<ToggleButton Content="{loc:Tr planning.diff.previewCombined}" IsChecked="{Binding IsCombinedMode}"/>
<TextBlock Text="{Binding CombinedWarning}"
Foreground="{DynamicResource BloodBrush}"
VerticalAlignment="Center"
IsVisible="{Binding CombinedWarning, Converter={x:Static ObjectConverters.IsNotNull}}"/>
<TextBlock Text="{loc:Tr planning.diff.loading}"
VerticalAlignment="Center"
IsVisible="{Binding IsLoadingCombined}"/>
</StackPanel>
<!-- Body: nav | splitter | diff -->
<Grid ColumnDefinitions="280,4,*" Margin="16">
<!-- Left nav: file tree (Files) OR subtask list (Planning) -->
<Border Grid.Column="0" Classes="island">
<DockPanel>
<Border DockPanel.Dock="Top" Classes="island-header" IsVisible="{Binding !IsPlanning}">
<TextBlock Classes="eyebrow" Text="{loc:Tr modals.diff.filesHeader}"/>
</Border>
<Panel>
<!-- Files: folder tree -->
<TreeView x:Name="FileTree"
ItemsSource="{Binding FileTree}"
SelectedItem="{Binding SelectedNode, Mode=TwoWay}"
Background="Transparent"
BorderThickness="0"
IsVisible="{Binding !IsPlanning}">
<TreeView.Styles>
<Style Selector="TreeViewItem" x:DataType="vm:DiffTreeNodeViewModel">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
</Style>
</TreeView.Styles>
<TreeView.ItemTemplate>
<TreeDataTemplate DataType="vm:DiffTreeNodeViewModel" ItemsSource="{Binding Children}">
<Border Background="Transparent" Tapped="OnNodeTapped" Cursor="Hand" Padding="0,2">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0" Tag="{Binding StatusCode}" CornerRadius="3" Padding="4,0" Margin="0,0,6,0"
VerticalAlignment="Center"
IsVisible="{Binding StatusCode, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
<TextBlock Text="{Binding StatusCode}"
FontFamily="{DynamicResource MonoFont}" FontSize="{StaticResource FontSizeEyebrow}"
Foreground="{DynamicResource TextBrush}"/>
</Border>
<TextBlock Grid.Column="1" Classes="meta" Text="{Binding Name}"
VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="4" VerticalAlignment="Center"
Margin="0,0,8,0"
IsVisible="{Binding ShowStats}">
<TextBlock Foreground="{DynamicResource MossBrightBrush}" FontSize="{StaticResource FontSizeEyebrow}"
Text="{Binding Additions, StringFormat='+{0}'}"/>
<TextBlock Foreground="{DynamicResource BloodBrush}" FontSize="{StaticResource FontSizeEyebrow}"
Text="{Binding Deletions, StringFormat='{0}'}"/>
</StackPanel>
</Grid>
</Border>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<!-- Planning: subtask list -->
<ListBox ItemsSource="{Binding Subtasks}"
SelectedItem="{Binding SelectedSubtask}"
IsEnabled="{Binding !IsCombinedMode}"
IsVisible="{Binding IsPlanning}"
Background="Transparent"
BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="vm:SubtaskDiffRow">
<Border Padding="10,8" Background="Transparent">
<StackPanel Spacing="2">
<TextBlock Classes="title" Text="{Binding Title}" TextTrimming="CharacterEllipsis"/>
<TextBlock Classes="meta" Text="{Binding DiffStat}"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Panel>
</DockPanel>
</Border>
<GridSplitter Grid.Column="1" ResizeDirection="Columns" Background="{DynamicResource LineBrush}"/>
<!-- Right: diff content (Files per-file pane OR Planning flat diff) -->
<Border Grid.Column="2" Classes="island">
<Panel>
<!-- Files mode: per-file pane with header + placeholders -->
<DockPanel IsVisible="{Binding !IsPlanning}">
<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.HeaderPath}"
VerticalAlignment="Center" TextTrimming="PrefixCharacterEllipsis"/>
</Grid>
</Border>
<Grid Background="{DynamicResource VoidBrush}">
<TextBlock Classes="body" Text="{Binding StatusMessage}"
IsVisible="{Binding StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Classes="body" Text="{loc:Tr modals.diff.binary}"
Foreground="{DynamicResource TextMuteBrush}"
IsVisible="{Binding SelectedFile.IsBinary}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Classes="body" Text="{loc:Tr modals.diff.empty}"
Foreground="{DynamicResource TextMuteBrush}"
IsVisible="{Binding SelectedFile.IsEmptyContent}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<ctl:DiffTextView IsVisible="{Binding SelectedFile.HasLines}"
File="{Binding SelectedFile}"
IsSplit="{Binding IsSplitView}"
WrapLines="{Binding WrapLines}"/>
</Grid>
</DockPanel>
<!-- Planning mode: flat aggregate/combined diff -->
<Grid Background="{DynamicResource VoidBrush}" IsVisible="{Binding IsPlanning}">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<ctl:DiffLinesView Lines="{Binding DiffLines}"/>
</ScrollViewer>
</Grid>
</Panel>
</Border>
</Grid>
</DockPanel>
</ctl:ModalShell>
</Window>