Continued playlist handling
This commit is contained in:
+13
-4
@@ -22,6 +22,14 @@
|
||||
${entries}
|
||||
</message>
|
||||
|
||||
<message id="btn-playlist-entry-play-btn">
|
||||
<i class="fa fa-play"></i>
|
||||
</message>
|
||||
|
||||
<message id="btn-playlist-entry-del-btn">
|
||||
<i class="fa fa-remove"></i>
|
||||
</message>
|
||||
|
||||
<message id="template-playlist-entry">
|
||||
<div class="media">
|
||||
<div class="pull-left media-middle">
|
||||
@@ -30,11 +38,12 @@
|
||||
<div class="media-body">
|
||||
<h4 class="media-heading">${name}</h4>
|
||||
</div>
|
||||
</div>
|
||||
${<if-has-release>}${release-name}${</if-has-release>}
|
||||
${<if-has-artist>}${artist-name}${</if-has-artist>}
|
||||
|
||||
${play-btn} ${remove-btn}
|
||||
${<if-has-release>}${release-name}${</if-has-release>}
|
||||
${<if-has-artist>}${artist-name}${</if-has-artist>}
|
||||
|
||||
${play-btn} ${del-btn}
|
||||
</div>
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
|
||||
@@ -61,6 +61,12 @@ Playlist::getAll(Wt::Dbo::Session& session, Wt::Dbo::ptr<User> user)
|
||||
return std::vector<Playlist::pointer>(res.begin(), res.end());
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::addTrack(Wt::Dbo::ptr<Track> track)
|
||||
{
|
||||
_entries.insert( PlaylistEntry::create(*session(), track, self(), _entries.size()) );
|
||||
}
|
||||
|
||||
PlaylistEntry::PlaylistEntry(Wt::Dbo::ptr<Track> track, Wt::Dbo::ptr<Playlist> playlist, int pos)
|
||||
: _pos(pos),
|
||||
_track(track),
|
||||
@@ -74,19 +80,23 @@ PlaylistEntry::create(Wt::Dbo::Session& session, Wt::Dbo::ptr<Track> track, Wt::
|
||||
{
|
||||
return session.add( new PlaylistEntry( track, playlist, pos) );
|
||||
}
|
||||
/*
|
||||
std::vector<Track::id_type>
|
||||
PlaylistEntry::getEntries(Wt::Dbo::Session& session, Playlist::pointer playlist)
|
||||
|
||||
|
||||
std::vector<Wt::Dbo::ptr<Track>>
|
||||
Playlist::getTracks(int offset, int size) const
|
||||
{
|
||||
typedef Wt::Dbo::collection<pointer> Entries;
|
||||
assert(session());
|
||||
|
||||
Entries entries = session.find<PlaylistEntry>().where("playlist_id = ?").bind(playlist.id()).orderBy("pos");
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<PlaylistEntry>> entries = session()->find<PlaylistEntry>().where("playlist_id = ?").bind(self().id()).orderBy("pos").offset(offset).limit(size);
|
||||
|
||||
std::vector<Track::id_type> res;
|
||||
for (Entries::iterator it = entries.begin(); it != entries.end(); ++it)
|
||||
res.push_back((*it)->getTrack().id());
|
||||
std::vector<Wt::Dbo::ptr<Track>> res;
|
||||
|
||||
for (auto entry : entries)
|
||||
{
|
||||
res.push_back(entry->getTrack());
|
||||
}
|
||||
|
||||
return res;
|
||||
}*/
|
||||
}
|
||||
|
||||
} // namespace Database
|
||||
|
||||
@@ -30,7 +30,7 @@ class PlaylistEntry;
|
||||
class User;
|
||||
class Track;
|
||||
|
||||
class Playlist
|
||||
class Playlist : public Wt::Dbo::Dbo<Playlist>
|
||||
{
|
||||
public:
|
||||
typedef Wt::Dbo::ptr<Playlist> pointer;
|
||||
@@ -50,12 +50,11 @@ class Playlist
|
||||
bool isPublic() const { return _isPublic; }
|
||||
|
||||
// Modifiers
|
||||
void addTrack(id_type trackId);
|
||||
void addTracks(const std::vector<id_type>& trackIds);
|
||||
void clear();
|
||||
void addTrack(Wt::Dbo::ptr<Track> track);
|
||||
void clear() { _entries.clear(); }
|
||||
|
||||
// Get tracks, ordered by position
|
||||
std::vector<Track::id_type> getEntries(Wt::Dbo::Session& session, int offset = -1, int size = -1);
|
||||
std::vector<Wt::Dbo::ptr<Track>> getTracks(int offset = -1, int size = -1) const;
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
@@ -82,7 +81,7 @@ class PlaylistEntry
|
||||
typedef Wt::Dbo::ptr<PlaylistEntry> pointer;
|
||||
|
||||
PlaylistEntry();
|
||||
PlaylistEntry(Wt::Dbo::ptr<Track> rack, Wt::Dbo::ptr<Playlist> playlist, int position);
|
||||
PlaylistEntry(Wt::Dbo::ptr<Track> track, Wt::Dbo::ptr<Playlist> playlist, int position);
|
||||
|
||||
// Create utility
|
||||
static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr<Track> track, Wt::Dbo::ptr<Playlist> playlist, int position);
|
||||
|
||||
@@ -84,7 +84,7 @@ User::getAll(Wt::Dbo::Session& session)
|
||||
}
|
||||
|
||||
User::pointer
|
||||
User::getById(Wt::Dbo::Session& session, std::string id)
|
||||
User::getById(Wt::Dbo::Session& session, id_type id)
|
||||
{
|
||||
return session.find<User>().where("id = ?").bind( id );
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ class User
|
||||
typedef Wt::Dbo::ptr<User> pointer;
|
||||
|
||||
// accessors
|
||||
static pointer getById(Wt::Dbo::Session& session, std::string id);
|
||||
static pointer getById(Wt::Dbo::Session& session, id_type id);
|
||||
static std::vector<pointer> getAll(Wt::Dbo::Session& session);
|
||||
static std::string getId(pointer user);
|
||||
|
||||
|
||||
+8
-12
@@ -42,28 +42,24 @@ Artists::Artists(Filters* filters, Wt::WContainerWidget* parent)
|
||||
auto artists = new Wt::WTemplate(Wt::WString::tr("template-artists"), this);
|
||||
artists->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
auto search = new Wt::WLineEdit();
|
||||
artists->bindWidget("search", search);
|
||||
search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
search->textInput().connect(std::bind([this, search]
|
||||
{
|
||||
auto keywords = splitString(search->text().toUTF8(), " ");
|
||||
refresh(keywords);
|
||||
}));
|
||||
_search = new Wt::WLineEdit();
|
||||
artists->bindWidget("search", _search);
|
||||
_search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
_search->textInput().connect(this, &Artists::refresh);
|
||||
|
||||
_artistsContainer = new Wt::WContainerWidget();
|
||||
artists->bindWidget("artists", _artistsContainer);
|
||||
|
||||
refresh();
|
||||
|
||||
filters->updated().connect(std::bind([=] {
|
||||
refresh();
|
||||
}));
|
||||
filters->updated().connect(this, &Artists::refresh);
|
||||
}
|
||||
|
||||
void
|
||||
Artists::refresh(std::vector<std::string> searchKeywords)
|
||||
Artists::refresh()
|
||||
{
|
||||
auto searchKeywords = splitString(_search->text().toUTF8(), " ");
|
||||
|
||||
_artistsContainer->clear();
|
||||
|
||||
auto clusterIds = _filters->getClusterIds();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/WLineEdit>
|
||||
#include <Wt/WSignal>
|
||||
|
||||
namespace UserInterface {
|
||||
@@ -35,9 +36,10 @@ class Artists : public Wt::WContainerWidget
|
||||
Wt::Signal<Database::id_type> artistPlay;
|
||||
|
||||
private:
|
||||
void refresh(std::vector<std::string> searchKeywords = std::vector<std::string>());
|
||||
void refresh();
|
||||
|
||||
Filters* _filters;
|
||||
Wt::WLineEdit* _search;
|
||||
Wt::WContainerWidget* _artistsContainer;
|
||||
};
|
||||
|
||||
|
||||
+29
-20
@@ -126,11 +126,9 @@ Explore::Explore(Wt::WContainerWidget* parent)
|
||||
}
|
||||
|
||||
// TODO SQL this?
|
||||
static std::vector<Database::id_type> getArtistTracks(Wt::Dbo::Session& session, Database::id_type artistId, std::set<Database::id_type> clusters)
|
||||
static std::vector<Database::Track::pointer> getArtistTracks(Wt::Dbo::Session& session, Database::id_type artistId, std::set<Database::id_type> clusters)
|
||||
{
|
||||
std::vector<Database::id_type> res;
|
||||
|
||||
Wt::Dbo::Transaction transaction(session);
|
||||
std::vector<Database::Track::pointer> res;
|
||||
|
||||
auto artist = Database::Artist::getById(session, artistId);
|
||||
if (!artist)
|
||||
@@ -140,31 +138,30 @@ static std::vector<Database::id_type> getArtistTracks(Wt::Dbo::Session& session,
|
||||
for (auto release : releases)
|
||||
{
|
||||
auto tracks = release->getTracks(clusters);
|
||||
|
||||
for (auto track : tracks)
|
||||
{
|
||||
res.push_back(track.id());
|
||||
}
|
||||
res.insert( res.end(), tracks.begin(), tracks.end() );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::vector<Database::id_type> getReleaseTracks(Wt::Dbo::Session& session, Database::id_type releaseId, std::set<Database::id_type> clusters)
|
||||
static std::vector<Database::Track::pointer> getReleaseTracks(Wt::Dbo::Session& session, Database::id_type releaseId, std::set<Database::id_type> clusters)
|
||||
{
|
||||
std::vector<Database::id_type> res;
|
||||
|
||||
Wt::Dbo::Transaction transaction(session);
|
||||
std::vector<Database::Track::pointer> res;
|
||||
|
||||
auto release = Database::Release::getById(session, releaseId);
|
||||
if (!release)
|
||||
return res;
|
||||
|
||||
auto tracks = release->getTracks(clusters);
|
||||
for (auto track : tracks)
|
||||
{
|
||||
res.push_back(track.id());
|
||||
}
|
||||
return release->getTracks(clusters);
|
||||
}
|
||||
|
||||
static std::vector<Database::Track::pointer> getTrack(Wt::Dbo::Session& session, Database::id_type trackId)
|
||||
{
|
||||
std::vector<Database::Track::pointer> res;
|
||||
|
||||
auto track = Database::Track::getById(session, trackId);
|
||||
if (track)
|
||||
res.push_back(track);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -172,37 +169,49 @@ static std::vector<Database::id_type> getReleaseTracks(Wt::Dbo::Session& session
|
||||
void
|
||||
Explore::handleArtistAdd(Database::id_type id)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksAdd.emit(getArtistTracks(DboSession(), id, _filters->getClusterIds()));
|
||||
}
|
||||
|
||||
void
|
||||
Explore::handleArtistPlay(Database::id_type id)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksPlay.emit(getArtistTracks(DboSession(), id, _filters->getClusterIds()));
|
||||
}
|
||||
|
||||
void
|
||||
Explore::handleReleaseAdd(Database::id_type id)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksAdd.emit(getReleaseTracks(DboSession(), id, _filters->getClusterIds()));
|
||||
}
|
||||
|
||||
void
|
||||
Explore::handleReleasePlay(Database::id_type id)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksPlay.emit(getReleaseTracks(DboSession(), id, _filters->getClusterIds()));
|
||||
}
|
||||
|
||||
void
|
||||
Explore::handleTrackAdd(Database::id_type id)
|
||||
{
|
||||
tracksAdd.emit(std::vector<Database::id_type>(1, id));
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksAdd.emit(getTrack(DboSession(), id));
|
||||
}
|
||||
|
||||
void
|
||||
Explore::handleTrackPlay(Database::id_type id)
|
||||
{
|
||||
tracksPlay.emit(std::vector<Database::id_type>(1, id));
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
tracksPlay.emit(getTrack(DboSession(), id));
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ class Explore : public Wt::WContainerWidget
|
||||
public:
|
||||
Explore(Wt::WContainerWidget *parent = 0);
|
||||
|
||||
Wt::Signal<std::vector<Database::id_type>> tracksAdd;
|
||||
Wt::Signal<std::vector<Database::id_type>> tracksPlay;
|
||||
Wt::Signal<std::vector<Database::Track::pointer>> tracksAdd;
|
||||
Wt::Signal<std::vector<Database::Track::pointer>> tracksPlay;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -123,7 +123,8 @@ const Wt::Auth::User& CurrentAuthUser()
|
||||
|
||||
Database::User::pointer CurrentUser()
|
||||
{
|
||||
return DbHandler().getCurrentUser();
|
||||
return Database::User::getById(DboSession(), 1);
|
||||
// return DbHandler().getCurrentUser();
|
||||
}
|
||||
|
||||
ImageResource* SessionImageResource()
|
||||
@@ -276,12 +277,12 @@ LmsApplication::handleAuthEvent(void)
|
||||
mainStack->addWidget(playlist);
|
||||
mainStack->addWidget(new Wt::WText("SETTINGS"));
|
||||
|
||||
explore->tracksAdd.connect(std::bind([=] (std::vector<Database::id_type> tracks)
|
||||
explore->tracksAdd.connect(std::bind([=] (std::vector<Database::Track::pointer> tracks)
|
||||
{
|
||||
playlist->addTracks(tracks);
|
||||
}, std::placeholders::_1));
|
||||
|
||||
explore->tracksPlay.connect(std::bind([=] (std::vector<Database::id_type> tracks)
|
||||
explore->tracksPlay.connect(std::bind([=] (std::vector<Database::Track::pointer> tracks)
|
||||
{
|
||||
playlist->playTracks(tracks);
|
||||
}, std::placeholders::_1));
|
||||
|
||||
+81
-6
@@ -17,13 +17,18 @@
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Wt/WAnchor>
|
||||
#include <Wt/WImage>
|
||||
#include <Wt/WTemplate>
|
||||
#include <Wt/WText>
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
#include "PlaylistView.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
static const std::string currentPlaylistName = "__current__playlist__";
|
||||
|
||||
Playlist::Playlist(Wt::WContainerWidget* parent)
|
||||
: Wt::WContainerWidget(parent)
|
||||
{
|
||||
@@ -41,26 +46,96 @@ Playlist::Playlist(Wt::WContainerWidget* parent)
|
||||
|
||||
_entriesContainer = new Wt::WContainerWidget();
|
||||
t->bindWidget("entries", _entriesContainer);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::addTracks(const std::vector<Database::id_type>& trackIds)
|
||||
Playlist::addTracks(const std::vector<Database::Track::pointer>& tracks)
|
||||
{
|
||||
for (auto trackId : trackIds)
|
||||
std::cerr << "Adding track " << trackId << std::endl;
|
||||
// Use a "session" playlist in order to store the current playlist
|
||||
// so that the user can disconnect and get its playlist back
|
||||
|
||||
auto playlist = Database::Playlist::get(DboSession(), currentPlaylistName, CurrentUser());
|
||||
if (!playlist)
|
||||
{
|
||||
playlist = Database::Playlist::create(DboSession(), currentPlaylistName, false, CurrentUser());
|
||||
}
|
||||
|
||||
for (auto track : tracks)
|
||||
{
|
||||
playlist.modify()->addTrack(track);
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::playTracks(const std::vector<Database::id_type>& trackIds)
|
||||
Playlist::playTracks(const std::vector<Database::Track::pointer>& tracks)
|
||||
{
|
||||
for (auto trackId : trackIds)
|
||||
std::cerr << "Playing track " << trackId << std::endl;
|
||||
Wt::Dbo::Transaction transaction(DboSession());
|
||||
|
||||
auto playlist = Database::Playlist::get(DboSession(), currentPlaylistName, CurrentUser());
|
||||
if (playlist)
|
||||
playlist.modify()->clear();
|
||||
|
||||
_entriesContainer->clear();
|
||||
|
||||
addTracks(tracks);
|
||||
|
||||
// TODO Immediate play
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::refresh()
|
||||
{
|
||||
Wt::Dbo::Transaction transaction (DboSession());
|
||||
|
||||
auto playlist = Database::Playlist::get(DboSession(), currentPlaylistName, CurrentUser());
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
auto tracks = playlist->getTracks(_entriesContainer->count(), 20); // TODO
|
||||
for (auto track : tracks)
|
||||
{
|
||||
Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-playlist-entry"), _entriesContainer);
|
||||
|
||||
entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText);
|
||||
|
||||
auto artist = track->getArtist();
|
||||
if (artist)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
Wt::WAnchor *artistAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/artist/" + std::to_string(track->getArtist().id())));
|
||||
Wt::WText *artistText = new Wt::WText(artistAnchor);
|
||||
artistText->setText(Wt::WString::fromUTF8(artist->getName(), Wt::PlainText));
|
||||
entry->bindWidget("artist-name", artistAnchor);
|
||||
}
|
||||
auto release = track->getRelease();
|
||||
if (release)
|
||||
{
|
||||
entry->setCondition("if-has-release", true);
|
||||
// TODO anchor
|
||||
Wt::WAnchor *releaseAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(track->getRelease().id())));
|
||||
Wt::WText *releaseText = new Wt::WText(releaseAnchor);
|
||||
releaseText->setText(Wt::WString::fromUTF8(release->getName(), Wt::PlainText));
|
||||
entry->bindWidget("release-name", releaseAnchor);
|
||||
}
|
||||
|
||||
Wt::WImage *cover = new Wt::WImage();
|
||||
cover->setImageLink(SessionImageResource()->getTrackUrl(track.id(), 64));
|
||||
// Some images may not be square
|
||||
cover->setWidth(64);
|
||||
entry->bindWidget("cover", cover);
|
||||
|
||||
auto playBtn = new Wt::WText(Wt::WString::tr("btn-playlist-entry-play-btn"), Wt::XHTMLText);
|
||||
entry->bindWidget("play-btn", playBtn);
|
||||
// TODO
|
||||
|
||||
auto addBtn = new Wt::WText(Wt::WString::tr("btn-playlist-entry-del-btn"), Wt::XHTMLText);
|
||||
entry->bindWidget("del-btn", addBtn);
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -30,8 +30,8 @@ class Playlist : public Wt::WContainerWidget
|
||||
public:
|
||||
Playlist(Wt::WContainerWidget* parent = 0);
|
||||
|
||||
void addTracks(const std::vector<Database::id_type>& trackIds);
|
||||
void playTracks(const std::vector<Database::id_type>& trackIds);
|
||||
void addTracks(const std::vector<Database::Track::pointer>& tracks);
|
||||
void playTracks(const std::vector<Database::Track::pointer>& tracks);
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
|
||||
+8
-13
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <Wt/WApplication>
|
||||
#include <Wt/WAnchor>
|
||||
#include <Wt/WLineEdit>
|
||||
#include <Wt/WImage>
|
||||
#include <Wt/WText>
|
||||
#include <Wt/WTemplate>
|
||||
@@ -44,29 +43,25 @@ Releases::Releases(Filters* filters, Wt::WContainerWidget* parent)
|
||||
auto releases = new Wt::WTemplate(Wt::WString::tr("template-releases"), this);
|
||||
releases->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
auto search = new Wt::WLineEdit();
|
||||
releases->bindWidget("search", search);
|
||||
search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
search->textInput().connect(std::bind([this, search]
|
||||
{
|
||||
auto keywords = splitString(search->text().toUTF8(), " ");
|
||||
refresh(keywords);
|
||||
}));
|
||||
_search = new Wt::WLineEdit();
|
||||
releases->bindWidget("search", _search);
|
||||
_search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
_search->textInput().connect(this, &Releases::refresh);
|
||||
|
||||
_releasesContainer = new Wt::WContainerWidget();
|
||||
releases->bindWidget("releases", _releasesContainer);
|
||||
|
||||
refresh();
|
||||
|
||||
filters->updated().connect(std::bind([=] {
|
||||
refresh();
|
||||
}));
|
||||
filters->updated().connect(this, &Releases::refresh);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Releases::refresh(std::vector<std::string> searchKeywords)
|
||||
Releases::refresh()
|
||||
{
|
||||
auto searchKeywords = splitString(_search->text().toUTF8(), " ");
|
||||
|
||||
_releasesContainer->clear();
|
||||
|
||||
auto clusterIds = _filters->getClusterIds();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/WLineEdit>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
@@ -34,9 +35,10 @@ class Releases : public Wt::WContainerWidget
|
||||
Wt::Signal<Database::id_type> releasePlay;
|
||||
|
||||
private:
|
||||
void refresh(std::vector<std::string> searchKeywords = std::vector<std::string>());
|
||||
void refresh();
|
||||
|
||||
Filters* _filters;
|
||||
Wt::WLineEdit* _search;
|
||||
Wt::WContainerWidget* _releasesContainer;
|
||||
};
|
||||
|
||||
|
||||
+8
-12
@@ -43,29 +43,25 @@ Tracks::Tracks(Filters* filters, Wt::WContainerWidget* parent)
|
||||
auto tracks = new Wt::WTemplate(Wt::WString::tr("template-tracks"), this);
|
||||
tracks->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
auto search = new Wt::WLineEdit();
|
||||
tracks->bindWidget("search", search);
|
||||
search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
search->textInput().connect(std::bind([this, search]
|
||||
{
|
||||
auto keywords = splitString(search->text().toUTF8(), " ");
|
||||
refresh(keywords);
|
||||
}));
|
||||
_search = new Wt::WLineEdit();
|
||||
tracks->bindWidget("search", _search);
|
||||
_search->setPlaceholderText(Wt::WString::tr("msg-search-placeholder"));
|
||||
_search->textInput().connect(this, &Tracks::refresh);
|
||||
|
||||
_tracksContainer = new Wt::WContainerWidget();
|
||||
tracks->bindWidget("tracks", _tracksContainer);
|
||||
|
||||
refresh();
|
||||
|
||||
filters->updated().connect(std::bind([=] {
|
||||
refresh();
|
||||
}));
|
||||
filters->updated().connect(this, &Tracks::refresh);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tracks::refresh(std::vector<std::string> searchKeywords)
|
||||
Tracks::refresh()
|
||||
{
|
||||
auto searchKeywords = splitString(_search->text().toUTF8(), " ");
|
||||
|
||||
_tracksContainer->clear();
|
||||
|
||||
auto clusterIds = _filters->getClusterIds();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/WLineEdit>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
@@ -33,9 +34,10 @@ class Tracks : public Wt::WContainerWidget
|
||||
Wt::Signal<Database::id_type> trackPlay;
|
||||
|
||||
private:
|
||||
void refresh(std::vector<std::string> searchKeywords = std::vector<std::string>());
|
||||
void refresh();
|
||||
|
||||
Wt::WContainerWidget* _tracksContainer;
|
||||
Wt::WLineEdit* _search;
|
||||
Filters* _filters;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user