diff --git a/approot/release.xml b/approot/release.xml index f67237ec..e836e793 100644 --- a/approot/release.xml +++ b/approot/release.xml @@ -15,7 +15,7 @@

${name}

${}${artists}${} ${}
${tr:Lms.Explore.various-artists}
${
} -
${}${year}${} (${orig-year})${} · ${}${duration}
+
${}${year} · ${}${duration}
${clusters class="mb-2"}
${play-btn class="btn btn-primary"} diff --git a/src/libs/services/database/impl/Release.cpp b/src/libs/services/database/impl/Release.cpp index d26bfc40..781a3017 100644 --- a/src/libs/services/database/impl/Release.cpp +++ b/src/libs/services/database/impl/Release.cpp @@ -41,6 +41,9 @@ createQuery(Session& session, const Release::FindParameters& params) auto query {session.getDboSession().query("SELECT DISTINCT r.id from release r")}; if (params.sortMethod == ReleaseSortMethod::LastWritten + || params.sortMethod == ReleaseSortMethod::Date + || params.sortMethod == ReleaseSortMethod::OriginalDate + || params.sortMethod == ReleaseSortMethod::OriginalDateDesc || params.writtenAfter.isValid() || params.dateRange || params.artist.isValid()) @@ -160,8 +163,11 @@ createQuery(Session& session, const Release::FindParameters& params) case ReleaseSortMethod::Date: query.orderBy("t.date, r.name COLLATE NOCASE"); break; - case ReleaseSortMethod::DateDesc: - query.orderBy("t.date DESC, r.name COLLATE NOCASE"); + case ReleaseSortMethod::OriginalDate: + query.orderBy("CASE WHEN t.original_date IS NULL THEN t.date ELSE t.original_date END, t.date, r.name COLLATE NOCASE"); + break; + case ReleaseSortMethod::OriginalDateDesc: + query.orderBy("CASE WHEN t.original_date IS NULL THEN t.date ELSE t.original_date END DESC, t.date, r.name COLLATE NOCASE"); break; case ReleaseSortMethod::StarredDateDesc: assert(params.starringUser.isValid()); diff --git a/src/libs/services/database/include/services/database/Types.hpp b/src/libs/services/database/include/services/database/Types.hpp index 57085732..0e50cb39 100644 --- a/src/libs/services/database/include/services/database/Types.hpp +++ b/src/libs/services/database/include/services/database/Types.hpp @@ -98,7 +98,8 @@ namespace Database None, Name, Date, - DateDesc, + OriginalDate, + OriginalDateDesc, Random, LastWritten, StarredDateDesc, diff --git a/src/libs/services/database/test/Release.cpp b/src/libs/services/database/test/Release.cpp index f0d90f70..573ed9c7 100644 --- a/src/libs/services/database/test/Release.cpp +++ b/src/libs/services/database/test/Release.cpp @@ -530,3 +530,73 @@ TEST_F(DatabaseFixture, Release_releaseType) EXPECT_TRUE(release.get()->getSecondaryTypes().contains(ReleaseTypeSecondary::Compilation)); } } + +TEST_F(DatabaseFixture, ReleaseSortOrder) +{ + ScopedRelease release1 {session, "MyRelease1"}; + const Wt::WDate release1Date {Wt::WDate {2000, 2, 3}}; + const Wt::WDate release1OriginalDate {Wt::WDate {1993, 4, 5}}; + + ScopedRelease release2 {session, "MyRelease2"}; + const Wt::WDate release2Date {Wt::WDate {1994, 2, 3}}; + + ScopedTrack track1 {session, "MyTrack1"}; + ScopedTrack track2 {session, "MyTrack2"}; + + ASSERT_LT(release2Date, release1Date); + ASSERT_GT(release2Date, release1OriginalDate); + + { + auto transaction {session.createUniqueTransaction()}; + + track1.get().modify()->setRelease(release1.get()); + track1.get().modify()->setOriginalDate(release1OriginalDate); + track1.get().modify()->setDate(release1Date); + + track2.get().modify()->setRelease(release2.get()); + track2.get().modify()->setDate(release2Date); + } + + { + auto transaction {session.createSharedTransaction()}; + + const auto releases {Release::find(session, Release::FindParameters {}.setSortMethod(ReleaseSortMethod::Name) )}; + ASSERT_EQ(releases.results.size(), 2); + EXPECT_EQ(releases.results.front(), release1.getId()); + EXPECT_EQ(releases.results.back(), release2.getId()); + } + + { + auto transaction {session.createSharedTransaction()}; + + const auto releases {Release::find(session, Release::FindParameters {}.setSortMethod(ReleaseSortMethod::Random) )}; + ASSERT_EQ(releases.results.size(), 2); + } + + { + auto transaction {session.createSharedTransaction()}; + + const auto releases {Release::find(session, Release::FindParameters {}.setSortMethod(ReleaseSortMethod::Date) )}; + ASSERT_EQ(releases.results.size(), 2); + EXPECT_EQ(releases.results.front(), release2.getId()); + EXPECT_EQ(releases.results.back(), release1.getId()); + } + + { + auto transaction {session.createSharedTransaction()}; + + const auto releases {Release::find(session, Release::FindParameters {}.setSortMethod(ReleaseSortMethod::OriginalDate) )}; + ASSERT_EQ(releases.results.size(), 2); + EXPECT_EQ(releases.results.front(), release1.getId()); + EXPECT_EQ(releases.results.back(), release2.getId()); + } + { + auto transaction {session.createSharedTransaction()}; + + const auto releases {Release::find(session, Release::FindParameters {}.setSortMethod(ReleaseSortMethod::OriginalDateDesc) )}; + ASSERT_EQ(releases.results.size(), 2); + EXPECT_EQ(releases.results.front(), release2.getId()); + EXPECT_EQ(releases.results.back(), release1.getId()); + } +} + diff --git a/src/lms/ui/explore/ArtistView.cpp b/src/lms/ui/explore/ArtistView.cpp index cd1f6323..13369377 100644 --- a/src/lms/ui/explore/ArtistView.cpp +++ b/src/lms/ui/explore/ArtistView.cpp @@ -212,7 +212,7 @@ Artist::refreshReleases() Release::FindParameters params; params.setClusters(_filters.getClusterIds()); params.setArtist(_artistId, {TrackArtistLinkType::ReleaseArtist}, {}); - params.setSortMethod(ReleaseSortMethod::DateDesc); + params.setSortMethod(ReleaseSortMethod::OriginalDateDesc); const auto releases {Release::find(LmsApp->getDbSession(), params)}; if (!releases.results.empty()) @@ -272,7 +272,7 @@ Artist::refreshAppearsOnReleases() Release::FindParameters params; params.setClusters(_filters.getClusterIds()); params.setArtist(_artistId, types, {TrackArtistLinkType::ReleaseArtist}); - params.setSortMethod(ReleaseSortMethod::DateDesc); + params.setSortMethod(ReleaseSortMethod::OriginalDateDesc); const auto releases {Release::find(LmsApp->getDbSession(), params)}; if (!releases.results.empty()) diff --git a/src/lms/ui/explore/ReleaseHelpers.cpp b/src/lms/ui/explore/ReleaseHelpers.cpp index a1db7549..c4b9fa32 100644 --- a/src/lms/ui/explore/ReleaseHelpers.cpp +++ b/src/lms/ui/explore/ReleaseHelpers.cpp @@ -66,19 +66,11 @@ namespace UserInterface::ReleaseListHelpers if (showYear) { - if (std::optional year {release->getReleaseYear()}) + Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseYear(), release->getReleaseYear(true))}; + if (!year.empty()) { entry->setCondition("if-has-year", true); - - std::string strYear {std::to_string(*year)}; - - std::optional originalYear {release->getReleaseYear(true)}; - if (originalYear && *originalYear != *year) - { - strYear += " (" + std::to_string(*originalYear) + ")"; - } - - entry->bindString("year", strYear, Wt::TextFormat::Plain); + entry->bindString("year", year, Wt::TextFormat::Plain); } } @@ -142,4 +134,20 @@ namespace UserInterface::ReleaseHelpers return res; } + + Wt::WString buildReleaseYearString(std::optional year, std::optional originalYear) + { + Wt::WString res; + + // Year can be here, but originalYear can't be here without year (enforced by scanner) + if (!year) + return res; + + if (originalYear && *originalYear != *year) + res = std::to_string(*originalYear) + " (" + std::to_string(*year) + ")"; + else + res = std::to_string(*year); + + return res; + } } // namespace UserInterface::ReleaseHelpers} diff --git a/src/lms/ui/explore/ReleaseHelpers.hpp b/src/lms/ui/explore/ReleaseHelpers.hpp index b0c61911..1d2e9e43 100644 --- a/src/lms/ui/explore/ReleaseHelpers.hpp +++ b/src/lms/ui/explore/ReleaseHelpers.hpp @@ -41,4 +41,5 @@ namespace UserInterface::ReleaseListHelpers namespace UserInterface::ReleaseHelpers { Wt::WString buildReleaseTypeString(Database::ReleaseTypePrimary primaryType, EnumSet secondaryTypes); + Wt::WString buildReleaseYearString(std::optional year, std::optional originalYear); } diff --git a/src/lms/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp index 816cd0c4..1060c7fc 100644 --- a/src/lms/ui/explore/ReleaseView.cpp +++ b/src/lms/ui/explore/ReleaseView.cpp @@ -246,18 +246,11 @@ Release::refreshView() bindString("name", Wt::WString::fromUTF8(release->getName()), Wt::TextFormat::Plain); - std::optional year {release->getReleaseYear()}; - if (year) + Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseYear(), release->getReleaseYear(true))}; + if (!year.empty()) { setCondition("if-has-year", true); - bindInt("year", *year); - - std::optional originalYear {release->getReleaseYear(true)}; - if (originalYear && *originalYear != *year) - { - setCondition("if-has-orig-year", true); - bindInt("orig-year", *originalYear); - } + bindString("year", year, Wt::TextFormat::Plain); } bindString("duration", Utils::durationToString(release->getDuration()), Wt::TextFormat::Plain);