Skip to content

Commit 02e71d4

Browse files
committed
feature: supports filter displayed branches
1 parent 17e48d8 commit 02e71d4

File tree

6 files changed

+121
-43
lines changed

6 files changed

+121
-43
lines changed

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@
342342
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Configure this repository</x:String>
343343
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">CONTINUE</x:String>
344344
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open In File Browser</x:String>
345+
<x:String x:Key="Text.Repository.FilterBranchTip" xml:space="preserve">Filter Branches</x:String>
345346
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOCAL BRANCHES</x:String>
346347
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navigate To HEAD</x:String>
347348
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Create Branch</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@
342342
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">配置本仓库</x:String>
343343
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">下一步</x:String>
344344
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">在文件浏览器中打开</x:String>
345+
<x:String x:Key="Text.Repository.FilterBranchTip" xml:space="preserve">过滤显示分支</x:String>
345346
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">本地分支</x:String>
346347
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">定位HEAD</x:String>
347348
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">新建分支</x:String>

src/Models/BranchTreeNode.cs renamed to src/ViewModels/BranchTreeNode.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
using Avalonia.Collections;
55

6-
namespace SourceGit.Models
6+
namespace SourceGit.ViewModels
77
{
88
public enum BranchTreeNodeType
99
{
@@ -23,12 +23,12 @@ public class BranchTreeNode
2323

2424
public bool IsUpstreamTrackStatusVisible
2525
{
26-
get => IsBranch && !string.IsNullOrEmpty((Backend as Branch).UpstreamTrackStatus);
26+
get => IsBranch && !string.IsNullOrEmpty((Backend as Models.Branch).UpstreamTrackStatus);
2727
}
2828

2929
public string UpstreamTrackStatus
3030
{
31-
get => Type == BranchTreeNodeType.Branch ? (Backend as Branch).UpstreamTrackStatus : "";
31+
get => Type == BranchTreeNodeType.Branch ? (Backend as Models.Branch).UpstreamTrackStatus : "";
3232
}
3333

3434
public bool IsRemote
@@ -48,15 +48,15 @@ public bool IsBranch
4848

4949
public bool IsCurrent
5050
{
51-
get => IsBranch && (Backend as Branch).IsCurrent;
51+
get => IsBranch && (Backend as Models.Branch).IsCurrent;
5252
}
5353

5454
public class Builder
5555
{
5656
public List<BranchTreeNode> Locals => _locals;
5757
public List<BranchTreeNode> Remotes => _remotes;
5858

59-
public void Run(List<Branch> branches, List<Remote> remotes)
59+
public void Run(List<Models.Branch> branches, List<Models.Remote> remotes, bool bForceExpanded)
6060
{
6161
foreach (var remote in remotes)
6262
{
@@ -66,7 +66,7 @@ public void Run(List<Branch> branches, List<Remote> remotes)
6666
Name = remote.Name,
6767
Type = BranchTreeNodeType.Remote,
6868
Backend = remote,
69-
IsExpanded = _expanded.Contains(path),
69+
IsExpanded = bForceExpanded || _expanded.Contains(path),
7070
};
7171

7272
_maps.Add(path, node);
@@ -78,13 +78,13 @@ public void Run(List<Branch> branches, List<Remote> remotes)
7878
var isFiltered = _filters.Contains(branch.FullName);
7979
if (branch.IsLocal)
8080
{
81-
MakeBranchNode(branch, _locals, "local", isFiltered);
81+
MakeBranchNode(branch, _locals, "local", isFiltered, bForceExpanded);
8282
}
8383
else
8484
{
8585
var remote = _remotes.Find(x => x.Name == branch.Remote);
8686
if (remote != null)
87-
MakeBranchNode(branch, remote.Children, $"remote/{remote.Name}", isFiltered);
87+
MakeBranchNode(branch, remote.Children, $"remote/{remote.Name}", isFiltered, bForceExpanded);
8888
}
8989
}
9090

@@ -113,7 +113,7 @@ private void CollectExpandedNodes(List<BranchTreeNode> nodes, string prefix)
113113
}
114114
}
115115

116-
private void MakeBranchNode(Branch branch, List<BranchTreeNode> roots, string prefix, bool isFiltered)
116+
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, string prefix, bool isFiltered, bool bForceExpanded)
117117
{
118118
var subs = branch.Name.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
119119

@@ -132,8 +132,8 @@ private void MakeBranchNode(Branch branch, List<BranchTreeNode> roots, string pr
132132
}
133133

134134
BranchTreeNode lastFolder = null;
135-
string path = prefix;
136-
for (int i = 0; i < subs.Length - 1; i++)
135+
var path = prefix;
136+
for (var i = 0; i < subs.Length - 1; i++)
137137
{
138138
path = string.Concat(path, "/", subs[i]);
139139
if (_maps.TryGetValue(path, out var value))
@@ -146,7 +146,7 @@ private void MakeBranchNode(Branch branch, List<BranchTreeNode> roots, string pr
146146
{
147147
Name = subs[i],
148148
Type = BranchTreeNodeType.Folder,
149-
IsExpanded = branch.IsCurrent || _expanded.Contains(path),
149+
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(path),
150150
};
151151
roots.Add(lastFolder);
152152
_maps.Add(path, lastFolder);
@@ -157,7 +157,7 @@ private void MakeBranchNode(Branch branch, List<BranchTreeNode> roots, string pr
157157
{
158158
Name = subs[i],
159159
Type = BranchTreeNodeType.Folder,
160-
IsExpanded = branch.IsCurrent || _expanded.Contains(path),
160+
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(path),
161161
};
162162
_maps.Add(path, folder);
163163
lastFolder.Children.Add(folder);
@@ -186,7 +186,7 @@ private void SortNodes(List<BranchTreeNode> nodes)
186186
}
187187
else
188188
{
189-
return (int)(l.Type) - (int)(r.Type);
189+
return (int)l.Type - (int)r.Type;
190190
}
191191
});
192192

src/ViewModels/Repository.cs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ public object SelectedView
8989
set => SetProperty(ref _selectedView, value);
9090
}
9191

