/// <summary> /// Called when the SongStartedMessage has been received /// </summary> /// <param name="message"></param> private static void SongStarted(Song songStarted) { // Update the song index for any playlists for which the previous song and the current song are adjacent Playlists.CheckForAdjacentSongEntries(previousSongIdentity, songStarted.Id); previousSongIdentity = songStarted.Id; }
/// <summary> /// Duplicate a playlist in the other libraries /// </summary> /// <param name="playlistToDuplicate"></param> public static void DuplicatePlaylist(Playlist playlistToDuplicate) { // Duplicate the playlist in all libraries except the one it is in foreach (Library library in Libraries.LibraryCollection) { if (library.Id != playlistToDuplicate.LibraryId) { // If a playlist with the same name already exists then delete it. This is being deleted rather than being reused just in case it // is the wrong type of playlist Playlist existingPlaylist = Playlists.PlaylistCollection .Where(playlist => (playlist.Name == playlistToDuplicate.Name) && (playlist.LibraryId == library.Id)).SingleOrDefault(); if (existingPlaylist != null) { Playlists.DeletePlaylist(existingPlaylist); } if (playlistToDuplicate is SongPlaylist playlist) { DuplicateSongPlaylistAsync(playlist, library.Id); } else { DuplicateAlbumPlaylistAsync(( AlbumPlaylist )playlistToDuplicate, library.Id); } } } }
/// <summary> /// Read all the managed collections and then tell any registered listeners /// </summary> private static async void ReadManagedCollections() { await Songs.GetDataAsync(); await Albums.GetDataAsync(); await Sources.GetDataAsync(); await Artists.GetDataAsync(); await ArtistAlbums.GetDataAsync(); await Libraries.GetDataAsync(); await Playback.GetDataAsync(); await Playlists.GetDataAsync(); await Autoplays.GetDataAsync(); await Tags.GetDataAsync(); await TaggedAlbums.GetDataAsync(); await GenrePopulations.GetDataAsync(); // Carry out some one-off data linking await PopulateArtistsAsync(); await FilterManagementController.FormGenreTagsAsync(); DataAvailable = true; new StorageDataAvailableMessage().Send(); }
/// <summary> /// Delete the specified playlist and its contents /// </summary> /// <param name="thePlaylist"></param> public static void DeletePlaylist(Playlist thePlaylist) { // Delete the playlist and then refresh the data held by the model Playlists.DeletePlaylist(thePlaylist); // Refresh the playlists held by the model and report the change StorageDataAvailable(); }
/// <summary> /// Clear the data held by this model /// </summary> public static void ClearModel() { Playlists.Clear(); SongPlaylists.Clear(); AlbumPlaylists.Clear(); PlaylistNames.Clear(); LibraryId = -1; BaseModel.Clear(); }
/// <summary> /// Add a new playlist with the specified name to the current library /// </summary> /// <param name="playlistName"></param> public static async Task <AlbumPlaylist> AddAlbumPlaylistAsync(string playlistName) { AlbumPlaylist newPlaylist = new() { Name = playlistName, LibraryId = PlaylistsViewModel.LibraryId }; await Playlists.AddPlaylistAsync(newPlaylist); // Refresh the playlists held by the model and report the change StorageDataAvailable(); return(newPlaylist); }
/// <summary> /// Duplicate the SongPlaylist in the specified library /// </summary> /// <param name="playlistToDuplicate"></param> /// <returns></returns> private static async void DuplicateSongPlaylistAsync(SongPlaylist playlistToDuplicate, int libraryId) { // Attempt to find matching songs for each SongPlaylistItem in the SongPlaylist // Need to access the songs via the Sources associated with the Library List <Source> sources = Sources.GetSourcesForLibrary(libraryId); // Keep track of the matching songs List <Song> songsToAdd = new(); foreach (SongPlaylistItem item in playlistToDuplicate.PlaylistItems) { Song matchingSong = null; int sourceIndex = 0; while ((matchingSong == null) && (sourceIndex < sources.Count)) { // Get a list of all the songs with matching Titles in the source List <Song> matchingTitles = Songs.GetSourceSongsWithName(sources[sourceIndex++].Id, item.Song.Title); // Now for each song access the associated artist int titleIndex = 0; while ((matchingSong == null) && (titleIndex < matchingTitles.Count)) { Artist nameCheck = Artists.GetArtistById(ArtistAlbums.GetArtistAlbumById(matchingTitles[titleIndex].ArtistAlbumId).ArtistId); // Correct name? if (nameCheck.Name == item.Artist.Name) { matchingSong = matchingTitles[titleIndex]; songsToAdd.Add(matchingSong); // Make sure that the Artist is stored with the song matchingSong.Artist = nameCheck; } titleIndex++; } } } // Only create the playlist if at least one of the songs was found if (songsToAdd.Count > 0) { SongPlaylist duplicatedPlaylist = new() { Name = playlistToDuplicate.Name, LibraryId = libraryId }; // Wait for the playlist to be added as we're going to use its id await Playlists.AddPlaylistAsync(duplicatedPlaylist); // Add the songs to the new SongPlaylist. duplicatedPlaylist.AddSongs(songsToAdd); } }
/// <summary> /// Called when the SongPlaylist data is available to be displayed, or needs to be refreshed /// </summary> private static void StorageDataAvailable() { // Save the libray being used locally to detect changes NowPlayingViewModel.LibraryId = ConnectionDetailsModel.LibraryId; // Get the NowPlaying playlist. NowPlayingViewModel.NowPlayingPlaylist = ( SongPlaylist )Playlists.GetNowPlayingPlaylist(NowPlayingViewModel.LibraryId); // Let the playback manager know the current song but don't play it yet NowPlayingViewModel.CurrentSongIndex = Playlists.CurrentSongIndex; new PlaySongMessage() { SongToPlay = NowPlayingViewModel.CurrentSong, DontPlay = true }.Send(); DataReporter?.DataAvailable(); }
/// <summary> /// Categorise the specified selected objects /// </summary> /// <param name="selectedObjects"></param> public GroupedSelection(IEnumerable <object> selectedObjects) { // Save the unprocessed objects. SelectedObjects = selectedObjects; // Group the objects into sets of Song, PlaylistItem, IPlaylist, Artist, ArtistAlbum, Album and Genre (string) items foreach (object selectedObject in selectedObjects) { if (selectedObject is Song song) { Songs.Add(song); } else if (selectedObject is PlaylistItem playlistItem) { PlaylistItems.Add(playlistItem); } else if (selectedObject is Playlist playlist) { Playlists.Add(playlist); } else if (selectedObject is Artist artist) { Artists.Add(artist); } else if (selectedObject is ArtistAlbum artistAlbum) { ArtistAlbums.Add(artistAlbum); } else if (selectedObject is Album album) { Albums.Add(album); } else if (selectedObject is string str) { Genres.Add(str); } } // Determine if there is a parent playlist if (PlaylistItems.Count > 0) { ParentPlaylist = DBTest.Playlists.GetParentPlaylist(PlaylistItems[0]); } }
/// <summary> /// Clear the contents of the specified library /// </summary> /// <param name="libraryToClear"></param> /// <returns></returns> public static void ClearLibrary(Library libraryToClear) { int libId = libraryToClear.Id; // Delete all the artists in the library and their associated ArtistAlbum entries List <Artist> artists = Artists.ArtistCollection.Where(art => art.LibraryId == libId).ToList(); Artists.DeleteArtists(artists); ArtistAlbums.DeleteArtistAlbums( ArtistAlbums.ArtistAlbumCollection.Where(artAlb => artists.Any(art => art.Id == artAlb.ArtistId)).Distinct().ToList()); // Delete all the albums in the library and any tags associated with them List <Album> albums = Albums.AlbumCollection.Where(alb => alb.LibraryId == libId).ToList(); Albums.DeleteAlbums(albums); // We can use the FilterManagementController to carry out the Tag deletions. new AlbumsDeletedMessage() { DeletedAlbumIds = albums.Select(alb => alb.Id).ToList() }.Send(); // Delete all the user playlists and thier contents Playlists.GetPlaylistsForLibrary(libId).ForEach(play => Playlists.DeletePlaylist(play)); // Delete the contents of the NowPlayingList but keep the playlist itself Playlist nowPlaying = Playlists.GetNowPlayingPlaylist(libId); nowPlaying.Clear(); nowPlaying.SongIndex = -1; // Delete all the songs in each of the sources associated with the library List <Source> sources = Sources.GetSourcesForLibrary(libId); foreach (Source source in sources) { Songs.DeleteSongs(Songs.GetSourceSongs(source.Id)); source.Songs = null; } }
/// <summary> /// Called during startup, or library change, when the storage data is available /// </summary> /// <param name="message"></param> private static async void StorageDataAvailable() { // Save the libray being used locally to detect changes PlaylistsViewModel.LibraryId = ConnectionDetailsModel.LibraryId; // Get the Playlists and playlist names. Make sure a copy of the list is used as we're going to sort it PlaylistsViewModel.Playlists = Playlists.GetPlaylistsForLibrary(PlaylistsViewModel.LibraryId).ToList(); PlaylistsViewModel.PlaylistNames = PlaylistsViewModel.Playlists.Select(i => i.Name).ToList(); // To generate the data to be displayed the Playlists need to be sorted. Not a simple sort of course, but the SongPlaylists followed by the // AlbumPlaylists await Task.Run(() => { PlaylistsViewModel.AlbumPlaylists.Clear(); PlaylistsViewModel.SongPlaylists.Clear(); foreach (Playlist playlist in PlaylistsViewModel.Playlists) { if (playlist is SongPlaylist songPlaylist) { PlaylistsViewModel.SongPlaylists.Add(songPlaylist); } else { PlaylistsViewModel.AlbumPlaylists.Add(( AlbumPlaylist )playlist); } } // Sort the playlists by name PlaylistsViewModel.SongPlaylists.Sort((a, b) => a.Name.CompareTo(b.Name)); PlaylistsViewModel.AlbumPlaylists.Sort((a, b) => a.Name.CompareTo(b.Name)); // Now copy to the combined list PlaylistsViewModel.Playlists.Clear(); PlaylistsViewModel.Playlists.AddRange(PlaylistsViewModel.SongPlaylists); PlaylistsViewModel.Playlists.AddRange(PlaylistsViewModel.AlbumPlaylists); }); DataReporter?.DataAvailable(); }
/// <summary> /// Duplicate the AlbumPlaylist in the specified library /// </summary> /// <param name="playlistToDuplicate"></param> /// <param name="libararyId"></param> private static async void DuplicateAlbumPlaylistAsync(AlbumPlaylist playlistToDuplicate, int libraryId) { List <Album> albumsToAdd = new(); foreach (AlbumPlaylistItem item in playlistToDuplicate.PlaylistItems) { // Find a matching Album name with the same Artist name Album matchingAlbum = Albums.AlbumCollection.Where(album => (album.LibraryId == libraryId) && (album.Name == item.Album.Name) && (album.ArtistName == item.Album.ArtistName)).FirstOrDefault(); if (matchingAlbum != null) { albumsToAdd.Add(matchingAlbum); } } // Only create the playlist if we've got something to add to it if (albumsToAdd.Count > 0) { AlbumPlaylist duplicatedPlaylist = new() { Name = playlistToDuplicate.Name, LibraryId = libraryId }; await Playlists.AddPlaylistAsync(duplicatedPlaylist); duplicatedPlaylist.AddAlbums(albumsToAdd); } }
/// <summary> /// Called when the SongFinishedMessage has been received /// </summary> /// <param name="songPlayed"></param> private static void SongFinished(Song songPlayed) => Playlists.SongFinished(songPlayed.Id);