/// <summary> /// Synchronizes the new songs. /// </summary> /// <param name="onlineSongs"> /// The online songs. /// </param> /// <returns> /// Task. /// </returns> private async Task PullSyncNewSongsAsync(List <CloudSong> onlineSongs) { var collectionSongs = _collectionService.Songs.Where(p => p.SongState != SongState.Local && !p.IsTemp).ToList(); // nothing different if (onlineSongs.Count - collectionSongs.Count == 0) { return; } // Wrap everything in one transaction _sqlService.BeginTransaction(); // when syncing over 20 new songs is best to supress the collection (avoiding unnecessary ui work) var reset = (onlineSongs.Count - collectionSongs.Count) > 20; if (reset) { await _dispatcherHelper.RunAsync( () => { if (OnLargeSyncStarted != null) { OnLargeSyncStarted(null, EventArgs.Empty); } _collectionService.Songs.SuppressEvents = true; _collectionService.Artists.SuppressEvents = true; _collectionService.Albums.SuppressEvents = true; }); } foreach (var onlineSong in from onlineSong in onlineSongs let localSong = collectionSongs.FirstOrDefault(p => p.CloudId == onlineSong.Id) where localSong == null select onlineSong) { if (LastSyncTime > onlineSong.CreatedAt) { await _mobileServiceClient.GetTable <CloudSong>().DeleteAsync(onlineSong).ConfigureAwait(false); continue; } // Cloud song is not in the collection, check if it was saved before syncing var collSong = collectionSongs.FirstOrDefault(p => p.ProviderId == onlineSong.ProviderId); if (collSong != null) { collSong.CloudId = onlineSong.Id; await _sqlService.UpdateItemAsync(collSong).ConfigureAwait(false); } else { if (onlineSong.Album == null | onlineSong.Artist == null) { await _mobileServiceClient.GetTable <CloudSong>().DeleteAsync(onlineSong).ConfigureAwait(false); continue; } if (onlineSong.Album.PrimaryArtist == null) { onlineSong.Album.PrimaryArtist = onlineSong.Artist; } // Can't change CloudSong to Song, so need to create a new song var newSong = new Song(onlineSong) { Album = new Album(onlineSong.Album), Artist = new Artist(onlineSong.Artist) }; // By setting it to just synced, the app knows it has to match an audio url to it await _collectionService.AddSongAsync(newSong).ConfigureAwait(false); } } // commit the transaction _sqlService.Commit(); if (reset) { await _dispatcherHelper.RunAsync( () => { if (OnLargeSyncFinished != null) { OnLargeSyncFinished(null, EventArgs.Empty); } _collectionService.Songs.Reset(); _collectionService.Albums.Reset(); _collectionService.Artists.Reset(); }); } }