diff --git a/src/lms/ui/MediaPlayer.cpp b/src/lms/ui/MediaPlayer.cpp index 0bc6d444..f423ebf7 100644 --- a/src/lms/ui/MediaPlayer.cpp +++ b/src/lms/ui/MediaPlayer.cpp @@ -259,15 +259,17 @@ namespace lms::ui artworkId = track->getPreferredArtworkId(); if (artworkId.isValid()) { + // Potential issue: If the image is really not here, we fall back on a default svg image: the provided type does not match, so we don't put type here + // Another solution would be to test the image presence and put type accordingly oss << " artwork: [" - << " { src: \"" << LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::Size::Small) << "\", sizes: \"128x128\", type: \"image/jpeg\" }," - << " { src: \"" << LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::Size::Large) << "\", sizes: \"512x512\", type: \"image/jpeg\" }," + << " { src: \"" << LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::DefaultArtworkType::Track, ArtworkResource::Size::Small) << "\", sizes: \"128x128\" }," + << " { src: \"" << LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::DefaultArtworkType::Track, ArtworkResource::Size::Large) << "\", sizes: \"512x512\" }," << " ]"; } else { oss << " artwork: [" - << " { src: \"" << LmsApp->getArtworkResource()->getDefaultTrackArtworkUrl() << "\", type: \"image/svg+xml\" }," + << " { src: \"" << LmsApp->getArtworkResource()->getDefaultArtworkUrl(ArtworkResource::DefaultArtworkType::Track) << "\", type: \"image/svg+xml\" }," << " ]"; } oss << "};"; diff --git a/src/lms/ui/PlayQueue.cpp b/src/lms/ui/PlayQueue.cpp index 3290581b..f152b434 100644 --- a/src/lms/ui/PlayQueue.cpp +++ b/src/lms/ui/PlayQueue.cpp @@ -496,9 +496,9 @@ namespace lms::ui std::unique_ptr image; if (artworkId.isValid()) - image = utils::createArtworkImage(artworkId, ArtworkResource::Size::Small); + image = utils::createArtworkImage(artworkId, ArtworkResource::DefaultArtworkType::Track, ArtworkResource::Size::Small); else - image = utils::createDefaultTrackArtworkImage(); + image = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Track); image->addStyleClass("Lms-cover-track rounded"); // HACK diff --git a/src/lms/ui/Utils.cpp b/src/lms/ui/Utils.cpp index a8ce3a8d..ac813775 100644 --- a/src/lms/ui/Utils.cpp +++ b/src/lms/ui/Utils.cpp @@ -88,31 +88,17 @@ namespace lms::ui::utils LmsApp->getModalManager().show(std::move(rawImage)); } - std::unique_ptr createArtworkImage(db::ArtworkId artworkId, ArtworkResource::Size size) + std::unique_ptr createArtworkImage(db::ArtworkId artworkId, ArtworkResource::DefaultArtworkType type, ArtworkResource::Size size) { auto image{ createArtworkImage() }; - image->setImageLink(LmsApp->getArtworkResource()->getArtworkUrl(artworkId, size)); + image->setImageLink(LmsApp->getArtworkResource()->getArtworkUrl(artworkId, type, size)); return image; } - std::unique_ptr createDefaultArtistArtworkImage() + std::unique_ptr createDefaultArtworkImage(ArtworkResource::DefaultArtworkType type) { auto image{ createArtworkImage() }; - image->setImageLink(LmsApp->getArtworkResource()->getDefaultArtistArtworkUrl()); - return image; - } - - std::unique_ptr createDefaultReleaseArtworkImage() - { - auto image{ createArtworkImage() }; - image->setImageLink(LmsApp->getArtworkResource()->getDefaultReleaseArtworkUrl()); - return image; - } - - std::unique_ptr createDefaultTrackArtworkImage() - { - auto image{ createArtworkImage() }; - image->setImageLink(LmsApp->getArtworkResource()->getDefaultTrackArtworkUrl()); + image->setImageLink(LmsApp->getArtworkResource()->getDefaultArtworkUrl(type)); return image; } diff --git a/src/lms/ui/Utils.hpp b/src/lms/ui/Utils.hpp index 64dcd021..0c849fde 100644 --- a/src/lms/ui/Utils.hpp +++ b/src/lms/ui/Utils.hpp @@ -57,10 +57,8 @@ namespace lms::ui::utils void showArtworkModal(Wt::WLink image); - std::unique_ptr createArtworkImage(db::ArtworkId artworkId, ArtworkResource::Size size); - std::unique_ptr createDefaultArtistArtworkImage(); - std::unique_ptr createDefaultReleaseArtworkImage(); - std::unique_ptr createDefaultTrackArtworkImage(); + std::unique_ptr createArtworkImage(db::ArtworkId artworkId, ArtworkResource::DefaultArtworkType type, ArtworkResource::Size size); + std::unique_ptr createDefaultArtworkImage(ArtworkResource::DefaultArtworkType type); std::unique_ptr createFilter(const Wt::WString& name, const Wt::WString& tooltip, std::string_view colorStyleClass, bool canDelete = false); std::unique_ptr createFilterCluster(db::ClusterId clusterId, bool canDelete = false); diff --git a/src/lms/ui/explore/ArtistListHelpers.cpp b/src/lms/ui/explore/ArtistListHelpers.cpp index 3d81a9c8..300e6d58 100644 --- a/src/lms/ui/explore/ArtistListHelpers.cpp +++ b/src/lms/ui/explore/ArtistListHelpers.cpp @@ -35,9 +35,9 @@ namespace lms::ui::ArtistListHelpers std::unique_ptr image; if (artist->getPreferredArtworkId().isValid()) - image = utils::createArtworkImage(artist->getPreferredArtworkId(), ArtworkResource::Size::Large); + image = utils::createArtworkImage(artist->getPreferredArtworkId(), ArtworkResource::DefaultArtworkType::Artist, ArtworkResource::Size::Large); else - image = utils::createDefaultArtistArtworkImage(); + image = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Artist); image->addStyleClass("Lms-image-artist Lms-cover-anchor"); // hack anchor->setImage(std::move(image)); diff --git a/src/lms/ui/explore/ArtistView.cpp b/src/lms/ui/explore/ArtistView.cpp index 36a0b8f5..38a8c8bc 100644 --- a/src/lms/ui/explore/ArtistView.cpp +++ b/src/lms/ui/explore/ArtistView.cpp @@ -197,17 +197,17 @@ namespace lms::ui std::unique_ptr artworkImage; if (artworkId.isValid()) { - artworkImage = utils::createArtworkImage(artworkId, ArtworkResource::Size::Large); + artworkImage = utils::createArtworkImage(artworkId, ArtworkResource::DefaultArtworkType::Artist, ArtworkResource::Size::Large); artworkImage->addStyleClass("Lms-cursor-pointer"); // HACK } else - artworkImage = utils::createDefaultArtistArtworkImage(); + artworkImage = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Artist); auto* image{ bindWidget("artwork", std::move(artworkImage)) }; if (artworkId.isValid()) { image->clicked().connect([artworkId] { - utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(artworkId) }); + utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::DefaultArtworkType::Artist) }); }); } } diff --git a/src/lms/ui/explore/ReleaseHelpers.cpp b/src/lms/ui/explore/ReleaseHelpers.cpp index 6fe653d5..f01ec00f 100644 --- a/src/lms/ui/explore/ReleaseHelpers.cpp +++ b/src/lms/ui/explore/ReleaseHelpers.cpp @@ -54,9 +54,9 @@ namespace lms::ui::releaseListHelpers std::unique_ptr image; if (release->getPreferredArtworkId().isValid()) - image = utils::createArtworkImage(release->getPreferredArtworkId(), ArtworkResource::Size::Large); + image = utils::createArtworkImage(release->getPreferredArtworkId(), ArtworkResource::DefaultArtworkType::Release, ArtworkResource::Size::Large); else - image = utils::createDefaultReleaseArtworkImage(); + image = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Release); image->addStyleClass("Lms-cover-release Lms-cover-anchor rounded"); // hack anchor->setImage(std::move(image)); diff --git a/src/lms/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp index c9ae9de9..4b5697be 100644 --- a/src/lms/ui/explore/ReleaseView.cpp +++ b/src/lms/ui/explore/ReleaseView.cpp @@ -396,13 +396,13 @@ namespace lms::ui if (mediaArtworkId.isValid()) { - auto image{ utils::createArtworkImage(mediaArtworkId, ArtworkResource::Size::Small) }; + auto image{ utils::createArtworkImage(mediaArtworkId, ArtworkResource::DefaultArtworkType::Release, ArtworkResource::Size::Small) }; disc->setCondition("if-has-artwork", true); image->addStyleClass("Lms-cover-track rounded"); // HACK image->clicked().connect([=] { - utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(mediaArtworkId) }); + utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(mediaArtworkId, ArtworkResource::DefaultArtworkType::Release) }); }); disc->bindWidget("artwork", std::move(image)); } @@ -570,17 +570,17 @@ namespace lms::ui std::unique_ptr artworkImage; if (artworkId.isValid()) { - artworkImage = utils::createArtworkImage(artworkId, ArtworkResource::Size::Large); + artworkImage = utils::createArtworkImage(artworkId, ArtworkResource::DefaultArtworkType::Release, ArtworkResource::Size::Large); artworkImage->addStyleClass("Lms-cursor-pointer"); // HACK } else - artworkImage = utils::createDefaultReleaseArtworkImage(); + artworkImage = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Release); auto* image{ bindWidget("artwork", std::move(artworkImage)) }; if (artworkId.isValid()) { image->clicked().connect([artworkId] { - utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(artworkId) }); + utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtworkUrl(artworkId, ArtworkResource::DefaultArtworkType::Release) }); }); } } diff --git a/src/lms/ui/explore/TrackListHelpers.cpp b/src/lms/ui/explore/TrackListHelpers.cpp index 1fea0698..2cc0bc2f 100644 --- a/src/lms/ui/explore/TrackListHelpers.cpp +++ b/src/lms/ui/explore/TrackListHelpers.cpp @@ -230,11 +230,11 @@ namespace lms::ui::TrackListHelpers std::unique_ptr image; if (track->getPreferredMediaArtworkId().isValid()) - image = utils::createArtworkImage(track->getPreferredMediaArtworkId(), ArtworkResource::Size::Small); + image = utils::createArtworkImage(track->getPreferredMediaArtworkId(), ArtworkResource::DefaultArtworkType::Track, ArtworkResource::Size::Small); else if (track->getPreferredArtworkId().isValid()) - image = utils::createArtworkImage(track->getPreferredArtworkId(), ArtworkResource::Size::Small); + image = utils::createArtworkImage(track->getPreferredArtworkId(), ArtworkResource::DefaultArtworkType::Track, ArtworkResource::Size::Small); else - image = utils::createDefaultTrackArtworkImage(); + image = utils::createDefaultArtworkImage(ArtworkResource::DefaultArtworkType::Track); image->addStyleClass("Lms-cover-track rounded"); // hack if (track->getRelease()) diff --git a/src/lms/ui/resource/ArtworkResource.cpp b/src/lms/ui/resource/ArtworkResource.cpp index 20b341ed..cb7a5893 100644 --- a/src/lms/ui/resource/ArtworkResource.cpp +++ b/src/lms/ui/resource/ArtworkResource.cpp @@ -34,6 +34,26 @@ namespace lms::ui { + namespace + { + std::string_view getDefaultArtworkPart(ArtworkResource::DefaultArtworkType fallbackType) + { + std::string_view res; + switch (fallbackType) + { + case ArtworkResource::DefaultArtworkType::Release: + case ArtworkResource::DefaultArtworkType::Track: + res = "&fallback=defrelease"; + break; + + case ArtworkResource::DefaultArtworkType::Artist: + res = "&fallback=defartist"; + } + + return res; + } + } // namespace + ArtworkResource::ArtworkResource() { LmsApp->getScannerEvents().scanComplete.connect(this, [this](const scanner::ScanStats& stats) { @@ -47,28 +67,22 @@ namespace lms::ui beingDeleted(); } - std::string ArtworkResource::getArtworkUrl(db::ArtworkId artworkId, std::optional size) const + std::string ArtworkResource::getArtworkUrl(db::ArtworkId artworkId, DefaultArtworkType fallbackType, std::optional size) const { std::string res{ url() + "&artworkid=" + artworkId.toString() }; if (size) res += "&size=" + std::to_string(static_cast(*size)); + res += getDefaultArtworkPart(fallbackType); + return res; } - std::string ArtworkResource::getDefaultArtistArtworkUrl() const + std::string ArtworkResource::getDefaultArtworkUrl(DefaultArtworkType type) const { - return url() + "&type=defartist"; - } - - std::string ArtworkResource::getDefaultReleaseArtworkUrl() const - { - return url() + "&type=defrelease"; - } - - std::string ArtworkResource::getDefaultTrackArtworkUrl() const - { - return url() + "&type=defrelease"; + std::string res{ url() }; + res += getDefaultArtworkPart(type); + return res; } void ArtworkResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) @@ -78,20 +92,13 @@ namespace lms::ui // Retrieve parameters const std::string* artworkIdStr = request.getParameter("artworkid"); const std::string* sizeStr = request.getParameter("size"); - const std::string* typeStr = request.getParameter("type"); + const std::string* fallbackStr = request.getParameter("fallback"); std::shared_ptr image; - if (artworkIdStr && typeStr) + if (!artworkIdStr && !fallbackStr) { - ARTWORK_RESOURCE_LOG(DEBUG, "both artwork ID and type provided, only one is allowed"); - response.setStatus(400); - return; - } - - if (!artworkIdStr && !typeStr) - { - ARTWORK_RESOURCE_LOG(DEBUG, "no artwork ID or type provided"); + ARTWORK_RESOURCE_LOG(DEBUG, "no artwork ID or fallback provided"); response.setStatus(400); return; } @@ -118,22 +125,22 @@ namespace lms::ui if (!image) ARTWORK_RESOURCE_LOG(DEBUG, "no image found for artwork ID: '" << *artworkIdStr << "'"); } - else + + if (!image && fallbackStr) { - assert(typeStr); - if (*typeStr == "defartist") + if (*fallbackStr == "defartist") image = core::Service::get()->getDefaultArtistArtwork(); - else if (*typeStr == "defrelease") + else if (*fallbackStr == "defrelease") image = core::Service::get()->getDefaultReleaseArtwork(); else { - ARTWORK_RESOURCE_LOG(DEBUG, "invalid type provided: '" << *typeStr << "'"); + ARTWORK_RESOURCE_LOG(DEBUG, "invalid type provided: '" << *fallbackStr << "'"); response.setStatus(400); return; } if (!image) - ARTWORK_RESOURCE_LOG(DEBUG, "no default image found for type: '" << *typeStr << "'"); + ARTWORK_RESOURCE_LOG(DEBUG, "no default image found for type: '" << *fallbackStr << "'"); } if (image) diff --git a/src/lms/ui/resource/ArtworkResource.hpp b/src/lms/ui/resource/ArtworkResource.hpp index 05d8266c..03d4b4f0 100644 --- a/src/lms/ui/resource/ArtworkResource.hpp +++ b/src/lms/ui/resource/ArtworkResource.hpp @@ -41,11 +41,15 @@ namespace lms::ui Large = 512, }; - std::string getArtworkUrl(db::ArtworkId artworkId, std::optional size = std::nullopt) const; + enum class DefaultArtworkType + { + Artist, + Release, + Track, + }; - std::string getDefaultArtistArtworkUrl() const; - std::string getDefaultReleaseArtworkUrl() const; - std::string getDefaultTrackArtworkUrl() const; + std::string getArtworkUrl(db::ArtworkId artworkId, DefaultArtworkType fallbackType, std::optional size = std::nullopt) const; + std::string getDefaultArtworkUrl(DefaultArtworkType type) const; private: void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;