Move the top/recently added parts into a dedicated panel on the left
This commit is contained in:
@@ -27,6 +27,7 @@ lms_approot_DATA = \
|
||||
approot/admin-initwizard.xml \
|
||||
approot/artist.xml \
|
||||
approot/artists.xml \
|
||||
approot/artistsinfo.xml \
|
||||
approot/explore.xml \
|
||||
approot/login.xml \
|
||||
approot/mediaplayer.xml \
|
||||
@@ -35,6 +36,7 @@ lms_approot_DATA = \
|
||||
approot/playqueue.xml \
|
||||
approot/release.xml \
|
||||
approot/releases.xml \
|
||||
approot/releasesinfo.xml \
|
||||
approot/settings.xml \
|
||||
approot/templates.xml \
|
||||
approot/tracks.xml
|
||||
|
||||
@@ -3,16 +3,6 @@
|
||||
<!--FORMS message blocks-->
|
||||
|
||||
<message id="Lms.Explore.Artists.template">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.most-played-artists}</h2>
|
||||
</div>
|
||||
${most-played-artists}
|
||||
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.recently-added-artists}</h2>
|
||||
</div>
|
||||
${recently-added-artists}
|
||||
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.artists}</h2>
|
||||
</div>
|
||||
@@ -26,10 +16,6 @@
|
||||
${show-more}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Artists.template.compact-entry">
|
||||
${name}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Artists.template.entry">
|
||||
<div class="list-group-item">
|
||||
<span class="badge">${nb-release}</span>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
<!--FORMS message blocks-->
|
||||
|
||||
<message id="Lms.Explore.ArtistsInfo.template">
|
||||
<div class="hidden-xs">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.ArtistsInfo.most-played}</h2>
|
||||
</div>
|
||||
${most-played}
|
||||
</div>
|
||||
|
||||
<div class="hidden-xs">
|
||||
<div class="page-header hidden-xs">
|
||||
<h2>${tr:Lms.Explore.ArtistsInfo.recently-added}</h2>
|
||||
</div>
|
||||
${recently-added}
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.ArtistsInfo.template.entry">
|
||||
${name}
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
+11
-1
@@ -2,8 +2,15 @@
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
|
||||
<message id="Lms.Explore.template">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
${filters}
|
||||
${info}
|
||||
</div>
|
||||
<div class="col-sm-8 col-sm-offset-1">
|
||||
${contents}
|
||||
</div>
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.template.show-more">
|
||||
@@ -12,7 +19,10 @@
|
||||
|
||||
<message id="Lms.Explore.template.filters">
|
||||
<div class="form-group">
|
||||
${add-filter}${clusters}
|
||||
<div class="page-header">
|
||||
<h3>${tr:Lms.Explore.filters} ${add-filter class="btn-primary"}</h3>
|
||||
</div>
|
||||
${clusters}
|
||||
</div>
|
||||
</message>
|
||||
|
||||
|
||||
+10
-7
@@ -62,14 +62,9 @@
|
||||
<message id="Lms.Auth.welcome">Welcome!</message>
|
||||
|
||||
<!--Explore-->
|
||||
<message id="Lms.Explore.add-filter">Add filter</message>
|
||||
<message id="Lms.Explore.add-filter">Add</message>
|
||||
<message id="Lms.Explore.artists">Artists</message>
|
||||
<message id="Lms.Explore.most-played-artists">Top artists</message>
|
||||
<message id="Lms.Explore.most-played-releases">Top albums</message>
|
||||
<message id="Lms.Explore.recently-added-artists">Recently added artists</message>
|
||||
<message id="Lms.Explore.recently-added-releases">Recently added albums</message>
|
||||
<message id="Lms.Explore.recently-played-artists">Recently played artists</message>
|
||||
<message id="Lms.Explore.recently-played-releases">Recently played albums</message>
|
||||
<message id="Lms.Explore.filters">Filters</message>
|
||||
<message id="Lms.Explore.releases">Albums</message>
|
||||
<message id="Lms.Explore.search-placeholder">Search...</message>
|
||||
<message id="Lms.Explore.show-more">Show more</message>
|
||||
@@ -78,6 +73,14 @@
|
||||
<message id="Lms.Explore.value">Value</message>
|
||||
<message id="Lms.Explore.various-artists">Various artists</message>
|
||||
|
||||
<!--Explore:Artists-->
|
||||
<message id="Lms.Explore.ArtistsInfo.recently-added">Recently added</message>
|
||||
<message id="Lms.Explore.ArtistsInfo.most-played">Top artists</message>
|
||||
|
||||
<!--Explore:Releases-->
|
||||
<message id="Lms.Explore.ReleasesInfo.recently-added">Recently added</message>
|
||||
<message id="Lms.Explore.ReleasesInfo.most-played">Top releases</message>
|
||||
|
||||
<!--Playque-->
|
||||
<message id="Lms.PlayQueue.nb-tracks">{1} tracks</message>
|
||||
<message id="Lms.PlayQueue.nb-tracks-added">Added {1} tracks</message>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
<!--FORMS message blocks-->
|
||||
|
||||
<message id="Lms.PlayHistory.template">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.PlayHistory.playhistory}</h2>
|
||||
</div>
|
||||
${entries}
|
||||
${show-more}
|
||||
</message>
|
||||
|
||||
<message id="Lms.PlayHistory.template.entry">
|
||||
${name} ${<if-has-release>}${release-name}${</if-has-release>} ${<if-has-artist>}${artist-name}${</if-has-artist>}
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
@@ -3,16 +3,6 @@
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
|
||||
<message id="Lms.Explore.Releases.template">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.most-played-releases}</h2>
|
||||
</div>
|
||||
${most-played-releases}
|
||||
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.recently-added-releases}</h2>
|
||||
</div>
|
||||
${recently-added-releases}
|
||||
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.releases}</h2>
|
||||
</div>
|
||||
@@ -34,12 +24,6 @@
|
||||
<i class="fa fa-plus"></i>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Releases.template.compact-entry">
|
||||
${cover}
|
||||
${release-name}
|
||||
${<if-has-artist>}${artist-name}${</if-has-artist>}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Releases.template.entry">
|
||||
<div class="media list-group-item">
|
||||
<div class="pull-left media-middle">
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
|
||||
<message id="Lms.Explore.ReleasesInfo.template">
|
||||
<div class="hidden-xs">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.ReleasesInfo.most-played}</h2>
|
||||
</div>
|
||||
${most-played}
|
||||
</div>
|
||||
|
||||
<div class="hidden-xs">
|
||||
<div class="page-header">
|
||||
<h2>${tr:Lms.Explore.ReleasesInfo.recently-added}</h2>
|
||||
</div>
|
||||
${recently-added}
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.ReleasesInfo.template.entry">
|
||||
${cover}
|
||||
${release-name}
|
||||
${<if-has-artist>}${artist-name}${</if-has-artist>}
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
@@ -32,9 +32,11 @@ lms_SOURCES = \
|
||||
$(srcdir)/ui/common/Validators.cpp \
|
||||
$(srcdir)/ui/explore/ArtistView.cpp \
|
||||
$(srcdir)/ui/explore/ArtistsView.cpp \
|
||||
$(srcdir)/ui/explore/ArtistsInfoView.cpp \
|
||||
$(srcdir)/ui/explore/Explore.cpp \
|
||||
$(srcdir)/ui/explore/Filters.cpp \
|
||||
$(srcdir)/ui/explore/ReleasesView.cpp \
|
||||
$(srcdir)/ui/explore/ReleasesInfoView.cpp \
|
||||
$(srcdir)/ui/explore/ReleaseView.cpp \
|
||||
$(srcdir)/ui/explore/TracksView.cpp \
|
||||
$(srcdir)/ui/resource/ImageResource.cpp \
|
||||
|
||||
@@ -95,6 +95,7 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
|
||||
messageResourceBundle().use(appRoot() + "admin-initwizard");
|
||||
messageResourceBundle().use(appRoot() + "artist");
|
||||
messageResourceBundle().use(appRoot() + "artists");
|
||||
messageResourceBundle().use(appRoot() + "artistsinfo");
|
||||
messageResourceBundle().use(appRoot() + "explore");
|
||||
messageResourceBundle().use(appRoot() + "login");
|
||||
messageResourceBundle().use(appRoot() + "mediaplayer");
|
||||
@@ -103,6 +104,7 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
|
||||
messageResourceBundle().use(appRoot() + "playhistory");
|
||||
messageResourceBundle().use(appRoot() + "release");
|
||||
messageResourceBundle().use(appRoot() + "releases");
|
||||
messageResourceBundle().use(appRoot() + "releasesinfo");
|
||||
messageResourceBundle().use(appRoot() + "settings");
|
||||
messageResourceBundle().use(appRoot() + "tracks");
|
||||
messageResourceBundle().use(appRoot() + "templates");
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ArtistsInfoView.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WLocalDateTime.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addEntries(Wt::WContainerWidget *container, const std::vector<Artist::pointer>& artists)
|
||||
{
|
||||
for (auto artist : artists)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.ArtistsInfo.template.entry"));
|
||||
|
||||
entry->bindWidget("name", LmsApplication::createArtistAnchor(artist));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ArtistsInfo::ArtistsInfo()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ArtistsInfo.template"))
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played");
|
||||
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added");
|
||||
|
||||
refreshMostPlayed();
|
||||
refreshRecentlyAdded();
|
||||
}
|
||||
|
||||
void
|
||||
ArtistsInfo::refreshRecentlyAdded()
|
||||
{
|
||||
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
auto artists = Artist::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addEntries(_recentlyAddedContainer, artists);
|
||||
}
|
||||
|
||||
void
|
||||
ArtistsInfo::refreshMostPlayed()
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
auto artists = LmsApp->getUser()->getPlayedTrackList()->getTopArtists(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addEntries(_mostPlayedContainer, artists);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ArtistsInfo : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ArtistsInfo();
|
||||
|
||||
void refreshRecentlyAdded();
|
||||
void refreshMostPlayed();
|
||||
|
||||
private:
|
||||
Wt::WContainerWidget* _mostPlayedContainer;
|
||||
Wt::WContainerWidget* _recentlyAddedContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
@@ -35,22 +34,6 @@
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addCompactEntries(Wt::WContainerWidget *container, const std::vector<Artist::pointer>& artists)
|
||||
{
|
||||
for (auto artist : artists)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artists.template.compact-entry"));
|
||||
|
||||
entry->bindWidget("name", LmsApplication::createArtistAnchor(artist));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
Artists::Artists(Filters* filters)
|
||||
@@ -64,9 +47,6 @@ Artists::Artists(Filters* filters)
|
||||
_search->textInput().connect(this, &Artists::refresh);
|
||||
|
||||
_container = bindNew<Wt::WContainerWidget>("artists");
|
||||
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played-artists");
|
||||
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added-artists");
|
||||
_recentlyPlayedContainer = bindNew<Wt::WContainerWidget>("recently-played-artists");
|
||||
|
||||
_showMore = bindNew<Wt::WTemplate>("show-more", Wt::WString::tr("Lms.Explore.template.show-more"));
|
||||
_showMore->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
@@ -77,34 +57,10 @@ Artists::Artists(Filters* filters)
|
||||
}));
|
||||
|
||||
refresh();
|
||||
refreshMostPlayed();
|
||||
refreshRecentlyAdded();
|
||||
|
||||
filters->updated().connect(this, &Artists::refresh);
|
||||
}
|
||||
|
||||
void
|
||||
Artists::refreshRecentlyAdded()
|
||||
{
|
||||
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
auto artists = Artist::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addCompactEntries(_recentlyAddedContainer, artists);
|
||||
}
|
||||
|
||||
void
|
||||
Artists::refreshMostPlayed()
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
auto artists = LmsApp->getUser()->getPlayedTrackList()->getTopArtists(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addCompactEntries(_mostPlayedContainer, artists);
|
||||
}
|
||||
|
||||
void
|
||||
Artists::refresh()
|
||||
{
|
||||
|
||||
@@ -38,9 +38,6 @@ class Artists : public Wt::WTemplate
|
||||
Wt::Signal<Database::IdType> artistAdd;
|
||||
Wt::Signal<Database::IdType> artistPlay;
|
||||
|
||||
void refreshRecentlyAdded();
|
||||
void refreshMostPlayed();
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
void addSome();
|
||||
@@ -49,9 +46,6 @@ class Artists : public Wt::WTemplate
|
||||
Wt::WTemplate* _showMore;
|
||||
Wt::WLineEdit* _search;
|
||||
Wt::WContainerWidget* _container;
|
||||
Wt::WContainerWidget* _mostPlayedContainer;
|
||||
Wt::WContainerWidget* _recentlyAddedContainer;
|
||||
Wt::WContainerWidget* _recentlyPlayedContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
+79
-27
@@ -29,26 +29,29 @@
|
||||
|
||||
#include "Filters.hpp"
|
||||
#include "ArtistsView.hpp"
|
||||
#include "ArtistsInfoView.hpp"
|
||||
#include "ArtistView.hpp"
|
||||
#include "ReleasesView.hpp"
|
||||
#include "ReleasesInfoView.hpp"
|
||||
#include "ReleaseView.hpp"
|
||||
#include "TracksView.hpp"
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
namespace {
|
||||
|
||||
enum IdxRoot
|
||||
void
|
||||
handleContentsPathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
enum Idx
|
||||
{
|
||||
IdxArtists = 0,
|
||||
IdxArtist,
|
||||
IdxReleases,
|
||||
IdxRelease,
|
||||
IdxTracks,
|
||||
};
|
||||
};
|
||||
|
||||
static void
|
||||
handlePathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
static const std::map<std::string, int> indexes =
|
||||
{
|
||||
{ "/artists", IdxArtists },
|
||||
@@ -70,65 +73,114 @@ handlePathChange(Wt::WStackedWidget* stack)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handleInfoPathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
enum Idx
|
||||
{
|
||||
IdxArtists = 0,
|
||||
IdxReleases,
|
||||
IdxEmpty,
|
||||
};
|
||||
|
||||
static const std::map<std::string, int> indexes =
|
||||
{
|
||||
{ "/artists", IdxArtists },
|
||||
{ "/artist", IdxArtists },
|
||||
{ "/releases", IdxReleases },
|
||||
{ "/release", IdxReleases },
|
||||
{ "/tracks", IdxEmpty },
|
||||
};
|
||||
|
||||
LMS_LOG(UI, DEBUG) << "Internal path changed to '" << wApp->internalPath() << "'";
|
||||
|
||||
for (auto index : indexes)
|
||||
{
|
||||
if (wApp->internalPathMatches(index.first))
|
||||
{
|
||||
stack->setCurrentIndex(index.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Explore::Explore()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.template"))
|
||||
{
|
||||
addFunction("tr", &Functions::tr);
|
||||
|
||||
_filters = bindNew<Filters>("filters");
|
||||
|
||||
// Contents
|
||||
Wt::WStackedWidget* stack = bindNew<Wt::WStackedWidget>("contents");
|
||||
Wt::WStackedWidget* contentsStack = bindNew<Wt::WStackedWidget>("contents");
|
||||
|
||||
auto artists = std::make_unique<Artists>(_filters);
|
||||
auto artists_raw = artists.get();
|
||||
artists->artistAdd.connect(this, &Explore::handleArtistAdd);
|
||||
artists->artistPlay.connect(this, &Explore::handleArtistPlay);
|
||||
stack->addWidget(std::move(artists));
|
||||
contentsStack->addWidget(std::move(artists));
|
||||
|
||||
auto artist = std::make_unique<Artist>(_filters);
|
||||
artist->artistAdd.connect(this, &Explore::handleArtistAdd);
|
||||
artist->artistPlay.connect(this, &Explore::handleArtistPlay);
|
||||
artist->releaseAdd.connect(this, &Explore::handleReleaseAdd);
|
||||
artist->releasePlay.connect(this, &Explore::handleReleasePlay);
|
||||
stack->addWidget(std::move(artist));
|
||||
contentsStack->addWidget(std::move(artist));
|
||||
|
||||
auto releases = std::make_unique<Releases>(_filters);
|
||||
auto releases_raw = releases.get();
|
||||
releases->releaseAdd.connect(this, &Explore::handleReleaseAdd);
|
||||
releases->releasePlay.connect(this, &Explore::handleReleasePlay);
|
||||
stack->addWidget(std::move(releases));
|
||||
contentsStack->addWidget(std::move(releases));
|
||||
|
||||
auto release = std::make_unique<Release>(_filters);
|
||||
release->releaseAdd.connect(this, &Explore::handleReleaseAdd);
|
||||
release->releasePlay.connect(this, &Explore::handleReleasePlay);
|
||||
release->trackAdd.connect(this, &Explore::handleTrackAdd);
|
||||
release->trackPlay.connect(this, &Explore::handleTrackPlay);
|
||||
stack->addWidget(std::move(release));
|
||||
|
||||
_dbChanged.connect([=]
|
||||
{
|
||||
artists_raw->refreshRecentlyAdded();
|
||||
releases_raw->refreshRecentlyAdded();
|
||||
});
|
||||
|
||||
_trackPlayed.connect([=]
|
||||
{
|
||||
artists_raw->refreshMostPlayed();
|
||||
releases_raw->refreshMostPlayed();
|
||||
});
|
||||
contentsStack->addWidget(std::move(release));
|
||||
|
||||
auto tracks = std::make_unique<Tracks>(_filters);
|
||||
tracks->trackAdd.connect(this, &Explore::handleTrackAdd);
|
||||
tracks->trackPlay.connect(this, &Explore::handleTrackPlay);
|
||||
tracks->tracksAdd.connect(this, &Explore::handleTracksAdd);
|
||||
tracks->tracksPlay.connect(this, &Explore::handleTracksPlay);
|
||||
stack->addWidget(std::move(tracks));
|
||||
contentsStack->addWidget(std::move(tracks));
|
||||
|
||||
// Info
|
||||
Wt::WStackedWidget* infoStack = bindNew<Wt::WStackedWidget>("info");
|
||||
|
||||
auto artistsInfo = std::make_unique<ArtistsInfo>();
|
||||
auto artistsInfoRaw = artistsInfo.get();
|
||||
infoStack->addWidget(std::move(artistsInfo));
|
||||
|
||||
auto releasesInfo = std::make_unique<ReleasesInfo>();
|
||||
auto releasesInfoRaw = releasesInfo.get();
|
||||
infoStack->addWidget(std::move(releasesInfo));
|
||||
|
||||
infoStack->addWidget(std::make_unique<Wt::WContainerWidget>());
|
||||
|
||||
_dbChanged.connect([=]
|
||||
{
|
||||
artistsInfoRaw->refreshRecentlyAdded();
|
||||
releasesInfoRaw->refreshRecentlyAdded();
|
||||
});
|
||||
|
||||
_trackPlayed.connect([=]
|
||||
{
|
||||
artistsInfoRaw->refreshMostPlayed();
|
||||
releasesInfoRaw->refreshMostPlayed();
|
||||
});
|
||||
|
||||
|
||||
wApp->internalPathChanged().connect(std::bind([=]
|
||||
{
|
||||
handlePathChange(stack);
|
||||
handleContentsPathChange(contentsStack);
|
||||
handleInfoPathChange(infoStack);
|
||||
}));
|
||||
|
||||
handlePathChange(stack);
|
||||
handleContentsPathChange(contentsStack);
|
||||
handleInfoPathChange(infoStack);
|
||||
}
|
||||
|
||||
// TODO SQL this?
|
||||
|
||||
@@ -142,6 +142,8 @@ Filters::add(Database::IdType clusterId)
|
||||
Filters::Filters()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.template.filters"))
|
||||
{
|
||||
addFunction("tr", &Functions::tr);
|
||||
|
||||
// Filters
|
||||
Wt::WPushButton *addFilterBtn = bindNew<Wt::WPushButton>("add-filter", Wt::WText::tr("Lms.Explore.add-filter"));
|
||||
addFilterBtn->clicked().connect(this, &Filters::showDialog);
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ReleasesInfoView.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WImage.h>
|
||||
#include <Wt/WLocalDateTime.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Release.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "resource/ImageResource.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addEntries(Wt::WContainerWidget* container, const std::vector<Release::pointer>& releases)
|
||||
{
|
||||
for (auto release : releases)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.ReleasesInfo.template.entry"));
|
||||
|
||||
entry->bindWidget("release-name", LmsApplication::createReleaseAnchor(release));
|
||||
|
||||
Wt::WAnchor* anchor = entry->bindWidget("cover", LmsApplication::createReleaseAnchor(release, false));
|
||||
auto cover = std::make_unique<Wt::WImage>();
|
||||
cover->setImageLink(LmsApp->getImageResource()->getReleaseUrl(release.id(), 128));
|
||||
anchor->setImage(std::move(cover));
|
||||
|
||||
auto artists = release->getArtists();
|
||||
if (artists.size() > 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindString("artist-name", Wt::WString::tr("Lms.Explore.various-artists"));
|
||||
}
|
||||
else if (artists.size() == 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindWidget("artist-name", LmsApplication::createArtistAnchor(artists.front()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
ReleasesInfo::ReleasesInfo()
|
||||
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.ReleasesInfo.template"))
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played");
|
||||
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added");
|
||||
|
||||
refreshRecentlyAdded();
|
||||
refreshMostPlayed();
|
||||
}
|
||||
|
||||
void
|
||||
ReleasesInfo::refreshRecentlyAdded()
|
||||
{
|
||||
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
auto releases = Release::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addEntries(_recentlyAddedContainer, releases);
|
||||
}
|
||||
|
||||
void
|
||||
ReleasesInfo::refreshMostPlayed()
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
auto releases = LmsApp->getUser()->getPlayedTrackList()->getTopReleases(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addEntries(_mostPlayedContainer, releases);
|
||||
}
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
class ReleasesInfo : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
ReleasesInfo();
|
||||
|
||||
void refreshRecentlyAdded();
|
||||
void refreshMostPlayed();
|
||||
|
||||
private:
|
||||
Wt::WContainerWidget* _mostPlayedContainer;
|
||||
Wt::WContainerWidget* _recentlyAddedContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
@@ -18,15 +18,13 @@
|
||||
*/
|
||||
|
||||
#include "ReleasesView.hpp"
|
||||
#include <Wt/WServer.h>
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
#include <Wt/WImage.h>
|
||||
#include <Wt/WLocalDateTime.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Release.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
@@ -38,39 +36,6 @@
|
||||
|
||||
using namespace Database;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace UserInterface;
|
||||
|
||||
void addCompactEntries(Wt::WContainerWidget* container, const std::vector<Release::pointer>& releases)
|
||||
{
|
||||
for (auto release : releases)
|
||||
{
|
||||
Wt::WTemplate* entry = container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Releases.template.compact-entry"));
|
||||
|
||||
entry->bindWidget("release-name", LmsApplication::createReleaseAnchor(release));
|
||||
|
||||
Wt::WAnchor* anchor = entry->bindWidget("cover", LmsApplication::createReleaseAnchor(release, false));
|
||||
auto cover = std::make_unique<Wt::WImage>();
|
||||
cover->setImageLink(LmsApp->getImageResource()->getReleaseUrl(release.id(), 128));
|
||||
anchor->setImage(std::move(cover));
|
||||
|
||||
auto artists = release->getArtists();
|
||||
if (artists.size() > 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindString("artist-name", Wt::WString::tr("Lms.Explore.various-artists"));
|
||||
}
|
||||
else if (artists.size() == 1)
|
||||
{
|
||||
entry->setCondition("if-has-artist", true);
|
||||
entry->bindWidget("artist-name", LmsApplication::createArtistAnchor(artists.front()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace UserInterface {
|
||||
|
||||
Releases::Releases(Filters* filters)
|
||||
@@ -84,9 +49,6 @@ _filters(filters)
|
||||
_search->textInput().connect(this, &Releases::refresh);
|
||||
|
||||
_container = bindNew<Wt::WContainerWidget>("releases");
|
||||
_mostPlayedContainer = bindNew<Wt::WContainerWidget>("most-played-releases");
|
||||
_recentlyAddedContainer = bindNew<Wt::WContainerWidget>("recently-added-releases");
|
||||
_recentlyPlayedContainer = bindNew<Wt::WContainerWidget>("recently-played-releases");
|
||||
|
||||
_showMore = bindNew<Wt::WTemplate>("show-more", Wt::WString::tr("Lms.Explore.show-more"));
|
||||
_showMore->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
@@ -95,37 +57,11 @@ _filters(filters)
|
||||
addSome();
|
||||
}));
|
||||
|
||||
refreshRecentlyAdded();
|
||||
refreshMostPlayed();
|
||||
refresh();
|
||||
|
||||
filters->updated().connect(this, &Releases::refresh);
|
||||
}
|
||||
|
||||
void
|
||||
Releases::refreshRecentlyAdded()
|
||||
{
|
||||
auto after = Wt::WLocalDateTime::currentServerDateTime().toUTC().addMonths(-1);
|
||||
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
auto releases = Release::getLastAdded(LmsApp->getDboSession(), after, 5);
|
||||
|
||||
_recentlyAddedContainer->clear();
|
||||
addCompactEntries(_recentlyAddedContainer, releases);
|
||||
}
|
||||
|
||||
void
|
||||
Releases::refreshMostPlayed()
|
||||
{
|
||||
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
|
||||
|
||||
auto releases = LmsApp->getUser()->getPlayedTrackList()->getTopReleases(5);
|
||||
|
||||
_mostPlayedContainer->clear();
|
||||
addCompactEntries(_mostPlayedContainer, releases);
|
||||
}
|
||||
|
||||
void
|
||||
Releases::refresh()
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WLineEdit.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
@@ -38,9 +37,6 @@ class Releases : public Wt::WTemplate
|
||||
Wt::Signal<Database::IdType> releaseAdd;
|
||||
Wt::Signal<Database::IdType> releasePlay;
|
||||
|
||||
void refreshRecentlyAdded();
|
||||
void refreshMostPlayed();
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
void addSome();
|
||||
@@ -49,9 +45,6 @@ class Releases : public Wt::WTemplate
|
||||
Wt::WTemplate* _showMore;
|
||||
Wt::WLineEdit* _search;
|
||||
Wt::WContainerWidget* _container;
|
||||
Wt::WContainerWidget* _mostPlayedContainer;
|
||||
Wt::WContainerWidget* _recentlyAddedContainer;
|
||||
Wt::WContainerWidget* _recentlyPlayedContainer;
|
||||
};
|
||||
|
||||
} // namespace UserInterface
|
||||
|
||||
Reference in New Issue
Block a user