diff --git a/approot/templates.xml b/approot/templates.xml
index ff40519c..27fc5b8a 100644
--- a/approot/templates.xml
+++ b/approot/templates.xml
@@ -490,7 +490,7 @@
-
+
diff --git a/src/ui/LmsApplication.cpp b/src/ui/LmsApplication.cpp
index cc99db01..faa87640 100644
--- a/src/ui/LmsApplication.cpp
+++ b/src/ui/LmsApplication.cpp
@@ -194,11 +194,9 @@ LmsApplication::handleAuthEvent(void)
this->root()->setOverflow(Wt::WContainerWidget::OverflowHidden);
setConfirmCloseMessage("Closing LMS. Are you sure?");
- // Handle internal paths
-
// Create a Vertical layout: top is the nav bar, bottom is the contents
Wt::WVBoxLayout *layout = new Wt::WVBoxLayout(this->root());
- // Create a navigation bar with a link to a web page.
+
Wt::WNavigationBar *navigation = new Wt::WNavigationBar();
navigation->setTitle("LMS", "https://github.com/epoupon/lms");
navigation->setResponsive(true);
@@ -219,19 +217,20 @@ LmsApplication::handleAuthEvent(void)
searchEdit->setWidth(150);
// TODO add a span with a search icon
- Audio *audio;
+ menu->setInternalPathEnabled();
+ menu->setInternalBasePath("/");
+ Audio *audio;
if (agentIsMobile())
audio = new Mobile::Audio();
else
audio = new Desktop::Audio();
- menu->addItem("Audio", audio);
+ menu->addItem("Audio", audio)->setPathComponent("audio");;
#if defined HAVE_VIDEO
- menu->addItem("Video", new VideoWidget());
+ menu->addItem("Video", new VideoWidget())->setPathComponent("video");
#endif
- menu->addItem("Settings", new Settings::Settings());
-
+ menu->addItem("Settings", new Settings::Settings())->setPathComponent("settings");
Wt::WPopupMenu *popup = new Wt::WPopupMenu();
popup->addItem("Logout");
diff --git a/src/ui/audio/mobile/MobileAudio.cpp b/src/ui/audio/mobile/MobileAudio.cpp
index c37c9fcc..c9e3fdbb 100644
--- a/src/ui/audio/mobile/MobileAudio.cpp
+++ b/src/ui/audio/mobile/MobileAudio.cpp
@@ -55,18 +55,6 @@ enum WidgetIdx
using namespace Database;
-static void playTrack(AudioPlayer *audioPlayer, Database::Track::id_type trackId)
-{
- LMS_LOG(UI, DEBUG) << "Playing track id " << trackId;
-
- Wt::Dbo::Transaction transaction(DboSession());
-
- Track::pointer track = Track::getById(DboSession(), trackId);
-
- if (track)
- audioPlayer->loadTrack(track.id());
-}
-
void
Audio::search(std::string text)
{
@@ -83,12 +71,12 @@ Audio::Audio(Wt::WContainerWidget *parent)
Wt::WStackedWidget *stack = new Wt::WStackedWidget(this);
// Same order as WidgetIdxXXX
- stack->addWidget(new PreviewSearchView());
+ stack->addWidget(new PreviewSearchView(_playQueueEvents));
stack->addWidget(new ArtistSearchView());
stack->addWidget(new ReleaseSearchView());
- stack->addWidget(new TrackSearchView());
+ stack->addWidget(new TrackSearchView(_playQueueEvents));
stack->addWidget(new ArtistView());
- stack->addWidget(new ReleaseView());
+ stack->addWidget(new ReleaseView(_playQueueEvents));
wApp->internalPathChanged().connect(std::bind([=] (std::string path)
{
@@ -117,6 +105,11 @@ Audio::Audio(Wt::WContainerWidget *parent)
AudioPlayer* audioPlayer = new AudioPlayer();
footer->bindWidget("player", audioPlayer);
+ // Connect the events to the player
+ _playQueueEvents.trackPlay.connect(std::bind([=] (Database::Track::id_type id)
+ {
+ audioPlayer->loadTrack(id);
+ }, std::placeholders::_1));
}
} // namespace Mobile
diff --git a/src/ui/audio/mobile/MobileAudio.hpp b/src/ui/audio/mobile/MobileAudio.hpp
index 1f8ea20d..c49b24ae 100644
--- a/src/ui/audio/mobile/MobileAudio.hpp
+++ b/src/ui/audio/mobile/MobileAudio.hpp
@@ -17,13 +17,15 @@
* along with LMS. If not, see .
*/
-#ifndef UI_AUDIO_MOBILE_HPP
-#define UI_AUDIO_MOBILE_HPP
+#pragma once
#include
#include "audio/Audio.hpp"
+#include "MobilePlayQueueEvents.hpp"
+
+
namespace UserInterface {
namespace Mobile {
@@ -35,9 +37,11 @@ class Audio : public UserInterface::Audio
void search(std::string text);
private:
+
+ PlayQueueEvents _playQueueEvents;
+
};
} // namespace Mobile
} // namespace UserInterface
-#endif
diff --git a/src/ui/audio/mobile/MobilePlayQueueEvents.hpp b/src/ui/audio/mobile/MobilePlayQueueEvents.hpp
new file mode 100644
index 00000000..9fb80bf4
--- /dev/null
+++ b/src/ui/audio/mobile/MobilePlayQueueEvents.hpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Emeric Poupon
+ *
+ * This file is part of LMS.
+ *
+ * LMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LMS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LMS. If not, see .
+ */
+
+#pragma once
+
+#include
+#include "database/Types.hpp"
+
+namespace UserInterface {
+namespace Mobile {
+
+struct PlayQueueEvents
+{
+ Wt::Signal trackPlay;
+};
+
+
+} // namespace Mobile
+} // namespace UserInterface
diff --git a/src/ui/audio/mobile/PreviewSearchView.cpp b/src/ui/audio/mobile/PreviewSearchView.cpp
index 2385b8c9..38cb7a33 100644
--- a/src/ui/audio/mobile/PreviewSearchView.cpp
+++ b/src/ui/audio/mobile/PreviewSearchView.cpp
@@ -36,13 +36,13 @@ namespace Mobile {
using namespace Database;
-PreviewSearchView::PreviewSearchView(Wt::WContainerWidget* parent)
+PreviewSearchView::PreviewSearchView(PlayQueueEvents& events, Wt::WContainerWidget* parent)
{
const std::string pathPrefix = "/audio/search/preview";
ArtistSearch* artistSearch = new ArtistSearch("Artists", this);
ReleaseSearch* releaseSearch = new ReleaseSearch(this);
- TrackSearch* trackSearch = new TrackSearch(this);
+ TrackSearch* trackSearch = new TrackSearch(events, this);
artistSearch->showMore().connect(std::bind([=]
{
diff --git a/src/ui/audio/mobile/PreviewSearchView.hpp b/src/ui/audio/mobile/PreviewSearchView.hpp
index bdcc079f..fab0b4e9 100644
--- a/src/ui/audio/mobile/PreviewSearchView.hpp
+++ b/src/ui/audio/mobile/PreviewSearchView.hpp
@@ -21,6 +21,8 @@
#include
+#include "MobilePlayQueueEvents.hpp"
+
namespace UserInterface {
namespace Mobile {
@@ -28,7 +30,7 @@ class PreviewSearchView : public Wt::WContainerWidget
{
public:
- PreviewSearchView(Wt::WContainerWidget* parent = 0);
+ PreviewSearchView(PlayQueueEvents& events, Wt::WContainerWidget* parent = 0);
};
diff --git a/src/ui/audio/mobile/ReleaseSearch.hpp b/src/ui/audio/mobile/ReleaseSearch.hpp
index e2a7586e..3e82eb57 100644
--- a/src/ui/audio/mobile/ReleaseSearch.hpp
+++ b/src/ui/audio/mobile/ReleaseSearch.hpp
@@ -20,7 +20,6 @@
#pragma once
#include
-#include
#include
#include "database/SearchFilter.hpp"
diff --git a/src/ui/audio/mobile/ReleaseView.cpp b/src/ui/audio/mobile/ReleaseView.cpp
index a74bcd16..7557e8ac 100644
--- a/src/ui/audio/mobile/ReleaseView.cpp
+++ b/src/ui/audio/mobile/ReleaseView.cpp
@@ -33,8 +33,9 @@ namespace Mobile {
using namespace Database;
-ReleaseView::ReleaseView(Wt::WContainerWidget *parent)
-: Wt::WContainerWidget(parent)
+ReleaseView::ReleaseView(PlayQueueEvents& events, Wt::WContainerWidget *parent)
+: Wt::WContainerWidget(parent),
+ _events(events)
{
Wt::WTemplate* wrapper = new Wt::WTemplate(this);
wrapper->setTemplateText(Wt::WString::tr("wa-trackview-wrapper"));
@@ -97,23 +98,6 @@ ReleaseView::search(SearchFilter filter, size_t nb)
addResults(nb);
}
-static
-std::vector
-getTracks(SearchFilter filter, size_t offset, size_t nb, bool &moreResults)
-{
- std::vector tracks = Track::getByFilter(DboSession(), filter, offset, nb + 1);
-
- if (tracks.size() == nb + 1)
- {
- moreResults = true;
- tracks.pop_back();
- }
- else
- moreResults = false;
-
- return tracks;
-}
-
static Wt::WString
getArtistNameFromRelease(Release::pointer release)
{
@@ -132,7 +116,7 @@ ReleaseView::addResults(size_t nb)
Wt::Dbo::Transaction transaction(DboSession());
bool moreResults;
- std::vector tracks = getTracks(_filter, _nbTracks, nb, moreResults);
+ std::vector tracks = Track::getByFilter(DboSession(), _filter, _nbTracks, nb, moreResults);
for (Track::pointer track : tracks)
{
@@ -150,7 +134,7 @@ ReleaseView::addResults(size_t nb)
Wt::WImage *cover = new Wt::WImage();
cover->setStyleClass ("center-block img-responsive"); // TODO move to CSS?
- cover->setImageLink(Wt::WLink (LmsApp->getImageResource()->getReleaseUrl(release.id(), 512)));
+ cover->setImageLink(Wt::WLink (SessionImageResource()->getReleaseUrl(release.id(), 512)));
releaseContainer->bindWidget("cover", cover);
releaseContainer->bindString("artist-name", getArtistNameFromRelease(release), Wt::PlainText);
@@ -191,16 +175,13 @@ ReleaseView::addResults(size_t nb)
trackRes->bindString("track-name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText);
// TODO, display artist name for compilation releases?
- std::string format = track->getDuration().total_seconds() < 3600 ? "%M:%S" : "%H:%M:%S";
- trackRes->bindString("time", durationToString(track->getDuration(), format), Wt::PlainText);
-
Wt::WText *playBtn = new Wt::WText("Play", Wt::PlainText);
playBtn->setStyleClass("center-block"); // TODO move to CSS?
playBtn->clicked().connect(std::bind([=] {
- _sigTrackPlay.emit(track.id());
+ _events.trackPlay.emit(track.id());
}));
- trackRes->bindWidget("btn", playBtn);
+ trackRes->bindWidget("play-btn", playBtn);
_nbTracks++;
}
diff --git a/src/ui/audio/mobile/ReleaseView.hpp b/src/ui/audio/mobile/ReleaseView.hpp
index c2553793..bb590702 100644
--- a/src/ui/audio/mobile/ReleaseView.hpp
+++ b/src/ui/audio/mobile/ReleaseView.hpp
@@ -22,6 +22,8 @@
#include
#include
+#include "MobilePlayQueueEvents.hpp"
+
namespace UserInterface {
namespace Mobile {
@@ -31,22 +33,21 @@ class ReleaseView : public Wt::WContainerWidget
static Wt::WLink getLink(Database::Release::id_type id);
- ReleaseView(Wt::WContainerWidget *parent = 0);
+ ReleaseView(PlayQueueEvents& events, Wt::WContainerWidget *parent = 0);
void search(Database::SearchFilter filter, size_t nb);
// Slots
- Wt::Signal& trackPlay() { return _sigTrackPlay;}
Wt::Signal& moreTracksSelected() { return _sigMoreTracksSelected;}
private:
- Wt::Signal _sigTrackPlay;
Wt::Signal _sigMoreTracksSelected;
void clear(void);
void addResults(size_t nb);
+ PlayQueueEvents& _events;
Wt::WTemplate* _showMore;
Database::SearchFilter _filter;
diff --git a/src/ui/audio/mobile/TrackSearch.cpp b/src/ui/audio/mobile/TrackSearch.cpp
index ce0ecc8f..504ca3b9 100644
--- a/src/ui/audio/mobile/TrackSearch.cpp
+++ b/src/ui/audio/mobile/TrackSearch.cpp
@@ -33,8 +33,9 @@ namespace Mobile {
using namespace Database;
-TrackSearch::TrackSearch(Wt::WContainerWidget *parent)
-: Wt::WContainerWidget(parent)
+TrackSearch::TrackSearch(PlayQueueEvents& events, Wt::WContainerWidget *parent)
+: Wt::WContainerWidget(parent),
+ _events(events)
{
Wt::WTemplate* t = new Wt::WTemplate(this);
t->setTemplateText(Wt::WString::tr("wa-track-search"));
@@ -97,7 +98,7 @@ TrackSearch::addResults(size_t nb)
Wt::WText *playBtn = new Wt::WText("Play", Wt::PlainText);
playBtn->setStyleClass("center-block"); // TODO move to CSS?
playBtn->clicked().connect(std::bind([=] {
- _sigTrackPlay.emit(track.id());
+ _events.trackPlay.emit(track.id());
}));
res->bindWidget("btn", playBtn);
diff --git a/src/ui/audio/mobile/TrackSearch.hpp b/src/ui/audio/mobile/TrackSearch.hpp
index 8fe7fe3b..0a98d886 100644
--- a/src/ui/audio/mobile/TrackSearch.hpp
+++ b/src/ui/audio/mobile/TrackSearch.hpp
@@ -25,6 +25,8 @@
#include "database/SearchFilter.hpp"
#include "database/Types.hpp"
+#include "MobilePlayQueueEvents.hpp"
+
namespace UserInterface {
namespace Mobile {
@@ -32,22 +34,21 @@ class TrackSearch : public Wt::WContainerWidget
{
public:
- TrackSearch(Wt::WContainerWidget *parent = 0);
+ TrackSearch(PlayQueueEvents& events, Wt::WContainerWidget *parent = 0);
void addResults(size_t nb);
void search(Database::SearchFilter filter, size_t nb);
// Slots
Wt::Signal& showMore() { return _sigShowMore;}
- Wt::Signal& trackPlay() { return _sigTrackPlay;}
private:
Wt::Signal _sigShowMore;
- Wt::Signal _sigTrackPlay;
void clear(void);
+ PlayQueueEvents& _events;
Wt::WTemplate* _showMore;
Database::SearchFilter _filter;
Wt::WContainerWidget* _contents;
diff --git a/src/ui/audio/mobile/TrackSearchView.cpp b/src/ui/audio/mobile/TrackSearchView.cpp
index 3141d561..c7138452 100644
--- a/src/ui/audio/mobile/TrackSearchView.cpp
+++ b/src/ui/audio/mobile/TrackSearchView.cpp
@@ -34,9 +34,9 @@ namespace Mobile {
using namespace Database;
-TrackSearchView::TrackSearchView(Wt::WContainerWidget* parent)
+TrackSearchView::TrackSearchView(PlayQueueEvents& events, Wt::WContainerWidget* parent)
{
- TrackSearch* trackSearch = new TrackSearch(this);
+ TrackSearch* trackSearch = new TrackSearch(events, this);
trackSearch->showMore().connect(std::bind([=] {
trackSearch->addResults(SEARCH_NB_ITEMS);
}));
diff --git a/src/ui/audio/mobile/TrackSearchView.hpp b/src/ui/audio/mobile/TrackSearchView.hpp
index 67f560b8..602d9c56 100644
--- a/src/ui/audio/mobile/TrackSearchView.hpp
+++ b/src/ui/audio/mobile/TrackSearchView.hpp
@@ -20,6 +20,7 @@
#pragma once
#include
+#include
namespace UserInterface {
namespace Mobile {
@@ -28,7 +29,7 @@ class TrackSearchView : public Wt::WContainerWidget
{
public:
- TrackSearchView(Wt::WContainerWidget* parent = 0);
+ TrackSearchView(PlayQueueEvents& events, Wt::WContainerWidget* parent = 0);
};
diff --git a/src/ui/settings/Settings.cpp b/src/ui/settings/Settings.cpp
index c2e8d727..84e38fd3 100644
--- a/src/ui/settings/Settings.cpp
+++ b/src/ui/settings/Settings.cpp
@@ -55,6 +55,8 @@ Settings::Settings(Wt::WContainerWidget* parent)
Wt::WMenu *menu = new Wt::WMenu(contents, Wt::Vertical);
menu->setStyleClass("nav nav-pills nav-stacked submenu");
menu->setWidth(150);
+ menu->setInternalPathEnabled();
+ menu->setInternalBasePath("/settings/");
hLayout->addWidget(menu);
hLayout->addWidget(contents, 1);
@@ -68,22 +70,22 @@ Settings::Settings(Wt::WContainerWidget* parent)
userIsAdmin = CurrentUser()->isAdmin();
}
- menu->addItem("Audio", new AudioFormView());
+ menu->addItem("Audio", new AudioFormView())->setPathComponent("audio");
if (userIsAdmin)
{
- MediaDirectories* mediaDirectory = new MediaDirectories();
- mediaDirectory->changed().connect(this, &Settings::handleDatabaseDirectoriesChanged);
- menu->addItem("Media Folders", mediaDirectory);
+ MediaDirectories* mediaDirectories = new MediaDirectories();
+ mediaDirectories->changed().connect(this, &Settings::handleDatabaseDirectoriesChanged);
+ menu->addItem("Media Folders", mediaDirectories)->setPathComponent("mediadirectories");
DatabaseFormView* databaseFormView = new DatabaseFormView();
databaseFormView->changed().connect(this, &Settings::restartDatabaseUpdateService);
- menu->addItem("Database", databaseFormView);
+ menu->addItem("Database", databaseFormView)->setPathComponent("database");
- menu->addItem("Users", new Users());
+ menu->addItem("Users", new Users())->setPathComponent("users");
}
else
{
- menu->addItem("Account", new AccountFormView(userId));
+ menu->addItem("Account", new AccountFormView(userId))->setPathComponent("account");
}
}