92+
[JsonIgnore]
93+
public string SearchBranchFilter
94+
{
95+
get => _searchBranchFilter;
96+
set
97+
{
98+
if (SetProperty(ref _searchBranchFilter, value))
99+
{
100+
var builder = BuildBranchTree(_branches, _remotes);
101+
LocalBranchTrees = builder.Locals;
102+
RemoteBranchTrees = builder.Remotes;
103+
}
104+
}
105+
}
106+
92107
[JsonIgnore]
93108
public List<Models.Remote> Remotes
94109
{
@@ -104,14 +119,14 @@ public List<Models.Branch> Branches
104119
}
105120

106121
[JsonIgnore]
107-
public List<Models.BranchTreeNode> LocalBranchTrees
122+
public List<BranchTreeNode> LocalBranchTrees
108123
{
109124
get => _localBranchTrees;
110125
private set => SetProperty(ref _localBranchTrees, value);
111126
}
112127

113128
[JsonIgnore]
114-
public List<Models.BranchTreeNode> RemoteBranchTrees
129+
public List<BranchTreeNode> RemoteBranchTrees
115130
{
116131
get => _remoteBranchTrees;
117132
private set => SetProperty(ref _remoteBranchTrees, value);
@@ -422,6 +437,11 @@ public void StartSearchCommits()
422437
SearchedCommits = visible;
423438
}
424439

