UI: Added star/unstar for tracks/albums/artists. ref #74

This commit is contained in:
emeric
2020-09-05 11:05:57 +02:00
parent 5dad7f9211
commit 26d12c39e4
25 changed files with 358 additions and 63 deletions
+57 -1
View File
@@ -303,7 +303,11 @@ Artist::getByFilter(Session& session,
}
std::vector<Artist::pointer>
Artist::getLastWritten(Session& session, std::optional<Wt::WDateTime> after, const std::set<IdType>& clusters, std::optional<TrackArtistLink::Type> linkType, std::optional<Range> range, bool& moreResults)
Artist::getLastWritten(Session& session,
std::optional<Wt::WDateTime> after,
const std::set<IdType>& clusters,
std::optional<TrackArtistLink::Type> linkType,
std::optional<Range> range, bool& moreResults)
{
session.checkSharedLocked();
@@ -330,6 +334,58 @@ Artist::getLastWritten(Session& session, std::optional<Wt::WDateTime> after, con
return std::vector<pointer>(res.begin(), res.end());
}
std::vector<Artist::pointer>
Artist::getStarred(Session& session,
User::pointer user,
const std::set<IdType>& clusters,
std::optional<TrackArtistLink::Type> linkType,
SortMethod sortMethod,
std::optional<Range> range, bool& moreResults)
{
session.checkSharedLocked();
auto query {createQuery<Artist::pointer>(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<Artist::pointer> collection = query
.groupBy("a.id")
.limit(range ? static_cast<int>(range->limit) + 1 : -1)
.offset(range ? static_cast<int>(range->offset) : -1);
auto res {std::vector<pointer>(collection.begin(), collection.end())};
if (range && res.size() == static_cast<std::size_t>(range->limit) + 1)
{
moreResults = true;
res.pop_back();
}
else
moreResults = false;
return std::vector<pointer>(res.begin(), res.end());
}
std::vector<Wt::Dbo::ptr<Release>>
Artist::getReleases(const std::set<IdType>& clusterIds) const
{
+40
View File
@@ -245,6 +245,46 @@ Release::getByYear(Session& session, int yearFrom, int yearTo, std::optional<std
return std::vector<pointer>(res.begin(), res.end());
}
std::vector<Release::pointer>
Release::getStarred(Session& session,
User::pointer user,
const std::set<IdType>& clusterIds,
std::optional<Range> range,
bool& moreResults)
{
session.checkSharedLocked();
auto query {createQuery<Release::pointer>(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<Release::pointer> collection = query
.groupBy("r.id")
.orderBy("r.name COLLATE NOCASE")
.offset(range ? static_cast<int>(range->offset) : -1)
.limit(range ? static_cast<int>(range->limit) + 1: -1);
auto res {std::vector<pointer>(collection.begin(), collection.end())};
if (range && res.size() == static_cast<std::size_t>(range->limit) + 1)
{
moreResults = true;
res.pop_back();
}
else
moreResults = false;
return res;
}
std::vector<Release::pointer>
Release::getByClusters(Session& session, const std::set<IdType>& clusters)
{
+35
View File
@@ -265,6 +265,41 @@ Track::getAllIdsWithClusters(Session& session, std::optional<std::size_t> limit)
return std::vector<IdType>(res.begin(), res.end());
}
std::vector<Track::pointer>
Track::getStarred(Session& session,
Wt::Dbo::ptr<User> user,
const std::set<IdType>& clusterIds,
std::optional<Range> range, bool& moreResults)
{
session.checkSharedLocked();
auto query {createQuery<Track::pointer>(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<Track::pointer> collection = query
.offset(range ? static_cast<int>(range->offset) : -1)
.limit(range ? static_cast<int>(range->limit) + 1: -1);
auto res {std::vector<pointer>(collection.begin(), collection.end())};
if (range && res.size() == static_cast<std::size_t>(range->limit) + 1)
{
moreResults = true;
res.pop_back();
}
else
moreResults = false;
return res;
}
std::vector<Cluster::pointer>
Track::getClusters() const
{
-23
View File
@@ -172,12 +172,6 @@ User::hasStarredArtist(Wt::Dbo::ptr<Artist> artist) const
return _starredArtists.count(artist) != 0;
}
std::vector<Wt::Dbo::ptr<Artist>>
User::getStarredArtists() const
{
return std::vector<Wt::Dbo::ptr<Artist>>(_starredArtists.begin(), _starredArtists.end());
}
void
User::starRelease(Wt::Dbo::ptr<Release> release)
{
@@ -198,17 +192,6 @@ User::hasStarredRelease(Wt::Dbo::ptr<Release> release) const
return _starredReleases.count(release) != 0;
}
std::vector<Wt::Dbo::ptr<Release>>
User::getStarredReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit) const
{
Wt::Dbo::collection<Wt::Dbo::ptr<Release>> res = _starredReleases.find()
.offset(offset ? static_cast<int>(*offset) : -1)
.limit(limit ? static_cast<int>(*limit) : -1);
return std::vector<Wt::Dbo::ptr<Release>>(res.begin(), res.end());
}
void
User::starTrack(Wt::Dbo::ptr<Track> track)
{
@@ -229,12 +212,6 @@ User::hasStarredTrack(Wt::Dbo::ptr<Track> track) const
return _starredTracks.count(track) != 0;
}
std::vector<Wt::Dbo::ptr<Track>>
User::getStarredTracks() const
{
return std::vector<Wt::Dbo::ptr<Track>>(_starredTracks.begin(), _starredTracks.end());
}
} // namespace Database
@@ -86,6 +86,12 @@ class Artist : public Wt::Dbo::Dbo<Artist>
std::optional<Range>,
bool& moreResults);
static std::vector<IdType> getAllIdsWithClusters(Session& session, std::optional<std::size_t> limit = {});
static std::vector<pointer> getStarred(Session& session,
Wt::Dbo::ptr<User> user,
const std::set<IdType>& clusters,
std::optional<TrackArtistLink::Type> linkType, // if set, only artists that have produced at least one track with this link type
SortMethod sortMethod,
std::optional<Range>, bool& moreResults);
// Accessors
const std::string& getName() const { return _name; }
@@ -59,6 +59,7 @@ class Release : public Wt::Dbo::Dbo<Release>
static std::vector<IdType> getAllIdsRandom(Session& session, const std::set<IdType>& clusters, std::optional<std::size_t> size = {});
static std::vector<pointer> getLastWritten(Session& session, std::optional<Wt::WDateTime> after, const std::set<IdType>& clusters, std::optional<Range> range, bool& moreResults);
static std::vector<pointer> getByYear(Session& session, int yearFrom, int yearTo, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getStarred(Session& session, Wt::Dbo::ptr<User> user, const std::set<IdType>& clusters, std::optional<Range> range, bool& moreResults);
static std::vector<pointer> getByClusters(Session& session, const std::set<IdType>& clusters);
static std::vector<pointer> getByFilter(Session& session,
@@ -81,6 +81,10 @@ class Track : public Wt::Dbo::Dbo<Track>
static std::vector<pointer> getAllWithMBIDAndMissingFeatures(Session& session);
static std::vector<IdType> getAllIdsWithFeatures(Session& session, std::optional<std::size_t> limit = {});
static std::vector<IdType> getAllIdsWithClusters(Session& session, std::optional<std::size_t> limit = {});
static std::vector<pointer> getStarred(Session& session,
Wt::Dbo::ptr<User> user,
const std::set<IdType>& clusters,
std::optional<Range> range, bool& hasMore);
// Create utility
static pointer create(Session& session, const std::filesystem::path& p);
@@ -197,18 +197,15 @@ class User : public Wt::Dbo::Dbo<User>
void starArtist(Wt::Dbo::ptr<Artist> artist);
void unstarArtist(Wt::Dbo::ptr<Artist> artist);
bool hasStarredArtist(Wt::Dbo::ptr<Artist> artist) const;
std::vector<Wt::Dbo::ptr<Artist>> getStarredArtists() const;
void starRelease(Wt::Dbo::ptr<Release> release);
void unstarRelease(Wt::Dbo::ptr<Release> release);
bool hasStarredRelease(Wt::Dbo::ptr<Release> release) const;
std::vector<Wt::Dbo::ptr<Release>> getStarredReleases(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
// Stars
void starTrack(Wt::Dbo::ptr<Track> track);
void unstarTrack(Wt::Dbo::ptr<Track> track);
bool hasStarredTrack(Wt::Dbo::ptr<Track> track) const;
std::vector<Wt::Dbo::ptr<Track>> getStarredTracks() const;
template<class Action>
void persist(Action& a)