Skip to content

Commit 867d043

Browse files
committed
refactor: Improve commit selection logic and handling
- Refactor commit selection logic to track last selected commit separately and improve multi-selection handling. - Refactor commit selection logic and remove commented auto-navigation code. - Pass the selected commit item to the histories view model when the selection changes.
1 parent b34f74c commit 867d043

File tree

3 files changed

+69
-19
lines changed

3 files changed

+69
-19
lines changed

src/ViewModels/Histories.cs

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.IO;
5-
using System.Linq;
65
using System.Threading.Tasks;
76

87
using Avalonia.Controls;
@@ -61,15 +60,7 @@ public bool IsDateTimeColumnVisible
6160
public List<Models.Commit> Commits
6261
{
6362
get => _commits;
64-
set
65-
{
66-
var lastSelected = SelectedCommit;
67-
if (SetProperty(ref _commits, value))
68-
{
69-
if (value.Count > 0 && lastSelected != null)
70-
SelectedCommit = value.Find(x => x.SHA.Equals(lastSelected.SHA, StringComparison.Ordinal));
71-
}
72-
}
63+
set => SetProperty(ref _commits, value);
7364
}
7465

7566
public Models.CommitGraph Graph
@@ -84,6 +75,12 @@ public Models.Commit SelectedCommit
8475
set => SetProperty(ref _selectedCommit, value);
8576
}
8677

78+
public Models.Commit LastSelectedCommit
79+
{
80+
get => _lastSelectedCommit;
81+
set => SetProperty(ref _lastSelectedCommit, value);
82+
}
83+
8784
public List<Models.Commit> LastSelectedCommits
8885
{
8986
get => _lastSelectedCommits;
@@ -144,6 +141,8 @@ public void Dispose()
144141
_repo = null;
145142
_graph = null;
146143
_selectedCommit = null;
144+
_lastSelectedCommits = null;
145+
_lastSelectedCommit = null;
147146
_detailContext?.Dispose();
148147
_detailContext = null;
149148
}
@@ -216,7 +215,14 @@ public void NavigateTo(string commitSHA)
216215
});
217216
}
218217

219-
public void Select(IList commits)
218+
/// <summary>
219+
///
220+
/// notes: if multi selects, `AutoSelectedCommit` which `Binding Mode=OneWay` will not be updated,
221+
/// so that we could not get the lastSelectedCommit automatically
222+
///
223+
/// </summary>
224+
/// <param name="commits"></param>
225+
public void Select(IList commits, object selectedCommit)
220226
{
221227
if (_ignoreSelectionChange)
222228
return;
@@ -225,13 +231,21 @@ public void Select(IList commits)
225231
{
226232
_repo.SearchCommitContext.Selected = null;
227233
DetailContext = null;
234+
return;
228235
}
229236
else if (commits.Count == 1)
230237
{
231238
var commit = (commits[0] as Models.Commit)!;
232239
if (_repo.SearchCommitContext.Selected == null || !_repo.SearchCommitContext.Selected.SHA.Equals(commit.SHA, StringComparison.Ordinal))
233-
_repo.SearchCommitContext.Selected = _repo.SearchCommitContext.Results?.Find(x => x.SHA.Equals(commit.SHA, StringComparison.Ordinal));
240+
{
241+
var results = _repo.SearchCommitContext.Results;
242+
if (results != null)
243+
{
244+
_repo.SearchCommitContext.Selected = results.Find(x => x.SHA.Equals(commit.SHA, StringComparison.Ordinal));
245+
}
246+
}
234247

248+
// MarkLastSelectedCommitsAsSelected();
235249
SelectedCommit = commit;
236250
NavigationId = _navigationId + 1;
237251

@@ -260,12 +274,48 @@ public void Select(IList commits)
260274
DetailContext = new Models.Count(commits.Count);
261275
}
262276

263-
_repo.SelectedCommits = commits.Cast<Models.Commit>().ToList();
277+
LastSelectedCommit = selectedCommit as Models.Commit;
278+
279+
var lastSelected = new List<Models.Commit>();
280+
foreach (var obj in commits)
281+
{
282+
if (obj is Models.Commit c)
283+
lastSelected.Add(c);
284+
}
285+
LastSelectedCommits = lastSelected;
264286
}
265287

266-
public void MarkCommitsAsSelected(IList<Models.Commit> commits)
288+
public void MarkLastSelectedCommitsAsSelected(IList<Models.Commit> commits)
267289
{
268-
LastSelectedCommits = _commits.Where(x => commits.Any(y => y.SHA == x.SHA)).ToList();
290+
if (commits == null || commits.Count == 0)
291+
{
292+
LastSelectedCommits = [];
293+
NavigationId = _navigationId + 1;
294+
return;
295+
}
296+
297+
var selectedSHAs = new HashSet<string>();
298+
foreach (var c in commits)
299+
selectedSHAs.Add(c.SHA);
300+
301+
var availableCommits = new List<Models.Commit>();
302+
foreach (var c in Commits)
303+
{
304+
if (selectedSHAs.Contains(c.SHA))
305+
availableCommits.Add(c);
306+
}
307+
308+
// if LastSelectedCommits is not empty, find the AutoSelectedCommit or get last one
309+
if (availableCommits.Count > 0 && LastSelectedCommit != null)
310+
{
311+
// List.Find is not LINQ, it's a method of List<T>
312+
SelectedCommit = availableCommits.Find(x => x.SHA == LastSelectedCommit.SHA)
313+
?? availableCommits[0];
314+
}
315+
316+
// set selectItem above(1item), now select others too
317+
LastSelectedCommits = availableCommits;
318+
NavigationId = _navigationId + 1;
269319
}
270320

271321
public async Task<Models.Commit> GetCommitAsync(string sha)
@@ -481,6 +531,7 @@ public void CompareWithWorktree(Models.Commit commit)
481531
private bool _isLoading = true;
482532
private List<Models.Commit> _commits = new List<Models.Commit>();
483533
private List<Models.Commit> _lastSelectedCommits = [];
534+
private Models.Commit _lastSelectedCommit = null;
484535
private Models.CommitGraph _graph = null;
485536
private Models.Commit _selectedCommit = null;
486537
private Models.Bisect _bisect = null;

src/ViewModels/Repository.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45
using System.Text;
56
using System.Threading;
67
using System.Threading.Tasks;
7-
88
using Avalonia.Collections;
99
using Avalonia.Threading;
10-
1110
using CommunityToolkit.Mvvm.ComponentModel;
1211

1312
namespace SourceGit.ViewModels
@@ -1255,7 +1254,7 @@ public void RefreshCommits()
12551254

12561255
BisectState = _histories.UpdateBisectInfo();
12571256

1258-
_histories.MarkCommitsAsSelected(oldSelectedCommits);
1257+
_histories.MarkLastSelectedCommitsAsSelected(_histories.LastSelectedCommits);
12591258

12601259
if (!string.IsNullOrEmpty(_navigateToCommitDelayed))
12611260
NavigateToCommit(_navigateToCommitDelayed);

src/Views/Histories.axaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ private void OnScrollToTopPointerPressed(object sender, PointerPressedEventArgs
322322
private void OnCommitListSelectionChanged(object _, SelectionChangedEventArgs e)
323323
{
324324
if (DataContext is ViewModels.Histories histories)
325-
histories.Select(CommitListContainer.SelectedItems);
325+
histories.Select(CommitListContainer.SelectedItems, CommitListContainer.SelectedItem);
326326

327327
e.Handled = true;
328328
}

0 commit comments

Comments
 (0)