Skip to content

Commit aef26d2

Browse files
committed
feat: indicate history filters with no matching branch/tag
1 parent 4fca32f commit aef26d2

4 files changed

Lines changed: 116 additions & 3 deletions

File tree

src/Converters/FilterModeConverters.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Avalonia.Data.Converters;
1+
using System.Collections.Generic;
2+
3+
using Avalonia.Data.Converters;
24
using Avalonia.Media;
35

46
namespace SourceGit.Converters
@@ -15,5 +17,23 @@ public static class FilterModeConverters
1517
_ => Brushes.Transparent,
1618
};
1719
});
20+
21+
public static readonly IMultiValueConverter ToBorderBrushWithMatchState =
22+
new FuncMultiValueConverter<object, IBrush>(values =>
23+
{
24+
var list = new List<object>(values);
25+
if (list.Count < 2 || list[0] is not Models.FilterMode mode)
26+
return Brushes.Transparent;
27+
28+
if (list[1] is true)
29+
return Brushes.Gray;
30+
31+
return mode switch
32+
{
33+
Models.FilterMode.Included => Brushes.Green,
34+
Models.FilterMode.Excluded => Brushes.Red,
35+
_ => Brushes.Transparent,
36+
};
37+
});
1838
}
1939
}

src/Models/HistoryFilter.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using CommunityToolkit.Mvvm.ComponentModel;
1+
using System.Text.Json.Serialization;
2+
3+
using CommunityToolkit.Mvvm.ComponentModel;
24

35
namespace SourceGit.Models
46
{
@@ -43,6 +45,13 @@ public bool IsBranch
4345
get => Type != FilterType.Tag;
4446
}
4547

48+
[JsonIgnore]
49+
public bool HasNoMatch
50+
{
51+
get => _hasNoMatch;
52+
set => SetProperty(ref _hasNoMatch, value);
53+
}
54+
4655
public HistoryFilter()
4756
{
4857
}
@@ -56,5 +65,6 @@ public HistoryFilter(string pattern, FilterType type, FilterMode mode)
5665

5766
private string _pattern = string.Empty;
5867
private FilterMode _mode = FilterMode.None;
68+
private bool _hasNoMatch = false;
5969
}
6070
}

src/ViewModels/Repository.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,7 @@ public void RefreshBranches()
11681168
CurrentBranch = branches.Find(x => x.IsCurrent);
11691169
LocalBranchTrees = builder.Locals;
11701170
RemoteBranchTrees = builder.Remotes;
1171+
UpdateBranchHistoryFilterMatchState();
11711172

11721173
var localBranchesCount = 0;
11731174
foreach (var b in branches)
@@ -1214,6 +1215,7 @@ public void RefreshTags()
12141215

12151216
Tags = tags;
12161217
VisibleTags = BuildVisibleTags();
1218+
UpdateTagHistoryFilterMatchState();
12171219
});
12181220
}, token);
12191221
}
@@ -1788,6 +1790,10 @@ private void RefreshHistoryFilters(bool refresh)
17881790
UpdateBranchTreeFilterMode(LocalBranchTrees, map);
17891791
UpdateBranchTreeFilterMode(RemoteBranchTrees, map);
17901792
UpdateTagFilterMode(map);
1793+
1794+
UpdateBranchHistoryFilterMatchState();
1795+
UpdateTagHistoryFilterMatchState();
1796+
17911797
RefreshCommits();
17921798
}
17931799

@@ -1816,6 +1822,78 @@ private void UpdateTagFilterMode(Dictionary<string, Models.FilterMode> map)
18161822
}
18171823
}
18181824

1825+
private void UpdateBranchHistoryFilterMatchState()
1826+
{
1827+
var branchPaths = new HashSet<string>(StringComparer.Ordinal);
1828+
CollectBranchPaths(LocalBranchTrees, branchPaths);
1829+
CollectBranchPaths(RemoteBranchTrees, branchPaths);
1830+
1831+
foreach (var filter in _uiStates.HistoryFilters)
1832+
{
1833+
switch (filter.Type)
1834+
{
1835+
case Models.FilterType.LocalBranch:
1836+
case Models.FilterType.RemoteBranch:
1837+
filter.HasNoMatch = !branchPaths.Contains(filter.Pattern);
1838+
break;
1839+
case Models.FilterType.LocalBranchFolder:
1840+
case Models.FilterType.RemoteBranchFolder:
1841+
var prefix = filter.Pattern + "/";
1842+
var hasChild = false;
1843+
foreach (var p in branchPaths)
1844+
{
1845+
if (p.StartsWith(prefix, StringComparison.Ordinal))
1846+
{
1847+
hasChild = true;
1848+
break;
1849+
}
1850+
}
1851+
filter.HasNoMatch = !hasChild;
1852+
break;
1853+
}
1854+
}
1855+
}
1856+
1857+
private void UpdateTagHistoryFilterMatchState()
1858+
{
1859+
var tagNames = new HashSet<string>(StringComparer.Ordinal);
1860+
if (VisibleTags is TagCollectionAsTree tree)
1861+
CollectTagNamesRecursive(tree.Tree, tagNames);
1862+
else if (VisibleTags is TagCollectionAsList list)
1863+
{
1864+
foreach (var item in list.TagItems)
1865+
tagNames.Add(item.Tag.Name);
1866+
}
1867+
1868+
foreach (var filter in _uiStates.HistoryFilters)
1869+
{
1870+
if (filter.Type == Models.FilterType.Tag)
1871+
filter.HasNoMatch = !tagNames.Contains(filter.Pattern);
1872+
}
1873+
}
1874+
1875+
private void CollectBranchPaths(List<BranchTreeNode> nodes, HashSet<string> set)
1876+
{
1877+
foreach (var node in nodes)
1878+
{
1879+
if (node.IsBranch)
1880+
set.Add(node.Path);
1881+
else
1882+
CollectBranchPaths(node.Children, set);
1883+
}
1884+
}
1885+
1886+
private static void CollectTagNamesRecursive(List<TagTreeNode> nodes, HashSet<string> set)
1887+
{
1888+
foreach (var node in nodes)
1889+
{
1890+
if (node.IsFolder)
1891+
CollectTagNamesRecursive(node.Children, set);
1892+
else
1893+
set.Add(node.FullPath);
1894+
}
1895+
}
1896+
18191897
private void ResetBranchTreeFilterMode(List<BranchTreeNode> nodes)
18201898
{
18211899
foreach (var node in nodes)

src/Views/Repository.axaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,13 @@
952952
Margin="0,0,6,0"
953953
CornerRadius="12"
954954
BorderThickness="1"
955-
BorderBrush="{Binding Mode, Converter={x:Static c:FilterModeConverters.ToBorderBrush}}"
956955
VerticalAlignment="Center">
956+
<Border.BorderBrush>
957+
<MultiBinding Converter="{x:Static c:FilterModeConverters.ToBorderBrushWithMatchState}">
958+
<Binding Path="Mode"/>
959+
<Binding Path="HasNoMatch"/>
960+
</MultiBinding>
961+
</Border.BorderBrush>
957962
<Grid Margin="8,0">
958963
<Grid.ColumnDefinitions>
959964
<ColumnDefinition Width="Auto"/>

0 commit comments

Comments
 (0)