Files
harmonia/Harmonia.Core/Playlists/PlaylistManager.cs

126 lines
3.4 KiB
C#

namespace Harmonia.Core.Playlists;
public class PlaylistManager : IPlaylistManager
{
private readonly IPlaylistRepository playlistRepository;
private readonly List<Playlist> _playlists = [];
private readonly Dictionary<string, Playlist> _playlistsBySongUid = [];
public IReadOnlyList<Playlist> Playlists => _playlists;
private Playlist? _currentPlaylist;
public Playlist? CurrentPlaylist
{
get
{
return _currentPlaylist;
}
set
{
_currentPlaylist = value;
CurrentPlaylistChanged?.Invoke(this, new());
}
}
public event EventHandler? CurrentPlaylistChanged;
public event EventHandler<PlaylistAddedEventArgs>? PlaylistAdded;
public event EventHandler<PlaylistRemovedEventArgs>? PlaylistRemoved;
public event EventHandler<PlaylistSaveFailedEventArgs>? PlaylistSaveFailed;
public PlaylistManager(IPlaylistRepository playlistRepository)
{
this.playlistRepository = playlistRepository;
}
public async Task InitializeAsync()
{
_playlists.AddRange(playlistRepository.Get());
foreach (Playlist playlist in _playlists)
{
playlist.PlaylistUpdated += OnPlaylistUpdated;
foreach (PlaylistSong song in playlist.Songs)
{
_playlistsBySongUid[song.UID] = playlist;
}
}
CurrentPlaylist = _playlists.Count > 0 ? _playlists[0] : await AddPlaylistAsync();
}
public async Task<Playlist> AddPlaylistAsync()
{
Playlist playlist = new("New Playlist");
playlist.PlaylistUpdated += OnPlaylistUpdated;
_playlists.Add(playlist);
foreach (PlaylistSong song in playlist.Songs)
{
_playlistsBySongUid[song.UID] = playlist;
}
await SavePlaylistAsync(playlist);
PlaylistAdded?.Invoke(this, new(playlist));
return playlist;
}
public void RemovePlaylist(Playlist playlist)
{
playlist.PlaylistUpdated -= OnPlaylistUpdated;
_playlists.Remove(playlist);
foreach (PlaylistSong song in playlist.Songs)
{
_playlistsBySongUid.Remove(song.UID);
}
playlistRepository.Delete(playlist);
PlaylistRemoved?.Invoke(this, new(playlist));
}
public Playlist? FindPlaylistContaining(PlaylistSong playlistSong)
{
return _playlistsBySongUid.GetValueOrDefault(playlistSong.UID);
}
private async void OnPlaylistUpdated(object? sender, PlaylistUpdatedEventArgs e)
{
if (sender is not Playlist playlist)
return;
switch (e.Action)
{
case PlaylistUpdateAction.Add:
foreach (PlaylistSong song in e.Songs)
{
_playlistsBySongUid[song.UID] = playlist;
}
break;
case PlaylistUpdateAction.Remove:
foreach (PlaylistSong song in e.Songs)
{
_playlistsBySongUid.Remove(song.UID);
}
break;
}
await SavePlaylistAsync(playlist);
}
private async Task SavePlaylistAsync(Playlist playlist)
{
try
{
await playlistRepository.SaveAsync(playlist);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
PlaylistSaveFailed?.Invoke(this, new(playlist, ex));
}
}
}