Files
harmonia/Harmonia.UI/Views/PlaylistView.axaml.cs

107 lines
3.0 KiB
C#

using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
using Harmonia.Core.Playlists;
using Harmonia.UI.ViewModels;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
namespace Harmonia.UI.Views;
public partial class PlaylistView : UserControl
{
private readonly PlaylistViewModel _viewModel;
private readonly ConcurrentDictionary<int, CancellationTokenSource> _imageCancellationTokens = [];
public PlaylistView()
{
InitializeComponent();
_viewModel = (PlaylistViewModel)DataContext!;
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
}
private async void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(_viewModel.FilteredPlaylistSongs))
{
await Dispatcher.UIThread.InvokeAsync(SlideInSongs);
}
}
private async Task SlideInSongs()
{
await Animations.Animations.SlideFromRight(100, duration: 300).RunAsync(PlaylistListBox);
}
private void OnLoaded(object? sender, RoutedEventArgs e)
{
//_storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
}
private async void ListBox_DoubleTapped(object? sender, TappedEventArgs e)
{
if (sender is ListBox listBox && listBox.SelectedItem is PlaylistSong playlistSong)
{
await _viewModel.PlaySongAsync(playlistSong);
}
}
private void Image_Loaded(object? sender, RoutedEventArgs e)
{
if (sender is not Image image)
return;
if (image.DataContext is not PlaylistSong playlistSong)
return;
Task.Run(() => DoSomethingAsync(image, playlistSong));
}
private async Task DoSomethingAsync(Image image, PlaylistSong playlistSong)
{
int hashCode = image.GetHashCode();
_imageCancellationTokens.TryGetValue(hashCode, out CancellationTokenSource? cancellationTokenSource);
cancellationTokenSource?.Cancel();
cancellationTokenSource = new();
Bitmap? bitmap = await _viewModel.GetBitmapAsync(playlistSong, cancellationTokenSource.Token);
if (bitmap == null)
return;
await Dispatcher.UIThread.InvokeAsync(() => SetSongImageSource(image, bitmap));
}
private static void SetSongImageSource(Image image, Bitmap bitmap)
{
image.Source = bitmap;
}
private void Image_Unloaded(object? sender, RoutedEventArgs e)
{
if (sender is not Image image)
return;
if (image.DataContext is not PlaylistSong)
return;
if (image.Source is Bitmap bitmap)
{
bitmap.Dispose();
}
image.Source = null;
int hashCode = image.GetHashCode();
_imageCancellationTokens.TryGetValue(hashCode, out CancellationTokenSource? cancellationTokenSource);
cancellationTokenSource?.Cancel();
}
}