feat(ui): show status messages and real diff-stats in DiffModal
- Count additions/deletions per file as lines are parsed. - Surface load failures and empty-diff states via StatusMessage. - Pass the worktree base commit so diffs render against the branch base, not just the working-tree HEAD.
This commit is contained in:
@@ -262,6 +262,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
|
|||||||
Notes = entity.Notes ?? "";
|
Notes = entity.Notes ?? "";
|
||||||
Model = entity.Model;
|
Model = entity.Model;
|
||||||
WorktreePath = entity.Worktree?.Path;
|
WorktreePath = entity.Worktree?.Path;
|
||||||
|
WorktreeBaseCommit = entity.Worktree?.BaseCommit;
|
||||||
WorktreeStateLabel = entity.Worktree?.State.ToString();
|
WorktreeStateLabel = entity.Worktree?.State.ToString();
|
||||||
BranchLine = entity.Worktree is { } w ? $"{w.BranchName} \u2190 main" : null;
|
BranchLine = entity.Worktree is { } w ? $"{w.BranchName} \u2190 main" : null;
|
||||||
AgentStatusLabel = entity.Status.ToString();
|
AgentStatusLabel = entity.Status.ToString();
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ public sealed class DiffLineViewModel
|
|||||||
public sealed class DiffFileViewModel
|
public sealed class DiffFileViewModel
|
||||||
{
|
{
|
||||||
public required string Path { get; init; }
|
public required string Path { get; init; }
|
||||||
public int Additions { get; init; }
|
public int Additions { get; set; }
|
||||||
public int Deletions { get; init; }
|
public int Deletions { get; set; }
|
||||||
public ObservableCollection<DiffLineViewModel> Lines { get; } = new();
|
public ObservableCollection<DiffLineViewModel> Lines { get; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
public ObservableCollection<DiffFileViewModel> Files { get; } = new();
|
public ObservableCollection<DiffFileViewModel> Files { get; } = new();
|
||||||
|
|
||||||
[ObservableProperty] private DiffFileViewModel? _selectedFile;
|
[ObservableProperty] private DiffFileViewModel? _selectedFile;
|
||||||
|
[ObservableProperty] private string? _statusMessage;
|
||||||
|
|
||||||
// Injected action to close the owning Window
|
// Injected action to close the owning Window
|
||||||
public Action? CloseAction { get; set; }
|
public Action? CloseAction { get; set; }
|
||||||
@@ -79,6 +80,7 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
public async Task LoadAsync(CancellationToken ct = default)
|
public async Task LoadAsync(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
Files.Clear();
|
Files.Clear();
|
||||||
|
StatusMessage = null;
|
||||||
|
|
||||||
string raw;
|
string raw;
|
||||||
try
|
try
|
||||||
@@ -87,9 +89,17 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
? await _git.GetBranchDiffAsync(WorktreePath, BaseRef, ct)
|
? await _git.GetBranchDiffAsync(WorktreePath, BaseRef, ct)
|
||||||
: await _git.GetDiffAsync(WorktreePath, ct);
|
: await _git.GetDiffAsync(WorktreePath, ct);
|
||||||
}
|
}
|
||||||
catch { return; }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
StatusMessage = $"Failed to load diff: {ex.Message}";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(raw)) return;
|
if (string.IsNullOrWhiteSpace(raw))
|
||||||
|
{
|
||||||
|
StatusMessage = "No changes to show.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse unified diff — state machine over lines
|
// Parse unified diff — state machine over lines
|
||||||
DiffFileViewModel? current = null;
|
DiffFileViewModel? current = null;
|
||||||
@@ -134,7 +144,7 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
NewNo = newLine++,
|
NewNo = newLine++,
|
||||||
Text = line.Length > 1 ? line[1..] : "",
|
Text = line.Length > 1 ? line[1..] : "",
|
||||||
});
|
});
|
||||||
// Count additions on the file VM
|
current.Additions++;
|
||||||
}
|
}
|
||||||
else if (line.StartsWith('-'))
|
else if (line.StartsWith('-'))
|
||||||
{
|
{
|
||||||
@@ -144,6 +154,7 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
OldNo = oldLine++,
|
OldNo = oldLine++,
|
||||||
Text = line.Length > 1 ? line[1..] : "",
|
Text = line.Length > 1 ? line[1..] : "",
|
||||||
});
|
});
|
||||||
|
current.Deletions++;
|
||||||
}
|
}
|
||||||
else if (line.StartsWith(' '))
|
else if (line.StartsWith(' '))
|
||||||
{
|
{
|
||||||
@@ -158,6 +169,7 @@ public sealed partial class DiffModalViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
SelectedFile = Files.Count > 0 ? Files[0] : null;
|
SelectedFile = Files.Count > 0 ? Files[0] : null;
|
||||||
|
if (Files.Count == 0) StatusMessage = "No changes to show.";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseHunkHeader(string header, out int oldStart, out int newStart)
|
private static void ParseHunkHeader(string header, out int oldStart, out int newStart)
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
FontFamily="{StaticResource MonoFamily}"
|
FontFamily="{StaticResource MonoFamily}"
|
||||||
FontSize="11"
|
FontSize="11"
|
||||||
Foreground="{StaticResource TextDimBrush}"
|
Foreground="{StaticResource TextDimBrush}"
|
||||||
TextTrimming="LeadingEllipsis"/>
|
TextTrimming="PrefixCharacterEllipsis"/>
|
||||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
<Border Classes="chip" Padding="5,2">
|
<Border Classes="chip" Padding="5,2">
|
||||||
<TextBlock Foreground="{StaticResource MossBrightBrush}"
|
<TextBlock Foreground="{StaticResource MossBrightBrush}"
|
||||||
@@ -119,10 +119,16 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- Diff content -->
|
<!-- Diff content -->
|
||||||
<ScrollViewer Grid.Column="1"
|
<Grid Grid.Column="1" Background="{StaticResource VoidBrush}">
|
||||||
HorizontalScrollBarVisibility="Auto"
|
<TextBlock Text="{Binding StatusMessage}"
|
||||||
VerticalScrollBarVisibility="Auto"
|
IsVisible="{Binding StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||||
Background="{StaticResource VoidBrush}">
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{StaticResource TextDimBrush}"
|
||||||
|
FontFamily="{StaticResource MonoFamily}"
|
||||||
|
FontSize="12"/>
|
||||||
|
<ScrollViewer HorizontalScrollBarVisibility="Auto"
|
||||||
|
VerticalScrollBarVisibility="Auto">
|
||||||
<ItemsControl ItemsSource="{Binding SelectedFile.Lines}">
|
<ItemsControl ItemsSource="{Binding SelectedFile.Lines}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate x:DataType="vm:DiffLineViewModel">
|
<DataTemplate x:DataType="vm:DiffLineViewModel">
|
||||||
@@ -169,5 +175,6 @@
|
|||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
Reference in New Issue
Block a user