diff --git a/src/ClaudeDo.Ui/Converters/DiffLineKindToBrushConverter.cs b/src/ClaudeDo.Ui/Converters/DiffLineKindToBrushConverter.cs new file mode 100644 index 0000000..e7c1f46 --- /dev/null +++ b/src/ClaudeDo.Ui/Converters/DiffLineKindToBrushConverter.cs @@ -0,0 +1,24 @@ +using System.Globalization; +using Avalonia.Data.Converters; +using Avalonia.Media; +using ClaudeDo.Ui.ViewModels.Modals; + +namespace ClaudeDo.Ui.Converters; + +public sealed class DiffLineKindToBrushConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) => + value is WorktreeDiffLineKind kind + ? kind switch + { + WorktreeDiffLineKind.Added => new SolidColorBrush(Color.Parse("#66BB6A")), + WorktreeDiffLineKind.Removed => new SolidColorBrush(Color.Parse("#EF5350")), + WorktreeDiffLineKind.Hunk => new SolidColorBrush(Color.Parse("#42A5F5")), + WorktreeDiffLineKind.Header => new SolidColorBrush(Color.Parse("#9E9E9E")), + _ => new SolidColorBrush(Color.Parse("#CFD8DC")), + } + : new SolidColorBrush(Color.Parse("#CFD8DC")); + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotSupportedException(); +} diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/WorktreeModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/WorktreeModalViewModel.cs index d0d1492..26661c5 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/WorktreeModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/WorktreeModalViewModel.cs @@ -5,6 +5,14 @@ using ClaudeDo.Data.Git; namespace ClaudeDo.Ui.ViewModels.Modals; +public enum WorktreeDiffLineKind { Header, Hunk, Added, Removed, Context } + +public sealed partial class WorktreeDiffLineViewModel : ViewModelBase +{ + public required string Text { get; init; } + public required WorktreeDiffLineKind Kind { get; init; } +} + public sealed partial class WorktreeNodeViewModel : ViewModelBase { public required string Name { get; init; } @@ -19,11 +27,11 @@ public sealed partial class WorktreeModalViewModel : ViewModelBase private readonly GitService _git; public ObservableCollection Root { get; } = new(); + public ObservableCollection SelectedFileDiffLines { get; } = new(); [ObservableProperty] private string _worktreePath = ""; [ObservableProperty] private string? _baseCommit; [ObservableProperty] private WorktreeNodeViewModel? _selectedNode; - [ObservableProperty] private string _selectedFileDiff = ""; // Set by the view (same pattern as DiffModalViewModel.CloseAction) public Action? CloseAction { get; set; } @@ -40,19 +48,33 @@ public sealed partial class WorktreeModalViewModel : ViewModelBase private async Task LoadFileDiffAsync(WorktreeNodeViewModel? node) { - if (node is null || node.IsDirectory || string.IsNullOrEmpty(node.RelativePath)) - { - SelectedFileDiff = ""; - return; - } + SelectedFileDiffLines.Clear(); + if (node is null || node.IsDirectory || string.IsNullOrEmpty(node.RelativePath)) + return; + + string diff; try { - SelectedFileDiff = await _git.GetFileDiffAsync(WorktreePath, BaseCommit, node.RelativePath); + diff = await _git.GetFileDiffAsync(WorktreePath, BaseCommit, node.RelativePath); } catch { - SelectedFileDiff = ""; + return; + } + + foreach (var line in diff.Split('\n')) + { + var kind = line switch + { + _ when line.StartsWith("+++") || line.StartsWith("---") => WorktreeDiffLineKind.Header, + _ when line.StartsWith("@@") => WorktreeDiffLineKind.Hunk, + _ when line.StartsWith('+') => WorktreeDiffLineKind.Added, + _ when line.StartsWith('-') => WorktreeDiffLineKind.Removed, + _ when line.StartsWith("diff ") || line.StartsWith("index ") || line.StartsWith("\\ ") => WorktreeDiffLineKind.Header, + _ => WorktreeDiffLineKind.Context, + }; + SelectedFileDiffLines.Add(new WorktreeDiffLineViewModel { Text = line, Kind = kind }); } } diff --git a/src/ClaudeDo.Ui/Views/Modals/WorktreeModalView.axaml b/src/ClaudeDo.Ui/Views/Modals/WorktreeModalView.axaml index 0bbf09a..c3b736d 100644 --- a/src/ClaudeDo.Ui/Views/Modals/WorktreeModalView.axaml +++ b/src/ClaudeDo.Ui/Views/Modals/WorktreeModalView.axaml @@ -1,18 +1,24 @@ + + + + @@ -77,11 +83,17 @@ HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="4,0,8,8"> - + + + + + + + diff --git a/src/ClaudeDo.Ui/Views/Modals/WorktreesOverviewModalView.axaml b/src/ClaudeDo.Ui/Views/Modals/WorktreesOverviewModalView.axaml index cbf552a..f5dd330 100644 --- a/src/ClaudeDo.Ui/Views/Modals/WorktreesOverviewModalView.axaml +++ b/src/ClaudeDo.Ui/Views/Modals/WorktreesOverviewModalView.axaml @@ -9,8 +9,9 @@ CanResize="True" WindowStartupLocation="CenterOwner" Background="{DynamicResource SurfaceBrush}" - SystemDecorations="None" - ExtendClientAreaToDecorationsHint="True"> + SystemDecorations="BorderOnly" + ExtendClientAreaToDecorationsHint="True" + ExtendClientAreaTitleBarHeightHint="-1">