コード例 #1
0
        public void AllArtistViewModelIsSortedFirst()
        {
            var allArtists = new ArtistViewModel("All Artists");
            var otherArtist = new ArtistViewModel("Aaa", Enumerable.Empty<LocalSong>());

            var list = new List<ArtistViewModel> { otherArtist, allArtists };
            list.Sort();

            Assert.Equal(allArtists, list[0]);
            Assert.Equal(otherArtist, list[1]);
        }
コード例 #2
0
        private void UpdateSelectableSongs()
        {
            IEnumerable <Song> filtered = this.Library.Songs.FilterSongs(this.SearchText).ToList();

            var artistInfos = filtered
                              .GroupBy(song => song.Artist)
                              .Select(group =>
                                      new ArtistViewModel(group.Key, group.Select(song => song.Album).Distinct().Count(), group.Count()))
                              .ToDictionary(model => model.Name);

            List <string> removableArtists = this.artists
                                             .Where(pair => !artistInfos.ContainsKey(pair.Key))
                                             .Select(pair => pair.Key)
                                             .ToList();

            foreach (string artist in removableArtists)
            {
                this.artists.Remove(artist);
            }

            foreach (ArtistViewModel artist in artistInfos.Values)
            {
                if (this.artists.ContainsKey(artist.Name))
                {
                    ArtistViewModel updated = this.artists[artist.Name];

                    updated.AlbumCount = artist.AlbumCount;
                    updated.SongCount  = artist.SongCount;
                }

                else
                {
                    this.artists.Add(artist.Name, artist);
                }
            }

            this.NotifyOfPropertyChange(() => this.Artists);

            this.allArtistsViewModel.ArtistCount = artistInfos.Count;

            this.SelectableSongs = filtered
                                   .Where(song => this.SelectedArtist.IsAllArtists || song.Artist == this.SelectedArtist.Name)
                                   .Select(song => new LocalSongViewModel(song))
                                   .OrderBy(this.SongOrderFunc)
                                   .ToList();

            this.SelectedSongs = this.SelectableSongs.Take(1);
        }
コード例 #3
0
        public void CertainPrefixesAreSortedCorrectly()
        {
            var aPrefixBig = new ArtistViewModel("A b", Enumerable.Empty<LocalSong>());
            var aPrefixSmall = new ArtistViewModel("a c", Enumerable.Empty<LocalSong>());
            var thePrefixBig = new ArtistViewModel("The d", Enumerable.Empty<LocalSong>());
            var thePrefixSmall = new ArtistViewModel("the e", Enumerable.Empty<LocalSong>());
            var firstArtist = new ArtistViewModel("Aa", Enumerable.Empty<LocalSong>());
            var lastArtist = new ArtistViewModel("Zz", Enumerable.Empty<LocalSong>());

            var correctList = new List<ArtistViewModel> { firstArtist, aPrefixBig, aPrefixSmall, thePrefixBig, thePrefixSmall, lastArtist };

            var incorrectList = correctList.ToList();
            incorrectList.Reverse();

            incorrectList.Sort();

            Assert.Equal(correctList, incorrectList);
        }
コード例 #4
0
        public LocalViewModel(Library library)
            : base(library)
        {
            library.Updated += (sender, args) =>
            {
                this.NotifyOfPropertyChange(() => this.Artists);
                this.UpdateSelectableSongs();
            };

            this.StatusViewModel = new StatusViewModel(library);

            this.searchText = String.Empty;

            this.artists             = new Dictionary <string, ArtistViewModel>();
            this.allArtistsViewModel = new ArtistViewModel("All Artists");

            // We need a default sorting order
            this.OrderByArtist();

            this.SelectedArtist = this.Artists.First();
        }
