131 lines
3.6 KiB
C#
131 lines
3.6 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);
|
|
}
|
|
|
|
public Playlist? FindPlaylistContaining(string playlistSongUID)
|
|
{
|
|
return _playlistsBySongUid.GetValueOrDefault(playlistSongUID);
|
|
}
|
|
|
|
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));
|
|
}
|
|
}
|
|
} |