Skip to content

Add filterbox in Staged area, same as in Unstaged area #1153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions src/ViewModels/WorkingCopy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,28 @@ public string UnstagedFilter
if (_isLoadingData)
return;

VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged);
VisibleUnstaged = GetVisibleChanges(_unstaged, _unstagedFilter);
SelectedUnstaged = [];
}
}
}

public string StagedFilter
{
get => _stagedFilter;
set
{
if (SetProperty(ref _stagedFilter, value))
{
if (_isLoadingData)
return;

VisibleStaged = GetVisibleChanges(_staged, _stagedFilter);
SelectedStaged = [];
}
}
}

public List<Models.Change> Unstaged
{
get => _unstaged;
Expand All @@ -133,6 +149,12 @@ public List<Models.Change> Staged
private set => SetProperty(ref _staged, value);
}

public List<Models.Change> VisibleStaged
{
get => _visibleStaged;
private set => SetProperty(ref _visibleStaged, value);
}

public List<Models.Change> SelectedUnstaged
{
get => _selectedUnstaged;
Expand Down Expand Up @@ -216,6 +238,9 @@ public void Cleanup()
_visibleUnstaged.Clear();
OnPropertyChanged(nameof(VisibleUnstaged));

_visibleStaged.Clear();
OnPropertyChanged(nameof(VisibleStaged));

_unstaged.Clear();
OnPropertyChanged(nameof(Unstaged));

Expand Down Expand Up @@ -269,7 +294,7 @@ public void SetData(List<Models.Change> changes)
}
}

var visibleUnstaged = GetVisibleUnstagedChanges(unstaged);
var visibleUnstaged = GetVisibleChanges(unstaged, _unstagedFilter);
var selectedUnstaged = new List<Models.Change>();
foreach (var c in visibleUnstaged)
{
Expand All @@ -278,8 +303,10 @@ public void SetData(List<Models.Change> changes)
}

var staged = GetStagedChanges();

var visibleStaged = GetVisibleChanges(staged, _stagedFilter);
var selectedStaged = new List<Models.Change>();
foreach (var c in staged)
foreach (var c in visibleStaged)
{
if (lastSelectedStaged.Contains(c.Path))
selectedStaged.Add(c);
Expand All @@ -290,6 +317,7 @@ public void SetData(List<Models.Change> changes)
_isLoadingData = true;
HasUnsolvedConflicts = hasConflict;
VisibleUnstaged = visibleUnstaged;
VisibleStaged = visibleStaged;
Unstaged = unstaged;
Staged = staged;
SelectedUnstaged = selectedUnstaged;
Expand Down Expand Up @@ -337,7 +365,7 @@ public void UnstageSelected(Models.Change next)

public void UnstageAll()
{
UnstageChanges(_staged, null);
UnstageChanges(_visibleStaged, null);
}

public void Discard(List<Models.Change> changes)
Expand All @@ -350,6 +378,11 @@ public void ClearUnstagedFilter()
{
UnstagedFilter = string.Empty;
}

public void ClearStagedFilter()
{
StagedFilter = string.Empty;
}

public async void UseTheirs(List<Models.Change> changes)
{
Expand Down Expand Up @@ -1472,16 +1505,16 @@ public ContextMenu CreateContextForOpenAI()
return menu;
}

private List<Models.Change> GetVisibleUnstagedChanges(List<Models.Change> unstaged)
private List<Models.Change> GetVisibleChanges(List<Models.Change> changes, string filter)
{
if (string.IsNullOrEmpty(_unstagedFilter))
return unstaged;
if (string.IsNullOrEmpty(filter))
return changes;

var visible = new List<Models.Change>();

foreach (var c in unstaged)
foreach (var c in changes)
{
if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase))
if (c.Path.Contains(filter, StringComparison.OrdinalIgnoreCase))
visible.Add(c);
}

Expand Down Expand Up @@ -1599,7 +1632,8 @@ private async void StageChanges(List<Models.Change> changes, Models.Change next)

