Added a message box to display release information
This commit is contained in:
@@ -41,4 +41,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<message id="Lms.Explore.template.info.artists">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-4 col-sm-3">
|
||||||
|
${type}
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
${artist-container data-bs-dismiss="modal"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</message>
|
||||||
|
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
|
|||||||
@@ -136,6 +136,7 @@
|
|||||||
<message id="Lms.Explore.recently-added">Recently added</message>
|
<message id="Lms.Explore.recently-added">Recently added</message>
|
||||||
<message id="Lms.Explore.recently-modified">Recently modified</message>
|
<message id="Lms.Explore.recently-modified">Recently modified</message>
|
||||||
<message id="Lms.Explore.recently-played">Recently played</message>
|
<message id="Lms.Explore.recently-played">Recently played</message>
|
||||||
|
<message id="Lms.Explore.release-info">Release information</message>
|
||||||
<message id="Lms.Explore.releases">Albums</message>
|
<message id="Lms.Explore.releases">Albums</message>
|
||||||
<message id="Lms.Explore.search">Search</message>
|
<message id="Lms.Explore.search">Search</message>
|
||||||
<message id="Lms.Explore.star">Star</message>
|
<message id="Lms.Explore.star">Star</message>
|
||||||
@@ -162,6 +163,10 @@
|
|||||||
<plural case="0">Composer</plural>
|
<plural case="0">Composer</plural>
|
||||||
<plural case="1">Composers</plural>
|
<plural case="1">Composers</plural>
|
||||||
</message>
|
</message>
|
||||||
|
<message id="Lms.Explore.Artists.linktype-conductor">
|
||||||
|
<plural case="0">Conductor</plural>
|
||||||
|
<plural case="1">Conductors</plural>
|
||||||
|
</message>
|
||||||
<message id="Lms.Explore.Artists.linktype-lyricist">
|
<message id="Lms.Explore.Artists.linktype-lyricist">
|
||||||
<plural case="0">Lyricist</plural>
|
<plural case="0">Lyricist</plural>
|
||||||
<plural case="1">Lyricists</plural>
|
<plural case="1">Lyricists</plural>
|
||||||
|
|||||||
@@ -136,6 +136,7 @@
|
|||||||
<message id="Lms.Explore.recently-added">Ajoutés récemment</message>
|
<message id="Lms.Explore.recently-added">Ajoutés récemment</message>
|
||||||
<message id="Lms.Explore.recently-modified">Modifiés récemment</message>
|
<message id="Lms.Explore.recently-modified">Modifiés récemment</message>
|
||||||
<message id="Lms.Explore.recently-played">Joués récemment</message>
|
<message id="Lms.Explore.recently-played">Joués récemment</message>
|
||||||
|
<message id="Lms.Explore.release-info">Informations sur l'album</message>
|
||||||
<message id="Lms.Explore.releases">Albums</message>
|
<message id="Lms.Explore.releases">Albums</message>
|
||||||
<message id="Lms.Explore.search">Rechercher</message>
|
<message id="Lms.Explore.search">Rechercher</message>
|
||||||
<message id="Lms.Explore.star">Ajouter aux favoris</message>
|
<message id="Lms.Explore.star">Ajouter aux favoris</message>
|
||||||
@@ -162,6 +163,10 @@
|
|||||||
<plural case="0">Compositeur</plural>
|
<plural case="0">Compositeur</plural>
|
||||||
<plural case="1">Compositeurs</plural>
|
<plural case="1">Compositeurs</plural>
|
||||||
</message>
|
</message>
|
||||||
|
<message id="Lms.Explore.Artists.linktype-conductor">
|
||||||
|
<plural case="0">Chef d'orchestre</plural>
|
||||||
|
<plural case="1">Chefs d'orchestre</plural>
|
||||||
|
</message>
|
||||||
<message id="Lms.Explore.Artists.linktype-lyricist">
|
<message id="Lms.Explore.Artists.linktype-lyricist">
|
||||||
<plural case="0">Parolier</plural>
|
<plural case="0">Parolier</plural>
|
||||||
<plural case="1">Paroliers</plural>
|
<plural case="1">Paroliers</plural>
|
||||||
|
|||||||
@@ -136,6 +136,7 @@
|
|||||||
<message id="Lms.Explore.recently-added">Aggiunti di recente</message>
|
<message id="Lms.Explore.recently-added">Aggiunti di recente</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.recently-played">Riprodotti di recente</message>
|
<message id="Lms.Explore.recently-played">Riprodotti di recente</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.releases">Album</message>
|
<message id="Lms.Explore.releases">Album</message>
|
||||||
<message id="Lms.Explore.search">Ricerca</message>
|
<message id="Lms.Explore.search">Ricerca</message>
|
||||||
<message id="Lms.Explore.star">Aggiungi ai preferiti</message>
|
<message id="Lms.Explore.star">Aggiungi ai preferiti</message>
|
||||||
@@ -178,6 +179,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -136,6 +136,7 @@
|
|||||||
<message id="Lms.Explore.recently-added">最近添加</message>
|
<message id="Lms.Explore.recently-added">最近添加</message>
|
||||||
<message id="Lms.Explore.recently-modified">最近更改</message>
|
<message id="Lms.Explore.recently-modified">最近更改</message>
|
||||||
<message id="Lms.Explore.recently-played">最近播放</message>
|
<message id="Lms.Explore.recently-played">最近播放</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.releases">专辑</message>
|
<message id="Lms.Explore.releases">专辑</message>
|
||||||
<message id="Lms.Explore.search">搜索</message>
|
<message id="Lms.Explore.search">搜索</message>
|
||||||
<message id="Lms.Explore.star">收藏</message>
|
<message id="Lms.Explore.star">收藏</message>
|
||||||
@@ -178,6 +179,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
<li><a href="${mbid-link}" target="_blank" class="dropdown-item">${tr:Lms.Explore.musicbrainz-release}</a></li>
|
<li><a href="${mbid-link}" target="_blank" class="dropdown-item">${tr:Lms.Explore.musicbrainz-release}</a></li>
|
||||||
${</if-has-mbid>}
|
${</if-has-mbid>}
|
||||||
<li>${download class="dropdown-item"}</li>
|
<li>${download class="dropdown-item"}</li>
|
||||||
|
<li>${release-info class="dropdown-item"}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,4 +85,45 @@
|
|||||||
</div>
|
</div>
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<message id="Lms.Explore.Release.template.release-info">
|
||||||
|
<div class="modal fade" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">${tr:Lms.Explore.release-info}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container-fluid d-grid gap-2">
|
||||||
|
${artist-table class="d-grid gap-2"}
|
||||||
|
${<if-has-codec>}
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-4 col-sm-3">
|
||||||
|
${tr:Lms.Explore.codec}
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
${codec}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
${</if-has-codec>}
|
||||||
|
${<if-has-bitrate>}
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-4 col-sm-3">
|
||||||
|
${tr:Lms.Explore.bitrate}
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
${bitrate}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
${</if-has-bitrate>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
${ok-btn class="btn btn-primary"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</message>
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
|
|||||||
+8
-19
@@ -80,39 +80,39 @@
|
|||||||
<div class="container-fluid d-grid gap-2">
|
<div class="container-fluid d-grid gap-2">
|
||||||
${<if-has-clusters>}
|
${<if-has-clusters>}
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-4">
|
<div class="col-4 col-sm-3">
|
||||||
${tr:Lms.clusters}
|
${tr:Lms.clusters}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col">
|
||||||
${clusters}
|
${clusters}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${</if-has-clusters>}
|
${</if-has-clusters>}
|
||||||
${artist-table class="d-grid gap-2"}
|
${artist-table class="d-grid gap-2"}
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-4">
|
<div class="col-4 col-sm-3">
|
||||||
${tr:Lms.Explore.duration}
|
${tr:Lms.Explore.duration}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col">
|
||||||
${duration}
|
${duration}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${<if-has-codec>}
|
${<if-has-codec>}
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-4">
|
<div class="col-4 col-sm-3">
|
||||||
${tr:Lms.Explore.codec}
|
${tr:Lms.Explore.codec}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col">
|
||||||
${codec}
|
${codec}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${</if-has-codec>}
|
${</if-has-codec>}
|
||||||
${<if-has-bitrate>}
|
${<if-has-bitrate>}
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-4">
|
<div class="col-4 col-sm-3">
|
||||||
${tr:Lms.Explore.bitrate}
|
${tr:Lms.Explore.bitrate}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col">
|
||||||
${bitrate}
|
${bitrate}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,15 +127,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
<message id="Lms.Explore.Tracks.template.track-info.artists">
|
|
||||||
<div class="row align-items-center">
|
|
||||||
<div class="col-4">
|
|
||||||
${type}
|
|
||||||
</div>
|
|
||||||
<div class="col-8">
|
|
||||||
${artist-container data-bs-dismiss="modal"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</message>
|
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ createQuery(Session& session, const Artist::FindParameters& params)
|
|||||||
if (params.sortMethod == ArtistSortMethod::LastWritten
|
if (params.sortMethod == ArtistSortMethod::LastWritten
|
||||||
|| params.writtenAfter.isValid()
|
|| params.writtenAfter.isValid()
|
||||||
|| params.linkType
|
|| params.linkType
|
||||||
|| params.track.isValid())
|
|| params.track.isValid()
|
||||||
|
|| params.release.isValid())
|
||||||
{
|
{
|
||||||
query.join("track t ON t.id = t_a_l.track_id");
|
query.join("track t ON t.id = t_a_l.track_id");
|
||||||
query.join("track_artist_link t_a_l ON t_a_l.artist_id = a.id");
|
query.join("track_artist_link t_a_l ON t_a_l.artist_id = a.id");
|
||||||
@@ -161,9 +162,10 @@ createQuery(Session& session, const Artist::FindParameters& params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.track.isValid())
|
if (params.track.isValid())
|
||||||
{
|
|
||||||
query.where("t.id = ?").bind(params.track);
|
query.where("t.id = ?").bind(params.track);
|
||||||
}
|
|
||||||
|
if (params.release.isValid())
|
||||||
|
query.where("t.release_id = ?").bind(params.release);
|
||||||
|
|
||||||
switch (params.sortMethod)
|
switch (params.sortMethod)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class Artist : public Object<Artist, ArtistId>
|
|||||||
UserId starringUser; // only artists starred by this user
|
UserId starringUser; // only artists starred by this user
|
||||||
std::optional<Scrobbler> scrobbler; // and for this scrobbler
|
std::optional<Scrobbler> scrobbler; // and for this scrobbler
|
||||||
TrackId track; // artists involved in this track
|
TrackId track; // artists involved in this track
|
||||||
|
ReleaseId release; // artists involved in this release
|
||||||
|
|
||||||
FindParameters& setClusters(const std::vector<ClusterId>& _clusters) { clusters = _clusters; return *this; }
|
FindParameters& setClusters(const std::vector<ClusterId>& _clusters) { clusters = _clusters; return *this; }
|
||||||
FindParameters& setKeywords(const std::vector<std::string_view>& _keywords) { keywords = _keywords; return *this; }
|
FindParameters& setKeywords(const std::vector<std::string_view>& _keywords) { keywords = _keywords; return *this; }
|
||||||
@@ -72,6 +73,7 @@ class Artist : public Object<Artist, ArtistId>
|
|||||||
FindParameters& setWrittenAfter(const Wt::WDateTime& _after) { writtenAfter = _after; return *this; }
|
FindParameters& setWrittenAfter(const Wt::WDateTime& _after) { writtenAfter = _after; return *this; }
|
||||||
FindParameters& setStarringUser(UserId _user, Scrobbler _scrobbler) { starringUser = _user; scrobbler = _scrobbler; return *this; }
|
FindParameters& setStarringUser(UserId _user, Scrobbler _scrobbler) { starringUser = _user; scrobbler = _scrobbler; return *this; }
|
||||||
FindParameters& setTrack(TrackId _track) { track = _track; return *this; }
|
FindParameters& setTrack(TrackId _track) { track = _track; return *this; }
|
||||||
|
FindParameters& setRelease(ReleaseId _release) { release = _release; return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
Artist() = default;
|
Artist() = default;
|
||||||
|
|||||||
@@ -372,9 +372,46 @@ TEST_F(DatabaseFixture, Artist_nonReleaseTracks)
|
|||||||
{
|
{
|
||||||
auto transaction {session.createSharedTransaction()};
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
|
||||||
const auto tracks {Track::find(session, Track::FindParameters {}.setArtist(artist->getId()).setNonRelease(true))};
|
const auto tracks {Track::find(session, Track::FindParameters {}.setArtist(artist.getId()).setNonRelease(true))};
|
||||||
ASSERT_EQ(tracks.results.size(), 1);
|
ASSERT_EQ(tracks.results.size(), 1);
|
||||||
EXPECT_EQ(tracks.results.front(), track2.getId());
|
EXPECT_EQ(tracks.results.front(), track2.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DatabaseFixture, Artist_findByRelease)
|
||||||
|
{
|
||||||
|
ScopedArtist artist {session, "artist"};
|
||||||
|
ScopedTrack track {session, "MyTrack"};
|
||||||
|
ScopedRelease release{session, "MyRelease"};
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
const auto artists {Artist::find(session, Artist::FindParameters {}.setRelease(release.getId()))};
|
||||||
|
EXPECT_EQ(artists.results.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
const auto artists {Artist::find(session, Artist::FindParameters {}.setRelease(release.getId()))};
|
||||||
|
EXPECT_EQ(artists.results.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
track.get().modify()->setRelease(release.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
const auto artists {Artist::find(session, Artist::FindParameters {}.setRelease(release.getId()))};
|
||||||
|
ASSERT_EQ(artists.results.size(), 1);
|
||||||
|
EXPECT_EQ(artists.results.front(), artist.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ Artists::refreshArtistLinkTypes()
|
|||||||
addTypeIfUsed(TrackArtistLinkType::Artist, "Lms.Explore.Artists.linktype-artist");
|
addTypeIfUsed(TrackArtistLinkType::Artist, "Lms.Explore.Artists.linktype-artist");
|
||||||
addTypeIfUsed(TrackArtistLinkType::ReleaseArtist, "Lms.Explore.Artists.linktype-releaseartist");
|
addTypeIfUsed(TrackArtistLinkType::ReleaseArtist, "Lms.Explore.Artists.linktype-releaseartist");
|
||||||
addTypeIfUsed(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");
|
addTypeIfUsed(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");
|
||||||
|
addTypeIfUsed(TrackArtistLinkType::Conductor, "Lms.Explore.Artists.linktype-conductor");
|
||||||
addTypeIfUsed(TrackArtistLinkType::Lyricist, "Lms.Explore.Artists.linktype-lyricist");
|
addTypeIfUsed(TrackArtistLinkType::Lyricist, "Lms.Explore.Artists.linktype-lyricist");
|
||||||
addTypeIfUsed(TrackArtistLinkType::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
addTypeIfUsed(TrackArtistLinkType::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
||||||
addTypeIfUsed(TrackArtistLinkType::Producer, "Lms.Explore.Artists.linktype-producer");
|
addTypeIfUsed(TrackArtistLinkType::Producer, "Lms.Explore.Artists.linktype-producer");
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <Wt/WImage.h>
|
#include <Wt/WImage.h>
|
||||||
#include <Wt/WPushButton.h>
|
#include <Wt/WPushButton.h>
|
||||||
|
|
||||||
|
#include "av/IAudioFile.hpp"
|
||||||
|
#include "services/database/Artist.hpp"
|
||||||
#include "services/database/Cluster.hpp"
|
#include "services/database/Cluster.hpp"
|
||||||
#include "services/database/Release.hpp"
|
#include "services/database/Release.hpp"
|
||||||
#include "services/database/ScanSettings.hpp"
|
#include "services/database/ScanSettings.hpp"
|
||||||
@@ -41,12 +43,84 @@
|
|||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
#include "LmsApplicationException.hpp"
|
#include "LmsApplicationException.hpp"
|
||||||
#include "MediaPlayer.hpp"
|
#include "MediaPlayer.hpp"
|
||||||
|
#include "ModalManager.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
namespace UserInterface {
|
namespace UserInterface {
|
||||||
|
|
||||||
|
void
|
||||||
|
showReleaseInfoModal(Database::ReleaseId releaseId)
|
||||||
|
{
|
||||||
|
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
||||||
|
|
||||||
|
const Database::Release::pointer release {Database::Release::find(LmsApp->getDbSession(), releaseId)};
|
||||||
|
if (!release)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto releaseInfo {std::make_unique<Template>(Wt::WString::tr("Lms.Explore.Release.template.release-info"))};
|
||||||
|
Wt::WWidget* releaseInfoPtr {releaseInfo.get()};
|
||||||
|
releaseInfo->addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||||
|
|
||||||
|
Wt::WContainerWidget* artistTable {releaseInfo->bindNew<Wt::WContainerWidget>("artist-table")};
|
||||||
|
|
||||||
|
auto addArtists = [&](TrackArtistLinkType linkType, const char* type)
|
||||||
|
{
|
||||||
|
Artist::FindParameters params;
|
||||||
|
params.setRelease(releaseId);
|
||||||
|
params.setLinkType(linkType);
|
||||||
|
const auto artistIds {Artist::find(LmsApp->getDbSession(), params)};
|
||||||
|
if (artistIds.results.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::unique_ptr<Wt::WContainerWidget> artistContainer {Utils::createArtistContainer(artistIds.results)};
|
||||||
|
auto artistsEntry {std::make_unique<Template>(Wt::WString::tr("Lms.Explore.template.info.artists"))};
|
||||||
|
artistsEntry->bindString("type", Wt::WString::trn(type, artistContainer->count()));
|
||||||
|
artistsEntry->bindWidget("artist-container", std::move(artistContainer));
|
||||||
|
artistTable->addWidget(std::move(artistsEntry));
|
||||||
|
};
|
||||||
|
|
||||||
|
addArtists(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");
|
||||||
|
addArtists(TrackArtistLinkType::Conductor, "Lms.Explore.Artists.linktype-conductor");
|
||||||
|
addArtists(TrackArtistLinkType::Lyricist, "Lms.Explore.Artists.linktype-lyricist");
|
||||||
|
addArtists(TrackArtistLinkType::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
||||||
|
addArtists(TrackArtistLinkType::Remixer, "Lms.Explore.Artists.linktype-remixer");
|
||||||
|
addArtists(TrackArtistLinkType::Producer, "Lms.Explore.Artists.linktype-producer");
|
||||||
|
|
||||||
|
// TODO: save in DB and mean all this
|
||||||
|
for (TrackId trackId : Track::find(LmsApp->getDbSession(), Track::FindParameters {}.setRelease(releaseId).setRange(Range {0, 1})).results)
|
||||||
|
{
|
||||||
|
const Track::pointer track {Track::find(LmsApp->getDbSession(), trackId)};
|
||||||
|
if (!track)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (const auto audioFile {Av::parseAudioFile(track->getPath())})
|
||||||
|
{
|
||||||
|
const std::optional<Av::StreamInfo> audioStream {audioFile->getBestStreamInfo()};
|
||||||
|
if (audioStream)
|
||||||
|
{
|
||||||
|
releaseInfo->setCondition("if-has-codec", true);
|
||||||
|
releaseInfo->bindString("codec", audioStream->codec);
|
||||||
|
if (audioStream->bitrate)
|
||||||
|
{
|
||||||
|
releaseInfo->setCondition("if-has-bitrate", true);
|
||||||
|
releaseInfo->bindString("bitrate", std::to_string(audioStream->bitrate / 1000) + " kbps");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Wt::WPushButton* okBtn {releaseInfo->bindNew<Wt::WPushButton>("ok-btn", Wt::WString::tr("Lms.ok"))};
|
||||||
|
okBtn->clicked().connect([=]
|
||||||
|
{
|
||||||
|
LmsApp->getModalManager().dispose(releaseInfoPtr);
|
||||||
|
});
|
||||||
|
|
||||||
|
LmsApp->getModalManager().show(std::move(releaseInfo));
|
||||||
|
}
|
||||||
|
|
||||||
Release::Release(Filters& filters, PlayQueueController& playQueueController)
|
Release::Release(Filters& filters, PlayQueueController& playQueueController)
|
||||||
: Template {Wt::WString::tr("Lms.Explore.Release.template")}
|
: Template {Wt::WString::tr("Lms.Explore.Release.template")}
|
||||||
, _filters {filters}
|
, _filters {filters}
|
||||||
@@ -177,6 +251,12 @@ Release::refreshView()
|
|||||||
bindNew<Wt::WPushButton>("download", Wt::WString::tr("Lms.Explore.download"))
|
bindNew<Wt::WPushButton>("download", Wt::WString::tr("Lms.Explore.download"))
|
||||||
->setLink(Wt::WLink {std::make_unique<DownloadReleaseResource>(*releaseId)});
|
->setLink(Wt::WLink {std::make_unique<DownloadReleaseResource>(*releaseId)});
|
||||||
|
|
||||||
|
bindNew<Wt::WPushButton>("release-info", Wt::WString::tr("Lms.Explore.release-info"))
|
||||||
|
->clicked().connect([=]
|
||||||
|
{
|
||||||
|
showReleaseInfoModal(*releaseId);
|
||||||
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
auto isStarred {[=] { return Service<Scrobbling::IScrobblingService>::get()->isStarred(LmsApp->getUserId(), *releaseId); }};
|
auto isStarred {[=] { return Service<Scrobbling::IScrobblingService>::get()->isStarred(LmsApp->getUserId(), *releaseId); }};
|
||||||
|
|
||||||
|
|||||||
@@ -69,13 +69,14 @@ namespace UserInterface::TrackListHelpers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::unique_ptr<Wt::WContainerWidget> artistContainer {Utils::createArtistContainer(artistIds.results)};
|
std::unique_ptr<Wt::WContainerWidget> artistContainer {Utils::createArtistContainer(artistIds.results)};
|
||||||
auto artistsEntry {std::make_unique<Template>(Wt::WString::tr("Lms.Explore.Tracks.template.track-info.artists"))};
|
auto artistsEntry {std::make_unique<Template>(Wt::WString::tr("Lms.Explore.template.info.artists"))};
|
||||||
artistsEntry->bindString("type", Wt::WString::trn(type, artistContainer->count()));
|
artistsEntry->bindString("type", Wt::WString::trn(type, artistContainer->count()));
|
||||||
artistsEntry->bindWidget("artist-container", std::move(artistContainer));
|
artistsEntry->bindWidget("artist-container", std::move(artistContainer));
|
||||||
artistTable->addWidget(std::move(artistsEntry));
|
artistTable->addWidget(std::move(artistsEntry));
|
||||||
};
|
};
|
||||||
|
|
||||||
addArtists(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");
|
addArtists(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");
|
||||||
|
addArtists(TrackArtistLinkType::Conductor, "Lms.Explore.Artists.linktype-conductor");
|
||||||
addArtists(TrackArtistLinkType::Lyricist, "Lms.Explore.Artists.linktype-lyricist");
|
addArtists(TrackArtistLinkType::Lyricist, "Lms.Explore.Artists.linktype-lyricist");
|
||||||
addArtists(TrackArtistLinkType::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
addArtists(TrackArtistLinkType::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
||||||
addArtists(TrackArtistLinkType::Remixer, "Lms.Explore.Artists.linktype-remixer");
|
addArtists(TrackArtistLinkType::Remixer, "Lms.Explore.Artists.linktype-remixer");
|
||||||
|
|||||||
Reference in New Issue
Block a user