diff --git a/approot/playqueue.xml b/approot/playqueue.xml index 4b26bd9d..2e45a05c 100644 --- a/approot/playqueue.xml +++ b/approot/playqueue.xml @@ -6,11 +6,16 @@ + + + + ${entries} diff --git a/src/database/Playlist.cpp b/src/database/Playlist.cpp index 341bc368..4e7a0ee0 100644 --- a/src/database/Playlist.cpp +++ b/src/database/Playlist.cpp @@ -19,6 +19,7 @@ #include "Playlist.hpp" #include +#include #include "Cluster.hpp" #include "User.hpp" @@ -115,6 +116,13 @@ Playlist::getEntries(int offset, int size, bool& moreResults) const return res; } +std::vector> +Playlist::getAllEntries() const +{ + bool moreResults; + return getEntries(-1, -1, moreResults); +} + Wt::Dbo::ptr Playlist::getEntry(std::size_t pos) const { @@ -171,8 +179,23 @@ Playlist::getTrackIds() const .where("p.id = ?").bind(self()->id()); return std::vector(res.begin(), res.end()); - } +void +Playlist::shuffle() +{ + assert(session()); + + auto entries = getAllEntries(); + + auto now = std::chrono::system_clock::now(); + std::mt19937 randGenerator(std::chrono::duration_cast(now.time_since_epoch()).count()); + + std::shuffle(entries.begin(), entries.end(), randGenerator); + + clear(); + for (auto entry : entries) + PlaylistEntry::create(*session(), entry->getTrack(), self()); +} } // namespace Database diff --git a/src/database/Playlist.hpp b/src/database/Playlist.hpp index 904f3ae3..ef9aa059 100644 --- a/src/database/Playlist.hpp +++ b/src/database/Playlist.hpp @@ -53,11 +53,14 @@ class Playlist : public Wt::Dbo::Dbo // Modifiers void clear() { _entries.clear(); } + void shuffle(); // Get tracks, ordered by position std::size_t getCount() const; Wt::Dbo::ptr getEntry(std::size_t pos) const; std::vector> getEntries(int offset, int size, bool& moreResults) const; + std::vector> getAllEntries() const; + std::vector getTrackIds() const; // Get clusters, order by occurence @@ -95,7 +98,7 @@ class PlaylistEntry static pointer getById(Wt::Dbo::Session& session, IdType id); // Create utility - static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr track, Wt::Dbo::ptr playlist); + static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr track, Wt::Dbo::ptr playlist); // Accessors Wt::Dbo::ptr getTrack() const { return _track; } diff --git a/src/ui/PlayQueueView.cpp b/src/ui/PlayQueueView.cpp index 333f2e40..15a9c125 100644 --- a/src/ui/PlayQueueView.cpp +++ b/src/ui/PlayQueueView.cpp @@ -50,6 +50,7 @@ PlayQueue::PlayQueue() _showMore->addFunction("tr", &Wt::WTemplate::Functions::tr); _showMore->setHidden(true); + Wt::WText* shuffleBtn = bindNew("shuffle-btn", Wt::WString::tr("Lms.PlayQueue.shuffle"), Wt::TextFormat::XHTML); _radioMode = bindNew("radio-mode", Wt::WString::tr("Lms.PlayQueue.radio-mode")); _nbTracks = bindNew("nb-tracks"); @@ -78,6 +79,18 @@ PlayQueue::PlayQueue() updateInfo(); })); + shuffleBtn->clicked().connect([=] + { + { + Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); + + auto playlist = Database::Playlist::get(LmsApp->getDboSession(), currentPlayQueueName, LmsApp->getCurrentUser()); + playlist.modify()->shuffle(); + } + _entriesContainer->clear(); + addSome(); + }); + _showMore->clicked().connect(std::bind([=] { addSome();