예제 #1
0
        /// <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();
                });
            }
        }