private async void UnstageChanges(List<Models.Change> changes, Models.Change next)
{
if (changes.Count == 0)
var count = changes.Count;
if (count == 0)
return;

// Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh.
Expand All @@ -1611,16 +1645,15 @@ private async void UnstageChanges(List<Models.Change> changes, Models.Change nex
{
await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec());
}
else if (changes.Count == _staged.Count)
else if (count == _staged.Count)
{
await Task.Run(() => new Commands.Reset(_repo.FullPath).Exec());
}
else
{
for (int i = 0; i < changes.Count; i += 10)
for (int i = 0; i < count; i += 10)
{
var count = Math.Min(10, changes.Count - i);
var step = changes.GetRange(i, count);
var step = changes.GetRange(i, Math.Min(10, count - i));
await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec());
}
}
Expand Down Expand Up @@ -1650,6 +1683,13 @@ private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty)
return;
}

if (!string.IsNullOrEmpty(_stagedFilter))
{
// FIXME - make this a proper warning message-box "Staged-area filter will not be applied to commit. Continue?" Yes/No
App.RaiseException(_repo.FullPath, "Committing with staged-area filter applied is NOT allowed!");
return;
}

if (string.IsNullOrWhiteSpace(_commitMessage))
{
App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!");
Expand Down Expand Up @@ -1729,11 +1769,13 @@ private bool IsChanged(List<Models.Change> old, List<Models.Change> cur)
private List<Models.Change> _unstaged = [];
private List<Models.Change> _visibleUnstaged = [];
private List<Models.Change> _staged = [];
private List<Models.Change> _visibleStaged = [];
private List<Models.Change> _selectedUnstaged = [];
private List<Models.Change> _selectedStaged = [];
private int _count = 0;
private object _detailContext = null;
private string _unstagedFilter = string.Empty;
private string _stagedFilter = string.Empty;
private string _commitMessage = string.Empty;

private bool _hasUnsolvedConflicts = false;
Expand Down
39 changes: 36 additions & 3 deletions src/Views/WorkingCopy.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
Background="{DynamicResource Brush.Border0}"/>

<!-- Staged -->
<Grid Grid.Row="2" RowDefinitions="28,*">
<Grid Grid.Row="2" RowDefinitions="28,36,*">
<!-- Staged Toolbar -->
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto">
Expand All @@ -156,14 +156,47 @@
</Grid>
</Border>

<!-- Staged Filter -->
<Border Grid.Row="1" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
<TextBox Height="24"
Margin="4,0"
BorderThickness="1"
CornerRadius="12"
Text="{Binding StagedFilter, Mode=TwoWay}"
BorderBrush="{DynamicResource Brush.Border2}"
VerticalContentAlignment="Center">
<TextBox.InnerLeftContent>
<Path Width="14" Height="14"
Margin="6,0,0,0"
Fill="{DynamicResource Brush.FG2}"
Data="{StaticResource Icons.Search}"/>
</TextBox.InnerLeftContent>

<TextBox.InnerRightContent>
<Button Classes="icon_button"
Width="16"
Margin="0,0,6,0"
Command="{Binding ClearStagedFilter}"
IsVisible="{Binding StagedFilter, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
HorizontalAlignment="Right">
<Path Width="14" Height="14"
Margin="0,1,0,0"
Fill="{DynamicResource Brush.FG1}"
Data="{StaticResource Icons.Clear}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
</Border>

<!-- Staged Changes -->
<v:ChangeCollectionView Grid.Row="1"
<v:ChangeCollectionView Grid.Row="2"
x:Name="StagedChangesView"
Focusable="True"
IsUnstagedChange="False"
SelectionMode="Multiple"
Background="{DynamicResource Brush.Contents}"
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=StagedChangeViewMode}"
Changes="{Binding Staged}"
Changes="{Binding VisibleStaged}"
SelectedChanges="{Binding SelectedStaged, Mode=TwoWay}"
ContextRequested="OnStagedContextRequested"
ChangeDoubleTapped="OnStagedChangeDoubleTapped"
Expand Down