Still converting to bootstrap 5. Updated releases again
This commit is contained in:
+2
-4
@@ -23,12 +23,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${<if-has-release>}
|
${<if-has-release>}
|
||||||
${releases class="row gy-4 mb-5"}
|
${releases}
|
||||||
${</if-has-release>}
|
${</if-has-release>}
|
||||||
${<if-has-non-release-track>}
|
${<if-has-non-release-track>}
|
||||||
<div class="Lms-explore-artist-tracks-container">
|
${tracks}
|
||||||
${tracks}
|
|
||||||
</div>
|
|
||||||
${</if-has-non-release-track>}
|
${</if-has-non-release-track>}
|
||||||
${<if-has-similar-artists>}
|
${<if-has-similar-artists>}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
${<if-has-similar-releases>}
|
${<if-has-similar-releases>}
|
||||||
<h3>${tr:Lms.Explore.Release.similar-releases}</h3>
|
<h3>${tr:Lms.Explore.Release.similar-releases}</h3>
|
||||||
${similar-releases class="row gy-4"}
|
${similar-releases class="row row-cols-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-6 gx-2 gy-4"}
|
||||||
${</if-has-similar-releases>}
|
${</if-has-similar-releases>}
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
|||||||
+11
-7
@@ -39,17 +39,21 @@
|
|||||||
</message>
|
</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.Releases.template.entry-grid">
|
<message id="Lms.Explore.Releases.template.entry-grid">
|
||||||
<div class="Lms-responsive-square Lms-cover-container">
|
<div class="col">
|
||||||
${cover class="shadow-sm"}
|
<div class="Lms-bg-dark-hover rounded p-2">
|
||||||
|
<div class="Lms-responsive-square Lms-cover-container">
|
||||||
|
${cover class="shadow-sm"}
|
||||||
|
</div>
|
||||||
|
${release-name class="d-block text-truncate text-nowrap text-decoration-none link-success"}
|
||||||
|
${<if-has-artist>}${artist-name class="d-block text-truncate text-nowrap text-decoration-none link-secondary"}${</if-has-artist>}
|
||||||
|
${<if-has-various-artists>}<div class="text-truncate text-nowrap text-secondary">${tr:Lms.Explore.various-artists}</div>${</if-has-various-artists>}
|
||||||
|
${<if-has-year>}<div class="small text-muted">${year}</div>${</if-has-year>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${release-name class="d-block text-truncate text-nowrap text-decoration-none link-success"}
|
|
||||||
${<if-has-artist>}${artist-name class="d-block text-truncate text-nowrap text-decoration-none link-secondary"}${</if-has-artist>}
|
|
||||||
${<if-has-various-artists>}<div class="text-truncate text-nowrap text-secondary">${tr:Lms.Explore.various-artists}</div>${</if-has-various-artists>}
|
|
||||||
${<if-has-year>}<div class="small text-muted">${year}</div>${</if-has-year>}
|
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.Releases.template.container">
|
<message id="Lms.Explore.Releases.template.container">
|
||||||
${elements class="row gy-4"}
|
${elements class="row row-cols-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-6 gx-2 gy-4"}
|
||||||
${loading-indicator}
|
${loading-indicator}
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -9,7 +9,7 @@
|
|||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
${tr:Lms.Settings.audio-settings-are-local}
|
${tr:Lms.Settings.audio-settings-are-local}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-mode}">
|
<label class="form-label" for="${id:transcode-mode}">
|
||||||
${tr:Lms.Settings.transcode-mode}
|
${tr:Lms.Settings.transcode-mode}
|
||||||
</label>
|
</label>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
${transcode-mode-info}
|
${transcode-mode-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-format}">
|
<label class="form-label" for="${id:transcode-format}">
|
||||||
${tr:Lms.Settings.transcode-format}
|
${tr:Lms.Settings.transcode-format}
|
||||||
</label>
|
</label>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
${transcode-format-info}
|
${transcode-format-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-bitrate}">
|
<label class="form-label" for="${id:transcode-bitrate}">
|
||||||
${tr:Lms.Settings.transcode-bitrate}
|
${tr:Lms.Settings.transcode-bitrate}
|
||||||
</label>
|
</label>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
${transcode-bitrate-info}
|
${transcode-bitrate-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:replaygain-mode}">
|
<label class="form-label" for="${id:replaygain-mode}">
|
||||||
${tr:Lms.Settings.replaygain-mode}
|
${tr:Lms.Settings.replaygain-mode}
|
||||||
</label>
|
</label>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
${replaygain-mode-info}
|
${replaygain-mode-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:replaygain-preamp}">
|
<label class="form-label" for="${id:replaygain-preamp}">
|
||||||
${tr:Lms.Settings.replaygain-preamp}
|
${tr:Lms.Settings.replaygain-preamp}
|
||||||
</label>
|
</label>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
${replaygain-preamp-info}
|
${replaygain-preamp-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:replaygain-preamp-no-rg-info}">
|
<label class="form-label" for="${id:replaygain-preamp-no-rg-info}">
|
||||||
${tr:Lms.Settings.replaygain-preamp-no-rg-info}
|
${tr:Lms.Settings.replaygain-preamp-no-rg-info}
|
||||||
</label>
|
</label>
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
</div>
|
</div>
|
||||||
${</if-has-subsonic-api>}
|
${</if-has-subsonic-api>}
|
||||||
<legend>${tr:Lms.Settings.scrobbling}</legend>
|
<legend>${tr:Lms.Settings.scrobbling}</legend>
|
||||||
<div class="col-12">
|
<div class="col-lg-6">
|
||||||
<label class="form-label" for="${id:scrobbler}">
|
<label class="form-label" for="${id:scrobbler}">
|
||||||
${tr:Lms.Settings.scrobbling.scrobbler}
|
${tr:Lms.Settings.scrobbling.scrobbler}
|
||||||
</label>
|
</label>
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
${scrobbler-info class="help-block"}
|
${scrobbler-info class="help-block"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-lg-6">
|
||||||
<label class="form-label" for="${id:listenbrainz-token}">
|
<label class="form-label" for="${id:listenbrainz-token}">
|
||||||
${tr:Lms.Settings.scrobbling.listenbrainz-token}
|
${tr:Lms.Settings.scrobbling.listenbrainz-token}
|
||||||
</label>
|
</label>
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${</if-has-old-password>}
|
${</if-has-old-password>}
|
||||||
<div class="col-12">
|
<div class="col-lg-6">
|
||||||
<label class="col-lg-3 control-label" for="${id:password}">
|
<label class="col-lg-3 control-label" for="${id:password}">
|
||||||
${tr:Lms.password-new}
|
${tr:Lms.password-new}
|
||||||
</label>
|
</label>
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
${password-info class="help-block"}
|
${password-info class="help-block"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-lg-6">
|
||||||
<label class="col-lg-3 control-label" for="${id:password-confirm}">
|
<label class="col-lg-3 control-label" for="${id:password-confirm}">
|
||||||
${tr:Lms.password-confirm}
|
${tr:Lms.password-confirm}
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ Artist::find(Session& session, const FindParameters& params)
|
|||||||
return execQuery(query, params.range);
|
return execQuery(query, params.range);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Release::pointer>
|
RangeResults<ReleaseId>
|
||||||
Artist::getReleases(const std::vector<ClusterId>& clusterIds) const
|
Artist::getReleases(Range range, const std::vector<ClusterId>& clusterIds) const
|
||||||
{
|
{
|
||||||
assert(session());
|
assert(session());
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ Artist::getReleases(const std::vector<ClusterId>& clusterIds) const
|
|||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
oss << "SELECT DISTINCT r FROM release r INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN track t ON t.release_id = r.id";
|
oss << "SELECT DISTINCT r.id FROM release r INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN track t ON t.release_id = r.id";
|
||||||
|
|
||||||
if (!clusterIds.empty())
|
if (!clusterIds.empty())
|
||||||
{
|
{
|
||||||
@@ -236,13 +236,12 @@ Artist::getReleases(const std::vector<ClusterId>& clusterIds) const
|
|||||||
|
|
||||||
oss << " ORDER BY t.date DESC, r.name COLLATE NOCASE";
|
oss << " ORDER BY t.date DESC, r.name COLLATE NOCASE";
|
||||||
|
|
||||||
auto query {session()->query<Wt::Dbo::ptr<Release>>(oss.str())};
|
auto query {session()->query<ReleaseId>(oss.str())};
|
||||||
|
|
||||||
for (const std::string& bindArg : where.getBindArgs())
|
for (const std::string& bindArg : where.getBindArgs())
|
||||||
query.bind(bindArg);
|
query.bind(bindArg);
|
||||||
|
|
||||||
auto res {query.resultList()};
|
return execQuery(query, range);
|
||||||
return std::vector<Release::pointer>(res.begin(), res.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "services/database/ArtistId.hpp"
|
#include "services/database/ArtistId.hpp"
|
||||||
#include "services/database/ClusterId.hpp"
|
#include "services/database/ClusterId.hpp"
|
||||||
#include "services/database/Object.hpp"
|
#include "services/database/Object.hpp"
|
||||||
|
#include "services/database/ReleaseId.hpp"
|
||||||
#include "services/database/Types.hpp"
|
#include "services/database/Types.hpp"
|
||||||
#include "services/database/UserId.hpp"
|
#include "services/database/UserId.hpp"
|
||||||
#include "utils/EnumSet.hpp"
|
#include "utils/EnumSet.hpp"
|
||||||
@@ -88,7 +89,7 @@ class Artist : public Object<Artist, ArtistId>
|
|||||||
const std::string& getSortName() const { return _sortName; }
|
const std::string& getSortName() const { return _sortName; }
|
||||||
std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); }
|
std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); }
|
||||||
|
|
||||||
std::vector<ObjectPtr<Release>> getReleases(const std::vector<ClusterId>& clusterIds = {}) const; // if non empty, get the releases that match all these clusters
|
RangeResults<ReleaseId> getReleases(Range range, const std::vector<ClusterId>& clusterIds = {}) const; // if non empty, get the releases that match all these clusters
|
||||||
std::size_t getReleaseCount() const;
|
std::size_t getReleaseCount() const;
|
||||||
std::vector<ObjectPtr<Track>> getTracks(std::optional<TrackArtistLinkType> linkType = {}) const;
|
std::vector<ObjectPtr<Track>> getTracks(std::optional<TrackArtistLinkType> linkType = {}) const;
|
||||||
bool hasNonReleaseTracks(std::optional<TrackArtistLinkType> linkType = std::nullopt) const;
|
bool hasNonReleaseTracks(std::optional<TrackArtistLinkType> linkType = std::nullopt) const;
|
||||||
|
|||||||
@@ -574,13 +574,13 @@ TEST_F(DatabaseFixture, SingleTrackSingleReleaseSingleArtistSingleCluster)
|
|||||||
ASSERT_EQ(artists.results.size(), 1);
|
ASSERT_EQ(artists.results.size(), 1);
|
||||||
EXPECT_EQ(artists.results.front(), artist.getId());
|
EXPECT_EQ(artists.results.front(), artist.getId());
|
||||||
|
|
||||||
auto releases {artist->getReleases()};
|
auto releases {artist->getReleases(Range {})};
|
||||||
ASSERT_EQ(releases.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
EXPECT_EQ(releases.front()->getId(), release.getId());
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
|
|
||||||
releases = artist->getReleases({cluster.getId()});
|
releases = artist->getReleases(Range {}, {cluster.getId()});
|
||||||
ASSERT_EQ(releases.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
EXPECT_EQ(releases.front()->getId(), release.getId());
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,13 +605,13 @@ TEST_F(DatabaseFixture, SingleTrackSingleReleaseSingleArtistMultiClusters)
|
|||||||
{
|
{
|
||||||
auto transaction {session.createSharedTransaction()};
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
|
||||||
auto releases {artist->getReleases()};
|
auto releases {artist->getReleases(Range {})};
|
||||||
ASSERT_EQ(releases.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
EXPECT_EQ(releases.front()->getId(), release.getId());
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
|
|
||||||
releases = artist->getReleases({cluster1.getId(), cluster2.getId()});
|
releases = artist->getReleases(Range {}, {cluster1.getId(), cluster2.getId()});
|
||||||
ASSERT_EQ(releases.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
EXPECT_EQ(releases.front()->getId(), release.getId());
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,9 @@ TEST_F(DatabaseFixture, MultiTracksSingleArtistSingleRelease)
|
|||||||
auto transaction {session.createSharedTransaction()};
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
|
||||||
EXPECT_EQ(artist->getReleaseCount(), 1);
|
EXPECT_EQ(artist->getReleaseCount(), 1);
|
||||||
ASSERT_EQ(artist->getReleases().size(), 1);
|
auto releases {artist->getReleases(Range {})};
|
||||||
EXPECT_EQ(artist->getReleases().front()->getId(), release.getId());
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
|
|
||||||
EXPECT_EQ(release->getTracks().size(), nbTracks);
|
EXPECT_EQ(release->getTracks().size(), nbTracks);
|
||||||
}
|
}
|
||||||
@@ -73,9 +74,9 @@ TEST_F(DatabaseFixture, SingleTrackSingleReleaseSingleArtist)
|
|||||||
{
|
{
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
auto releases {artist->getReleases()};
|
auto releases {artist->getReleases(Range {})};
|
||||||
ASSERT_EQ(releases.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
EXPECT_EQ(releases.front()->getId(), release.getId());
|
EXPECT_EQ(releases.results.front(), release.getId());
|
||||||
|
|
||||||
EXPECT_EQ(artist->getReleaseCount(), 1);
|
EXPECT_EQ(artist->getReleaseCount(), 1);
|
||||||
|
|
||||||
|
|||||||
@@ -885,9 +885,12 @@ handleGetArtistRequest(RequestContext& context)
|
|||||||
Response response {Response::createOkResponse(context.serverProtocolVersion)};
|
Response response {Response::createOkResponse(context.serverProtocolVersion)};
|
||||||
Response::Node artistNode {artistToResponseNode(user, artist, true /* id3 */)};
|
Response::Node artistNode {artistToResponseNode(user, artist, true /* id3 */)};
|
||||||
|
|
||||||
auto releases {artist->getReleases()};
|
auto releases {artist->getReleases(Range {})};
|
||||||
for (const Release::pointer& release : releases)
|
for (const ReleaseId releaseId : releases.results)
|
||||||
|
{
|
||||||
|
const Release::pointer release {Release::find(context.dbSession, releaseId)};
|
||||||
artistNode.addArrayChild("album", releaseToResponseNode(release, context.dbSession, user, true /* id3 */));
|
artistNode.addArrayChild("album", releaseToResponseNode(release, context.dbSession, user, true /* id3 */));
|
||||||
|
}
|
||||||
|
|
||||||
response.addNode("artist", std::move(artistNode));
|
response.addNode("artist", std::move(artistNode));
|
||||||
|
|
||||||
@@ -997,9 +1000,12 @@ handleGetMusicDirectoryRequest(RequestContext& context)
|
|||||||
|
|
||||||
directoryNode.setAttribute("name", makeNameFilesystemCompatible(artist->getName()));
|
directoryNode.setAttribute("name", makeNameFilesystemCompatible(artist->getName()));
|
||||||
|
|
||||||
auto releases {artist->getReleases()};
|
auto releases {artist->getReleases(Range {})};
|
||||||
for (const Release::pointer& release : releases)
|
for (const ReleaseId releaseId : releases.results)
|
||||||
|
{
|
||||||
|
const Release::pointer release {Release::find(context.dbSession, releaseId)};
|
||||||
directoryNode.addArrayChild("child", releaseToResponseNode(release, context.dbSession, user, false /* no id3 */));
|
directoryNode.addArrayChild("child", releaseToResponseNode(release, context.dbSession, user, false /* no id3 */));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (releaseId)
|
else if (releaseId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <Wt/WBootstrap5Theme.h>
|
#include <Wt/WBootstrap5Theme.h>
|
||||||
#include <Wt/WEnvironment.h>
|
#include <Wt/WEnvironment.h>
|
||||||
#include <Wt/WLineEdit.h>
|
#include <Wt/WLineEdit.h>
|
||||||
#include <Wt/WPopupMenu.h>
|
|
||||||
#include <Wt/WPushButton.h>
|
#include <Wt/WPushButton.h>
|
||||||
#include <Wt/WServer.h>
|
#include <Wt/WServer.h>
|
||||||
#include <Wt/WStackedWidget.h>
|
#include <Wt/WStackedWidget.h>
|
||||||
@@ -330,13 +329,6 @@ LmsApplication::createCluster(Database::Cluster::pointer cluster, bool canDelete
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wt::WPopupMenu*
|
|
||||||
LmsApplication::createPopupMenu()
|
|
||||||
{
|
|
||||||
_popupMenu = std::make_unique<Wt::WPopupMenu>();
|
|
||||||
return _popupMenu.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LmsApplication::handleException(LmsApplicationException& e)
|
LmsApplication::handleException(LmsApplicationException& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,10 +38,6 @@ namespace Database
|
|||||||
class Session;
|
class Session;
|
||||||
class User;
|
class User;
|
||||||
}
|
}
|
||||||
namespace Wt
|
|
||||||
{
|
|
||||||
class WPopupMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace UserInterface {
|
namespace UserInterface {
|
||||||
|
|
||||||
@@ -88,7 +84,6 @@ class LmsApplication : public Wt::WApplication
|
|||||||
static Wt::WLink createReleaseLink(Database::ObjectPtr<Database::Release> release);
|
static Wt::WLink createReleaseLink(Database::ObjectPtr<Database::Release> release);
|
||||||
static std::unique_ptr<Wt::WAnchor> createReleaseAnchor(Database::ObjectPtr<Database::Release> release, bool addText = true);
|
static std::unique_ptr<Wt::WAnchor> createReleaseAnchor(Database::ObjectPtr<Database::Release> release, bool addText = true);
|
||||||
static std::unique_ptr<Wt::WText> createCluster(Database::ObjectPtr<Database::Cluster> cluster, bool canDelete = false);
|
static std::unique_ptr<Wt::WText> createCluster(Database::ObjectPtr<Database::Cluster> cluster, bool canDelete = false);
|
||||||
Wt::WPopupMenu* createPopupMenu();
|
|
||||||
|
|
||||||
MediaPlayer& getMediaPlayer() const { return *_mediaPlayer; }
|
MediaPlayer& getMediaPlayer() const { return *_mediaPlayer; }
|
||||||
PlayQueue& getPlayQueue() const { return *_playQueue; }
|
PlayQueue& getPlayQueue() const { return *_playQueue; }
|
||||||
@@ -125,7 +120,6 @@ class LmsApplication : public Wt::WApplication
|
|||||||
std::shared_ptr<CoverResource> _coverResource;
|
std::shared_ptr<CoverResource> _coverResource;
|
||||||
MediaPlayer* _mediaPlayer {};
|
MediaPlayer* _mediaPlayer {};
|
||||||
PlayQueue* _playQueue {};
|
PlayQueue* _playQueue {};
|
||||||
std::unique_ptr<Wt::WPopupMenu> _popupMenu;
|
|
||||||
NotificationContainer* _notificationContainer {};
|
NotificationContainer* _notificationContainer {};
|
||||||
ModalManager* _modalManager {};
|
ModalManager* _modalManager {};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ PlayQueue::addEntry(const Database::TrackListEntry::pointer& tracklistEntry)
|
|||||||
Wt::WText* moreBtn {entry->bindNew<Wt::WText>("more-btn", Wt::WString::tr("Lms.PlayQueue.template.more-btn"), Wt::TextFormat::XHTML)};
|
Wt::WText* moreBtn {entry->bindNew<Wt::WText>("more-btn", Wt::WString::tr("Lms.PlayQueue.template.more-btn"), Wt::TextFormat::XHTML)};
|
||||||
moreBtn->clicked().connect([=]
|
moreBtn->clicked().connect([=]
|
||||||
{
|
{
|
||||||
Wt::WPopupMenu* popup {LmsApp->createPopupMenu()};
|
/* Wt::WPopupMenu* popup {LmsApp->createPopupMenu()};
|
||||||
|
|
||||||
const bool isStarred {Service<Scrobbling::IScrobblingService>::get()->isStarred(LmsApp->getUserId(), trackId)};
|
const bool isStarred {Service<Scrobbling::IScrobblingService>::get()->isStarred(LmsApp->getUserId(), trackId)};
|
||||||
popup->addItem(Wt::WString::tr(isStarred ? "Lms.Explore.unstar" : "Lms.Explore.star"))
|
popup->addItem(Wt::WString::tr(isStarred ? "Lms.Explore.unstar" : "Lms.Explore.star"))
|
||||||
@@ -504,6 +504,7 @@ PlayQueue::addEntry(const Database::TrackListEntry::pointer& tracklistEntry)
|
|||||||
->setLink(Wt::WLink {std::make_unique<DownloadTrackResource>(trackId)});
|
->setLink(Wt::WLink {std::make_unique<DownloadTrackResource>(trackId)});
|
||||||
|
|
||||||
popup->popup(moreBtn);
|
popup->popup(moreBtn);
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,17 +180,16 @@ Artist::refreshView()
|
|||||||
void
|
void
|
||||||
Artist::refreshReleases(const ObjectPtr<Database::Artist>& artist)
|
Artist::refreshReleases(const ObjectPtr<Database::Artist>& artist)
|
||||||
{
|
{
|
||||||
const auto releases {artist->getReleases(_filters->getClusterIds())};
|
if (artist->getReleaseCount() == 0)
|
||||||
if (releases.empty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setCondition("if-has-release", true);
|
setCondition("if-has-release", true);
|
||||||
|
_releaseContainer = bindNew<InfiniteScrollingContainer>("releases", Wt::WString::tr("Lms.Explore.Releases.template.container"));
|
||||||
Wt::WContainerWidget* releasesContainer = bindNew<Wt::WContainerWidget>("releases");
|
_releaseContainer->onRequestElements.connect(this, [this]
|
||||||
for (const auto& release : releases)
|
|
||||||
{
|
{
|
||||||
releasesContainer->addWidget(ReleaseListHelpers::createEntryForArtist(release, artist));
|
addSomeReleases();
|
||||||
}
|
});
|
||||||
|
addSomeReleases();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -239,6 +238,27 @@ Artist::refreshLinks(const Database::Artist::pointer& artist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Artist::addSomeReleases()
|
||||||
|
{
|
||||||
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
const Database::Artist::pointer artist {Database::Artist::find(LmsApp->getDbSession(), _artistId)};
|
||||||
|
if (!artist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Range range {static_cast<std::size_t>(_releaseContainer->getCount()), _releasesBatchSize};
|
||||||
|
const auto releases {artist->getReleases(range, _filters->getClusterIds())};
|
||||||
|
|
||||||
|
for (const ReleaseId releaseId : releases.results)
|
||||||
|
{
|
||||||
|
const Database::Release::pointer release {Database::Release::find(LmsApp->getDbSession(), releaseId)};
|
||||||
|
_releaseContainer->add(ReleaseListHelpers::createEntryForArtist(release, artist));
|
||||||
|
}
|
||||||
|
|
||||||
|
_releaseContainer->setHasMore(releases.moreResults);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Artist::addSomeNonReleaseTracks()
|
Artist::addSomeNonReleaseTracks()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,11 +51,14 @@ namespace UserInterface
|
|||||||
void refreshSimilarArtists(const std::vector<Database::ArtistId>& similarArtistsId);
|
void refreshSimilarArtists(const std::vector<Database::ArtistId>& similarArtistsId);
|
||||||
void refreshLinks(const Database::ObjectPtr<Database::Artist>& artist);
|
void refreshLinks(const Database::ObjectPtr<Database::Artist>& artist);
|
||||||
|
|
||||||
|
void addSomeReleases();
|
||||||
void addSomeNonReleaseTracks();
|
void addSomeNonReleaseTracks();
|
||||||
|
static constexpr std::size_t _releasesBatchSize {6};
|
||||||
static constexpr std::size_t _tracksBatchSize {6};
|
static constexpr std::size_t _tracksBatchSize {6};
|
||||||
static constexpr std::size_t _tracksMaxCount {160};
|
static constexpr std::size_t _tracksMaxCount {160};
|
||||||
|
|
||||||
Filters* _filters {};
|
Filters* _filters {};
|
||||||
|
InfiniteScrollingContainer* _releaseContainer {};
|
||||||
InfiniteScrollingContainer* _trackContainer {};
|
InfiniteScrollingContainer* _trackContainer {};
|
||||||
Database::ArtistId _artistId {};
|
Database::ArtistId _artistId {};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ namespace UserInterface::ReleaseListHelpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hack
|
|
||||||
entry->setStyleClass("p-2 Lms-bg-dark-hover rounded col-6 col-md-4 col-lg-3 col-xl-2");
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user