using Harmonia.Core.Models; using Harmonia.Core.Player; using Harmonia.WinUI.Caching; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml.Media.Imaging; using System; using System.Threading; using System.Threading.Tasks; namespace Harmonia.WinUI.ViewModels; public class PlayingSongViewModel : ViewModelBase { private readonly IAudioPlayer _audioPlayer; private readonly IAudioBitmapImageCache _audioBitmapImageCache; private readonly DispatcherQueue _dispatcherQueue; private CancellationTokenSource? _songImageCancellationTokenSource; private Song? _song; public Song? Song { get { return _song; } private set { SetProperty(ref _song, value); } } private BitmapImage? _songImageSource; public BitmapImage? SongImageSource { get { return _songImageSource; } private set { SetProperty(ref _songImageSource, value); } } public PlayingSongViewModel(IAudioPlayer audioPlayer, IAudioBitmapImageCache audioBitmapImageCache) { _audioPlayer = audioPlayer; _audioPlayer.PlayingSongChanged += OnAudioPlayerPlayingSongChanged; _audioBitmapImageCache = audioBitmapImageCache; _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); } private void OnAudioPlayerPlayingSongChanged(object? sender, EventArgs e) { Song = _audioPlayer.PlayingSong?.Song; Task.Run(UpdateImage); } private async Task UpdateImage() { // TODO: Show default picture if (Song == null) return; if (_songImageCancellationTokenSource != null) await _songImageCancellationTokenSource.CancelAsync(); _songImageCancellationTokenSource = new(); CancellationToken cancellationToken = _songImageCancellationTokenSource.Token; _dispatcherQueue.TryEnqueue(async () => { BitmapImage? bitmapImage = await _audioBitmapImageCache.GetAsync(Song, cancellationToken); SongImageSource = bitmapImage; }); } }