Commit cb393b0c authored by Kevin Whitaker's avatar Kevin Whitaker

Uncomment user actions and fix by finding active DB object instead of...

Uncomment user actions and fix by finding active DB object instead of converting dead one. Use font-awesome to make icons for buttons. Implement rest of basic logic for login page. Some style fixings. Start adding skip controls.
parent c5e979e9
......@@ -355,8 +355,8 @@ void GroovePlayerMgr::grooveEventLoop()
Wt::Dbo::Transaction voteTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::VoteTrack;
action->user = Wt::Dbo::ptr<User>(&event.userInvolved);
action->trackInvolved = Wt::Dbo::ptr<AudioTrack>(&event.tracksInvolved.front());
action->user = sqlSession.find<User>().where("username = ?").bind(event.userInvolved.username);
action->trackInvolved = sqlSession.find<AudioTrack>().where("fingerprint = ?").bind(event.tracksInvolved.front().trackFingerprint);
action->datetime = Wt::WDateTime::currentDateTime();
sqlSession.add(action);
voteTransaction.commit();
......@@ -383,15 +383,15 @@ void GroovePlayerMgr::grooveEventLoop()
}
else if(event.eventType == PLAYING_PAUSED)
{
//Add action to DB TODO
// Wt::Dbo::Transaction pauseTransaction(sqlSession);
// UserAction* action = new UserAction();
// action->action = UserAction::UAction::PlayPause;
// action->user = Wt::Dbo::ptr<User>(&event.userInvolved);
// action->trackInvolved = Wt::Dbo::ptr<AudioTrack>(&event.tracksInvolved.front());
// action->datetime = Wt::WDateTime::currentDateTime();
// sqlSession.add(action);
// pauseTransaction.commit();
//Add action to DB
Wt::Dbo::Transaction pauseTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::PlayPause;
action->user = sqlSession.find<User>().where("username = ?").bind(event.userInvolved.username);
action->trackInvolved = sqlSession.find<AudioTrack>().where("fingerprint = ?").bind(event.tracksInvolved.front().trackFingerprint);
action->datetime = Wt::WDateTime::currentDateTime();
sqlSession.add(action);
pauseTransaction.commit();
groove_playlist_pause(currentPlaylist);
......@@ -407,15 +407,15 @@ void GroovePlayerMgr::grooveEventLoop()
}
else if(event.eventType == PLAYING_RESUMED)
{
//Add action to DB TODO
// Wt::Dbo::Transaction playTransaction(sqlSession);
// UserAction* action = new UserAction();
// action->action = UserAction::UAction::PlayPause;
// action->user = Wt::Dbo::ptr<User>(&event.userInvolved);
// action->trackInvolved = Wt::Dbo::ptr<AudioTrack>(&event.tracksInvolved.front());
// action->datetime = Wt::WDateTime::currentDateTime();
// sqlSession.add(action);
// playTransaction.commit();
//Add action to DB
Wt::Dbo::Transaction playTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::PlayPause;
action->user = sqlSession.find<User>().where("username = ?").bind(event.userInvolved.username);
action->trackInvolved = sqlSession.find<AudioTrack>().where("fingerprint = ?").bind(event.tracksInvolved.front().trackFingerprint);
action->datetime = Wt::WDateTime::currentDateTime();
sqlSession.add(action);
playTransaction.commit();
groove_playlist_play(currentPlaylist);
......@@ -439,8 +439,8 @@ void GroovePlayerMgr::grooveEventLoop()
Wt::Dbo::Transaction skipTransaction(sqlSession);
UserAction* action = new UserAction();
action->action = UserAction::UAction::RequestSkip;
action->user = Wt::Dbo::ptr<User>(&event.userInvolved);
action->trackInvolved = Wt::Dbo::ptr<AudioTrack>(&event.tracksInvolved.front());
action->user = sqlSession.find<User>().where("username = ?").bind(event.userInvolved.username);
action->trackInvolved = sqlSession.find<AudioTrack>().where("fingerprint = ?").bind(event.tracksInvolved.front().trackFingerprint);
action->datetime = Wt::WDateTime::currentDateTime();
sqlSession.add(action);
skipTransaction.commit();
......
......@@ -32,14 +32,16 @@ struct WebInterface::internal
WebInterface::WebInterface(const Wt::WEnvironment& env) : Wt::WApplication(env)
{
priv_int = new internal;
this->useStyleSheet(Wt::WLink("/resources/font-awesome/css/font-awesome.min.css"));
setTitle("Arbitrateor - Audio Jukebox");
enableUpdates(true);
priv_int->playerUI = new PlayerInterface(this);
priv_int->playerUI->hide();
priv_int->loginUI = new LoginInterface(this);
priv_int->loginUI->animateShow(Wt::WAnimation(Wt::WAnimation::AnimationEffect::SlideInFromTop));
root()->addWidget(priv_int->playerUI);
root()->addWidget(priv_int->loginUI);
priv_int->loginUI->animateShow(Wt::WAnimation(Wt::WAnimation::AnimationEffect::SlideInFromTop));
priv_int->loginUI->checkSessionValidity();
}
WebInterface::~WebInterface()
......
......@@ -19,11 +19,15 @@
#include "LoginInterface.h"
#include "../db/UserAction.h"
#include <Wt/WApplication>
#include <Wt/WEnvironment>
#include <Wt/Dbo/ptr>
#include <Wt/Auth/HashFunction>
#include <Wt/WRandom>
LoginInterface::LoginInterface(WebInterface* app)
{
this->app = app;
//TODO: First check if cookie is set and if is a valid user. Skip login if valid.
loginContainer = new Wt::WContainerWidget();
loginLayout = new Wt::WVBoxLayout();
loginMessage = new Wt::WText("Please Login to access.");
......@@ -52,6 +56,24 @@ LoginInterface::LoginInterface(WebInterface* app)
loginContainer->setWidth(Wt::WLength(50, Wt::WLength::Percentage));
}
void LoginInterface::checkSessionValidity()
{
Wt::Dbo::Session sqlSession;
sqlSession.setConnectionPool(*GroovePlayerMgr::getInstance()->connectionPool);
sqlSession.mapClass<User>("user");
sqlSession.mapClass<AudioTrack>("tracks");
sqlSession.mapClass<UserAction>("actions");
//First check if cookie is set and if is a valid user. Skip login if valid.
try{
if(Wt::WApplication::instance()->environment().getCookieValue("arbitrateor_user") != nullptr && getUserForLoginCookie(&sqlSession, *Wt::WApplication::instance()->environment().getCookieValue("arbitrateor_user")).username != User().username)
{
app->currentUser = getUserForLoginCookie(&sqlSession, *Wt::WApplication::instance()->environment().getCookieValue("arbitrateor_user"));
app->loginCompleted();
}
}
catch(std::runtime_error e){}
}
void LoginInterface::loginCheck()
{
//Reset message in case of success.
......@@ -78,9 +100,10 @@ void LoginInterface::loginCheck()
createUser(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8(), true);
}
//Check if the credentials match anything in the DB. If so, store cookie to skip login.
if(getUserForLoginAuth(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8()) != nullptr)
if(getUserForLoginAuth(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8()).username != User().username && !getUserForLoginAuth(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8()).isDisabled)
{
app->currentUser = *getUserForLoginAuth(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8());
app->currentUser = getUserForLoginAuth(&sqlSession, usernameField->text().toUTF8(),passwordField->text().toUTF8());
Wt::log("info") << "login by "<< app->currentUser.username << " happened.";
setLocalCookieForUser(app->currentUser);
app->loginCompleted();
}
......@@ -94,25 +117,54 @@ void LoginInterface::loginCheck()
void LoginInterface::createUser(Wt::Dbo::Session* session, std::string username, std::string rawPassword, bool isAdmin)
{
//TODO
Wt::Dbo::Transaction transaction(*session);
Wt::Auth::BCryptHashFunction hasher;
User* user = new User();
user->isAdmin = isAdmin;
user->username = username;
user->isDisabled = false;
user->passwordSalt = Wt::WRandom::generateId();
user->passwordHash = hasher.compute(rawPassword, user->passwordSalt);
user->loginCookieToken = Wt::WRandom::generateId();
session->add(user);
transaction.commit();
}
int LoginInterface::getUserCount(Wt::Dbo::Session* session)
{
//TODO
Wt::Dbo::Transaction transaction(*session);
int userCount = session->query<int>("select count(username) from user");
transaction.commit();
return userCount;
}
User* LoginInterface::getUserForLoginCookie(Wt::Dbo::Session* session, std::string cookie)
User LoginInterface::getUserForLoginCookie(Wt::Dbo::Session* session, std::string cookie)
{
//TODO
Wt::Dbo::Transaction transaction(*session);
Wt::Dbo::ptr<User> user = session->find<User>().where("cookie = ?").bind(cookie);
transaction.commit();
if(user.get() != nullptr)
{
return (*user);
}
return User();
}
User* LoginInterface::getUserForLoginAuth(Wt::Dbo::Session* session, std::string username, std::string rawPassword)
User LoginInterface::getUserForLoginAuth(Wt::Dbo::Session* session, std::string username, std::string rawPassword)
{
//TODO
Wt::Dbo::Transaction transaction(*session);
Wt::Auth::BCryptHashFunction hasher;
Wt::Dbo::ptr<User> user = session->find<User>().where("username = ?").bind(username);
if(user.get() != nullptr && hasher.compute(rawPassword,(*user).passwordSalt) == (*user).passwordHash)
{
transaction.commit();
return (*user);
}
transaction.commit();
return User();
}
void LoginInterface::setLocalCookieForUser(User user)
{
//TODO
this->app->setCookie("arbitrateor_user", user.loginCookieToken,2628000);
}
......@@ -33,6 +33,7 @@ class LoginInterface : public Wt::WContainerWidget
{
public:
LoginInterface(WebInterface* app);
void checkSessionValidity();
private:
Wt::WPushButton* loginButton;
Wt::WVBoxLayout* loginLayout;
......@@ -48,8 +49,8 @@ private:
void loginCheck();
void createUser(Wt::Dbo::Session* session, std::string username, std::string rawPassword, bool isAdmin);
int getUserCount(Wt::Dbo::Session* session);
User* getUserForLoginCookie(Wt::Dbo::Session* session, std::string cookie);
User* getUserForLoginAuth(Wt::Dbo::Session* session, std::string username, std::string rawPassword);
User getUserForLoginCookie(Wt::Dbo::Session* session, std::string cookie);
User getUserForLoginAuth(Wt::Dbo::Session* session, std::string username, std::string rawPassword);
void setLocalCookieForUser(User user);
};
......
......@@ -24,6 +24,7 @@
#include <Wt/WLength>
#include <Wt/WColor>
#include <Wt/WBorder>
#include <Wt/WString>
PlayerInterface::PlayerInterface(WebInterface* app)
{
......@@ -33,6 +34,7 @@ PlayerInterface::PlayerInterface(WebInterface* app)
playControlLayout = new Wt::WHBoxLayout();
voteControlLayout = new Wt::WVBoxLayout();
playControlWidget = new Wt::WContainerWidget();
skipControls = new Wt::WContainerWidget();
playControlWidget->setLayout(playControlLayout);
currentTrackProgress = new Wt::WProgressBar();
......@@ -43,10 +45,17 @@ PlayerInterface::PlayerInterface(WebInterface* app)
trackProgress->timeout().connect(this,&PlayerInterface::updateProgressFromTimer);
currentTrackDetails = new TrackDetails();
playpause = new Wt::WPushButton();
playpause->setText(groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist)==1?"Pause":"Resume");
playpause->setTextFormat(Wt::XHTMLText);
playpause->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
playpause->setText(groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist)==1?Wt::WString::fromUTF8("&#61516;"):Wt::WString::fromUTF8("&#61515;"));
playpause->setMaximumSize(Wt::WLength(60,Wt::WLength::Point),Wt::WLength(30,Wt::WLength::Point));
isPaused = groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist)==0;
playpause->clicked().connect(this, &PlayerInterface::playpauseClicked);
skipRequest = new Wt::WPushButton();
skipRequest->setTextFormat(Wt::XHTMLText);
skipRequest->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
skipRequest->setText("&#61521;"); //cancel skip? &#61534;
skipControls->addWidget(skipRequest);
interfaceLayout->addWidget(playControlWidget);
interfaceLayout->addWidget(currentTrackProgress);
......@@ -55,17 +64,18 @@ PlayerInterface::PlayerInterface(WebInterface* app)
playControlWidget->decorationStyle().setBackgroundColor(Wt::WColor("#00B200"));
playControlLayout->addWidget(playpause,0,Wt::AlignmentFlag::AlignLeft | Wt::AlignmentFlag::AlignMiddle);
playControlLayout->addWidget(currentTrackDetails);
playControlLayout->addWidget(skipControls,0,Wt::AlignmentFlag::AlignRight | Wt::AlignmentFlag::AlignMiddle);
}
void PlayerInterface::playpauseClicked()
{
if(!isPaused)
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_PAUSED, app->currentUser});
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_PAUSED, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
}
else
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_RESUMED, app->currentUser});
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_RESUMED, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
}
}
......@@ -73,11 +83,11 @@ void PlayerInterface::playpauseUpdated()
{
if(isPaused)
{
playpause->setText("Resume");
playpause->setText(Wt::WString::fromUTF8("&#61515;"));
}
else
{
playpause->setText("Pause");
playpause->setText(Wt::WString::fromUTF8("&#61516;"));
}
}
......
......@@ -48,6 +48,8 @@ public:
Wt::WHBoxLayout* currentTrackLayout;
Wt::WContainerWidget* currentTrackContainer;
Wt::WPushButton* playpause;
Wt::WContainerWidget* skipControls;
Wt::WPushButton* skipRequest;
bool isPaused = false;
//TODO:put in controls for requesting/admin skip and adding users as admin.
......
......@@ -23,7 +23,7 @@
TrackDetails::TrackDetails()
{
this->setMaximumSize(Wt::WLength(600, Wt::WLength::Pixel),Wt::WLength(200, Wt::WLength::Pixel));
this->setMaximumSize(Wt::WLength::Auto,Wt::WLength(200, Wt::WLength::Pixel));
this->decorationStyle().setBorder(Wt::WBorder::Ridge);
this->decorationStyle().setBackgroundColor(Wt::WColor("#6FFF6F"));
mainLayout = new Wt::WHBoxLayout();
......@@ -34,14 +34,18 @@ TrackDetails::TrackDetails()
albumCover->setMinimumSize(Wt::WLength(100,Wt::WLength::Pixel),Wt::WLength(100,Wt::WLength::Pixel));
albumCover->setMaximumSize(Wt::WLength(200,Wt::WLength::Pixel),Wt::WLength(200,Wt::WLength::Pixel));
mainLayout->addWidget(albumCover);
mainLayout->addSpacing(Wt::WLength(20, Wt::WLength::Pixel));
mainLayout->addSpacing(Wt::WLength(10, Wt::WLength::Pixel));
mainLayout->addLayout(metaLayout);
mainLayout->addSpacing(Wt::WLength(10, Wt::WLength::Pixel));
trackTitle = new Wt::WText();
trackTitle->setWordWrap(false);
trackTitle->decorationStyle().setTextDecoration(Wt::WCssDecorationStyle::Underline);
trackTitle->decorationStyle().font().setSize(Wt::WFont::Size::Large);
trackTitle->decorationStyle().font().setWeight(Wt::WFont::Weight::Bold);
trackArtist = new Wt::WText();
trackArtist->setWordWrap(false);
trackAlbum = new Wt::WText();
trackAlbum->setWordWrap(false);
metaLayout->addWidget(trackTitle,2);
metaLayout->addWidget(trackAlbum,1,Wt::AlignmentFlag::AlignBottom);
metaLayout->addWidget(trackArtist,1,Wt::AlignmentFlag::AlignBottom);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment