Merge branch 'new-track-layout-v2' into develop, fix #313
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
<message id="Lms.Admin.Users.template">
|
||||
<h3>${tr:Lms.Admin.Users.users}</h3>
|
||||
${users class="d-grid gap-1 mb-3"}
|
||||
${users class="d-grid gap-1 mb-3 Lms-row-container"}
|
||||
${<if-can-create-user>}
|
||||
${add-btn class="btn btn-primary"}
|
||||
${</if-can-create-user>}
|
||||
|
||||
@@ -27,10 +27,14 @@
|
||||
</div>
|
||||
<div class="flex-fill text-center text-truncate">
|
||||
${title class="d-block text-truncate"}
|
||||
${release class="text-decoration-none text-truncate link-success"}
|
||||
${artist class="d-inline text-decoration-none text-truncate link-success"}
|
||||
<span class="d-none d-md-inline">
|
||||
${separator}
|
||||
${release class="text-decoration-none text-truncate link-success"}
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-2 d-none d-sm-block text-muted text-nowrap">
|
||||
<span id="lms-transcoding-active" title="${tr:Lms.Player.transcoding-active}" class="p-2" style="visibility:hidden"><i class="fa fa-fw fa-info-circle" aria-hidden="true"></i></span>
|
||||
<span id="lms-transcoding-active" title="${tr:Lms.Player.transcoding-active}" class="p-2" style="display:none"><i class="fa fa-fw fa-info-circle" aria-hidden="true"></i></span>
|
||||
<span id="lms-mp-curtime">--</span> / <span id="lms-mp-duration">--</span>
|
||||
</div>
|
||||
<div class="p-2 d-none d-md-flex align-items-center Lms-player-volume-container">
|
||||
|
||||
+25
-9
@@ -30,28 +30,44 @@
|
||||
${entries}
|
||||
</message>
|
||||
|
||||
<message id="Lms.PlayQueue.template.entry-container">
|
||||
${elements class="Lms-row-container"}
|
||||
${loading-indicator}
|
||||
</message>
|
||||
|
||||
<message id="Lms.PlayQueue.template.entry">
|
||||
<div class="d-flex align-items-center rounded Lms-bg-dark-hover mb-2">
|
||||
<div class="p-1 Lms-cover-small">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="p-1">
|
||||
${cover}
|
||||
</div>
|
||||
<div class="p-2 flex-fill text-truncate">
|
||||
<div class="d-block text-truncate">${name}</div>
|
||||
${<if-has-release>}${release class="text-decoration-none link-success text-truncate"}${</if-has-release>}
|
||||
<div class="row align-items-center flex-fill overflow-hidden">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="p-2 overflow-hidden">
|
||||
<div class="d-block text-truncate">${name}</div>
|
||||
${<if-has-artists>}${artists class="d-block d-md-none text-truncate"}${</if-has-artists>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
${<if-has-artists>}${artists-md class="d-none d-md-block text-truncate"}${</if-has-artists>}
|
||||
</div>
|
||||
<div class="col-lg-4 text-truncate">
|
||||
${<if-has-release>}${release class="d-none d-lg-inline text-truncate text-decoration-none link-success"}${</if-has-release>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2 d-none d-sm-block text-muted">
|
||||
<div class="p-2 d-none d-sm-block text-muted text-center Lms-tracks-entry-duration">
|
||||
${duration}
|
||||
</div>
|
||||
<div class="p-2 d-flex">
|
||||
${play-btn class="btn btn-sm btn-outline-secondary border-0"}
|
||||
<div class="dropdown d-none d-sm-block">
|
||||
${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"}
|
||||
${del-btn class="btn btn-sm btn-outline-secondary border-0"}
|
||||
<div class="dropdown d-inline-block">
|
||||
${more-btn data-bs-toggle="dropdown" aria-expanded="false" class="btn btn-sm btn-outline-secondary border-0"}
|
||||
<ul class="dropdown-menu" aria-labelledby="${id:more-btn}">
|
||||
<li>${play class="dropdown-item"}</li>
|
||||
<li>${star class="dropdown-item"}</li>
|
||||
<li>${download class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
${del-btn class="btn btn-sm btn-outline-secondary border-0"}
|
||||
</div>
|
||||
</div>
|
||||
</message>
|
||||
|
||||
+17
-9
@@ -51,30 +51,38 @@
|
||||
|
||||
<message id="Lms.Explore.Release.template.entry-disc">
|
||||
<h4>${disc-title}</h4>
|
||||
${tracks class="d-grid gap-1"}
|
||||
${tracks class="d-grid gap-1 Lms-row-container"}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Release.template.entry-nodisc">
|
||||
${tracks class="d-grid gap-1"}
|
||||
${tracks class="d-grid gap-1 Lms-row-container"}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Release.template.entry">
|
||||
<div class="d-flex align-items-center rounded Lms-bg-dark-hover">
|
||||
<div class="p-2 text-muted text-end" style="min-width: 2.1rem;">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="p-2 text-muted text-end Lms-tracks-entry-position">
|
||||
${<if-has-track-number>}${track-number}${</if-has-track-number>}
|
||||
</div>
|
||||
<div class="p-2 flex-fill">
|
||||
${name}
|
||||
${<if-has-artists>}${artists}${</if-has-artists>}
|
||||
<div class="row align-items-center flex-fill overflow-hidden">
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">
|
||||
${name}
|
||||
${<if-has-artists>}${artists class="d-block d-md-none"}${</if-has-artists>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
${<if-has-artists>}${artists-md class="d-none d-md-block"}${</if-has-artists>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2 d-none d-sm-block text-muted">
|
||||
<div class="p-2 d-none d-sm-block text-muted text-center Lms-tracks-entry-duration">
|
||||
${duration}
|
||||
</div>
|
||||
<div class="p-2 d-flex">
|
||||
${play-btn class="btn btn-sm btn-outline-secondary border-0"}
|
||||
${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"}
|
||||
<div class="dropdown d-inline-block">
|
||||
${more-btn data-bs-toggle="dropdown" aria-expanded="false" class="btn btn-sm btn-outline-secondary border-0"}
|
||||
<ul class="dropdown-menu" aria-labelledby="${id:more-btn}">
|
||||
<li>${play class="dropdown-item"}</li>
|
||||
<li>${play-last class="dropdown-item"}</li>
|
||||
<li>${star class="dropdown-item"}</li>
|
||||
<li>${download class="dropdown-item"}</li>
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
${tracks}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.TrackList.template.entry-container">
|
||||
${elements class="Lms-row-container"}
|
||||
${loading-indicator}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.TrackList.template.delete-tracklist">
|
||||
<div class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
|
||||
+23
-11
@@ -37,23 +37,39 @@
|
||||
${tracks}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Tracks.template.entry-container">
|
||||
${elements class="Lms-row-container"}
|
||||
${loading-indicator}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Tracks.template.entry">
|
||||
<div class="d-flex align-items-center rounded Lms-bg-dark-hover mb-2">
|
||||
<div class="p-1 Lms-cover-small">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="p-1">
|
||||
${cover}
|
||||
</div>
|
||||
<div class="p-2 flex-fill text-truncate">
|
||||
<div class="d-block text-truncate">${name}</div>
|
||||
${<if-has-release>}${release class="text-decoration-none link-success text-truncate"}${</if-has-release>}
|
||||
<div class="row align-items-center flex-fill overflow-hidden">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<div class="p-2 overflow-hidden">
|
||||
<div class="d-block text-truncate">${name}</div>
|
||||
${<if-has-artists>}${artists class="d-block d-md-none text-truncate"}${</if-has-artists>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
${<if-has-artists>}${artists-md class="d-none d-md-block text-truncate"}${</if-has-artists>}
|
||||
</div>
|
||||
<div class="col-lg-4 text-truncate">
|
||||
${<if-has-release>}${release class="d-none d-lg-inline text-truncate text-decoration-none link-success"}${</if-has-release>}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2 d-none d-sm-block text-muted">
|
||||
<div class="p-2 d-none d-sm-block text-muted text-center Lms-tracks-entry-duration">
|
||||
${duration}
|
||||
</div>
|
||||
<div class="p-2 d-flex">
|
||||
${play-btn class="btn btn-sm btn-outline-secondary border-0"}
|
||||
${play-btn class="d-none d-sm-block btn btn-sm btn-outline-secondary border-0"}
|
||||
<div class="dropdown d-inline-block">
|
||||
${more-btn data-bs-toggle="dropdown" aria-expanded="false" class="btn btn-sm btn-outline-secondary border-0"}
|
||||
<ul class="dropdown-menu" aria-labelledby="${id:more-btn}">
|
||||
<li>${play class="dropdown-item"}</li>
|
||||
<li>${play-last class="dropdown-item"}</li>
|
||||
<li>${star class="dropdown-item"}</li>
|
||||
<li>${download class="dropdown-item"}</li>
|
||||
@@ -64,10 +80,6 @@
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Tracks.template.entry-artist">
|
||||
${artist class="text-decoration-none link-secondary"}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Tracks.template.track-info">
|
||||
<div class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-scrollable">
|
||||
|
||||
+26
-1
@@ -1,5 +1,9 @@
|
||||
/* Generic rules */
|
||||
|
||||
:root {
|
||||
--lms-striped-bg: #022f3a;
|
||||
}
|
||||
|
||||
.link-success {
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
@@ -16,6 +20,19 @@
|
||||
background-color: var(--bs-dark);
|
||||
}
|
||||
|
||||
.Lms-row-container {
|
||||
--lms-striped-bg: #022f3a;
|
||||
--lms-hover-bg: var(--bs-dark);
|
||||
}
|
||||
|
||||
.Lms-row-container > :nth-child(odd) {
|
||||
background-color: var(--lms-striped-bg);
|
||||
}
|
||||
|
||||
.Lms-row-container > *:hover {
|
||||
background-color: var(--lms-hover-bg);
|
||||
}
|
||||
|
||||
/* Specific rules */
|
||||
body {
|
||||
padding-bottom: 78px;
|
||||
@@ -32,7 +49,7 @@ body {
|
||||
}
|
||||
|
||||
.Lms-entry-playing {
|
||||
background-color: var(--bs-dark);
|
||||
background-color: #0d4655!important;
|
||||
}
|
||||
|
||||
.Lms-cover {
|
||||
@@ -144,3 +161,11 @@ body {
|
||||
display: block;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
|
||||
.Lms-tracks-entry-position{
|
||||
min-width: 2.1rem;
|
||||
}
|
||||
|
||||
.Lms-tracks-entry-duration {
|
||||
min-width: 4rem;
|
||||
}
|
||||
|
||||
@@ -271,10 +271,10 @@ LMS.mediaplayer = function () {
|
||||
|
||||
_elems.audio.addEventListener("canplay", function() {
|
||||
if (_getAudioMode() == Mode.Transcode) {
|
||||
_elems.transcodingActive.style.visibility = "visible";
|
||||
_elems.transcodingActive.style.display = "inline";
|
||||
}
|
||||
else {
|
||||
_elems.transcodingActive.style.visibility = "hidden";
|
||||
_elems.transcodingActive.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -248,7 +248,6 @@ getMedium(const TagMap& tags)
|
||||
if (strings.size() == 2)
|
||||
medium->trackCount = StringUtils::readAs<std::size_t>(strings[1]);
|
||||
}
|
||||
|
||||
}
|
||||
// Expecting 'Number[/Total]'
|
||||
medium->position = getPropertyValueAs<std::size_t>(tags, "DISCNUMBER");
|
||||
|
||||
@@ -401,9 +401,8 @@ Track::getArtists(EnumSet<TrackArtistLinkType> linkTypes) const
|
||||
oss << " AND t_a_l.type IN (";
|
||||
|
||||
bool first {true};
|
||||
for (TrackArtistLinkType type : linkTypes)
|
||||
for ([[maybe_unused]] TrackArtistLinkType type : linkTypes)
|
||||
{
|
||||
(void) type;
|
||||
if (!first)
|
||||
oss << ", ";
|
||||
oss << "?";
|
||||
@@ -430,7 +429,7 @@ Track::getArtistIds(EnumSet<TrackArtistLinkType> linkTypes) const
|
||||
|
||||
std::ostringstream oss;
|
||||
oss <<
|
||||
"SELECT a.id from artist a"
|
||||
"SELECT DISTINCT a.id from artist a"
|
||||
" INNER JOIN track_artist_link t_a_l ON a.id = t_a_l.artist_id"
|
||||
" INNER JOIN track t ON t.id = t_a_l.track_id";
|
||||
|
||||
@@ -439,9 +438,8 @@ Track::getArtistIds(EnumSet<TrackArtistLinkType> linkTypes) const
|
||||
oss << " AND t_a_l.type IN (";
|
||||
|
||||
bool first {true};
|
||||
for (TrackArtistLinkType type : linkTypes)
|
||||
for ([[maybe_unused]] TrackArtistLinkType type : linkTypes)
|
||||
{
|
||||
(void) type;
|
||||
if (!first)
|
||||
oss << ", ";
|
||||
oss << "?";
|
||||
@@ -450,14 +448,14 @@ Track::getArtistIds(EnumSet<TrackArtistLinkType> linkTypes) const
|
||||
oss << ")";
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<ArtistId> query {session()->query<ArtistId>(oss.str())
|
||||
.where("t.id = ?").bind(getId())};
|
||||
|
||||
auto query {session()->query<ArtistId>(oss.str())};
|
||||
for (TrackArtistLinkType type : linkTypes)
|
||||
query.bind(type);
|
||||
|
||||
Wt::Dbo::collection<ArtistId> res = query;
|
||||
return std::vector<ArtistId>(std::begin(res), std::end(res));
|
||||
query.where("t.id = ?").bind(getId());
|
||||
|
||||
auto res {query.resultList()};
|
||||
return std::vector<ArtistId>(std::cbegin(res), std::cend(res));
|
||||
}
|
||||
|
||||
std::vector<TrackArtistLink::pointer>
|
||||
|
||||
@@ -91,6 +91,18 @@ TEST_F(DatabaseFixture, Artist_singleTrack)
|
||||
EXPECT_EQ(track->getArtists({}).size(), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
|
||||
auto artists {track->getArtistIds({TrackArtistLinkType::Artist})};
|
||||
ASSERT_EQ(artists.size(), 1);
|
||||
EXPECT_EQ(artists.front(), artist.getId());
|
||||
|
||||
ASSERT_EQ(track->getArtistIds({TrackArtistLinkType::Artist}).size(), 1);
|
||||
EXPECT_TRUE(track->getArtistIds({TrackArtistLinkType::ReleaseArtist}).empty());
|
||||
EXPECT_EQ(track->getArtistIds({}).size(), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackName").setArtistName("MyArtist"))};
|
||||
|
||||
@@ -210,6 +210,7 @@ MediaPlayer::MediaPlayer()
|
||||
_title = bindNew<Wt::WText>("title");
|
||||
_artist = bindNew<Wt::WAnchor>("artist");
|
||||
_release = bindNew<Wt::WAnchor>("release");
|
||||
_separator = bindNew<Wt::WText>("separator");
|
||||
_playQueue = bindNew<Wt::WPushButton>("playqueue-btn", Wt::WString::tr("Lms.MediaPlayer.template.playqueue-btn").arg(0), Wt::TextFormat::XHTML);
|
||||
_playQueue->setLink(Wt::WLink {Wt::LinkType::InternalPath, "/playqueue"});
|
||||
_playQueue->setToolTip(tr("Lms.PlayQueue.playqueue"));
|
||||
@@ -275,6 +276,8 @@ MediaPlayer::loadTrack(Database::TrackId trackId, bool play, float replayGain)
|
||||
_title->setTextFormat(Wt::TextFormat::Plain);
|
||||
_title->setText(Wt::WString::fromUTF8(track->getName()));
|
||||
|
||||
bool needSeparator {true};
|
||||
|
||||
if (!artists.empty())
|
||||
{
|
||||
_artist->setTextFormat(Wt::TextFormat::Plain);
|
||||
@@ -285,6 +288,7 @@ MediaPlayer::loadTrack(Database::TrackId trackId, bool play, float replayGain)
|
||||
{
|
||||
_artist->setText("");
|
||||
_artist->setLink({});
|
||||
needSeparator = false;
|
||||
}
|
||||
|
||||
if (track->getRelease())
|
||||
@@ -297,7 +301,13 @@ MediaPlayer::loadTrack(Database::TrackId trackId, bool play, float replayGain)
|
||||
{
|
||||
_release->setText("");
|
||||
_release->setLink({});
|
||||
needSeparator = false;
|
||||
}
|
||||
|
||||
if (needSeparator)
|
||||
_separator->setText(" — ");
|
||||
else
|
||||
_separator->setText("");
|
||||
}
|
||||
|
||||
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
||||
|
||||
@@ -127,6 +127,7 @@ class MediaPlayer : public Wt::WTemplate
|
||||
|
||||
Wt::WText* _title {};
|
||||
Wt::WAnchor* _release {};
|
||||
Wt::WText* _separator {};
|
||||
Wt::WAnchor* _artist {};
|
||||
Wt::WPushButton* _playQueue {};
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <Wt/WStackedWidget.h>
|
||||
#include <Wt/WTemplateFormView.h>
|
||||
|
||||
#include "services/database/Artist.hpp"
|
||||
#include "services/database/Release.hpp"
|
||||
#include "services/database/Session.hpp"
|
||||
#include "services/database/Track.hpp"
|
||||
@@ -136,7 +137,7 @@ PlayQueue::PlayQueue()
|
||||
saveAsTrackList();
|
||||
});
|
||||
|
||||
_entriesContainer = bindNew<InfiniteScrollingContainer>("entries");
|
||||
_entriesContainer = bindNew<InfiniteScrollingContainer>("entries", Wt::WString::tr("Lms.PlayQueue.template.entry-container"));
|
||||
_entriesContainer->onRequestElements.connect([this]
|
||||
{
|
||||
addSome();
|
||||
@@ -489,6 +490,15 @@ PlayQueue::addEntry(const Database::TrackListEntry::pointer& tracklistEntry)
|
||||
|
||||
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::TextFormat::Plain);
|
||||
|
||||
const auto artists {track->getArtistIds({Database::TrackArtistLinkType::Artist})};
|
||||
LMS_LOG(UI, DEBUG) << "Found " << artists.size() << " artists!";
|
||||
if (!artists.empty())
|
||||
{
|
||||
entry->setCondition("if-has-artists", true);
|
||||
entry->bindWidget("artists", Utils::createArtistContainer(artists));
|
||||
entry->bindWidget("artists-md", Utils::createArtistContainer(artists));
|
||||
}
|
||||
|
||||
const auto release {track->getRelease()};
|
||||
if (release)
|
||||
{
|
||||
@@ -542,6 +552,13 @@ PlayQueue::addEntry(const Database::TrackListEntry::pointer& tracklistEntry)
|
||||
});
|
||||
|
||||
entry->bindNew<Wt::WPushButton>("more-btn", Wt::WString::tr("Lms.template.more-btn"), Wt::TextFormat::XHTML);
|
||||
entry->bindNew<Wt::WPushButton>("play", Wt::WString::tr("Lms.Explore.play"))
|
||||
->clicked().connect([=]
|
||||
{
|
||||
const std::optional<std::size_t> pos {_entriesContainer->getIndexOf(*entry)};
|
||||
if (pos)
|
||||
loadTrack(*pos, true);
|
||||
});
|
||||
|
||||
auto isStarred {[=] { return Service<Scrobbling::IScrobblingService>::get()->isStarred(LmsApp->getUserId(), trackId); }};
|
||||
|
||||
|
||||
@@ -377,22 +377,12 @@ Release::refreshView()
|
||||
|
||||
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::TextFormat::Plain);
|
||||
|
||||
const auto artists {track->getArtists({TrackArtistLinkType::Artist})};
|
||||
const auto artists {track->getArtistIds({TrackArtistLinkType::Artist})};
|
||||
if (variousArtists && !artists.empty())
|
||||
{
|
||||
entry->setCondition("if-has-artists", true);
|
||||
|
||||
Wt::WContainerWidget* artistsContainer {entry->bindNew<Wt::WContainerWidget>("artists")};
|
||||
bool firstArtist {true};
|
||||
for (const auto& artist : artists)
|
||||
{
|
||||
if (!firstArtist)
|
||||
artistsContainer->addNew<Wt::WText>(" · ");
|
||||
auto anchor {Utils::createArtistAnchor(artist)};
|
||||
anchor->addStyleClass("link-success text-decoration-none"); // hack
|
||||
artistsContainer->addWidget(std::move(anchor));
|
||||
firstArtist = false;
|
||||
}
|
||||
entry->bindWidget("artists", Utils::createArtistContainer(artists));
|
||||
entry->bindWidget("artists-md", Utils::createArtistContainer(artists));
|
||||
}
|
||||
|
||||
auto trackNumber {track->getTrackNumber()};
|
||||
@@ -410,6 +400,11 @@ Release::refreshView()
|
||||
|
||||
{
|
||||
entry->bindNew<Wt::WPushButton>("more-btn", Wt::WString::tr("Lms.template.more-btn"), Wt::TextFormat::XHTML);
|
||||
entry->bindNew<Wt::WPushButton>("play", Wt::WString::tr("Lms.Explore.play"))
|
||||
->clicked().connect([=]
|
||||
{
|
||||
_playQueueController.playTrackInRelease(trackId);
|
||||
});
|
||||
entry->bindNew<Wt::WPushButton>("play-last", Wt::WString::tr("Lms.Explore.play-last"))
|
||||
->clicked().connect([=]
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "services/database/Track.hpp"
|
||||
#include "services/database/TrackArtistLink.hpp"
|
||||
#include "services/scrobbling/IScrobblingService.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
|
||||
#include "common/Template.hpp"
|
||||
@@ -160,6 +161,15 @@ namespace UserInterface::TrackListHelpers
|
||||
const Release::pointer release {track->getRelease()};
|
||||
const TrackId trackId {track->getId()};
|
||||
|
||||
const auto artists {track->getArtistIds({TrackArtistLinkType::Artist})};
|
||||
LMS_LOG(UI, DEBUG) << "Found " << artists.size() << " artists!";
|
||||
if (!artists.empty())
|
||||
{
|
||||
entry->setCondition("if-has-artists", true);
|
||||
entry->bindWidget("artists", Utils::createArtistContainer(artists));
|
||||
entry->bindWidget("artists-md", Utils::createArtistContainer(artists));
|
||||
}
|
||||
|
||||
if (track->getRelease())
|
||||
{
|
||||
entry->setCondition("if-has-release", true);
|
||||
@@ -185,6 +195,11 @@ namespace UserInterface::TrackListHelpers
|
||||
});
|
||||
|
||||
entry->bindNew<Wt::WPushButton>("more-btn", Wt::WString::tr("Lms.template.more-btn"), Wt::TextFormat::XHTML);
|
||||
entry->bindNew<Wt::WPushButton>("play", Wt::WString::tr("Lms.Explore.play"))
|
||||
->clicked().connect([trackId, &playQueueController]
|
||||
{
|
||||
playQueueController.processCommand(PlayQueueController::Command::Play, {trackId});
|
||||
});
|
||||
entry->bindNew<Wt::WPushButton>("play-last", Wt::WString::tr("Lms.Explore.play-last"))
|
||||
->clicked().connect([=, &playQueueController]
|
||||
{
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace UserInterface
|
||||
LmsApp->getModalManager().show(std::move(modal));
|
||||
});
|
||||
|
||||
_container = bindNew<InfiniteScrollingContainer>("tracks");
|
||||
_container = bindNew<InfiniteScrollingContainer>("tracks", Wt::WString::tr("Lms.Explore.TrackList.template.entry-container"));
|
||||
_container->onRequestElements.connect([this]
|
||||
{
|
||||
addSome();
|
||||
|
||||
@@ -86,7 +86,7 @@ Tracks::Tracks(Filters& filters, PlayQueueController& playQueueController)
|
||||
_playQueueController.processCommand(PlayQueueController::Command::PlayOrAddLast, getAllTracks());
|
||||
});
|
||||
|
||||
_container = bindNew<InfiniteScrollingContainer>("tracks");
|
||||
_container = bindNew<InfiniteScrollingContainer>("tracks", Wt::WString::tr("Lms.Explore.Tracks.template.entry-container"));
|
||||
_container->onRequestElements.connect([this]
|
||||
{
|
||||
addSome();
|
||||
|
||||
Reference in New Issue
Block a user