diff --git a/approot/messages.xml b/approot/messages.xml
index d60cd82c..dad967c1 100644
--- a/approot/messages.xml
+++ b/approot/messages.xml
@@ -128,8 +128,11 @@
Recently added
Recently played
Albums
+Star
+Starred
Tracks
Type
+Unstar
Value
Various artists
diff --git a/approot/messages_fr.xml b/approot/messages_fr.xml
index 310fe585..955938ae 100644
--- a/approot/messages_fr.xml
+++ b/approot/messages_fr.xml
@@ -128,8 +128,11 @@
Ajoutés récemment
Joués récemment
Albums
+Ajouter aux favoris
+Favoris
Pistes
Type
+Retirer des favoris
Valeur
Artistes divers
diff --git a/src/libs/database/impl/Artist.cpp b/src/libs/database/impl/Artist.cpp
index 267c0eee..2f41aa80 100644
--- a/src/libs/database/impl/Artist.cpp
+++ b/src/libs/database/impl/Artist.cpp
@@ -303,7 +303,11 @@ Artist::getByFilter(Session& session,
}
std::vector
-Artist::getLastWritten(Session& session, std::optional after, const std::set& clusters, std::optional linkType, std::optional range, bool& moreResults)
+Artist::getLastWritten(Session& session,
+ std::optional after,
+ const std::set& clusters,
+ std::optional linkType,
+ std::optional range, bool& moreResults)
{
session.checkSharedLocked();
@@ -330,6 +334,58 @@ Artist::getLastWritten(Session& session, std::optional after, con
return std::vector(res.begin(), res.end());
}
+std::vector
+Artist::getStarred(Session& session,
+ User::pointer user,
+ const std::set& clusters,
+ std::optional linkType,
+ SortMethod sortMethod,
+ std::optional range, bool& moreResults)
+{
+ session.checkSharedLocked();
+
+ auto query {createQuery(session, "SELECT DISTINCT a from artist a", clusters, {}, linkType)};
+
+ {
+ std::ostringstream oss;
+ oss << "a.id IN (SELECT DISTINCT a.id FROM artist a"
+ " INNER JOIN user_artist_starred uas ON uas.artist_id = a.id"
+ " INNER JOIN user u ON u.id = uas.user_id WHERE u.id = ?)";
+
+ query.bind(user.id());
+ query.where(oss.str());
+ }
+
+ switch (sortMethod)
+ {
+ case Artist::SortMethod::None:
+ break;
+ case Artist::SortMethod::ByName:
+ query.orderBy("name COLLATE NOCASE");
+ break;
+ case Artist::SortMethod::BySortName:
+ query.orderBy("sort_name COLLATE NOCASE");
+ break;
+ }
+
+ Wt::Dbo::collection collection = query
+ .groupBy("a.id")
+ .limit(range ? static_cast(range->limit) + 1 : -1)
+ .offset(range ? static_cast(range->offset) : -1);
+
+ auto res {std::vector(collection.begin(), collection.end())};
+
+ if (range && res.size() == static_cast(range->limit) + 1)
+ {
+ moreResults = true;
+ res.pop_back();
+ }
+ else
+ moreResults = false;
+
+ return std::vector(res.begin(), res.end());
+}
+
std::vector>
Artist::getReleases(const std::set& clusterIds) const
{
diff --git a/src/libs/database/impl/Release.cpp b/src/libs/database/impl/Release.cpp
index 5b2e088c..64a04b31 100644
--- a/src/libs/database/impl/Release.cpp
+++ b/src/libs/database/impl/Release.cpp
@@ -245,6 +245,46 @@ Release::getByYear(Session& session, int yearFrom, int yearTo, std::optional(res.begin(), res.end());
}
+std::vector
+Release::getStarred(Session& session,
+ User::pointer user,
+ const std::set& clusterIds,
+ std::optional range,
+ bool& moreResults)
+{
+ session.checkSharedLocked();
+
+ auto query {createQuery(session, "SELECT r from release r", clusterIds, {})};
+ {
+ std::ostringstream oss;
+ oss << "r.id IN (SELECT DISTINCT r.id FROM release r"
+ " INNER JOIN user_release_starred urs ON urs.release_id = r.id"
+ " INNER JOIN user u ON u.id = urs.user_id WHERE u.id = ?)";
+
+ query.bind(user.id());
+ query.where(oss.str());
+ }
+
+ Wt::Dbo::collection collection = query
+ .groupBy("r.id")
+ .orderBy("r.name COLLATE NOCASE")
+ .offset(range ? static_cast(range->offset) : -1)
+ .limit(range ? static_cast(range->limit) + 1: -1);
+
+ auto res {std::vector(collection.begin(), collection.end())};
+ if (range && res.size() == static_cast(range->limit) + 1)
+ {
+ moreResults = true;
+ res.pop_back();
+ }
+ else
+ moreResults = false;
+
+ return res;
+
+
+}
+
std::vector
Release::getByClusters(Session& session, const std::set& clusters)
{
diff --git a/src/libs/database/impl/Track.cpp b/src/libs/database/impl/Track.cpp
index 04a16f1f..aaf4b53a 100644
--- a/src/libs/database/impl/Track.cpp
+++ b/src/libs/database/impl/Track.cpp
@@ -265,6 +265,41 @@ Track::getAllIdsWithClusters(Session& session, std::optional limit)
return std::vector(res.begin(), res.end());
}
+std::vector
+Track::getStarred(Session& session,
+ Wt::Dbo::ptr user,
+ const std::set& clusterIds,
+ std::optional range, bool& moreResults)
+{
+ session.checkSharedLocked();
+
+ auto query {createQuery(session, "SELECT t from track t", clusterIds, {})};
+ {
+ std::ostringstream oss;
+ oss << "t.id IN (SELECT DISTINCT t.id FROM track t"
+ " INNER JOIN user_track_starred uts ON uts.track_id = t.id"
+ " INNER JOIN user u ON u.id = uts.user_id WHERE u.id = ?)";
+
+ query.bind(user.id());
+ query.where(oss.str());
+ }
+
+ Wt::Dbo::collection collection = query
+ .offset(range ? static_cast(range->offset) : -1)
+ .limit(range ? static_cast(range->limit) + 1: -1);
+
+ auto res {std::vector(collection.begin(), collection.end())};
+ if (range && res.size() == static_cast(range->limit) + 1)
+ {
+ moreResults = true;
+ res.pop_back();
+ }
+ else
+ moreResults = false;
+
+ return res;
+}
+
std::vector
Track::getClusters() const
{
diff --git a/src/libs/database/impl/User.cpp b/src/libs/database/impl/User.cpp
index 26321542..df761cff 100644
--- a/src/libs/database/impl/User.cpp
+++ b/src/libs/database/impl/User.cpp
@@ -172,12 +172,6 @@ User::hasStarredArtist(Wt::Dbo::ptr artist) const
return _starredArtists.count(artist) != 0;
}
-std::vector>
-User::getStarredArtists() const
-{
- return std::vector>(_starredArtists.begin(), _starredArtists.end());
-}
-
void
User::starRelease(Wt::Dbo::ptr release)
{
@@ -198,17 +192,6 @@ User::hasStarredRelease(Wt::Dbo::ptr release) const
return _starredReleases.count(release) != 0;
}
-std::vector>
-User::getStarredReleases(std::optional offset, std::optional limit) const
-{
- Wt::Dbo::collection> res = _starredReleases.find()
- .offset(offset ? static_cast(*offset) : -1)
- .limit(limit ? static_cast(*limit) : -1);
-
- return std::vector>(res.begin(), res.end());
-}
-
-
void
User::starTrack(Wt::Dbo::ptr