Added artwork+biography in artist view, ref #640
This commit is contained in:
+24
-16
@@ -3,22 +3,30 @@
|
|||||||
<!--FORMS message blocks-->
|
<!--FORMS message blocks-->
|
||||||
|
|
||||||
<message id="Lms.Explore.Artist.template">
|
<message id="Lms.Explore.Artist.template">
|
||||||
<div class="mb-3">
|
<div class="row mb-3 gy-3">
|
||||||
<h2>${name}</h2>
|
<div class="col-lg-3 col-md-4">
|
||||||
${clusters class="mb-2"}
|
${artwork class="Lms-cursor-pointer rounded"}
|
||||||
<div class="btn-group">
|
</div>
|
||||||
${play-btn class="btn btn-primary"}
|
<div class="col">
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
|
<h2>${name}</h2>
|
||||||
<ul class="dropdown-menu">
|
${clusters class="mb-2"}
|
||||||
<li>${play-next class="dropdown-item"}</li>
|
${<if-has-biography>}
|
||||||
<li>${play-last class="dropdown-item"}</li>
|
${biography class="mb-2 Lms-multiline-clamp Lms-cursor-pointer"}
|
||||||
<li>${play-shuffled class="dropdown-item"}</li>
|
${</if-has-biography>}
|
||||||
<li>${star class="dropdown-item"}</li>
|
<div class="btn-group">
|
||||||
${<if-has-mbid>}
|
${play-btn class="btn btn-primary"}
|
||||||
<li><a href="${mbid-link}" target="_blank" class="dropdown-item">${tr:Lms.Explore.musicbrainz-artist}</a></li>
|
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
|
||||||
${</if-has-mbid>}
|
<ul class="dropdown-menu">
|
||||||
<li>${download class="dropdown-item"}</li>
|
<li>${play-next class="dropdown-item"}</li>
|
||||||
</ul>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
${release-containers}
|
${release-containers}
|
||||||
|
|||||||
@@ -69,4 +69,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</message>
|
</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>
|
</messages>
|
||||||
|
|||||||
@@ -209,6 +209,7 @@
|
|||||||
|
|
||||||
<!--Explore:Artist-->
|
<!--Explore:Artist-->
|
||||||
<message id="Lms.Explore.Artist.appears-on">Appears on</message>
|
<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>
|
<message id="Lms.Explore.Artist.similar-artists">Similar artists</message>
|
||||||
|
|
||||||
<!--Explore:Artists-->
|
<!--Explore:Artists-->
|
||||||
|
|||||||
@@ -209,6 +209,7 @@
|
|||||||
|
|
||||||
<!--Explore:Artist-->
|
<!--Explore:Artist-->
|
||||||
<message id="Lms.Explore.Artist.appears-on">Apparaît dans</message>
|
<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>
|
<message id="Lms.Explore.Artist.similar-artists">Artistes similaires</message>
|
||||||
|
|
||||||
<!--Explore:Artists-->
|
<!--Explore:Artists-->
|
||||||
|
|||||||
@@ -209,6 +209,7 @@
|
|||||||
|
|
||||||
<!--Explore:Artist-->
|
<!--Explore:Artist-->
|
||||||
<message id="Lms.Explore.Artist.appears-on">Appare su</message>
|
<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>
|
<message id="Lms.Explore.Artist.similar-artists">Artisti simili</message>
|
||||||
|
|
||||||
<!--Explore:Artists-->
|
<!--Explore:Artists-->
|
||||||
|
|||||||
@@ -226,6 +226,7 @@
|
|||||||
|
|
||||||
<!--Explore:Artist-->
|
<!--Explore:Artist-->
|
||||||
<message id="Lms.Explore.Artist.appears-on">Pojawia się na</message>
|
<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>
|
<message id="Lms.Explore.Artist.similar-artists">Podobni artyści</message>
|
||||||
|
|
||||||
<!--Explore:Artists-->
|
<!--Explore:Artists-->
|
||||||
|
|||||||
@@ -209,6 +209,7 @@
|
|||||||
|
|
||||||
<!--Explore:Artist-->
|
<!--Explore:Artist-->
|
||||||
<message id="Lms.Explore.Artist.appears-on">出现于</message>
|
<message id="Lms.Explore.Artist.appears-on">出现于</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.Artist.similar-artists">相似歌手</message>
|
<message id="Lms.Explore.Artist.similar-artists">相似歌手</message>
|
||||||
|
|
||||||
<!--Explore:Artists-->
|
<!--Explore:Artists-->
|
||||||
|
|||||||
@@ -49,18 +49,6 @@
|
|||||||
${</if-has-similar-releases>}
|
${</if-has-similar-releases>}
|
||||||
</message>
|
</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">
|
<message id="Lms.Explore.Release.template.entry-release-artist">
|
||||||
${artist class="text-decoration-none link-success"}
|
${artist class="text-decoration-none link-success"}
|
||||||
</message>
|
</message>
|
||||||
|
|||||||
+2
-3
@@ -87,7 +87,7 @@ body {
|
|||||||
min-width: 64px;
|
min-width: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Lms-cover-full-modal-dialog {
|
.Lms-artwork-full-modal-dialog {
|
||||||
width: auto;
|
width: auto;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
@@ -103,12 +103,11 @@ body {
|
|||||||
height: auto;
|
height: auto;
|
||||||
display: block;
|
display: block;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
cursor: pointer;
|
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Lms-cursor-pointer {
|
.Lms-cursor-pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lms-mp-progress {
|
#lms-mp-progress {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "database/TrackList.hpp"
|
#include "database/TrackList.hpp"
|
||||||
|
|
||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
|
#include "ModalManager.hpp"
|
||||||
#include "explore/Filters.hpp"
|
#include "explore/Filters.hpp"
|
||||||
|
|
||||||
namespace lms::ui::utils
|
namespace lms::ui::utils
|
||||||
@@ -63,6 +64,18 @@ namespace lms::ui::utils
|
|||||||
return oss.str();
|
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)
|
std::unique_ptr<Wt::WImage> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size)
|
||||||
{
|
{
|
||||||
auto image{ std::make_unique<Wt::WImage>() };
|
auto image{ std::make_unique<Wt::WImage>() };
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ namespace lms::ui::utils
|
|||||||
{
|
{
|
||||||
std::string durationToString(std::chrono::milliseconds msDuration);
|
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> 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> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size);
|
std::unique_ptr<Wt::WImage> createArtistImage(db::ArtistId artistId, ArtworkResource::Size size);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "core/String.hpp"
|
#include "core/String.hpp"
|
||||||
#include "database/Artist.hpp"
|
#include "database/Artist.hpp"
|
||||||
|
#include "database/ArtistInfo.hpp"
|
||||||
#include "database/Cluster.hpp"
|
#include "database/Cluster.hpp"
|
||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "database/ScanSettings.hpp"
|
#include "database/ScanSettings.hpp"
|
||||||
@@ -118,6 +119,8 @@ namespace lms::ui
|
|||||||
LmsApp->setTitle(artist->getName());
|
LmsApp->setTitle(artist->getName());
|
||||||
_artistId = *artistId;
|
_artistId = *artistId;
|
||||||
|
|
||||||
|
refreshArtwork();
|
||||||
|
refreshArtistInfo();
|
||||||
refreshReleases();
|
refreshReleases();
|
||||||
refreshAppearsOnReleases();
|
refreshAppearsOnReleases();
|
||||||
refreshNonReleaseTracks();
|
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()
|
void Artist::refreshReleases()
|
||||||
{
|
{
|
||||||
_releaseContainers.clear();
|
_releaseContainers.clear();
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ namespace lms::ui
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshView();
|
void refreshView();
|
||||||
|
void refreshArtwork();
|
||||||
|
void refreshArtistInfo();
|
||||||
void refreshReleases();
|
void refreshReleases();
|
||||||
void refreshAppearsOnReleases();
|
void refreshAppearsOnReleases();
|
||||||
void refreshNonReleaseTracks();
|
void refreshNonReleaseTracks();
|
||||||
|
|||||||
@@ -309,14 +309,7 @@ namespace lms::ui
|
|||||||
|
|
||||||
auto* image{ bindWidget<Wt::WImage>("cover", utils::createReleaseCover(release->getId(), ArtworkResource::Size::Large)) };
|
auto* image{ bindWidget<Wt::WImage>("cover", utils::createReleaseCover(release->getId(), ArtworkResource::Size::Large)) };
|
||||||
image->clicked().connect([=] {
|
image->clicked().connect([=] {
|
||||||
auto fullCover{ std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Release.template.full-cover")) };
|
utils::showArtworkModal(Wt::WLink{ LmsApp->getArtworkResource()->getReleaseCoverUrl(*releaseId) });
|
||||||
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));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Wt::WContainerWidget* clusterContainers{ bindNew<Wt::WContainerWidget>("clusters") };
|
Wt::WContainerWidget* clusterContainers{ bindNew<Wt::WContainerWidget>("clusters") };
|
||||||
|
|||||||
Reference in New Issue
Block a user