[UI] Restore the playing queue when creating the session
This commit is contained in:
@@ -71,7 +71,8 @@ _isAdmin(false),
|
||||
_audioBitrate(defaultAudioBitrate),
|
||||
_audioEncoding(AudioEncoding::AUTO),
|
||||
_videoBitrate(defaultVideoBitrate),
|
||||
_videoEncoding(VideoEncoding::AUTO)
|
||||
_videoEncoding(VideoEncoding::AUTO),
|
||||
_curPlayingTrackPos(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ class User
|
||||
void setVideoEncoding(VideoEncoding encoding) { _videoEncoding = encoding; }
|
||||
void setMaxAudioBitrate(std::size_t bitrate);
|
||||
void setMaxVideoBitrate(std::size_t bitrate);
|
||||
void setCurPlayingTrackPos(std::size_t pos) { _curPlayingTrackPos = pos; }
|
||||
|
||||
// read
|
||||
bool isAdmin() const {return _isAdmin;}
|
||||
@@ -87,6 +88,7 @@ class User
|
||||
VideoEncoding getVideoEncoding() const { return _videoEncoding;}
|
||||
std::size_t getMaxAudioBitrate() const;
|
||||
std::size_t getMaxVideoBitrate() const;
|
||||
std::size_t getCurPlayingTrackPos() const { return _curPlayingTrackPos; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
@@ -98,6 +100,8 @@ class User
|
||||
Wt::Dbo::field(a, _audioEncoding, "audio_encoding");
|
||||
Wt::Dbo::field(a, _videoBitrate, "video_bitrate");
|
||||
Wt::Dbo::field(a, _videoEncoding, "video_encoding");
|
||||
// User's dynamic data
|
||||
Wt::Dbo::field(a, _curPlayingTrackPos, "cur_playing_track_pos");
|
||||
Wt::Dbo::hasMany(a, _playlists, Wt::Dbo::ManyToOne, "user");
|
||||
}
|
||||
|
||||
@@ -120,6 +124,9 @@ class User
|
||||
int _videoBitrate;
|
||||
VideoEncoding _videoEncoding;
|
||||
|
||||
// User's dynamic data
|
||||
int _curPlayingTrackPos; // Current track position in queue
|
||||
|
||||
Wt::Dbo::collection< Wt::Dbo::ptr<Playlist> > _playlists;
|
||||
|
||||
};
|
||||
|
||||
@@ -51,6 +51,10 @@ void WPopupMenuClear(Wt::WPopupMenu* menu)
|
||||
namespace UserInterface {
|
||||
namespace Desktop {
|
||||
|
||||
// Special playlist generated each time the playque gets changed
|
||||
// Restored at the beginning of the session
|
||||
static const std::string CurrentQueuePlaylistName = "__current__";
|
||||
|
||||
Audio::Audio(SessionData& sessionData, Wt::WContainerWidget* parent)
|
||||
: UserInterface::Audio(parent),
|
||||
_db(sessionData.getDatabaseHandler()),
|
||||
@@ -180,6 +184,11 @@ _playQueue(nullptr)
|
||||
playQueueLayout->addLayout(playlistControls);
|
||||
|
||||
mainLayout->addWidget(playQueueContainer, 0, 0, 2, 1);
|
||||
|
||||
// Load the last known queue
|
||||
playlistLoadToPlayqueue(CurrentQueuePlaylistName);
|
||||
// Select the last known playing track
|
||||
_playQueue->select(user->getCurPlayingTrackPos());
|
||||
}
|
||||
|
||||
mainLayout->setRowStretch(1, 1);
|
||||
@@ -212,6 +221,13 @@ _playQueue(nullptr)
|
||||
_mediaPlayer->shuffle().connect(boost::bind(&PlayQueue::setShuffle, _playQueue, _1));
|
||||
_mediaPlayer->loop().connect(boost::bind(&PlayQueue::setLoop,_playQueue, _1));
|
||||
|
||||
_playQueue->tracksUpdated().connect(std::bind([=] () {
|
||||
LMS_LOG(MOD_UI, SEV_INFO) << "Playqueue updated!";
|
||||
|
||||
playlistSaveFromPlayqueue(CurrentQueuePlaylistName);
|
||||
}));
|
||||
|
||||
|
||||
playlistRefreshMenus();
|
||||
}
|
||||
|
||||
@@ -337,17 +353,21 @@ Audio::playlistLoadToPlayqueue(std::string playlistName)
|
||||
{
|
||||
LMS_LOG(MOD_UI, SEV_DEBUG) << "Loading playlist '" << playlistName << "' to playqueue";
|
||||
|
||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||
std::vector<Database::Track::id_type> entries;
|
||||
|
||||
Database::User::pointer user = _db.getCurrentUser();
|
||||
if (!user)
|
||||
return;
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||
|
||||
Database::Playlist::pointer playlist = Database::Playlist::get(_db.getSession(), playlistName, user);
|
||||
if (!playlist)
|
||||
return;
|
||||
Database::User::pointer user = _db.getCurrentUser();
|
||||
if (!user)
|
||||
return;
|
||||
|
||||
std::vector<Database::Track::id_type> entries = Database::PlaylistEntry::getEntries(_db.getSession(), playlist);
|
||||
Database::Playlist::pointer playlist = Database::Playlist::get(_db.getSession(), playlistName, user);
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
entries = Database::PlaylistEntry::getEntries(_db.getSession(), playlist);
|
||||
}
|
||||
|
||||
_playQueue->clear();
|
||||
_playQueue->addTracks(entries);
|
||||
@@ -414,6 +434,9 @@ Audio::playlistRefreshMenus()
|
||||
|
||||
BOOST_FOREACH(Database::Playlist::pointer playlist, playlists)
|
||||
{
|
||||
if (playlist->getName() == CurrentQueuePlaylistName)
|
||||
continue;
|
||||
|
||||
// Add playlists in each menu
|
||||
_popupMenuDelete->addItem(playlist->getName())->triggered().connect(std::bind([=] ()
|
||||
{
|
||||
@@ -496,7 +519,7 @@ Audio::playSelectedTracks(PlayQueueAddType addType)
|
||||
}
|
||||
|
||||
void
|
||||
Audio::playTrack(boost::filesystem::path p)
|
||||
Audio::playTrack(boost::filesystem::path p, int pos)
|
||||
{
|
||||
LMS_LOG(MOD_UI, SEV_DEBUG) << "play track '" << p << "'";
|
||||
try {
|
||||
@@ -508,7 +531,10 @@ Audio::playTrack(boost::filesystem::path p)
|
||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||
Database::User::pointer user = _db.getCurrentUser();
|
||||
if (user)
|
||||
{
|
||||
bitrate = user->getAudioBitrate();
|
||||
user.modify()->setCurPlayingTrackPos(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
LMS_LOG(MOD_UI, SEV_ERROR) << "Can't play: user does not exists!";
|
||||
|
||||
@@ -55,7 +55,7 @@ class Audio : public UserInterface::Audio
|
||||
void playlistShowDeleteDialog(std::string name);
|
||||
void playlistRefreshMenus();
|
||||
|
||||
void playTrack(boost::filesystem::path p);
|
||||
void playTrack(boost::filesystem::path p, int pos);
|
||||
|
||||
enum PlayQueueAddType
|
||||
{
|
||||
|
||||
@@ -357,14 +357,25 @@ PlayQueue::play(int rowId)
|
||||
playNext();
|
||||
}
|
||||
|
||||
void
|
||||
PlayQueue::select(int rowId)
|
||||
{
|
||||
// Update the track selector to use the requested track as current position
|
||||
_trackSelector->setPosByRowId(rowId);
|
||||
|
||||
Wt::WTableView::select(_model->index(_trackSelector->getCurrent(), 0));
|
||||
|
||||
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
|
||||
}
|
||||
|
||||
void
|
||||
PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
|
||||
{
|
||||
// Add tracks to model
|
||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||
|
||||
//
|
||||
BOOST_FOREACH(Database::Track::id_type trackId, trackIds)
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||
Database::Track::pointer track (Database::Track::getById(_db.getSession(), trackId));
|
||||
|
||||
if (track)
|
||||
@@ -391,6 +402,8 @@ PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
|
||||
}
|
||||
|
||||
_trackSelector->setSize( _model->rowCount() );
|
||||
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -401,6 +414,8 @@ PlayQueue::clear(void)
|
||||
// Reset play id
|
||||
_curPlayedTrackPos = trackPosInvalid;
|
||||
_trackSelector->setSize( 0 );
|
||||
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -458,7 +473,7 @@ PlayQueue::readTrack(int rowPos)
|
||||
{
|
||||
setPlayingTrackPos(rowPos);
|
||||
|
||||
_sigTrackPlay.emit(track->getPath());
|
||||
_sigTrackPlay.emit(track->getPath(), rowPos);
|
||||
|
||||
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
|
||||
|
||||
@@ -504,6 +519,7 @@ PlayQueue::delSelected(void)
|
||||
_trackSelector->setSize(_model->rowCount());
|
||||
|
||||
renumber(minId, _model->rowCount() - 1);
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -511,6 +527,7 @@ PlayQueue::delAll(void)
|
||||
{
|
||||
_model->removeRows(0, _model->rowCount());
|
||||
_trackSelector->setSize(0);
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -551,6 +568,8 @@ PlayQueue::moveSelectedUp(void)
|
||||
this->setSelectedIndexes( newIndexSet );
|
||||
|
||||
renumber(minId, maxId);
|
||||
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
|
||||
@@ -592,6 +611,8 @@ PlayQueue::moveSelectedDown(void)
|
||||
this->setSelectedIndexes( newIndexSet );
|
||||
|
||||
renumber(minId, maxId);
|
||||
|
||||
_sigTracksUpdated.emit();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -49,6 +49,7 @@ class PlayQueue : public Wt::WTableView
|
||||
// Play functions
|
||||
void play(void); // Play the queue from the beginning
|
||||
void play(int rowId); // Play the queue from the given rowId
|
||||
void select(int rowId); // Select the given rowId
|
||||
void playNext(void); // Play the next track
|
||||
void playPrevious(void); // Play the previous track
|
||||
|
||||
@@ -59,7 +60,10 @@ class PlayQueue : public Wt::WTableView
|
||||
void moveSelectedDown(void);
|
||||
|
||||
// Signals
|
||||
Wt::Signal< boost::filesystem::path >& playTrack() { return _sigTrackPlay; }
|
||||
// Emitted when a song has to be played
|
||||
Wt::Signal< boost::filesystem::path, int >& playTrack() { return _sigTrackPlay; }
|
||||
// Emitted when the list has changed
|
||||
Wt::Signal< void >& tracksUpdated() { return _sigTracksUpdated; }
|
||||
|
||||
// Slots
|
||||
void handlePlaybackComplete(void);
|
||||
@@ -72,7 +76,8 @@ class PlayQueue : public Wt::WTableView
|
||||
void setPlayingTrackPos(int newRowPos);
|
||||
void renumber(int firstId, int lastId);
|
||||
|
||||
Wt::Signal< boost::filesystem::path > _sigTrackPlay;
|
||||
Wt::Signal< boost::filesystem::path, int > _sigTrackPlay;
|
||||
Wt::Signal< void > _sigTracksUpdated;
|
||||
|
||||
Database::Handler& _db;
|
||||
|
||||
|
||||
@@ -59,12 +59,17 @@ _sessionData(sessionData)
|
||||
hLayout->addWidget(menu);
|
||||
hLayout->addWidget(contents, 1);
|
||||
|
||||
Wt::Dbo::Transaction transaction( sessionData.getDatabaseHandler().getSession());
|
||||
|
||||
::Database::User::pointer user = sessionData.getDatabaseHandler().getCurrentUser();
|
||||
std::string userId;
|
||||
bool userIsAdmin;
|
||||
{
|
||||
Wt::Dbo::Transaction transaction( sessionData.getDatabaseHandler().getSession());
|
||||
::Database::User::pointer user = sessionData.getDatabaseHandler().getCurrentUser();
|
||||
userId = Database::User::getId(user);
|
||||
userIsAdmin = user->isAdmin();
|
||||
}
|
||||
|
||||
menu->addItem("Audio", new AudioFormView(sessionData));
|
||||
if (user->isAdmin())
|
||||
if (userIsAdmin)
|
||||
{
|
||||
MediaDirectories* mediaDirectory = new MediaDirectories(sessionData);
|
||||
mediaDirectory->changed().connect(this, &Settings::handleDatabaseDirectoriesChanged);
|
||||
@@ -78,7 +83,7 @@ _sessionData(sessionData)
|
||||
}
|
||||
else
|
||||
{
|
||||
menu->addItem("Account", new AccountFormView(sessionData, Database::User::getId(user)));
|
||||
menu->addItem("Account", new AccountFormView(sessionData, userId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user