diff --git a/CHANGELOG.md b/CHANGELOG.md index e858c19b2..b040c44d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +- Fix song sorting with `Chronological` and `Shuffle In Order` playback orders ## [0.4.2-alpha] - 2022-02-26 ### Fixed diff --git a/ErsatzTV.Core/Scheduling/ChronologicalMediaComparer.cs b/ErsatzTV.Core/Scheduling/ChronologicalMediaComparer.cs index 3c6add122..6a5c0682d 100644 --- a/ErsatzTV.Core/Scheduling/ChronologicalMediaComparer.cs +++ b/ErsatzTV.Core/Scheduling/ChronologicalMediaComparer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using ErsatzTV.Core.Domain; namespace ErsatzTV.Core.Scheduling @@ -47,6 +46,23 @@ namespace ErsatzTV.Core.Scheduling return date1.CompareTo(date2); } + string songDate1 = x switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Date ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + string songDate2 = y switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Date ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + if (songDate1 != songDate2) + { + return string.Compare(songDate1, songDate2, StringComparison.Ordinal); + } + int season1 = x switch { Episode e => e.Season?.SeasonNumber ?? int.MaxValue, @@ -85,6 +101,40 @@ namespace ErsatzTV.Core.Scheduling return episode1.CompareTo(episode2); } + string album1 = x switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Album ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + string album2 = y switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Album ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + if (album1 != album2) + { + return string.Compare(album1, album2, StringComparison.Ordinal); + } + + string track1 = x switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Track ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + string track2 = y switch + { + Song s => s.SongMetadata.HeadOrNone().Match(sm => sm.Track ?? string.Empty, () => string.Empty), + _ => string.Empty + }; + + if (track1 != track2) + { + return string.Compare(track1, track2, StringComparison.Ordinal); + } + return x.Id.CompareTo(y.Id); } } diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs index 10d83dbb6..a0038d578 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs @@ -315,6 +315,45 @@ namespace ErsatzTV.Infrastructure.Data.Repositories false)); } + var allArtists = items.OfType() + .SelectMany(s => s.SongMetadata) + .Map(sm => sm.Artist) + .Distinct() + .ToList(); + + if (!allArtists.Contains(string.Empty)) + { + allArtists.Add(string.Empty); + } + + var songArtistCollections = new Dictionary>(); + foreach (Song song in items.OfType()) + { + int key = allArtists.IndexOf(song.SongMetadata.HeadOrNone().Match(sm => sm.Artist, string.Empty)); + + List list = songArtistCollections.ContainsKey(key) + ? songArtistCollections[key] + : new List(); + + if (list.All(i => i.Id != song.Id)) + { + list.Add(song); + } + + songArtistCollections[key] = list; + } + + foreach ((int _, List list) in songArtistCollections) + { + result.Add( + new CollectionWithItems( + id--, + list, + true, + PlaybackOrder.Chronological, + false)); + } + result.Add( new CollectionWithItems( id,