Added delayed search update timer to XCI File Trimmer dialog and Games Compatibility window to stop phantom duplicate keystrokes from occurring.

This commit is contained in:
Aaron Murgatroyd 2025-05-19 21:01:59 +10:00
parent 1544f54603
commit 4d16b2b4e4
4 changed files with 33 additions and 17 deletions

View file

@ -4,12 +4,15 @@ using Ryujinx.Ava.Systems.AppLibrary;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {
public class CompatibilityViewModel : BaseModel, IDisposable public class CompatibilityViewModel : BaseModel, IDisposable
{ {
private readonly ApplicationLibrary _appLibrary; private readonly ApplicationLibrary _appLibrary;
private string _search;
private Timer _searchTimer;
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityDatabase.Entries; private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityDatabase.Entries;
private string[] _ownedGameTitleIds = []; private string[] _ownedGameTitleIds = [];
@ -54,7 +57,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public void Search(string searchTerm) private void UpdateSearch(string searchTerm)
{ {
if (string.IsNullOrEmpty(searchTerm)) if (string.IsNullOrEmpty(searchTerm))
{ {
@ -64,6 +67,9 @@ namespace Ryujinx.Ava.UI.ViewModels
SetEntries(CompatibilityDatabase.Entries.Where(x => SetEntries(CompatibilityDatabase.Entries.Where(x =>
x.GameName.ContainsIgnoreCase(searchTerm) x.GameName.ContainsIgnoreCase(searchTerm)
|| x.FormattedIssueLabels.ContainsIgnoreCase(searchTerm)
|| x.LocalizedStatus.ContainsIgnoreCase(searchTerm)
|| x.LocalizedStatusDescription.ContainsIgnoreCase(searchTerm)
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm)))); || x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
} }
@ -74,5 +80,21 @@ namespace Ryujinx.Ava.UI.ViewModels
#pragma warning restore MVVMTK0034 #pragma warning restore MVVMTK0034
OnPropertyChanged(nameof(CurrentEntries)); OnPropertyChanged(nameof(CurrentEntries));
} }
public string Search
{
get => _search;
set
{
_search = value;
_searchTimer?.Dispose();
_searchTimer = new Timer(_ =>
{
UpdateSearch(_search);
_searchTimer.Dispose();
_searchTimer = null;
}, null, 250, 0);
}
}
} }
} }

View file

@ -44,6 +44,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private MainWindowViewModel _mainWindowViewModel; private MainWindowViewModel _mainWindowViewModel;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
private string _search; private string _search;
private Timer _searchTimer;
private ProcessingMode _processingMode; private ProcessingMode _processingMode;
private SortField _sortField = SortField.Name; private SortField _sortField = SortField.Name;
private bool _sortAscending = true; private bool _sortAscending = true;
@ -478,7 +479,13 @@ namespace Ryujinx.Ava.UI.ViewModels
set set
{ {
_search = value; _search = value;
FilteringChanged(); _searchTimer?.Dispose();
_searchTimer = new Timer(_ =>
{
FilteringChanged();
_searchTimer.Dispose();
_searchTimer = null;
}, null, 250, 0);
} }
} }

View file

@ -23,12 +23,12 @@
Grid.Column="0" Grid.Column="0"
Margin="15, 0, 7, 0" Margin="15, 0, 7, 0"
ToolTip.Tip="{ext:WindowTitle CompatibilityListTitle, False}"/> ToolTip.Tip="{ext:WindowTitle CompatibilityListTitle, False}"/>
<TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" /> <TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" Text="{Binding Search}" />
<CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" /> <CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" /> <TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid> </Grid>
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto" Name="NormalControls"> <Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto" Name="NormalControls">
<TextBox Name="SearchBoxNormal" Grid.Column="0" Margin="15, 0, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" /> <TextBox Name="SearchBoxNormal" Grid.Column="0" Margin="15, 0, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" Text="{Binding Search}" />
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" /> <CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="2" Padding="0, 0, 1, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" /> <TextBlock Grid.Column="2" Padding="0, 0, 1, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid> </Grid>

View file

@ -29,18 +29,5 @@ namespace Ryujinx.Ava.UI.Windows
FlushControls.IsVisible = !ConfigurationState.Instance.ShowOldUI; FlushControls.IsVisible = !ConfigurationState.Instance.ShowOldUI;
NormalControls.IsVisible = ConfigurationState.Instance.ShowOldUI; NormalControls.IsVisible = ConfigurationState.Instance.ShowOldUI;
} }
// ReSharper disable once UnusedMember.Local
// its referenced in the axaml but rider keeps yelling at me that its unused so
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (DataContext is not CompatibilityViewModel cvm)
return;
if (sender is not TextBox searchBox)
return;
cvm.Search(searchBox.Text);
}
} }
} }