Added artwork+biography in artist view, ref #640

This commit is contained in:
emeric
2025-03-23 14:49:27 +01:00
parent cb631eea06
commit 9dd8b4b381
14 changed files with 88 additions and 39 deletions
+24 -16
View File
@@ -3,22 +3,30 @@
<!--FORMS message blocks-->
<message id="Lms.Explore.Artist.template">
<div class="mb-3">
<h2>${name}</h2>
${clusters class="mb-2"}
<div class="btn-group">
${play-btn class="btn btn-primary"}
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
<ul class="dropdown-menu">
<li>${play-next class="dropdown-item"}</li>
<li>${play-last class="dropdown-item"}</li>
<li>${play-shuffled class="dropdown-item"}</li>
<li>${star class="dropdown-item"}</li>
${<if-has-mbid>}
<li><a href="${mbid-link}" target="_blank" class="dropdown-item">${tr:Lms.Explore.musicbrainz-artist}</a></li>
${</if-has-mbid>}
<li>${download class="dropdown-item"}</li>
</ul>
<div class="row mb-3 gy-3">
<div class="col-lg-3 col-md-4">
${artwork class="Lms-cursor-pointer rounded"}
</div>
<div class="col">
<h2>${name}</h2>
${clusters class="mb-2"}
${<if-has-biography>}
${biography class="mb-2 Lms-multiline-clamp Lms-cursor-pointer"}
${</if-has-biography>}
<div class="btn-group">
${play-btn class="btn btn-primary"}
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
<ul class="dropdown-menu">
<li>${play-next class="dropdown-item"}</li>
<li>${play-last class="dropdown-item"}</li>
<li>${play-shuffled class="dropdown-item"}</li>
<li>${star class="dropdown-item"}</li>
${<if-has-mbid>}
<li><a href="${mbid-link}" target="_blank" class="dropdown-item">${tr:Lms.Explore.musicbrainz-artist}</a></li>
${</if-has-mbid>}
<li>${download class="dropdown-item"}</li>
</ul>
</div>
</div>
</div>
${release-containers}
+12
View File
@@ -69,4 +69,16 @@
</div>
</message>
<message id="Lms.Explore.template.full-modal-artwork">
<div class="modal fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered Lms-artwork-full-modal-dialog">
<div class="modal-content bg-transparent border-0">
<div class="modal-body text-center">
${artwork class="Lms-cover-full Lms-cursor-pointer"}
</div>
</div>
</div>
</div>
</message>
</messages>
+1
View File
@@ -209,6 +209,7 @@
<!--Explore:Artist-->
<message id="Lms.Explore.Artist.appears-on">Appears on</message>
<message id="Lms.Explore.Artist.biography">Biography</message>
<message id="Lms.Explore.Artist.similar-artists">Similar artists</message>
<!--Explore:Artists-->
+1
View File
@@ -209,6 +209,7 @@
<!--Explore:Artist-->
<message id="Lms.Explore.Artist.appears-on">Apparaît dans</message>
<message id="Lms.Explore.Artist.biography">Biographie</message>
<message id="Lms.Explore.Artist.similar-artists">Artistes similaires</message>
<!--Explore:Artists-->
+1
View File
@@ -209,6 +209,7 @@
<!--Explore:Artist-->
<message id="Lms.Explore.Artist.appears-on">Appare su</message>
<message id="Lms.Explore.Artist.biography">Biografia</message>
<message id="Lms.Explore.Artist.similar-artists">Artisti simili</message>
<!--Explore:Artists-->
+1
View File
@@ -226,6 +226,7 @@
<!--Explore:Artist-->
<message id="Lms.Explore.Artist.appears-on">Pojawia się na</message>
<message id="Lms.Explore.Artist.biography">Biografia</message>
<message id="Lms.Explore.Artist.similar-artists">Podobni artyści</message>
<!--Explore:Artists-->
+1
View File
@@ -209,6 +209,7 @@
<!--Explore:Artist-->
<message id="Lms.Explore.Artist.appears-on">出现于</message>
<message id="Lms.Explore.Artist.similar-artists">相似歌手</message>
<!--Explore:Artists-->
-12
View File
@@ -49,18 +49,6 @@
${</if-has-similar-releases>}
</message>
<message id="Lms.Explore.Release.template.full-cover">
<div class="modal fade" tabindex="-1">
<div class="modal-dialog modal-dialog-centered Lms-cover-full-modal-dialog">
<div class="modal-content bg-transparent border-0">
<div class="modal-body text-center">
${cover-full class="Lms-cover-full"}
</div>
</div>
</div>
</div>
</message>
<message id="Lms.Explore.Release.template.entry-release-artist">
${artist class="text-decoration-none link-success"}
</message>
+2 -3
View File
@@ -87,7 +87,7 @@ body {
min-width: 64px;
}
.Lms-cover-full-modal-dialog {
.Lms-artwork-full-modal-dialog {
width: auto;
max-width: none;
max-height: 90vh;
@@ -103,12 +103,11 @@ body {
height: auto;
display: block;
margin: auto;
cursor: pointer;
object-fit: contain;
}
.Lms-cursor-pointer {
cursor: pointer;
cursor: pointer;
}
#lms-mp-progress {
+13
View File
@@ -35,6 +35,7 @@
#include "database/TrackList.hpp"
#include "LmsApplication.hpp"
#include "ModalManager.hpp"
#include "explore/Filters.hpp"
namespace lms::ui::utils
@@ -63,6 +64,18 @@ namespace lms::ui::utils
return oss.str();
}
void showArtworkModal(Wt::WLink image)
{
auto rawImage{ std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.template.full-modal-artwork")) };
rawImage->bindNew<Wt::WImage>("artwork", image);
Wt::WTemplate* rawImagePtr{ rawImage.get() };
rawImage->clicked().connect([=] {
LmsApp->getModalManager().dispose(rawImagePtr);
});
LmsApp->getModalManager().show(std::move(rawImage));
}
std::unique_ptr<Wt::WImage> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size)
{
auto image{ std::make_unique<Wt::WImage>() };
+2
View File
@@ -54,6 +54,8 @@ namespace lms::ui::utils
{
std::string durationToString(std::chrono::milliseconds msDuration);
void showArtworkModal(Wt::WLink image);
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> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size);
+27
View File
@@ -23,6 +23,7 @@
#include "core/String.hpp"
#include "database/Artist.hpp"
#include "database/ArtistInfo.hpp"
#include "database/Cluster.hpp"
#include "database/Release.hpp"
#include "database/ScanSettings.hpp"
@@ -118,6 +119,8 @@ namespace lms::ui
LmsApp->setTitle(artist->getName());
_artistId = *artistId;
refreshArtwork();
refreshArtistInfo();
refreshReleases();
refreshAppearsOnReleases();
refreshNonReleaseTracks();
@@ -188,6 +191,30 @@ namespace lms::ui
}
}
void Artist::refreshArtwork()
{
auto* image{ bindWidget<Wt::WImage>("artwork", utils::createArtistImage(_artistId, ArtworkResource::Size::Large)) };
image->clicked().connect([this] {
utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getArtistImageUrl(_artistId) });
});
}
void Artist::refreshArtistInfo()
{
db::ArtistInfo::find(LmsApp->getDbSession(), _artistId, db::Range{ .offset = 0, .size = 1 }, [this](const db::ArtistInfo::pointer& _info) {
if (!_info->getBiography().empty())
{
setCondition("if-has-biography", true);
Wt::WText* bio{ bindNew<Wt::WText>("biography", std::string{ _info->getBiography() }, Wt::TextFormat::Plain) };
bio->setInline(false);
bio->setToolTip(tr("Lms.Explore.Artist.biography"));
bio->clicked().connect([bio] {
bio->toggleStyleClass("Lms-multiline-clamp", !bio->hasStyleClass("Lms-multiline-clamp")); // hack
});
}
});
}
void Artist::refreshReleases()
{
_releaseContainers.clear();
+2
View File
@@ -47,6 +47,8 @@ namespace lms::ui
private:
void refreshView();
void refreshArtwork();
void refreshArtistInfo();
void refreshReleases();
void refreshAppearsOnReleases();
void refreshNonReleaseTracks();
+1 -8
View File
@@ -309,14 +309,7 @@ namespace lms::ui
auto* image{ bindWidget<Wt::WImage>("cover", utils::createReleaseCover(release->getId(), ArtworkResource::Size::Large)) };
image->clicked().connect([=] {
auto fullCover{ std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Release.template.full-cover")) };
fullCover->bindNew<Wt::WImage>("cover-full", Wt::WLink{ LmsApp->getArtworkResource()->getReleaseCoverUrl(*releaseId) });
Wt::WTemplate* fullCoverPtr{ fullCover.get() };
fullCover->clicked().connect([=] {
LmsApp->getModalManager().dispose(fullCoverPtr);
});
LmsApp->getModalManager().show(std::move(fullCover));
utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getReleaseCoverUrl(*releaseId) });
});
Wt::WContainerWidget* clusterContainers{ bindNew<Wt::WContainerWidget>("clusters") };