diff --git a/approot/artists.xml b/approot/artists.xml index 43dcc37c..c5c70050 100644 --- a/approot/artists.xml +++ b/approot/artists.xml @@ -3,6 +3,10 @@ + + ${most-played-artists} @@ -16,6 +20,10 @@ ${show-more} + + ${name} + +
${nb-release} diff --git a/approot/messages.xml b/approot/messages.xml index 75297f4f..cf0918e3 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -59,6 +59,7 @@ Add filter Artists +Most played artists Albums Search... Show more diff --git a/src/Makefile.am b/src/Makefile.am index 663e56cc..fd9f89d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ lms_SOURCES = \ $(srcdir)/database/ScanSettings.cpp \ $(srcdir)/database/SqlQuery.cpp \ $(srcdir)/database/Track.cpp \ + $(srcdir)/database/TrackStats.cpp \ $(srcdir)/database/User.cpp \ $(srcdir)/image/Image.cpp \ $(srcdir)/metadata/AvFormat.cpp \ diff --git a/src/database/DatabaseHandler.cpp b/src/database/DatabaseHandler.cpp index 7d3eb8d5..f835c09f 100644 --- a/src/database/DatabaseHandler.cpp +++ b/src/database/DatabaseHandler.cpp @@ -41,6 +41,7 @@ #include "Release.hpp" #include "ScanSettings.hpp" #include "Track.hpp" +#include "TrackStats.hpp" namespace Database { @@ -106,6 +107,7 @@ Handler::Handler(Wt::Dbo::SqlConnectionPool& connectionPool) _session.mapClass("release"); _session.mapClass("setting"); _session.mapClass("track"); + _session.mapClass("track_stats"); _session.mapClass("scan_settings"); diff --git a/src/database/Track.hpp b/src/database/Track.hpp index e1acb8ee..c63de183 100644 --- a/src/database/Track.hpp +++ b/src/database/Track.hpp @@ -35,10 +35,11 @@ namespace Database { class Artist; -class Release; -class PlaylistEntry; class Cluster; class ClusterType; +class PlaylistEntry; +class Release; +class TrackStats; class Track : public Wt::Dbo::Dbo { @@ -143,6 +144,7 @@ class Track : public Wt::Dbo::Dbo Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade); Wt::Dbo::hasMany(a, _clusters, Wt::Dbo::ManyToMany, "track_cluster", "", Wt::Dbo::OnDeleteCascade); Wt::Dbo::hasMany(a, _playlistEntries, Wt::Dbo::ManyToOne, "track"); + Wt::Dbo::hasMany(a, _stats, Wt::Dbo::ManyToOne, "track"); } private: @@ -170,8 +172,9 @@ class Track : public Wt::Dbo::Dbo Wt::Dbo::ptr _artist; Wt::Dbo::ptr _release; - Wt::Dbo::collection< Wt::Dbo::ptr > _clusters; - Wt::Dbo::collection< Wt::Dbo::ptr > _playlistEntries; + Wt::Dbo::collection> _clusters; + Wt::Dbo::collection> _playlistEntries; + Wt::Dbo::collection> _stats; }; diff --git a/src/ui/PlayQueueView.cpp b/src/ui/PlayQueueView.cpp index 6721805a..6f124884 100644 --- a/src/ui/PlayQueueView.cpp +++ b/src/ui/PlayQueueView.cpp @@ -28,6 +28,7 @@ #include "utils/Logger.hpp" #include "database/Playlist.hpp" +#include "database/TrackStats.hpp" #include "LmsApplication.hpp" @@ -116,7 +117,12 @@ PlayQueue::play(std::size_t pos) addRadioTrack(); _trackPos = pos; - trackId = playlist->getEntry(*_trackPos)->getTrack().id(); + auto track = playlist->getEntry(*_trackPos)->getTrack(); + + trackId = track.id(); + + Database::TrackStats::get(LmsApp->getDboSession(), track, LmsApp->getCurrentUser()).modify()->incPlayCount(); + updateCurrentTrack(true); } diff --git a/src/ui/explore/ArtistsView.cpp b/src/ui/explore/ArtistsView.cpp index 201cbc65..d7e32bf0 100644 --- a/src/ui/explore/ArtistsView.cpp +++ b/src/ui/explore/ArtistsView.cpp @@ -25,6 +25,7 @@ #include "database/Artist.hpp" #include "database/Setting.hpp" +#include "database/TrackStats.hpp" #include "utils/Logger.hpp" #include "utils/Utils.hpp" @@ -47,6 +48,7 @@ Artists::Artists(Filters* filters) _search->textInput().connect(this, &Artists::refresh); _artistsContainer = bindNew("artists"); + _mostPlayedArtistsContainer = bindNew("most-played-artists"); _showMore = bindNew("show-more", Wt::WString::tr("Lms.Explore.template.show-more")); _showMore->addFunction("tr", &Wt::WTemplate::Functions::tr); @@ -57,10 +59,27 @@ Artists::Artists(Filters* filters) })); refresh(); + refreshMostPlayed(); filters->updated().connect(this, &Artists::refresh); } +void +Artists::refreshMostPlayed() +{ + _mostPlayedArtistsContainer->clear(); + + Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); + auto artists = TrackStats::getMostPlayedArtists(LmsApp->getDboSession(), LmsApp->getCurrentUser(), 5); + + for (auto artist : artists) + { + Wt::WTemplate* entry = _mostPlayedArtistsContainer->addNew(Wt::WString::tr("Lms.Explore.Artists.template.most-played-entry")); + + entry->bindWidget("name", LmsApplication::createArtistAnchor(artist)); + } +} + void Artists::refresh() { diff --git a/src/ui/explore/ArtistsView.hpp b/src/ui/explore/ArtistsView.hpp index 7aa9bb0c..78c5b019 100644 --- a/src/ui/explore/ArtistsView.hpp +++ b/src/ui/explore/ArtistsView.hpp @@ -39,6 +39,7 @@ class Artists : public Wt::WTemplate Wt::Signal artistPlay; private: + void refreshMostPlayed(); void refresh(); void addSome(); @@ -46,6 +47,7 @@ class Artists : public Wt::WTemplate Wt::WTemplate* _showMore; Wt::WLineEdit* _search; Wt::WContainerWidget* _artistsContainer; + Wt::WContainerWidget* _mostPlayedArtistsContainer; }; } // namespace UserInterface