Added media related image in the release view, if found, ref #604

This commit is contained in:
emeric
2025-06-15 14:41:58 +02:00
parent f906212fc4
commit dd57275858
6 changed files with 52 additions and 6 deletions
+6 -3
View File
@@ -54,8 +54,11 @@
</message> </message>
<message id="Lms.Explore.Release.template.entry-disc"> <message id="Lms.Explore.Release.template.entry-disc">
<div class="d-flex align-items-center"> <h4 class="d-flex align-items-center">
<h4 class="flex-fill">${disc-title}</h4> ${<if-has-image>}
<div class="p-1">${image class="Lms-cursor-pointer"}</div>
${</if-has-image>}
<div class="p-2 flex-fill">${disc-title}</div>
<div class="p-2 d-flex"> <div class="p-2 d-flex">
${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"} ${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"}
<div class="dropdown d-inline-block"> <div class="dropdown d-inline-block">
@@ -68,7 +71,7 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </h4>
${tracks class="d-grid gap-1 Lms-row-container"} ${tracks class="d-grid gap-1 Lms-row-container"}
</message> </message>
+14
View File
@@ -104,6 +104,20 @@ namespace lms::ui::utils
return cover; return cover;
} }
std::unique_ptr<Wt::WImage> 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<Wt::WImage>() };
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<Wt::WInteractWidget> createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete) std::unique_ptr<Wt::WInteractWidget> createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete)
{ {
auto res{ std::make_unique<Wt::WText>(Wt::WString{ canDelete ? "<i class=\"fa fa-times-circle\"></i> " : "" } + name, Wt::TextFormat::UnsafeXHTML) }; auto res{ std::make_unique<Wt::WText>(Wt::WString{ canDelete ? "<i class=\"fa fa-times-circle\"></i> " : "" } + name, Wt::TextFormat::UnsafeXHTML) };
+2
View File
@@ -34,6 +34,7 @@
#include "database/ReleaseId.hpp" #include "database/ReleaseId.hpp"
#include "database/TrackId.hpp" #include "database/TrackId.hpp"
#include "database/Types.hpp"
#include "resource/ArtworkResource.hpp" #include "resource/ArtworkResource.hpp"
namespace lms::db namespace lms::db
@@ -58,6 +59,7 @@ namespace lms::ui::utils
std::unique_ptr<Wt::WImage> createReleaseCover(db::ReleaseId releaseId, ArtworkResource::Size size); std::unique_ptr<Wt::WImage> createReleaseCover(db::ReleaseId releaseId, ArtworkResource::Size size);
std::unique_ptr<Wt::WImage> createTrackImage(db::TrackId trackId, ArtworkResource::Size size); std::unique_ptr<Wt::WImage> createTrackImage(db::TrackId trackId, ArtworkResource::Size size);
std::unique_ptr<Wt::WImage> createTrackMediaImage(db::TrackId trackId, ArtworkResource::Size size); // return nullptr if no image
std::unique_ptr<Wt::WImage> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size); std::unique_ptr<Wt::WImage> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size);
std::unique_ptr<Wt::WInteractWidget> createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete = false); std::unique_ptr<Wt::WInteractWidget> createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete = false);
+14 -3
View File
@@ -391,13 +391,24 @@ namespace lms::ui
// Expect to be called in asc order // Expect to be called in asc order
std::map<std::size_t, Wt::WContainerWidget*> trackContainers; std::map<std::size_t, Wt::WContainerWidget*> 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)) if (auto it{ trackContainers.find(discNumber) }; it != std::cend(trackContainers))
return it->second; return it->second;
Template* disc{ rootContainer->addNew<Template>(Wt::WString::tr("Lms.Explore.Release.template.entry-disc")) }; Template* disc{ rootContainer->addNew<Template>(Wt::WString::tr("Lms.Explore.Release.template.entry-disc")) };
disc->addFunction("id", &Wt::WTemplate::Functions::id); 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<Wt::WImage>("image", std::move(image));
}
if (discSubtitle.empty()) if (discSubtitle.empty())
disc->bindNew<Wt::WText>("disc-title", Wt::WString::tr("Lms.Explore.Release.disc").arg(discNumber)); disc->bindNew<Wt::WText>("disc-title", Wt::WString::tr("Lms.Explore.Release.disc").arg(discNumber));
else else
@@ -458,9 +469,9 @@ namespace lms::ui
Wt::WContainerWidget* container{}; Wt::WContainerWidget* container{};
if (useSubtitleContainers && discNumber) if (useSubtitleContainers && discNumber)
container = getOrAddDiscContainer(*discNumber, track->getDiscSubtitle()); container = getOrAddDiscContainer(*discNumber, track->getDiscSubtitle(), track->getId());
else if (hasDiscSubtitle && !discNumber) else if (hasDiscSubtitle && !discNumber)
container = getOrAddDiscContainer(0, track->getDiscSubtitle()); container = getOrAddDiscContainer(0, track->getDiscSubtitle(), track->getId());
else else
container = getOrAddNoDiscContainer(); container = getOrAddNoDiscContainer();
+15
View File
@@ -98,6 +98,21 @@ namespace lms::ui
return url; return url;
} }
std::string ArtworkResource::getTrackMediaImageUrl(db::TrackId trackId, std::optional<Size> size)
{
std::string url;
const auto imageResult{ core::Service<cover::IArtworkService>::get()->findTrackMediaImage(trackId) };
std::visit([&](const auto& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (!std::is_same_v<T, std::monostate>)
url = getImageUrl(arg, size, "release");
},
imageResult);
return url;
}
std::string ArtworkResource::getImageUrl(db::ImageId imageId, std::optional<Size> size, std::string_view type) const std::string ArtworkResource::getImageUrl(db::ImageId imageId, std::optional<Size> size, std::string_view type) const
{ {
std::string res{ url() + "&imageid=" + imageId.toString() + "&type=" + std::string{ type } }; std::string res{ url() + "&imageid=" + imageId.toString() + "&type=" + std::string{ type } };
+1
View File
@@ -48,6 +48,7 @@ namespace lms::ui
std::string getArtistImageUrl(db::ArtistId artistId, std::optional<Size> size = std::nullopt) const; std::string getArtistImageUrl(db::ArtistId artistId, std::optional<Size> size = std::nullopt) const;
std::string getReleaseCoverUrl(db::ReleaseId releaseId, std::optional<Size> size = std::nullopt) const; std::string getReleaseCoverUrl(db::ReleaseId releaseId, std::optional<Size> size = std::nullopt) const;
std::string getTrackImageUrl(db::TrackId trackId, std::optional<Size> size = std::nullopt) const; std::string getTrackImageUrl(db::TrackId trackId, std::optional<Size> size = std::nullopt) const;
std::string getTrackMediaImageUrl(db::TrackId trackId, std::optional<Size> size = std::nullopt);
private: private:
std::string getImageUrl(db::ImageId imageId, std::optional<Size> size, std::string_view type) const; std::string getImageUrl(db::ImageId imageId, std::optional<Size> size, std::string_view type) const;