440+
public void ClearSearchBranchFilter()
441+
{
442+
SearchBranchFilter = string.Empty;
443+
}
444+
425445
public void SetWatcherEnabled(bool enabled)
426446
{
427447
if (_watcher != null)
@@ -533,12 +553,7 @@ public void RefreshBranches()
533553
{
534554
var branches = new Commands.QueryBranches(FullPath).Result();
535555
var remotes = new Commands.QueryRemotes(FullPath).Result();
536-
537-
var builder = new Models.BranchTreeNode.Builder();
538-
builder.SetFilters(Filters);
539-
builder.CollectExpandedNodes(_localBranchTrees, true);
540-
builder.CollectExpandedNodes(_remoteBranchTrees, false);
541-
builder.Run(branches, remotes);
556+
var builder = BuildBranchTree(branches, remotes);
542557

543558
Dispatcher.UIThread.Invoke(() =>
544559
{
@@ -1354,6 +1369,32 @@ public ContextMenu CreateContextMenuForSubmodule(string submodule)
13541369
return menu;
13551370
}
13561371

1372+
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
1373+
{
1374+
var builder = new BranchTreeNode.Builder();
1375+
builder.SetFilters(Filters);
1376+
1377+
if (string.IsNullOrEmpty(_searchBranchFilter))
1378+
{
1379+
builder.CollectExpandedNodes(_localBranchTrees, true);
1380+
builder.CollectExpandedNodes(_remoteBranchTrees, false);
1381+
builder.Run(branches, remotes, false);
1382+
}
1383+
else
1384+
{
1385+
var visibles = new List<Models.Branch>();
1386+
foreach (var b in branches)
1387+
{
1388+
if (b.FullName.Contains(_searchBranchFilter, StringComparison.OrdinalIgnoreCase))
1389+
visibles.Add(b);
1390+
}
1391+
1392+
builder.Run(visibles, remotes, true);
1393+
}
1394+
1395+
return builder;
1396+
}
1397+
13571398
private string _fullpath = string.Empty;
13581399
private string _gitDir = string.Empty;
13591400
private Models.GitFlow _gitflow = new Models.GitFlow();
@@ -1372,10 +1413,12 @@ public ContextMenu CreateContextMenuForSubmodule(string submodule)
13721413
private bool _isTagGroupExpanded = false;
13731414
private bool _isSubmoduleGroupExpanded = false;
13741415

1416+
private string _searchBranchFilter = string.Empty;
1417+
13751418
private List<Models.Remote> _remotes = new List<Models.Remote>();
13761419
private List<Models.Branch> _branches = new List<Models.Branch>();
1377-
private List<Models.BranchTreeNode> _localBranchTrees = new List<Models.BranchTreeNode>();
1378-
private List<Models.BranchTreeNode> _remoteBranchTrees = new List<Models.BranchTreeNode>();
1420+
private List<BranchTreeNode> _localBranchTrees = new List<BranchTreeNode>();
1421+
private List<BranchTreeNode> _remoteBranchTrees = new List<BranchTreeNode>();
13791422
private List<Models.Tag> _tags = new List<Models.Tag>();
13801423
private List<string> _submodules = new List<string>();
13811424
private bool _canCommitWithPush = false;

src/Views/Repository.axaml

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
</Grid.ColumnDefinitions>
110110

111111
<!-- Left Normal Mode -->
112-
<Grid Grid.Column="0" RowDefinitions="28,Auto,28,Auto,28,*,28,Auto,28,Auto" Margin="0,0,0,4" IsVisible="{Binding !IsSearching}">
112+
<Grid Grid.Column="0" RowDefinitions="28,Auto,5,28,28,Auto,28,*,28,Auto,28,Auto" Margin="0,0,0,4" IsVisible="{Binding !IsSearching}">
113113
<!-- WorkingCopy -->
114114
<TextBlock Grid.Row="0" Classes="group_header_label" Text="{DynamicResource Text.Repository.Workspace}"/>
115115
<ListBox Grid.Row="1" Classes="page_switcher" Background="Transparent" SelectedIndex="{Binding SelectedViewIndex, Mode=TwoWay}">
@@ -159,9 +159,42 @@
159159
</ListBoxItem>
160160
</ListBox>
161161

162+
<!-- Filter Branches -->
163+
<Rectangle Grid.Row="2" Height=".65" HorizontalAlignment="Stretch" VerticalAlignment="Center" Fill="{DynamicResource Brush.Border2}"/>
164+
<TextBox Grid.Row="3"
165+
Margin="4,2,4,0"
166+
Height="24"
167+
BorderThickness="1"
168+
BorderBrush="{DynamicResource Brush.Border2}"
169+
Background="{DynamicResource Brush.Contents}"
170+
Watermark="{DynamicResource Text.Repository.FilterBranchTip}"
171+
Text="{Binding SearchBranchFilter, Mode=TwoWay}"
172+
VerticalContentAlignment="Center">
173+
<TextBox.InnerLeftContent>
174+
<Path Width="14" Height="14"
175+
Margin="6,0,0,0"
176+
Fill="{DynamicResource Brush.FG2}"
177+
Data="{StaticResource Icons.Search}"/>
178+
</TextBox.InnerLeftContent>
179+
180+
<TextBox.InnerRightContent>
181+
<Button Classes="icon_button"
182+
Width="16"
183+
Margin="0,0,6,0"
184+
Command="{Binding ClearSearchBranchFilter}"
185+
IsVisible="{Binding SearchBranchFilter, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
186+
HorizontalAlignment="Right">
187+
<Path Width="14" Height="14"
188+
Margin="0,1,0,0"
189+
Fill="{DynamicResource Brush.FG1}"
190+
Data="{StaticResource Icons.Clear}"/>
191+
</Button>
192+
</TextBox.InnerRightContent>
193+
</TextBox>
194+
162195
<!-- Local Branches -->
163-
<TextBlock Grid.Row="2" Classes="group_header_label" Text="{DynamicResource Text.Repository.LocalBranches}"/>
164-
<TreeView Grid.Row="3"
196+
<TextBlock Grid.Row="4" Classes="group_header_label" Text="{DynamicResource Text.Repository.LocalBranches}"/>
197+
<TreeView Grid.Row="5"
165198
x:Name="localBranchTree"
166199
MaxHeight="400"
167200
ItemsSource="{Binding LocalBranchTrees}"
@@ -170,12 +203,12 @@
170203
LostFocus="OnLocalBranchTreeLostFocus"
171204
SelectionChanged="OnLocalBranchTreeSelectionChanged">
172205
<TreeView.Styles>
173-
<Style Selector="TreeViewItem" x:DataType="m:BranchTreeNode">
206+
<Style Selector="TreeViewItem" x:DataType="vm:BranchTreeNode">
174207
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
175208
</Style>
176209
</TreeView.Styles>
177210
<TreeView.ItemTemplate>
178-
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type m:BranchTreeNode}">
211+
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:BranchTreeNode}">
179212
<Grid Height="24" ColumnDefinitions="20,*,Auto,Auto" Background="Transparent" ContextRequested="OnLocalBranchContextMenuRequested" DoubleTapped="OnDoubleTappedLocalBranchNode">
180213
<Path Grid.Column="0" Classes="folder_icon" Width="12" Height="12" HorizontalAlignment="Left" Margin="0,1,0,0" IsVisible="{Binding IsFolder}"/>
181214
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Margin="0,2,0,0" Data="{StaticResource Icons.Check}" IsVisible="{Binding IsCurrent}" VerticalAlignment="Center"/>
@@ -208,27 +241,27 @@
208241
</TreeView>
209242

210243
<!-- Remotes -->
211-
<Grid Grid.Row="4" ColumnDefinitions="*,Auto">
244+
<Grid Grid.Row="6" ColumnDefinitions="*,Auto">
212245
<TextBlock Grid.Column="0" Classes="group_header_label" Text="{DynamicResource Text.Repository.Remotes}"/>
213246
<Button Grid.Column="1" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding AddRemote}" ToolTip.Tip="{DynamicResource Text.Repository.Remotes.Add}">
214247
<Path Width="12" Height="12" Data="{StaticResource Icons.Remote.Add}"/>
215248
</Button>
216249
</Grid>
217-
<TreeView Grid.Row="5"
250+
<TreeView Grid.Row="7"
218251
x:Name="remoteBranchTree"
219252
ItemsSource="{Binding RemoteBranchTrees}"
220253
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
221254
ScrollViewer.VerticalScrollBarVisibility="Auto"
222255
LostFocus="OnRemoteBranchTreeLostFocus"
223256
SelectionChanged="OnRemoteBranchTreeSelectionChanged">
224257
<TreeView.Styles>
225-
<Style Selector="TreeViewItem" x:DataType="m:BranchTreeNode">
258+
<Style Selector="TreeViewItem" x:DataType="vm:BranchTreeNode">
226259
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
227260
</Style>
228261
</TreeView.Styles>
229262