コード例 #5
0
        private void UpdateArtists()
        {
            var groupedByArtist = this.Library.Songs
                                  .ToLookup(x => x.Artist, StringComparer.InvariantCultureIgnoreCase);

            List <ArtistViewModel> artistsToRemove = this.allArtists.Where(x => !groupedByArtist.Contains(x.Name)).ToList();

            artistsToRemove.Remove(this.allArtistsViewModel);

            this.allArtists.RemoveAll(artistsToRemove);

            foreach (ArtistViewModel artistViewModel in artistsToRemove)
            {
                artistViewModel.Dispose();
            }

            // We use this reverse ordered list of artists so we can priorize the loading of album
            // covers of artists that we display first in the artist list. This way we can "fake" a
            // fast loading of all covers, as the user doesn't see most of the artists down the
            // list. The higher the number, the higher the prioritization.
            List <string> orderedArtists = groupedByArtist.Select(x => x.Key)
                                           .OrderByDescending(SortHelpers.RemoveArtistPrefixes)
                                           .ToList();

            foreach (var songs in groupedByArtist)
            {
                ArtistViewModel model = this.allArtists.FirstOrDefault(x => x.Name.Equals(songs.Key, StringComparison.OrdinalIgnoreCase));

                if (model == null)
                {
                    int priority = orderedArtists.IndexOf(songs.Key) + 1;
                    this.allArtists.Add(new ArtistViewModel(songs.Key, songs, priority));
                }

                else
                {
                    model.UpdateSongs(songs);
                }
            }
        }
コード例 #6
0
        public LocalViewModel(Library library, ViewSettings viewSettings, CoreSettings coreSettings, Guid accessToken)
            : base(library, coreSettings, accessToken)
        {
            if (viewSettings == null)
            {
                throw new ArgumentNullException(nameof(viewSettings));
            }

            this.viewSettings = viewSettings;

            this.artistUpdateSignal = new Subject <Unit>();

            this.allArtistsViewModel = new ArtistViewModel("All Artists");
            this.allArtists          = new ReactiveList <ArtistViewModel> {
                this.allArtistsViewModel
            };

            this.Artists = this.allArtists.CreateDerivedCollection(x => x,
                                                                   x => x.IsAllArtists || this.filteredSongs.Contains(x.Name), (x, y) => x.CompareTo(y), this.artistUpdateSignal);

            // We need a default sorting order
            this.ApplyOrder(SortHelpers.GetOrderByArtist <LocalSongViewModel>, ref this.artistOrder);

            this.SelectedArtist = this.allArtistsViewModel;

            var gate = new object();

            this.Library.SongsUpdated
            .Buffer(TimeSpan.FromSeconds(1), RxApp.TaskpoolScheduler)
            .Where(x => x.Any())
            .Select(_ => Unit.Default)
            .Merge(this.WhenAny(x => x.SearchText, _ => Unit.Default)
                   .Do(_ => this.SelectedArtist = this.allArtistsViewModel))
            .Synchronize(gate)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                this.UpdateSelectableSongs();
                this.UpdateArtists();
            });

            this.WhenAnyValue(x => x.SelectedArtist)
            .Skip(1)
            .Synchronize(gate)
            .Subscribe(_ => this.UpdateSelectableSongs());

            this.playNowCommand = ReactiveCommand.CreateAsyncTask(this.Library.LocalAccessControl.ObserveAccessPermission(accessToken)
                                                                  .Select(x => x == AccessPermission.Admin || !coreSettings.LockPlayPause), _ =>
            {
                int songIndex = this.SelectableSongs.TakeWhile(x => x.Model != this.SelectedSongs.First().Model).Count();

                return(this.Library.PlayInstantlyAsync(this.SelectableSongs.Skip(songIndex).Select(x => x.Model), accessToken));
            });

            this.showAddSongsHelperMessage = this.Library.SongsUpdated
                                             .StartWith(Unit.Default)
                                             .Select(_ => this.Library.Songs.Count == 0)
                                             .TakeWhile(x => x)
                                             .Concat(Observable.Return(false))
                                             .ToProperty(this, x => x.ShowAddSongsHelperMessage);

            this.isUpdating = this.Library.WhenAnyValue(x => x.IsUpdating)
                              .ToProperty(this, x => x.IsUpdating);

            this.OpenTagEditor = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedSongs, x => x.Any()));
        }