diff --git a/docroot/css/lms.css b/docroot/css/lms.css index 168af16c..84fdec1d 100644 --- a/docroot/css/lms.css +++ b/docroot/css/lms.css @@ -8,20 +8,21 @@ body { padding-bottom: 78px; } +a img:hover { + filter: brightness(85%); +} + +.Lms-badge-cluster:hover { + filter: brightness(85%); + cursor: pointer; +} + .Lms-notification-container { position: fixed; bottom: 78px; right: 0px; } -.Lms-player { - height: 70px; -} - -.fixed-bottom.Lms-player { - z-index: 999; -} - .Lms-entry-playing { background-color: var(--bs-dark); } @@ -57,6 +58,15 @@ body { min-width: 64px; } +.Lms-player { + height: 70px; +} + +.fixed-bottom.Lms-player { + z-index: 999; +} + + .Lms-responsive-square { width: 100%; } diff --git a/src/lms/ui/LmsApplication.cpp b/src/lms/ui/LmsApplication.cpp index 9aef8471..7f76f09b 100644 --- a/src/lms/ui/LmsApplication.cpp +++ b/src/lms/ui/LmsApplication.cpp @@ -300,35 +300,6 @@ LmsApplication::createReleaseAnchor(Database::Release::pointer release, bool add return res; } -std::unique_ptr -LmsApplication::createCluster(Database::Cluster::pointer cluster, bool canDelete) -{ - auto getStyleClass = [](const Database::Cluster::pointer cluster) - { - switch (cluster->getType()->getId().getValue() % 8) - { - case 0: return "bg-primary"; - case 1: return "bg-secondary"; - case 2: return "bg-success"; - case 3: return "bg-danger"; - case 4: return "bg-warning text-dark"; - case 5: return "bg-info text-dark"; - case 6: return "bg-light text-dark"; - case 7: return "bg-dark"; - } - return "bg-primary"; - }; - - const std::string styleClass {getStyleClass(cluster)}; - auto res {std::make_unique(std::string {} + (canDelete ? " " : "") + Wt::WString::fromUTF8(cluster->getName()), Wt::TextFormat::UnsafeXHTML)}; - - res->setStyleClass("badge me-1 " + styleClass); - res->setToolTip(cluster->getType()->getName(), Wt::TextFormat::Plain); - res->setInline(true); - - return res; -} - void LmsApplication::handleException(LmsApplicationException& e) { diff --git a/src/lms/ui/LmsApplication.hpp b/src/lms/ui/LmsApplication.hpp index eae65285..559b9b18 100644 --- a/src/lms/ui/LmsApplication.hpp +++ b/src/lms/ui/LmsApplication.hpp @@ -83,7 +83,6 @@ class LmsApplication : public Wt::WApplication static std::unique_ptr createArtistAnchor(Database::ObjectPtr artist, bool addText = true); static Wt::WLink createReleaseLink(Database::ObjectPtr release); static std::unique_ptr createReleaseAnchor(Database::ObjectPtr release, bool addText = true); - static std::unique_ptr createCluster(Database::ObjectPtr cluster, bool canDelete = false); MediaPlayer& getMediaPlayer() const { return *_mediaPlayer; } PlayQueue& getPlayQueue() const { return *_playQueue; } diff --git a/src/lms/ui/Utils.cpp b/src/lms/ui/Utils.cpp index 4fae3c62..0fd2acd3 100644 --- a/src/lms/ui/Utils.cpp +++ b/src/lms/ui/Utils.cpp @@ -22,6 +22,10 @@ #include #include +#include + +#include "services/database/Cluster.hpp" +#include "services/database/Session.hpp" #include "LmsApplication.hpp" namespace UserInterface::Utils @@ -60,4 +64,40 @@ namespace UserInterface::Utils cover->setAttributeValue("onload", LmsApp->javaScriptClass() + ".onLoadCover(this)"); // HACK return cover; } + + std::unique_ptr + createCluster(Database::ClusterId clusterId, bool canDelete) + { + auto transaction {LmsApp->getDbSession().createSharedTransaction()}; + + const Database::Cluster::pointer cluster {Database::Cluster::find(LmsApp->getDbSession(), clusterId)}; + if (!cluster) + return {}; + + auto getStyleClass {[](const Database::Cluster::pointer& cluster) -> const char* + { + switch (cluster->getType()->getId().getValue() % 8) + { + case 0: return "bg-primary"; + case 1: return "bg-secondary"; + case 2: return "bg-success"; + case 3: return "bg-danger"; + case 4: return "bg-warning text-dark"; + case 5: return "bg-info text-dark"; + case 6: return "bg-light text-dark"; + case 7: return "bg-dark"; + } + + return "bg-primary"; + }}; + + const std::string styleClass {getStyleClass(cluster)}; + auto res {std::make_unique(std::string {} + (canDelete ? " " : "") + Wt::WString::fromUTF8(cluster->getName()), Wt::TextFormat::UnsafeXHTML)}; + + res->setStyleClass("Lms-badge-cluster badge me-1 " + styleClass); // HACK + res->setToolTip(cluster->getType()->getName(), Wt::TextFormat::Plain); + res->setInline(true); + + return res; + } } diff --git a/src/lms/ui/Utils.hpp b/src/lms/ui/Utils.hpp index 19ca01dd..9a4f9fbc 100644 --- a/src/lms/ui/Utils.hpp +++ b/src/lms/ui/Utils.hpp @@ -23,7 +23,9 @@ #include #include +#include +#include "services/database/ClusterId.hpp" #include "services/database/ReleaseId.hpp" #include "services/database/TrackId.hpp" @@ -36,5 +38,6 @@ namespace UserInterface::Utils std::unique_ptr createCover(Database::ReleaseId releaseId, CoverResource::Size size); std::unique_ptr createCover(Database::TrackId trackId, CoverResource::Size size); -} + std::unique_ptr createCluster(Database::ClusterId clusterId, bool canDelete = false); +} diff --git a/src/lms/ui/explore/ArtistView.cpp b/src/lms/ui/explore/ArtistView.cpp index e98d0254..c53c3247 100644 --- a/src/lms/ui/explore/ArtistView.cpp +++ b/src/lms/ui/explore/ArtistView.cpp @@ -41,6 +41,7 @@ #include "LmsApplicationException.hpp" #include "ReleaseListHelpers.hpp" #include "TrackListHelpers.hpp" +#include "Utils.hpp" using namespace Database; @@ -115,7 +116,7 @@ Artist::refreshView() refreshLinks(artist); refreshSimilarArtists(similarArtistIds); - Wt::WContainerWidget* clusterContainers = bindNew("clusters"); + Wt::WContainerWidget* clusterContainers {bindNew("clusters")}; { auto clusterTypes = ScanSettings::get(LmsApp->getDbSession())->getClusterTypes(); @@ -123,10 +124,10 @@ Artist::refreshView() for (auto clusters : clusterGroups) { - for (auto cluster : clusters) + for (const Database::Cluster::pointer& cluster : clusters) { - auto clusterId = cluster->getId(); - auto entry = clusterContainers->addWidget(LmsApp->createCluster(cluster)); + const Database::ClusterId clusterId = cluster->getId(); + Wt::WInteractWidget* entry {clusterContainers->addWidget(Utils::createCluster(clusterId))}; entry->clicked().connect([=] { _filters->add(clusterId); diff --git a/src/lms/ui/explore/Filters.cpp b/src/lms/ui/explore/Filters.cpp index bdf46f72..c66b743f 100644 --- a/src/lms/ui/explore/Filters.cpp +++ b/src/lms/ui/explore/Filters.cpp @@ -28,6 +28,7 @@ #include "services/database/Session.hpp" #include "LmsApplication.hpp" +#include "Utils.hpp" #include "ModalManager.hpp" namespace UserInterface { @@ -124,23 +125,21 @@ void Filters::add(ClusterId clusterId) { + if (std::find(std::cbegin(_clusterIds), std::cend(_clusterIds), clusterId) != std::cend(_clusterIds)) + return; + Wt::WInteractWidget* filter {}; { - auto transaction {LmsApp->getDbSession().createSharedTransaction()}; - - Cluster::pointer cluster {Cluster::find(LmsApp->getDbSession(), clusterId)}; + auto cluster {Utils::createCluster(clusterId, true)}; if (!cluster) return; - if (std::find(std::cbegin(_clusterIds), std::cend(_clusterIds), clusterId) != std::cend(_clusterIds)) - return; - - _clusterIds.push_back(clusterId); - - filter = _filters->addWidget(LmsApp->createCluster(cluster, true)); + filter = _filters->addWidget(std::move(cluster)); } + _clusterIds.push_back(clusterId); + filter->clicked().connect([=] { _filters->removeWidget(filter); diff --git a/src/lms/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp index 0cbafedb..ef67908d 100644 --- a/src/lms/ui/explore/ReleaseView.cpp +++ b/src/lms/ui/explore/ReleaseView.cpp @@ -139,10 +139,10 @@ Release::refreshView() for (const auto& clusters : clusterGroups) { - for (const auto& cluster : clusters) + for (const Database::Cluster::pointer& cluster : clusters) { const ClusterId clusterId {cluster->getId()}; - auto entry {clusterContainers->addWidget(LmsApp->createCluster(cluster))}; + Wt::WInteractWidget* entry {clusterContainers->addWidget(Utils::createCluster(clusterId))}; entry->clicked().connect([=] { _filters->add(clusterId);