Added artwork+biography in artist view, ref #640
This commit is contained in:
+24
-16
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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-->
|
||||
|
||||
@@ -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-->
|
||||
|
||||
@@ -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-->
|
||||
|
||||
@@ -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-->
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
|
||||
<!--Explore:Artist-->
|
||||
<message id="Lms.Explore.Artist.appears-on">出现于</message>
|
||||
|
||||
<message id="Lms.Explore.Artist.similar-artists">相似歌手</message>
|
||||
|
||||
<!--Explore:Artists-->
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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>() };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace lms::ui
|
||||
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshArtwork();
|
||||
void refreshArtistInfo();
|
||||
void refreshReleases();
|
||||
void refreshAppearsOnReleases();
|
||||
void refreshNonReleaseTracks();
|
||||
|
||||
@@ -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") };
|
||||
|
||||
Reference in New Issue
Block a user