Fixed fallback artworks not shown when removed from library (and scan not triggered yet)

This commit is contained in:
emeric
2025-07-14 15:14:20 +02:00
parent 5d2db5c02b
commit 5c8a18d86e
11 changed files with 72 additions and 75 deletions
+5 -3
View File
@@ -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 << "};";
+2 -2
View File
@@ -496,9 +496,9 @@ namespace lms::ui
std::unique_ptr<Wt::WImage> 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
+4 -18
View File
@@ -88,31 +88,17 @@ namespace lms::ui::utils
LmsApp->getModalManager().show(std::move(rawImage));
}
std::unique_ptr<Wt::WImage> createArtworkImage(db::ArtworkId artworkId, ArtworkResource::Size size)
std::unique_ptr<Wt::WImage> 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<Wt::WImage> createDefaultArtistArtworkImage()
std::unique_ptr<Wt::WImage> createDefaultArtworkImage(ArtworkResource::DefaultArtworkType type)
{
auto image{ createArtworkImage() };
image->setImageLink(LmsApp->getArtworkResource()->getDefaultArtistArtworkUrl());
return image;
}
std::unique_ptr<Wt::WImage> createDefaultReleaseArtworkImage()
{
auto image{ createArtworkImage() };
image->setImageLink(LmsApp->getArtworkResource()->getDefaultReleaseArtworkUrl());
return image;
}
std::unique_ptr<Wt::WImage> createDefaultTrackArtworkImage()
{
auto image{ createArtworkImage() };
image->setImageLink(LmsApp->getArtworkResource()->getDefaultTrackArtworkUrl());
image->setImageLink(LmsApp->getArtworkResource()->getDefaultArtworkUrl(type));
return image;
}
+2 -4
View File
@@ -57,10 +57,8 @@ namespace lms::ui::utils
void showArtworkModal(Wt::WLink image);
std::unique_ptr<Wt::WImage> createArtworkImage(db::ArtworkId artworkId, ArtworkResource::Size size);
std::unique_ptr<Wt::WImage> createDefaultArtistArtworkImage();
std::unique_ptr<Wt::WImage> createDefaultReleaseArtworkImage();
std::unique_ptr<Wt::WImage> createDefaultTrackArtworkImage();
std::unique_ptr<Wt::WImage> createArtworkImage(db::ArtworkId artworkId, ArtworkResource::DefaultArtworkType type, ArtworkResource::Size size);
std::unique_ptr<Wt::WImage> createDefaultArtworkImage(ArtworkResource::DefaultArtworkType type);
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> createFilterCluster(db::ClusterId clusterId, bool canDelete = false);
+2 -2
View File
@@ -35,9 +35,9 @@ namespace lms::ui::ArtistListHelpers
std::unique_ptr<Wt::WImage> 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));
+3 -3
View File
@@ -197,17 +197,17 @@ namespace lms::ui
std::unique_ptr<Wt::WImage> 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<Wt::WImage>("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) });
});
}
}
+2 -2
View File
@@ -54,9 +54,9 @@ namespace lms::ui::releaseListHelpers
std::unique_ptr<Wt::WImage> 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));
+5 -5
View File
@@ -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<Wt::WImage>("artwork", std::move(image));
}
@@ -570,17 +570,17 @@ namespace lms::ui
std::unique_ptr<Wt::WImage> 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<Wt::WImage>("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) });
});
}
}
+3 -3
View File
@@ -230,11 +230,11 @@ namespace lms::ui::TrackListHelpers
std::unique_ptr<Wt::WImage> 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())
+36 -29
View File
@@ -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> size) const
std::string ArtworkResource::getArtworkUrl(db::ArtworkId artworkId, DefaultArtworkType fallbackType, std::optional<Size> size) const
{
std::string res{ url() + "&artworkid=" + artworkId.toString() };
if (size)
res += "&size=" + std::to_string(static_cast<std::size_t>(*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::IEncodedImage> 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<artwork::IArtworkService>::get()->getDefaultArtistArtwork();
else if (*typeStr == "defrelease")
else if (*fallbackStr == "defrelease")
image = core::Service<artwork::IArtworkService>::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)
+8 -4
View File
@@ -41,11 +41,15 @@ namespace lms::ui
Large = 512,
};
std::string getArtworkUrl(db::ArtworkId artworkId, std::optional<Size> 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> size = std::nullopt) const;
std::string getDefaultArtworkUrl(DefaultArtworkType type) const;
private:
void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;