From da6a70aec1491878d14d5f104b91e62f79a7df4e Mon Sep 17 00:00:00 2001 From: mika kuns Date: Fri, 24 Jul 2026 11:14:06 +0200 Subject: [PATCH] feat(ui): conflict resolver shows why Continue is disabled Continue was already gated on CanContinue (all files resolved); surface a footer hint counting the still-unresolved conflicts/files so the disabled state is explained, not just for binary files. --- .../Conflicts/ConflictResolverViewModel.cs | 18 +++++++++++++++--- .../Views/Conflicts/ConflictResolverView.axaml | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ClaudeDo.Ui/ViewModels/Conflicts/ConflictResolverViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Conflicts/ConflictResolverViewModel.cs index a4018a81..186d8484 100644 --- a/src/ClaudeDo.Ui/ViewModels/Conflicts/ConflictResolverViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Conflicts/ConflictResolverViewModel.cs @@ -103,9 +103,19 @@ public sealed partial class ConflictResolverViewModel : ObservableObject } } - public string ContinueHint => HasBinaryFiles - ? "Binary conflicts must be resolved externally — abort and resolve in your editor." - : ""; + public string ContinueHint + { + get + { + if (HasBinaryFiles) + return "Binary conflicts must be resolved externally — abort and resolve in your editor."; + var openFiles = Files.Count(f => !f.AllResolved); + if (openFiles == 0) return ""; + var openConflicts = _flat.Count(x => !x.Block.IsResolved); + return $"{openConflicts} {(openConflicts == 1 ? "conflict" : "conflicts")} in " + + $"{openFiles} {(openFiles == 1 ? "file" : "files")} still unresolved."; + } + } private bool InRange => CurrentIndex >= 0 && CurrentIndex < _flat.Count; @@ -188,6 +198,7 @@ public sealed partial class ConflictResolverViewModel : ObservableObject OnPropertyChanged(nameof(HasBinaryFiles)); OnPropertyChanged(nameof(HasMultipleFiles)); OnPropertyChanged(nameof(FilesSummary)); + OnPropertyChanged(nameof(ContinueHint)); RecomputeCanContinue(); if (_flat.Count > 0) MoveTo(0); // also sets ActiveFile via MoveTo @@ -211,6 +222,7 @@ public sealed partial class ConflictResolverViewModel : ObservableObject OnPropertyChanged(nameof(PositionText)); OnPropertyChanged(nameof(ActiveResultText)); OnPropertyChanged(nameof(FilesSummary)); + OnPropertyChanged(nameof(ContinueHint)); } } diff --git a/src/ClaudeDo.Ui/Views/Conflicts/ConflictResolverView.axaml b/src/ClaudeDo.Ui/Views/Conflicts/ConflictResolverView.axaml index 157bd47d..a94c3613 100644 --- a/src/ClaudeDo.Ui/Views/Conflicts/ConflictResolverView.axaml +++ b/src/ClaudeDo.Ui/Views/Conflicts/ConflictResolverView.axaml @@ -67,7 +67,7 @@ + IsVisible="{Binding ContinueHint, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>