From 740712b53947caa686aa6e8a2509b522170ac7bf Mon Sep 17 00:00:00 2001 From: heartacker Date: Sat, 4 Apr 2026 21:58:38 +0800 Subject: [PATCH 1/3] build: update packages (CommunityToolkit.Mvvm, OpenAI, LiveChartsCore) --- src/SourceGit.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index b2d603770..009d2c89d 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -55,9 +55,9 @@ - - - + + + From b5d0f9de65adb393a2df7121c38f8fe575e5d213 Mon Sep 17 00:00:00 2001 From: heartacker Date: Fri, 8 Aug 2025 15:38:37 +0800 Subject: [PATCH 2/3] feat: remember the multi selected commit if avalible - it is usefull for multi selection. - like two revision compare, - it will keep those selection for compare while filter changed - and it will restore those selection if grapht fresh --- src/ViewModels/Histories.cs | 15 +++++++++++++++ src/ViewModels/Repository.cs | 10 ++++++++++ src/Views/Histories.axaml.cs | 21 +++++++++++++++++++++ src/Views/Repository.axaml | 5 +++-- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index fcd77b17f..be8c771ba 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; using Avalonia.Controls; @@ -83,6 +84,12 @@ public Models.Commit SelectedCommit set => SetProperty(ref _selectedCommit, value); } + public List LastSelectedCommits + { + get => _lastSelectedCommits; + private set => SetProperty(ref _lastSelectedCommits, value); + } + public long NavigationId { get => _navigationId; @@ -252,6 +259,13 @@ public void Select(IList commits) _repo.SearchCommitContext.Selected = null; DetailContext = new Models.Count(commits.Count); } + + _repo.SelectedCommits = commits.Cast().ToList(); + } + + public void MarkCommitsAsSelected(IList commits) + { + LastSelectedCommits = _commits.Where(x => commits.Any(y => y.SHA == x.SHA)).ToList(); } public async Task GetCommitAsync(string sha) @@ -466,6 +480,7 @@ public void CompareWithWorktree(Models.Commit commit) private CommitDetailSharedData _commitDetailSharedData = null; private bool _isLoading = true; private List _commits = new List(); + private List _lastSelectedCommits = []; private Models.CommitGraph _graph = null; private Models.Commit _selectedCommit = null; private Models.Bisect _bisect = null; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 2945f7c63..3918d966d 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -282,6 +282,12 @@ public SearchCommitContext SearchCommitContext get => _searchCommitContext; } + public List SelectedCommits + { + get => _selectCommits; + set => SetProperty(ref _selectCommits, value); + } + public bool IsLocalBranchGroupExpanded { get => _uiStates.IsLocalBranchesExpandedInSideBar; @@ -1219,6 +1225,7 @@ public void RefreshCommits() { if (_cancellationRefreshCommits is { IsCancellationRequested: false }) _cancellationRefreshCommits.Cancel(); + var oldSelectedCommits = _selectCommits.ToList(); _cancellationRefreshCommits = new CancellationTokenSource(); var token = _cancellationRefreshCommits.Token; @@ -1248,6 +1255,8 @@ public void RefreshCommits() BisectState = _histories.UpdateBisectInfo(); + _histories.MarkCommitsAsSelected(oldSelectedCommits); + if (!string.IsNullOrEmpty(_navigateToCommitDelayed)) NavigateToCommit(_navigateToCommitDelayed); } @@ -1957,6 +1966,7 @@ private async Task AutoFetchOnUIThread() private bool _isSearchingCommits = false; private SearchCommitContext _searchCommitContext = null; + private List _selectCommits = new List(); private string _filter = string.Empty; private List _remotes = []; diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 39312ec6e..7dc98f878 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -123,6 +123,15 @@ public long NavigationId set => SetValue(NavigationIdProperty, value); } + public static readonly StyledProperty> LastSelectedCommitsProperty = + AvaloniaProperty.Register>(nameof(LastSelectedCommits)); + + public List LastSelectedCommits + { + get => GetValue(LastSelectedCommitsProperty); + set => SetValue(LastSelectedCommitsProperty, value); + } + public static readonly StyledProperty IsScrollToTopVisibleProperty = AvaloniaProperty.Register(nameof(IsScrollToTopVisible)); @@ -146,6 +155,18 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang if (CommitListContainer is { SelectedItems.Count: 1, IsLoaded: true } dataGrid) dataGrid.ScrollIntoView(dataGrid.SelectedItem, null); } + if (change.Property == LastSelectedCommitsProperty) + { + if (LastSelectedCommits?.Count > 1 && + (CommitListContainer is DataGrid { IsLoaded: true } dataGrid)) + { + foreach (var c in LastSelectedCommits) + { + dataGrid.SelectedItems.Add(c); + } + } + } + } private void OnCommitListLoaded(object sender, RoutedEventArgs e) diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 8151765df..3866331e4 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -424,7 +424,7 @@ - + - + From d6e87594ab6296db15b90c4150532b358b111226 Mon Sep 17 00:00:00 2001 From: heartacker Date: Tue, 24 Mar 2026 10:38:38 +0800 Subject: [PATCH 3/3] 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. --- src/ViewModels/Histories.cs | 48 ++++++++++++++++++++++++++---------- src/ViewModels/Repository.cs | 5 ++-- src/Views/Histories.axaml.cs | 2 +- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index be8c771ba..d6c15930c 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -61,15 +61,7 @@ public bool IsDateTimeColumnVisible public List Commits { get => _commits; - set - { - var lastSelected = SelectedCommit; - if (SetProperty(ref _commits, value)) - { - if (value.Count > 0 && lastSelected != null) - SelectedCommit = value.Find(x => x.SHA == lastSelected.SHA); - } - } + set => SetProperty(ref _commits, value); } public Models.CommitGraph Graph @@ -84,6 +76,12 @@ public Models.Commit SelectedCommit set => SetProperty(ref _selectedCommit, value); } + public Models.Commit LastSelectedCommit + { + get => _lastSelectedCommit; + set => SetProperty(ref _lastSelectedCommit, value); + } + public List LastSelectedCommits { get => _lastSelectedCommits; @@ -144,6 +142,8 @@ public void Dispose() _repo = null; _graph = null; _selectedCommit = null; + _lastSelectedCommits = null; + _lastSelectedCommit = null; _detailContext?.Dispose(); _detailContext = null; } @@ -216,7 +216,14 @@ public void NavigateTo(string commitSHA) }); } - public void Select(IList commits) + /// + /// + /// notes: if multi selects, `AutoSelectedCommit` which `Binding Mode=OneWay` will not be updated, + /// so that we could not get the lastSelectedCommit automatically + /// + /// + /// + public void Select(IList commits, object selectedCommit) { if (_ignoreSelectionChange) return; @@ -225,6 +232,7 @@ public void Select(IList commits) { _repo.SearchCommitContext.Selected = null; DetailContext = null; + return; } else if (commits.Count == 1) { @@ -232,6 +240,7 @@ public void Select(IList commits) if (_repo.SearchCommitContext.Selected == null || _repo.SearchCommitContext.Selected.SHA != commit.SHA) _repo.SearchCommitContext.Selected = _repo.SearchCommitContext.Results?.Find(x => x.SHA == commit.SHA); + // MarkLastSelectedCommitsAsSelected(); SelectedCommit = commit; NavigationId = _navigationId + 1; @@ -260,12 +269,24 @@ public void Select(IList commits) DetailContext = new Models.Count(commits.Count); } - _repo.SelectedCommits = commits.Cast().ToList(); + LastSelectedCommit = selectedCommit as Models.Commit; + LastSelectedCommits = commits.Cast().ToList(); } - public void MarkCommitsAsSelected(IList commits) + public void MarkLastSelectedCommitsAsSelected(params IList commits) { - LastSelectedCommits = _commits.Where(x => commits.Any(y => y.SHA == x.SHA)).ToList(); + var availableCommits = Commits.Where(x => commits.Any(y => y.SHA == x.SHA)).ToList(); + + // if LastSelectedCommits is not empty, find the AutoSelectedCommit or get last one + if (availableCommits.Count > 0 && LastSelectedCommit != null) + { + // find in oldAvailable or get last one + SelectedCommit = availableCommits.Find(x => x.SHA == LastSelectedCommit.SHA) + ?? availableCommits.FirstOrDefault(); + } + // set selectItem above(1item), now select others too + LastSelectedCommits = availableCommits; + NavigationId = _navigationId + 1; } public async Task GetCommitAsync(string sha) @@ -481,6 +502,7 @@ public void CompareWithWorktree(Models.Commit commit) private bool _isLoading = true; private List _commits = new List(); private List _lastSelectedCommits = []; + private Models.Commit _lastSelectedCommit = null; private Models.CommitGraph _graph = null; private Models.Commit _selectedCommit = null; private Models.Bisect _bisect = null; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 3918d966d..82b0e8d4b 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1,13 +1,12 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; - using Avalonia.Collections; using Avalonia.Threading; - using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels @@ -1255,7 +1254,7 @@ public void RefreshCommits() BisectState = _histories.UpdateBisectInfo(); - _histories.MarkCommitsAsSelected(oldSelectedCommits); + _histories.MarkLastSelectedCommitsAsSelected(_histories.LastSelectedCommits); if (!string.IsNullOrEmpty(_navigateToCommitDelayed)) NavigateToCommit(_navigateToCommitDelayed); diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 7dc98f878..e4fb4fc96 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -322,7 +322,7 @@ private void OnScrollToTopPointerPressed(object sender, PointerPressedEventArgs private void OnCommitListSelectionChanged(object _, SelectionChangedEventArgs e) { if (DataContext is ViewModels.Histories histories) - histories.Select(CommitListContainer.SelectedItems); + histories.Select(CommitListContainer.SelectedItems, CommitListContainer.SelectedItem); e.Handled = true; }