Added Play/Queue buttons in the releases view

This commit is contained in:
emeric
2019-08-06 13:55:43 +02:00
parent cf46f1a7c2
commit f8cb16954b
12 changed files with 135 additions and 122 deletions
+1
View File
@@ -5,6 +5,7 @@
<message id="Lms.Explore.Releases.template">
<div class="page-header">
<h2>${tr:Lms.Explore.releases}</h2>
${play-btn}${add-btn}
</div>
<div class="form-group">
<div class="input-group">
+8 -8
View File
@@ -102,19 +102,19 @@ Artist::refresh()
{
Wt::WText* playBtn = t->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
playBtn->clicked().connect([=]
{
artistPlay.emit(*artistId);
}));
artistsPlay.emit({*artistId});
});
}
{
Wt::WText* addBtn = t->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
addBtn->clicked().connect([=]
{
artistAdd.emit(*artistId);
}));
artistsAdd.emit({*artistId});
});
}
Wt::WContainerWidget* releasesContainer = t->bindNew<Wt::WContainerWidget>("releases");
@@ -179,13 +179,13 @@ Artist::refresh()
Wt::WText* playBtn = entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
{
releasePlay.emit(releaseId);
releasesPlay.emit({releaseId});
}));
Wt::WText* addBtn = entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
{
releaseAdd.emit(releaseId);
releasesAdd.emit({releaseId});
}));
}
}
+4 -4
View File
@@ -33,11 +33,11 @@ class Artist : public Wt::WContainerWidget
public:
Artist(Filters* filters);
Wt::Signal<Database::IdType> artistAdd;
Wt::Signal<Database::IdType> artistPlay;
Wt::Signal<const std::vector<Database::IdType>&> artistsAdd;
Wt::Signal<const std::vector<Database::IdType>&> artistsPlay;
Wt::Signal<Database::IdType> releaseAdd;
Wt::Signal<Database::IdType> releasePlay;
Wt::Signal<const std::vector<Database::IdType>&> releasesAdd;
Wt::Signal<const std::vector<Database::IdType>&> releasesPlay;
private:
void refresh();
+2 -2
View File
@@ -36,8 +36,8 @@ class Artists : public Wt::WTemplate
public:
Artists(Filters* filters);
Wt::Signal<Database::IdType> artistAdd;
Wt::Signal<Database::IdType> artistPlay;
Wt::Signal<const std::vector<Database::IdType>&> artistsAdd;
Wt::Signal<const std::vector<Database::IdType>&> artistsPlay;
private:
void refresh();
+50 -69
View File
@@ -121,32 +121,30 @@ Explore::Explore()
Wt::WStackedWidget* contentsStack = bindNew<Wt::WStackedWidget>("contents");
auto artists = std::make_unique<Artists>(_filters);
artists->artistAdd.connect(this, &Explore::handleArtistAdd);
artists->artistPlay.connect(this, &Explore::handleArtistPlay);
artists->artistsAdd.connect(this, &Explore::handleArtistsAdd);
artists->artistsPlay.connect(this, &Explore::handleArtistsPlay);
contentsStack->addWidget(std::move(artists));
auto artist = std::make_unique<Artist>(_filters);
artist->artistAdd.connect(this, &Explore::handleArtistAdd);
artist->artistPlay.connect(this, &Explore::handleArtistPlay);
artist->releaseAdd.connect(this, &Explore::handleReleaseAdd);
artist->releasePlay.connect(this, &Explore::handleReleasePlay);
artist->artistsAdd.connect(this, &Explore::handleArtistsAdd);
artist->artistsPlay.connect(this, &Explore::handleArtistsPlay);
artist->releasesAdd.connect(this, &Explore::handleReleasesAdd);
artist->releasesPlay.connect(this, &Explore::handleReleasesPlay);
contentsStack->addWidget(std::move(artist));
auto releases = std::make_unique<Releases>(_filters);
releases->releaseAdd.connect(this, &Explore::handleReleaseAdd);
releases->releasePlay.connect(this, &Explore::handleReleasePlay);
releases->releasesAdd.connect(this, &Explore::handleReleasesAdd);
releases->releasesPlay.connect(this, &Explore::handleReleasesPlay);
contentsStack->addWidget(std::move(releases));
auto release = std::make_unique<Release>(_filters);
release->releaseAdd.connect(this, &Explore::handleReleaseAdd);
release->releasePlay.connect(this, &Explore::handleReleasePlay);
release->trackAdd.connect(this, &Explore::handleTrackAdd);
release->trackPlay.connect(this, &Explore::handleTrackPlay);
release->releasesAdd.connect(this, &Explore::handleReleasesAdd);
release->releasesPlay.connect(this, &Explore::handleReleasesPlay);
release->tracksAdd.connect(this, &Explore::handleTracksAdd);
release->tracksPlay.connect(this, &Explore::handleTracksPlay);
contentsStack->addWidget(std::move(release));
auto tracks = std::make_unique<Tracks>(_filters);
tracks->trackAdd.connect(this, &Explore::handleTrackAdd);
tracks->trackPlay.connect(this, &Explore::handleTrackPlay);
tracks->tracksAdd.connect(this, &Explore::handleTracksAdd);
tracks->tracksPlay.connect(this, &Explore::handleTracksPlay);
contentsStack->addWidget(std::move(tracks));
@@ -181,102 +179,85 @@ Explore::Explore()
static
std::vector<Database::IdType>
getArtistTracks(Database::Session& session, Database::IdType artistId, const std::set<Database::IdType>& clusters)
getArtistsTracks(Database::Session& session, const std::vector<Database::IdType>& artistsId, const std::set<Database::IdType>& clusters)
{
std::vector<Database::IdType> res;
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Database::Artist::pointer artist {Database::Artist::getById(session, artistId)};
if (!artist)
return {};
for (Database::IdType artistId : artistsId)
{
Database::Artist::pointer artist {Database::Artist::getById(session, artistId)};
if (!artist)
continue;
// TODO handle clusters here
const std::vector<Database::Track::pointer> tracks {artist->getTracks()};
// TODO handle clusters here
const std::vector<Database::Track::pointer> tracks {artist->getTracks()};
std::vector<Database::IdType> res;
res.reserve(tracks.size());
res.reserve(res.size() + tracks.size());
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
}
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
return res;
}
static
std::vector<Database::IdType>
getReleaseTracks(Database::Session& session, Database::IdType releaseId, std::set<Database::IdType> clusters)
getReleasesTracks(Database::Session& session, const std::vector<Database::IdType>& releasesId, const std::set<Database::IdType>& clusters)
{
std::vector<Database::IdType> res;
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Database::Release::pointer release {Database::Release::getById(session, releaseId)};
if (!release)
return {};
for (Database::IdType releaseId : releasesId)
{
Database::Release::pointer release {Database::Release::getById(session, releaseId)};
if (!release)
continue;
const std::vector<Database::Track::pointer> tracks {release->getTracks(clusters)};
const std::vector<Database::Track::pointer> tracks {release->getTracks(clusters)};
std::vector<Database::IdType> res;
res.reserve(tracks.size());
res.reserve(res.size() + tracks.size());
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
}
std::transform(std::cbegin(tracks), std::cend(tracks), std::back_inserter(res), [](const Database::Track::pointer& track) { return track.id(); });
return res;
}
static
std::vector<Database::IdType>
getTrack(Database::Session& session, Database::IdType trackId)
void
Explore::handleArtistsAdd(const std::vector<Database::IdType>& artistsId)
{
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
Database::Track::pointer track {Database::Track::getById(session, trackId)};
if (!track)
return {};
return {track.id()};
tracksAdd.emit(getArtistsTracks(LmsApp->getDbSession(), artistsId, _filters->getClusterIds()));
}
void
Explore::handleArtistAdd(Database::IdType id)
Explore::handleArtistsPlay(const std::vector<Database::IdType>& artistsId)
{
tracksAdd.emit(getArtistTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
tracksPlay.emit(getArtistsTracks(LmsApp->getDbSession(), artistsId, _filters->getClusterIds()));
}
void
Explore::handleArtistPlay(Database::IdType id)
Explore::handleReleasesAdd(const std::vector<Database::IdType>& releasesId)
{
tracksPlay.emit(getArtistTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
tracksAdd.emit(getReleasesTracks(LmsApp->getDbSession(), releasesId, _filters->getClusterIds()));
}
void
Explore::handleReleaseAdd(Database::IdType id)
Explore::handleReleasesPlay(const std::vector<Database::IdType>& releasesId)
{
tracksAdd.emit(getReleaseTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
tracksPlay.emit(getReleasesTracks(LmsApp->getDbSession(), releasesId, _filters->getClusterIds()));
}
void
Explore::handleReleasePlay(Database::IdType id)
Explore::handleTracksAdd(const std::vector<Database::IdType>& tracksId)
{
tracksPlay.emit(getReleaseTracks(LmsApp->getDbSession(), id, _filters->getClusterIds()));
tracksAdd.emit(tracksId);
}
void
Explore::handleTrackAdd(Database::IdType id)
Explore::handleTracksPlay(const std::vector<Database::IdType>& tracksId)
{
tracksAdd.emit(getTrack(LmsApp->getDbSession(), id));
}
void
Explore::handleTrackPlay(Database::IdType id)
{
tracksPlay.emit(getTrack(LmsApp->getDbSession(), id));
}
void
Explore::handleTracksAdd(const std::vector<Database::IdType>& trackIds)
{
tracksAdd.emit(trackIds);
}
void
Explore::handleTracksPlay(const std::vector<Database::IdType>& trackIds)
{
tracksPlay.emit(trackIds);
tracksPlay.emit(tracksId);
}
} // namespace UserInterface
+6 -8
View File
@@ -37,14 +37,12 @@ class Explore : public Wt::WTemplate
private:
void handleArtistAdd(Database::IdType artistId);
void handleArtistPlay(Database::IdType artistId);
void handleReleaseAdd(Database::IdType releaseId);
void handleReleasePlay(Database::IdType releaseId);
void handleTrackAdd(Database::IdType trackId);
void handleTrackPlay(Database::IdType trackId);
void handleTracksAdd(const std::vector<Database::IdType>& trackIds);
void handleTracksPlay(const std::vector<Database::IdType>& trackIds);
void handleArtistsAdd(const std::vector<Database::IdType>& artistsId);
void handleArtistsPlay(const std::vector<Database::IdType>& artistsId);
void handleReleasesAdd(const std::vector<Database::IdType>& releasesId);
void handleReleasesPlay(const std::vector<Database::IdType>& releasesId);
void handleTracksAdd(const std::vector<Database::IdType>& tracksId);
void handleTracksPlay(const std::vector<Database::IdType>& tracksId);
Filters* _filters;
};
+4 -4
View File
@@ -139,7 +139,7 @@ Release::refresh()
Wt::WText* playBtn {t->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML)};
playBtn->clicked().connect([=]
{
releasePlay.emit(*releaseId);
releasesPlay.emit({*releaseId});
});
}
@@ -147,7 +147,7 @@ Release::refresh()
Wt::WText* addBtn {t->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML)};
addBtn->clicked().connect([=]
{
releaseAdd.emit(*releaseId);
releasesAdd.emit({*releaseId});
});
}
@@ -196,13 +196,13 @@ Release::refresh()
Wt::WText* playBtn {entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML)};
playBtn->clicked().connect(std::bind([=]
{
trackPlay.emit(trackId);
tracksPlay.emit({trackId});
}));
Wt::WText* addBtn {entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML)};
addBtn->clicked().connect(std::bind([=]
{
trackAdd.emit(trackId);
tracksAdd.emit({trackId});
}));
LmsApp->getEvents().trackLoaded.connect(entry, [=] (Database::IdType loadedTrackId, bool /*play*/)
+4 -4
View File
@@ -32,11 +32,11 @@ class Release : public Wt::WContainerWidget
public:
Release(Filters* filters);
Wt::Signal<Database::IdType> releaseAdd;
Wt::Signal<Database::IdType> releasePlay;
Wt::Signal<const std::vector<Database::IdType>&> releasesAdd;
Wt::Signal<const std::vector<Database::IdType>&> releasesPlay;
Wt::Signal<Database::IdType> trackAdd;
Wt::Signal<Database::IdType> trackPlay;
Wt::Signal<const std::vector<Database::IdType>&> tracksAdd;
Wt::Signal<const std::vector<Database::IdType>&> tracksPlay;
private:
void refresh();
+43 -12
View File
@@ -48,10 +48,21 @@ _filters(filters)
_search->setPlaceholderText(Wt::WString::tr("Lms.Explore.search-placeholder"));
_search->textInput().connect(this, &Releases::refresh);
Wt::WText* playBtn {bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML)};
playBtn->clicked().connect([this]
{
releasesPlay.emit(getReleases());
});
Wt::WText* addBtn {bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML)};
addBtn->clicked().connect([this]
{
releasesAdd.emit(getReleases());
});
_container = bindNew<Wt::WContainerWidget>("releases");
_showMore = bindNew<Wt::WPushButton>("show-more", Wt::WString::tr("Lms.Explore.show-more"));
_showMore->clicked().connect([=]
_showMore->clicked().connect([this]
{
addSome();
});
@@ -71,17 +82,14 @@ Releases::refresh()
void
Releases::addSome()
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
const auto clusterIds {_filters->getClusterIds()};
bool moreResults {};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
bool moreResults;
const auto releases {Release::getByFilter(LmsApp->getDbSession(), clusterIds, searchKeywords, _container->count(), 20, moreResults)};
for (const Database::Release::pointer& release : releases)
const auto releasesId {getReleases(_container->count(), 20, moreResults)};
for (const Database::IdType releaseId : releasesId )
{
const Database::IdType releaseId {release.id()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::Release::pointer release {Database::Release::getById(LmsApp->getDbSession(), releaseId)};
Wt::WTemplate* entry = _container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Releases.template.entry"));
entry->addFunction("tr", Wt::WTemplate::Functions::tr);
@@ -113,18 +121,41 @@ Releases::addSome()
Wt::WText* playBtn = entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect([=]
{
releasePlay.emit(releaseId);
releasesPlay.emit({releaseId});
});
Wt::WText* addBtn = entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect([=]
{
releaseAdd.emit(releaseId);
releasesAdd.emit({releaseId});
});
}
_showMore->setHidden(!moreResults);
}
std::vector<Database::IdType>
Releases::getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const auto releases {Release::getByFilter(LmsApp->getDbSession(), _filters->getClusterIds(), searchKeywords, offset, limit, moreResults)};
std::vector<Database::IdType> res;
for (const Database::Release::pointer& release : releases)
res.push_back(release.id());
return res;
}
std::vector<Database::IdType>
Releases::getReleases() const
{
bool moreResults;
return getReleases({}, {}, moreResults);
}
} // namespace UserInterface
+7 -2
View File
@@ -19,6 +19,8 @@
#pragma once
#include <boost/optional.hpp>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
@@ -35,13 +37,16 @@ class Releases : public Wt::WTemplate
public:
Releases(Filters* filters);
Wt::Signal<Database::IdType> releaseAdd;
Wt::Signal<Database::IdType> releasePlay;
Wt::Signal<const std::vector<Database::IdType>&> releasesAdd;
Wt::Signal<const std::vector<Database::IdType>&> releasesPlay;
private:
void refresh();
void addSome();
std::vector<Database::IdType> getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const;
std::vector<Database::IdType> getReleases() const;
Filters* _filters;
Wt::WPushButton* _showMore;
Wt::WLineEdit* _search;
+4 -4
View File
@@ -50,10 +50,10 @@ _filters(filters)
_search->textInput().connect(this, &Tracks::refresh);
Wt::WText* playBtn = bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
playBtn->clicked().connect([=]
{
tracksPlay.emit(getTracks());
}));
});
Wt::WText* addBtn = bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
@@ -148,13 +148,13 @@ Tracks::addSome()
Wt::WText* playBtn = entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
{
trackPlay.emit(trackId);
tracksPlay.emit({trackId});
}));
Wt::WText* addBtn = entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
{
trackAdd.emit(trackId);
tracksAdd.emit({trackId});
}));
}
+2 -5
View File
@@ -36,11 +36,8 @@ class Tracks : public Wt::WTemplate
public:
Tracks(Filters* filters);
Wt::Signal<Database::IdType> trackAdd;
Wt::Signal<Database::IdType> trackPlay;
Wt::Signal<std::vector<Database::IdType>> tracksAdd;
Wt::Signal<std::vector<Database::IdType>> tracksPlay;
Wt::Signal<const std::vector<Database::IdType>&> tracksAdd;
Wt::Signal<const std::vector<Database::IdType>&> tracksPlay;
private:
void refresh();