Improved work display, when available, ref #834
This commit is contained in:
@@ -244,7 +244,7 @@ namespace lms::ui
|
||||
const std::string nativeResource{ _audioFileResource->getUrl(trackId) };
|
||||
|
||||
const auto artistDisplayInfo{ utils::computeArtistDisplayInfo(track, db::TrackArtistLinkType::Artist) };
|
||||
const std::string displayTitle{ utils::computeTrackDisplayTitle(track) };
|
||||
const std::string displayTitle{ utils::computeTrackDisplayInfo(track).title };
|
||||
|
||||
oss
|
||||
<< "var params = {"
|
||||
|
||||
@@ -497,12 +497,17 @@ namespace lms::ui
|
||||
const auto track{ tracklistEntry->getTrack() };
|
||||
const db::TrackId trackId{ track->getId() };
|
||||
|
||||
const std::string displayTitle{ utils::computeTrackDisplayTitle(track) };
|
||||
const utils::TrackDisplayInfo displayInfo{ utils::computeTrackDisplayInfo(track) };
|
||||
|
||||
Template* entry{ _entriesContainer->addNew<Template>(Wt::WString::tr("Lms.PlayQueue.template.entry")) };
|
||||
entry->addFunction("id", &Wt::WTemplate::Functions::id);
|
||||
|
||||
entry->bindString("name", Wt::WString::fromUTF8(displayTitle), Wt::TextFormat::Plain);
|
||||
entry->bindString("name", Wt::WString::fromUTF8(displayInfo.title), Wt::TextFormat::Plain);
|
||||
if (displayInfo.workName)
|
||||
{
|
||||
entry->setCondition("if-has-work", true);
|
||||
entry->bindString("work", Wt::WString::fromUTF8(*displayInfo.workName), Wt::TextFormat::Plain);
|
||||
}
|
||||
|
||||
const auto artists{ track->getArtistIds({ db::TrackArtistLinkType::Artist }) };
|
||||
if (!artists.empty())
|
||||
@@ -541,7 +546,7 @@ namespace lms::ui
|
||||
entry->bindString("duration", utils::durationToString(track->getDuration()), Wt::TextFormat::Plain);
|
||||
|
||||
Wt::WPushButton* playBtn{ entry->bindNew<Wt::WPushButton>("play-btn", Wt::WString::tr("Lms.template.play-btn"), Wt::TextFormat::XHTML) };
|
||||
playBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.play-item").arg(displayTitle));
|
||||
playBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.play-item").arg(displayInfo.title));
|
||||
playBtn->clicked().connect([this, entry] {
|
||||
const std::optional<std::size_t> pos{ _entriesContainer->getIndexOf(*entry) };
|
||||
if (pos)
|
||||
@@ -549,7 +554,7 @@ namespace lms::ui
|
||||
});
|
||||
|
||||
Wt::WPushButton* delBtn{ entry->bindNew<Wt::WPushButton>("del-btn", Wt::WString::tr("Lms.template.delete-btn"), Wt::TextFormat::XHTML) };
|
||||
delBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.delete-item").arg(displayTitle));
|
||||
delBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.delete-item").arg(displayInfo.title));
|
||||
delBtn->setToolTip(Wt::WString::tr("Lms.delete"));
|
||||
delBtn->clicked().connect([this, tracklistEntryId, entry] {
|
||||
// Remove the entry n both the widget tree and the playqueue
|
||||
|
||||
+14
-7
@@ -43,6 +43,7 @@
|
||||
#include "database/objects/Track.hpp"
|
||||
#include "database/objects/TrackArtistLink.hpp"
|
||||
#include "database/objects/TrackList.hpp"
|
||||
#include "database/objects/Work.hpp"
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
#include "ModalManager.hpp"
|
||||
@@ -562,25 +563,31 @@ namespace lms::ui::utils
|
||||
LmsApp->doJavaScript("navigator.clipboard.writeText('" + core::stringUtils::jsEscape(text) + "').catch(function(){})");
|
||||
}
|
||||
|
||||
std::string computeTrackDisplayTitle(const db::ObjectPtr<db::Track>& track)
|
||||
TrackDisplayInfo computeTrackDisplayInfo(const db::ObjectPtr<db::Track>& track)
|
||||
{
|
||||
const auto movements{ track->getMovements() };
|
||||
if (!movements.empty() && track->hasWork())
|
||||
{
|
||||
const db::Movement::pointer& movement{ movements.front() };
|
||||
std::string result;
|
||||
std::string title;
|
||||
if (const auto n{ movement->getNumber() })
|
||||
{
|
||||
if (const std::string numeral{ core::stringUtils::toRomanNumeral(*n) }; !numeral.empty())
|
||||
result += numeral + ". ";
|
||||
title += numeral + ". ";
|
||||
}
|
||||
|
||||
result += movement->getName();
|
||||
title += movement->getName();
|
||||
|
||||
if (!result.empty())
|
||||
return result;
|
||||
if (!title.empty())
|
||||
{
|
||||
TrackDisplayInfo info{ .title = std::move(title), .workName = std::nullopt };
|
||||
if (const auto works{ track->getWorks() }; !works.empty())
|
||||
info.workName = std::string{ works.front()->getName() };
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string{ track->getName() };
|
||||
return TrackDisplayInfo{ .title = std::string{ track->getName() }, .workName = std::nullopt };
|
||||
}
|
||||
} // namespace lms::ui::utils
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
@@ -104,6 +105,10 @@ namespace lms::ui::utils
|
||||
|
||||
void copyToClipboard(std::string_view text);
|
||||
|
||||
// Returns "i. MovementName" when track has work(s) + movement(s), otherwise track->getName().
|
||||
std::string computeTrackDisplayTitle(const db::ObjectPtr<db::Track>& track);
|
||||
struct TrackDisplayInfo
|
||||
{
|
||||
std::string title; // "i. MovementName" when track has work + movement, otherwise just the track's title
|
||||
std::optional<std::string> workName; // only set when title comes from a movement
|
||||
};
|
||||
TrackDisplayInfo computeTrackDisplayInfo(const db::ObjectPtr<db::Track>& track);
|
||||
} // namespace lms::ui::utils
|
||||
|
||||
@@ -230,8 +230,13 @@ namespace lms::ui::TrackListHelpers
|
||||
auto entry{ std::make_unique<Template>(Wt::WString::tr("Lms.Explore.Tracks.template.entry")) };
|
||||
auto* entryPtr{ entry.get() };
|
||||
|
||||
const std::string displayTitle{ utils::computeTrackDisplayTitle(track) };
|
||||
entry->bindString("name", Wt::WString::fromUTF8(displayTitle), Wt::TextFormat::Plain);
|
||||
const utils::TrackDisplayInfo displayInfo{ utils::computeTrackDisplayInfo(track) };
|
||||
entry->bindString("name", Wt::WString::fromUTF8(displayInfo.title), Wt::TextFormat::Plain);
|
||||
if (displayInfo.workName)
|
||||
{
|
||||
entry->setCondition("if-has-work", true);
|
||||
entry->bindString("work", Wt::WString::fromUTF8(*displayInfo.workName), Wt::TextFormat::Plain);
|
||||
}
|
||||
|
||||
const db::Release::pointer release{ track->getRelease() };
|
||||
const db::TrackId trackId{ track->getId() };
|
||||
@@ -270,7 +275,7 @@ namespace lms::ui::TrackListHelpers
|
||||
entry->bindString("duration", utils::durationToString(track->getDuration()), Wt::TextFormat::Plain);
|
||||
|
||||
Wt::WPushButton* playBtn{ entry->bindNew<Wt::WPushButton>("play-btn", Wt::WString::tr("Lms.template.play-btn"), Wt::TextFormat::XHTML) };
|
||||
playBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.play-item").arg(displayTitle));
|
||||
playBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.play-item").arg(displayInfo.title));
|
||||
playBtn->clicked().connect([trackId, &playQueueController] {
|
||||
db::TrackId trackIds[]{ trackId };
|
||||
playQueueController.processCommand(PlayQueueController::Command::Play, trackIds);
|
||||
@@ -302,7 +307,7 @@ namespace lms::ui::TrackListHelpers
|
||||
auto isStarred{ [=] { return core::Service<feedback::IFeedbackService>::get()->isStarred(LmsApp->getUserId(), trackId); } };
|
||||
|
||||
Wt::WPushButton* starBtn{ entry->bindNew<Wt::WPushButton>("star-btn", Wt::WString::tr(isStarred() ? "Lms.template.unstar-btn" : "Lms.template.star-btn"), Wt::TextFormat::XHTML) };
|
||||
starBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.Explore.star-item").arg(displayTitle));
|
||||
starBtn->setAttributeValue("aria-label", Wt::WString::tr("Lms.Explore.star-item").arg(displayInfo.title));
|
||||
starBtn->setAttributeValue("aria-pressed", isStarred() ? "true" : "false");
|
||||
Wt::WPushButton* starMenuEntry{ entry->bindNew<Wt::WPushButton>("star", Wt::WString::tr(isStarred() ? "Lms.Explore.unstar" : "Lms.Explore.star")) };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user