230263
<TreeView.ItemTemplate>
231-
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type m:BranchTreeNode}">
264+
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:BranchTreeNode}">
232265
<Grid Height="24" ColumnDefinitions="20,*,Auto" Background="Transparent" ContextRequested="OnRemoteBranchContextMenuRequested">
233266
<Path Grid.Column="0" Classes="folder_icon" Width="10" Height="10" HorizontalAlignment="Left" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" VerticalAlignment="Center"/>
234267
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Margin="0,2,0,0" Data="{StaticResource Icons.Remote}" IsVisible="{Binding IsRemote}" VerticalAlignment="Center"/>
@@ -250,7 +283,7 @@
250283
</TreeView>
251284

252285
<!-- Tags -->
253-
<ToggleButton Grid.Row="6" Classes="group_expander" IsChecked="{Binding IsTagGroupExpanded, Mode=TwoWay}">
286+
<ToggleButton Grid.Row="8" Classes="group_expander" IsChecked="{Binding IsTagGroupExpanded, Mode=TwoWay}">
254287
<Grid ColumnDefinitions="Auto,*,Auto">
255288
<TextBlock Grid.Column="0" Classes="group_header_label" Margin="4,0,0,0" Text="{DynamicResource Text.Repository.Tags}"/>
256289
<TextBlock Grid.Column="1" Text="{Binding Tags, Converter={x:Static c:ListConverters.ToCount}}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold"/>
@@ -259,7 +292,7 @@
259292
</Button>
260293
</Grid>
261294
</ToggleButton>
262-
<DataGrid Grid.Row="7"
295+
<DataGrid Grid.Row="9"
263296
MaxHeight="200"
264297
Background="Transparent"
265298
ItemsSource="{Binding Tags}"
@@ -310,7 +343,7 @@
310343
</DataGrid>
311344

312345
<!-- Submodules -->
313-
<ToggleButton Grid.Row="8" Classes="group_expander" IsChecked="{Binding IsSubmoduleGroupExpanded, Mode=TwoWay}">
346+
<ToggleButton Grid.Row="10" Classes="group_expander" IsChecked="{Binding IsSubmoduleGroupExpanded, Mode=TwoWay}">
314347
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
315348
<TextBlock Grid.Column="0" Classes="group_header_label" Margin="4,0,0,0" Text="{DynamicResource Text.Repository.Submodules}"/>
316349
<TextBlock Grid.Column="1" Text="{Binding Submodules, Converter={x:Static c:ListConverters.ToCount}}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold"/>
@@ -328,7 +361,7 @@
328361
</Button>
329362
</Grid>
330363
</ToggleButton>
331-
<DataGrid Grid.Row="9"
364+
<DataGrid Grid.Row="11"
332365
MaxHeight="200"
333366
Background="Transparent"
334367
ItemsSource="{Binding Submodules}"

0 commit comments

Comments
 (0)