diff --git a/approot/release.xml b/approot/release.xml index 0dbbc8ed..caf2b811 100644 --- a/approot/release.xml +++ b/approot/release.xml @@ -54,8 +54,11 @@ - - ${disc-title} + + ${} + ${image class="Lms-cursor-pointer"} + ${} + ${disc-title} ${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"} @@ -68,7 +71,7 @@ - + ${tracks class="d-grid gap-1 Lms-row-container"} diff --git a/src/lms/ui/Utils.cpp b/src/lms/ui/Utils.cpp index 858c533f..1e8191f4 100644 --- a/src/lms/ui/Utils.cpp +++ b/src/lms/ui/Utils.cpp @@ -104,6 +104,20 @@ namespace lms::ui::utils return cover; } + std::unique_ptr createTrackMediaImage(db::TrackId trackId, ArtworkResource::Size size) + { + std::string url{ LmsApp->getArtworkResource()->getTrackMediaImageUrl(trackId, size) }; + if (url.empty()) + return nullptr; + + auto cover{ std::make_unique() }; + cover->setImageLink(std::move(url)); + cover->setStyleClass("Lms-cover img-fluid"); // HACK + cover->setAttributeValue("onload", LmsApp->javaScriptClass() + ".onLoadCover(this)"); // HACK + + return cover; + } + std::unique_ptr createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete) { auto res{ std::make_unique(Wt::WString{ canDelete ? " " : "" } + name, Wt::TextFormat::UnsafeXHTML) }; diff --git a/src/lms/ui/Utils.hpp b/src/lms/ui/Utils.hpp index 2039db95..c29077e2 100644 --- a/src/lms/ui/Utils.hpp +++ b/src/lms/ui/Utils.hpp @@ -34,6 +34,7 @@ #include "database/ReleaseId.hpp" #include "database/TrackId.hpp" +#include "database/Types.hpp" #include "resource/ArtworkResource.hpp" namespace lms::db @@ -58,6 +59,7 @@ namespace lms::ui::utils std::unique_ptr createReleaseCover(db::ReleaseId releaseId, ArtworkResource::Size size); std::unique_ptr createTrackImage(db::TrackId trackId, ArtworkResource::Size size); + std::unique_ptr createTrackMediaImage(db::TrackId trackId, ArtworkResource::Size size); // return nullptr if no image std::unique_ptr createArtistImage(db::ArtistId artistId, ArtworkResource::Size size); std::unique_ptr createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete = false); diff --git a/src/lms/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp index 8fd13d70..9241d1d0 100644 --- a/src/lms/ui/explore/ReleaseView.cpp +++ b/src/lms/ui/explore/ReleaseView.cpp @@ -391,13 +391,24 @@ namespace lms::ui // Expect to be called in asc order std::map trackContainers; - auto getOrAddDiscContainer = [&, releaseId = _releaseId](std::size_t discNumber, const std::string& discSubtitle) -> Wt::WContainerWidget* { + auto getOrAddDiscContainer = [&, releaseId = _releaseId](std::size_t discNumber, const std::string& discSubtitle, db::TrackId trackId) -> Wt::WContainerWidget* { if (auto it{ trackContainers.find(discNumber) }; it != std::cend(trackContainers)) return it->second; Template* disc{ rootContainer->addNew(Wt::WString::tr("Lms.Explore.Release.template.entry-disc")) }; disc->addFunction("id", &Wt::WTemplate::Functions::id); + if (auto image{ utils::createTrackMediaImage(trackId, ArtworkResource::Size::Large) }) + { + disc->setCondition("if-has-image", true); + + image->addStyleClass("Lms-cover-track rounded"); // HACK + image->clicked().connect([=] { + utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getTrackMediaImageUrl(trackId) }); + }); + disc->bindWidget("image", std::move(image)); + } + if (discSubtitle.empty()) disc->bindNew("disc-title", Wt::WString::tr("Lms.Explore.Release.disc").arg(discNumber)); else @@ -458,9 +469,9 @@ namespace lms::ui Wt::WContainerWidget* container{}; if (useSubtitleContainers && discNumber) - container = getOrAddDiscContainer(*discNumber, track->getDiscSubtitle()); + container = getOrAddDiscContainer(*discNumber, track->getDiscSubtitle(), track->getId()); else if (hasDiscSubtitle && !discNumber) - container = getOrAddDiscContainer(0, track->getDiscSubtitle()); + container = getOrAddDiscContainer(0, track->getDiscSubtitle(), track->getId()); else container = getOrAddNoDiscContainer(); diff --git a/src/lms/ui/resource/ArtworkResource.cpp b/src/lms/ui/resource/ArtworkResource.cpp index 424824a4..909a7cbb 100644 --- a/src/lms/ui/resource/ArtworkResource.cpp +++ b/src/lms/ui/resource/ArtworkResource.cpp @@ -98,6 +98,21 @@ namespace lms::ui return url; } + std::string ArtworkResource::getTrackMediaImageUrl(db::TrackId trackId, std::optional size) + { + std::string url; + + const auto imageResult{ core::Service::get()->findTrackMediaImage(trackId) }; + std::visit([&](const auto& arg) { + using T = std::decay_t; + if constexpr (!std::is_same_v) + url = getImageUrl(arg, size, "release"); + }, + imageResult); + + return url; + } + std::string ArtworkResource::getImageUrl(db::ImageId imageId, std::optional size, std::string_view type) const { std::string res{ url() + "&imageid=" + imageId.toString() + "&type=" + std::string{ type } }; diff --git a/src/lms/ui/resource/ArtworkResource.hpp b/src/lms/ui/resource/ArtworkResource.hpp index dda8b5e1..c61c07e7 100644 --- a/src/lms/ui/resource/ArtworkResource.hpp +++ b/src/lms/ui/resource/ArtworkResource.hpp @@ -48,6 +48,7 @@ namespace lms::ui std::string getArtistImageUrl(db::ArtistId artistId, std::optional size = std::nullopt) const; std::string getReleaseCoverUrl(db::ReleaseId releaseId, std::optional size = std::nullopt) const; std::string getTrackImageUrl(db::TrackId trackId, std::optional size = std::nullopt) const; + std::string getTrackMediaImageUrl(db::TrackId trackId, std::optional size = std::nullopt); private: std::string getImageUrl(db::ImageId imageId, std::optional size, std::string_view type) const;