From cc8c4bcb7eed869e2eacb2f59e56b56213b2190a Mon Sep 17 00:00:00 2001 From: Kevin Whitaker Date: Sat, 18 Feb 2017 22:23:09 -0500 Subject: [PATCH] Implement basics of voting ui. Change vote selection code to also inject cover before putting in list. Make sure player sends winning track to highlight on client. --- src/GroovePlayer.cpp | 28 ++++++++++---- src/WebInterface.cpp | 7 ++-- src/WebInterface.h | 2 +- src/ui/PlayerInterface.cpp | 76 +++++++++++++++++++++++++++++++++++++- src/ui/PlayerInterface.h | 18 ++++++++- src/ui/TrackDetails.cpp | 10 ++++- src/ui/TrackDetails.h | 1 + 7 files changed, 126 insertions(+), 16 deletions(-) diff --git a/src/GroovePlayer.cpp b/src/GroovePlayer.cpp index a927ab6..a22e210 100644 --- a/src/GroovePlayer.cpp +++ b/src/GroovePlayer.cpp @@ -105,7 +105,9 @@ std::list GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio eligibleTrack = session->find().where("album = ?").limit(1).offset(rand() % trackAlbumCount).bind(currentTrack.trackAlbumName); } } - selectedTracks.push_back(*eligibleTrack); + AudioTrack selected = *eligibleTrack; + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } else { @@ -119,7 +121,9 @@ std::list GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio eligibleTrack = session->find().where("artist = ?").limit(1).offset(rand() % trackArtistCount).bind(currentTrack.trackArtistName); } } - selectedTracks.push_back(*eligibleTrack); + AudioTrack selected = *eligibleTrack; + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } //Determine second track @@ -136,7 +140,9 @@ std::list GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio eligibleTrack = session->find().where("genre = ?").limit(1).offset(rand() % trackGenreCount).bind(currentTrack.trackGenre); } } - selectedTracks.push_back(*eligibleTrack); + AudioTrack selected = *eligibleTrack; + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } //Determine third track @@ -144,19 +150,25 @@ std::list GroovePlayerMgr::getNextVoteBatch(Wt::Dbo::Session* sessio if(requestQueue.size() > 0) { //There's a request. Pick one up front and put as third item. - selectedTracks.push_back(requestQueue.front()); + AudioTrack selected = requestQueue.front(); + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } else if(trackNotGenreCount > 0) { //Pick from other genre Wt::Dbo::ptr eligibleTrack = session->find().where("genre != ?").limit(1).offset(rand() % trackNotGenreCount).bind(currentTrack.trackGenre); - selectedTracks.push_back(*eligibleTrack); + AudioTrack selected = *eligibleTrack; + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } else { //Pick randomly Wt::Dbo::ptr eligibleTrack = session->find().limit(1).offset(rand() % trackCount); - selectedTracks.push_back(*eligibleTrack); + AudioTrack selected = *eligibleTrack; + getPictureFromTrack(&selected); + selectedTracks.push_back(selected); } transaction.commit(); Wt::log("info") << "Next set of tracks to vote picked: 1=>[" << (*selectedTracks.begin()).trackName << "] 2=>[" << (*std::next(selectedTracks.begin(),1)).trackName << "] 3=>[" << (*std::next(selectedTracks.begin(),2)).trackName << "]"; @@ -337,11 +349,11 @@ void GroovePlayerMgr::grooveEventLoop() } } groove_playlist_insert(currentPlaylist,groove_file_open(winner.trackPath.c_str()),1.0,1.0,nullptr); - Wt::WServer::instance()->postAll([]() { + Wt::WServer::instance()->postAll([winner]() { Wt::WApplication* app = Wt::WApplication::instance(); if(app != nullptr) { - static_cast(app)->voteNextPollClosedFromServer(); + static_cast(app)->voteNextPollClosedFromServer(winner); } } ); diff --git a/src/WebInterface.cpp b/src/WebInterface.cpp index 4c807d4..c8510cf 100644 --- a/src/WebInterface.cpp +++ b/src/WebInterface.cpp @@ -60,6 +60,7 @@ void WebInterface::loginCompleted() priv_int->loginUI->animateHide(Wt::WAnimation(Wt::WAnimation::AnimationEffect::Fade)); priv_int->playerUI->animateShow(Wt::WAnimation(Wt::WAnimation::AnimationEffect::Fade, Wt::WAnimation::TimingFunction::EaseIn, 500)); priv_int->playerUI->updateDetailsFromServer(GroovePlayerMgr::getInstance()->currentTrack); + priv_int->playerUI->updateVoteableTracksFromServer(GroovePlayerMgr::getInstance()->currentVoteBatch); } void WebInterface::playPauseActionFromServer(User userPausing, bool pause) @@ -94,14 +95,14 @@ void WebInterface::voteNextSongFromServer(User userVoting, AudioTrack trackVoted triggerUpdate(); } -void WebInterface::voteNextPollClosedFromServer() +void WebInterface::voteNextPollClosedFromServer(AudioTrack winner) { - priv_int->playerUI->updateVotingEnded(); + priv_int->playerUI->updateVotingEnded(winner); triggerUpdate(); } void WebInterface::voteTracksUpdatedFromServer(std::list voteableTracks) { - //priv_int->playerUI->tempText->setText(priv_int->playerUI->tempText->text()+"votechanged"); + priv_int->playerUI->updateVoteableTracksFromServer(voteableTracks); triggerUpdate(); } diff --git a/src/WebInterface.h b/src/WebInterface.h index 647335e..f492760 100644 --- a/src/WebInterface.h +++ b/src/WebInterface.h @@ -37,7 +37,7 @@ public: void skipVotedFromServer(User userRequestingToSkipCurrentTrack); void skipVoteUpdateFromServer(User userVoting, bool forSkip); void voteNextSongFromServer(User userVoting, AudioTrack trackVoted); - void voteNextPollClosedFromServer(); + void voteNextPollClosedFromServer(AudioTrack winner); User currentUser; private: struct internal; diff --git a/src/ui/PlayerInterface.cpp b/src/ui/PlayerInterface.cpp index 8673f43..853f908 100644 --- a/src/ui/PlayerInterface.cpp +++ b/src/ui/PlayerInterface.cpp @@ -44,6 +44,7 @@ PlayerInterface::PlayerInterface(WebInterface* app) trackProgress->timeout().connect(this,&PlayerInterface::updateProgressFromTimer); currentTrackDetails = new TrackDetails(); currentTrackDetails->setMinimumSize(Wt::WLength(100,Wt::WLength::Pixel),Wt::WLength(100,Wt::WLength::Pixel)); + currentTrackDetails->changeBackgroundColor(Wt::WColor("#6FFF6F")); playpause = new Wt::WPushButton(); playpause->setTextFormat(Wt::XHTMLText); playpause->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome"); @@ -65,15 +66,63 @@ PlayerInterface::PlayerInterface(WebInterface* app) skipControls->addWidget(skipRequest); skipControls->addWidget(skipDeny); + voteControlContainer = new Wt::WContainerWidget(); + voteControlContainer->setMaximumSize(Wt::WLength(75,Wt::WLength::Percentage),Wt::WLength::Auto); + voteControlContainer->decorationStyle().setBackgroundColor(Wt::WColor("lightsteelblue")); + voteControlContainer->addStyleClass("panel"); + voteHeader = new Wt::WText("Upcoming Tracks To Vote On"); + voteHeader->addStyleClass("panel-heading"); + voteTracksContainer = new Wt::WContainerWidget(); + voteTracksContainer->addStyleClass("panel-body"); + voteTracksLayout = new Wt::WVBoxLayout(); + track1 = new Wt::WHBoxLayout(); + track1details = new TrackDetails(); + track1details->changeBackgroundColor(Wt::WColor("gainsboro")); + track1vote = new Wt::WPushButton(); + track1vote->setTextFormat(Wt::XHTMLText); + track1vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome"); + track1vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel)); + track1vote->setText(""); + track1->addWidget(track1details); + track1->addWidget(track1vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight); + track2 = new Wt::WHBoxLayout(); + track2details = new TrackDetails(); + track2details->changeBackgroundColor(Wt::WColor("gainsboro")); + track2vote = new Wt::WPushButton(); + track2vote->setTextFormat(Wt::XHTMLText); + track2vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome"); + track2vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel)); + track2vote->setText(""); + track2->addWidget(track2details); + track2->addWidget(track2vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight); + track3 = new Wt::WHBoxLayout(); + track3details = new TrackDetails(); + track3details->changeBackgroundColor(Wt::WColor("gainsboro")); + track3vote = new Wt::WPushButton(); + track3vote->setTextFormat(Wt::XHTMLText); + track3vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome"); + track3vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel)); + track3vote->setText(""); + track3->addWidget(track3details); + track3->addWidget(track3vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight); + //TODO: implement voting actions + interfaceLayout->addWidget(playControlWidget); interfaceLayout->addWidget(currentTrackProgress); - interfaceLayout->addLayout(voteControlLayout); + interfaceLayout->addWidget(voteControlContainer,0,Wt::AlignmentFlag::AlignCenter); playControlWidget->addStyleClass("panel"); playControlWidget->addStyleClass("panel-default"); playControlWidget->decorationStyle().setBackgroundColor(Wt::WColor("gainsboro")); playControlLayout->addWidget(playpause,0,Wt::AlignmentFlag::AlignLeft | Wt::AlignmentFlag::AlignMiddle); playControlLayout->addWidget(currentTrackDetails,0,Wt::AlignmentFlag::AlignCenter | Wt::AlignmentFlag::AlignMiddle); playControlLayout->addWidget(skipControls,0,Wt::AlignmentFlag::AlignRight | Wt::AlignmentFlag::AlignMiddle); + voteControlContainer->setLayout(voteControlLayout); + voteControlLayout->addWidget(voteHeader,0,Wt::AlignmentFlag::AlignCenter); + voteControlLayout->addWidget(voteTracksContainer); + voteTracksContainer->setLayout(voteTracksLayout); + voteTracksLayout->addLayout(track1); + voteTracksLayout->addLayout(track2); + voteTracksLayout->addLayout(track3); } void PlayerInterface::playpauseClicked() @@ -116,9 +165,16 @@ void PlayerInterface::updateSkipDeniedFromServer() skipRequest->setHidden(false); } -void PlayerInterface::updateVotingEnded() +void PlayerInterface::updateVotingEnded(AudioTrack winner) { skipRequest->setEnabled(false); + track1vote->setEnabled(false); + track2vote->setEnabled(false); + track3vote->setEnabled(false); + //show winning track + if(track1details->trackMatches(winner)) track1details->changeBackgroundColor(Wt::WColor("gold")); + else if(track2details->trackMatches(winner)) track2details->changeBackgroundColor(Wt::WColor("gold")); + else if(track3details->trackMatches(winner)) track3details->changeBackgroundColor(Wt::WColor("gold")); } void PlayerInterface::playpauseUpdated() @@ -174,3 +230,19 @@ void PlayerInterface::updateDetailsFromServer(AudioTrack track) currentTrackDetails->updateWithTrackDetails(track); } + +void PlayerInterface::updateVoteableTracksFromServer(std::list tracks) +{ + //Update current vote items + auto trackIter = tracks.begin(); + track1details->updateWithTrackDetails(*trackIter); + track2details->updateWithTrackDetails(*++trackIter); + track3details->updateWithTrackDetails(*++trackIter); + track1vote->setEnabled(true); + track2vote->setEnabled(true); + track3vote->setEnabled(true); + //reset color state of tracks + track1details->changeBackgroundColor(Wt::WColor("gainsboro")); + track2details->changeBackgroundColor(Wt::WColor("gainsboro")); + track3details->changeBackgroundColor(Wt::WColor("gainsboro")); +} diff --git a/src/ui/PlayerInterface.h b/src/ui/PlayerInterface.h index 40950b3..d2da440 100644 --- a/src/ui/PlayerInterface.h +++ b/src/ui/PlayerInterface.h @@ -52,6 +52,21 @@ public: Wt::WPushButton* skipRequest; Wt::WPushButton* skipDeny; + //Vote Controls + Wt::WContainerWidget* voteControlContainer; + Wt::WContainerWidget* voteTracksContainer; + Wt::WText* voteHeader; + Wt::WVBoxLayout* voteTracksLayout; + Wt::WHBoxLayout* track1; + Wt::WHBoxLayout* track2; + Wt::WHBoxLayout* track3; + TrackDetails* track1details; + Wt::WPushButton* track1vote; + TrackDetails* track2details; + Wt::WPushButton* track2vote; + TrackDetails* track3details; + Wt::WPushButton* track3vote; + bool isPaused = false; //TODO:put in controls for requesting/admin skip and adding users as admin. @@ -64,10 +79,11 @@ public: void skipRequestClicked(); void skipDenyClicked(); void updateDetailsFromServer(AudioTrack track); + void updateVoteableTracksFromServer(std::list tracks); void updateProgressFromTimer(); void updateSkipRequestedFromServer(); void updateSkipDeniedFromServer(); - void updateVotingEnded(); + void updateVotingEnded(AudioTrack winner); }; #endif // PLAYERINTERFACE_H diff --git a/src/ui/TrackDetails.cpp b/src/ui/TrackDetails.cpp index cb1011b..0709e6e 100644 --- a/src/ui/TrackDetails.cpp +++ b/src/ui/TrackDetails.cpp @@ -24,7 +24,6 @@ TrackDetails::TrackDetails() { this->setMaximumSize(Wt::WLength::Auto,Wt::WLength(200, Wt::WLength::Pixel)); - changeBackgroundColor(Wt::WColor("#6FFF6F")); this->addStyleClass("panel"); this->addStyleClass("panel-default"); mainLayout = new Wt::WHBoxLayout(); @@ -71,3 +70,12 @@ void TrackDetails::changeBackgroundColor(Wt::WColor color) { this->decorationStyle().setBackgroundColor(color); } + +bool TrackDetails::trackMatches(AudioTrack track) +{ + if(track.trackName == trackTitle->text() && track.trackArtistName == trackArtist->text() && track.trackAlbumName == trackAlbum->text()) + { + return true; + } + return false; +} diff --git a/src/ui/TrackDetails.h b/src/ui/TrackDetails.h index 969a094..bd79dcd 100644 --- a/src/ui/TrackDetails.h +++ b/src/ui/TrackDetails.h @@ -43,6 +43,7 @@ public: void updateWithTrackDetails(AudioTrack track); void changeBackgroundColor(Wt::WColor color); + bool trackMatches(AudioTrack track); }; #endif // TRACKDETAILS_H -- GitLab