Optimized filtering playlist songs.
This commit is contained in:
@@ -20,11 +20,10 @@ using System.Linq;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Windows.ApplicationModel.DataTransfer;
|
using Windows.ApplicationModel.DataTransfer;
|
||||||
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;
|
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;
|
||||||
using Timer = System.Timers.Timer;
|
using DispatcherQueueTimer = Microsoft.UI.Dispatching.DispatcherQueueTimer;
|
||||||
|
|
||||||
namespace Harmonia.WinUI.ViewModels;
|
namespace Harmonia.WinUI.ViewModels;
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ public partial class PlaylistViewModel : ViewModelBase
|
|||||||
private readonly DispatcherQueue _dispatcherQueue;
|
private readonly DispatcherQueue _dispatcherQueue;
|
||||||
private readonly ConcurrentDictionary<int, CancellationTokenSource> _imageCancellationTokens = [];
|
private readonly ConcurrentDictionary<int, CancellationTokenSource> _imageCancellationTokens = [];
|
||||||
|
|
||||||
private Timer? _filterTimer;
|
private DispatcherQueueTimer? _filterTimer;
|
||||||
|
|
||||||
public Playlist? Playlist { get; private set; }
|
public Playlist? Playlist { get; private set; }
|
||||||
|
|
||||||
@@ -300,26 +299,19 @@ public partial class PlaylistViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
if (_filterTimer == null)
|
if (_filterTimer == null)
|
||||||
{
|
{
|
||||||
_filterTimer = new Timer(300);
|
_filterTimer = _dispatcherQueue.CreateTimer();
|
||||||
_filterTimer.Elapsed += OnFilterTimerElapsed;
|
_filterTimer.Interval = TimeSpan.FromMilliseconds(300);
|
||||||
_filterTimer.Start();
|
_filterTimer.IsRepeating = false;
|
||||||
|
_filterTimer.Tick += OnFilterTimerTick;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_filterTimer.Interval = 300;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnFilterTimerElapsed(object? sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
if (_filterTimer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_filterTimer.Stop();
|
_filterTimer.Stop();
|
||||||
_filterTimer.Dispose();
|
_filterTimer.Start();
|
||||||
_filterTimer = null;
|
}
|
||||||
|
|
||||||
_dispatcherQueue.TryEnqueue(UpdateFilteredSongs);
|
private void OnFilterTimerTick(DispatcherQueueTimer sender, object args)
|
||||||
|
{
|
||||||
|
UpdateFilteredSongs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFilteredSongs()
|
private void UpdateFilteredSongs()
|
||||||
@@ -327,32 +319,31 @@ public partial class PlaylistViewModel : ViewModelBase
|
|||||||
if (Playlist == null)
|
if (Playlist == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<PlaylistSong> filteredPlaylistSongs = [.. Playlist.Songs.Where(playlistSong => IsFiltered(playlistSong.Song))];
|
string? filter = Filter;
|
||||||
//FilteredPlaylistSongs = [.. filteredPlaylistSongs];
|
HashSet<PlaylistSong> updatedFilterSet = [.. Playlist.Songs.Where(playlistSong => IsFiltered(playlistSong.Song, filter))];
|
||||||
|
|
||||||
for (int i = FilteredPlaylistSongs.Count - 1; i >= 0; i--)
|
for (int i = FilteredPlaylistSongs.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
PlaylistSong playlistSong = FilteredPlaylistSongs[i];
|
PlaylistSong playlistSong = FilteredPlaylistSongs[i];
|
||||||
|
|
||||||
bool inPlaylist = Playlist.Songs.Contains(playlistSong);
|
bool inFilterSet = updatedFilterSet.Contains(playlistSong);
|
||||||
bool inFilter = filteredPlaylistSongs.Contains(playlistSong);
|
|
||||||
|
|
||||||
if (!inPlaylist || !inFilter)
|
if (!inFilterSet)
|
||||||
{
|
FilteredPlaylistSongs.RemoveAt(i);
|
||||||
FilteredPlaylistSongs.Remove(playlistSong);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashSet<PlaylistSong> currentSet = [.. FilteredPlaylistSongs];
|
||||||
int insertionIndex = 0;
|
int insertionIndex = 0;
|
||||||
|
|
||||||
foreach (PlaylistSong playlistSong in Playlist.Songs)
|
foreach (PlaylistSong playlistSong in Playlist.Songs)
|
||||||
{
|
{
|
||||||
bool inFilter = filteredPlaylistSongs.Contains(playlistSong);
|
bool inFilterSet = updatedFilterSet.Contains(playlistSong);
|
||||||
bool inCurrentFilteredList = FilteredPlaylistSongs.Contains(playlistSong);
|
bool inCurrentSet = currentSet.Contains(playlistSong);
|
||||||
|
|
||||||
if (inFilter)
|
if (!inFilterSet)
|
||||||
{
|
continue;
|
||||||
if (!inCurrentFilteredList)
|
|
||||||
|
if (!inCurrentSet)
|
||||||
{
|
{
|
||||||
FilteredPlaylistSongs.Insert(insertionIndex, playlistSong);
|
FilteredPlaylistSongs.Insert(insertionIndex, playlistSong);
|
||||||
}
|
}
|
||||||
@@ -360,28 +351,27 @@ public partial class PlaylistViewModel : ViewModelBase
|
|||||||
insertionIndex++;
|
insertionIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsFiltered(Song song)
|
private static bool IsFiltered(Song song, string? filter)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(Filter))
|
if (string.IsNullOrWhiteSpace(filter))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var shortFileName = Path.GetFileName(song.FileName);
|
var shortFileName = Path.GetFileName(song.FileName);
|
||||||
|
|
||||||
if (shortFileName.Contains(Filter, StringComparison.OrdinalIgnoreCase))
|
if (shortFileName.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(song.Title) == false && song.Title.Contains(Filter, StringComparison.OrdinalIgnoreCase))
|
if (string.IsNullOrWhiteSpace(song.Title) == false && song.Title.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(song.Album) == false && song.Album.Contains(Filter, StringComparison.OrdinalIgnoreCase))
|
if (string.IsNullOrWhiteSpace(song.Album) == false && song.Album.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (song.AlbumArtists.Any(x => x.Contains(Filter, StringComparison.OrdinalIgnoreCase)))
|
if (song.AlbumArtists.Any(x => x.Contains(filter, StringComparison.OrdinalIgnoreCase)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (song.Artists.Any(x => x.Contains(Filter, StringComparison.OrdinalIgnoreCase)))
|
if (song.Artists.Any(x => x.Contains(filter, StringComparison.OrdinalIgnoreCase)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user