Added basic lyrics display in UI

This commit is contained in:
emeric
2024-10-27 23:03:46 +01:00
parent f613d16fc2
commit 41504bf4d7
17 changed files with 227 additions and 19 deletions
+5
View File
@@ -441,6 +441,11 @@ namespace lms::db
_trackLyrics.insert(getDboPtr(lyrics));
}
bool Track::hasLyrics() const
{
return !_trackLyrics.empty();
}
std::optional<std::string> Track::getCopyright() const
{
return _copyright != "" ? std::make_optional<std::string>(_copyright) : std::nullopt;
+31 -6
View File
@@ -34,6 +34,34 @@
namespace lms::db
{
namespace
{
Wt::Dbo::Query<Wt::Dbo::ptr<TrackLyrics>> createQuery(Session& session, const TrackLyrics::FindParameters& params)
{
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<TrackLyrics>>("SELECT t_lrc from track_lyrics t_lrc") };
if (params.track.isValid())
query.where("t_lrc.track_id = ?").bind(params.track);
if (params.external.has_value())
query.where("t_lrc.absolute_file_path " + std::string{ *params.external ? "<>" : "=" } + " ''");
switch (params.sortMethod)
{
case TrackLyricsSortMethod::None:
break;
case TrackLyricsSortMethod::ExternalFirst:
query.orderBy("CASE WHEN absolute_file_path <> '' THEN 0 ELSE 1 END");
break;
case TrackLyricsSortMethod::EmbeddedFirst:
query.orderBy("CASE WHEN absolute_file_path = '' THEN 0 ELSE 1 END");
break;
}
return query;
}
} // namespace
TrackLyrics::pointer TrackLyrics::create(Session& session)
{
return session.getDboSession()->add(std::unique_ptr<TrackLyrics>{ new TrackLyrics{} });
@@ -67,15 +95,12 @@ namespace lms::db
return utils::fetchQuerySingleResult(session.getDboSession()->query<Wt::Dbo::ptr<TrackLyrics>>("SELECT t_lrc from track_lyrics t_lrc").where("t_lrc.absolute_file_path = ?").bind(path));
}
void TrackLyrics::find(Session& session, TrackId trackId, const std::function<void(const TrackLyrics::pointer&)>& func)
void TrackLyrics::find(Session& session, const FindParameters& params, const std::function<void(const TrackLyrics::pointer&)>& func)
{
session.checkReadTransaction();
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<TrackLyrics>>("SELECT t_lrc from track_lyrics t_lrc").where("t_lrc.track_id = ?").bind(trackId) };
utils::forEachQueryResult(query, [&](const TrackLyrics::pointer& lyrics) {
func(lyrics);
});
auto query{ createQuery(session, params) };
utils::forEachQueryRangeResult(query, params.range, func);
}
void TrackLyrics::find(Session& session, TrackLyricsId& lastRetrievedId, std::size_t count, const std::function<void(const TrackLyrics::pointer&)>& func)
@@ -274,6 +274,7 @@ namespace lms::db
const Wt::WDateTime& getLastWriteTime() const { return _fileLastWrite; }
const Wt::WDateTime& getAddedTime() const { return _fileAdded; }
bool hasCover() const { return _hasCover; }
bool hasLyrics() const;
std::optional<core::UUID> getTrackMBID() const { return core::UUID::fromString(_trackMBID); }
std::optional<core::UUID> getRecordingMBID() const { return core::UUID::fromString(_recordingMBID); }
std::optional<std::string> getCopyright() const;
@@ -45,12 +45,41 @@ namespace lms::db
public:
TrackLyrics() = default;
struct FindParameters
{
std::optional<Range> range;
TrackId track;
std::optional<bool> external; // if set, true means external, false means embedded
TrackLyricsSortMethod sortMethod{ TrackLyricsSortMethod::None };
FindParameters& setRange(std::optional<Range> _range)
{
range = _range;
return *this;
}
FindParameters& setTrack(TrackId _track)
{
track = _track;
return *this;
}
FindParameters& setExternal(std::optional<bool> _external)
{
external = _external;
return *this;
}
FindParameters& setSortMethod(TrackLyricsSortMethod _sortMethod)
{
sortMethod = _sortMethod;
return *this;
}
};
// Find utilities
static std::size_t getCount(Session& session);
static std::size_t getExternalLyricsCount(Session& session);
static pointer find(Session& session, TrackLyricsId id);
static pointer find(Session& session, const std::filesystem::path& file);
static void find(Session& session, TrackId trackId, const std::function<void(const TrackLyrics::pointer&)>& func);
static void find(Session& session, const FindParameters& params, const std::function<void(const TrackLyrics::pointer&)>& func);
static void find(Session& session, TrackLyricsId& lastRetrievedId, std::size_t count, const std::function<void(const TrackLyrics::pointer&)>& func);
static RangeResults<TrackLyricsId> findOrphanIds(Session& session, std::optional<Range> range);
@@ -166,6 +166,13 @@ namespace lms::db
TrackList, // order by asc order in tracklist
};
enum class TrackLyricsSortMethod
{
None,
ExternalFirst,
EmbeddedFirst,
};
enum class TrackArtistLinkType
{
Artist = 0, // regular track artist
+41 -6
View File
@@ -157,12 +157,47 @@ namespace lms::db::tests
EXPECT_EQ(TrackLyrics::getCount(session), 1);
EXPECT_EQ(TrackLyrics::getExternalLyricsCount(session), 1);
bool visited{};
TrackLyrics::find(session, track.getId(), [&](const TrackLyrics::pointer& lyrics) {
EXPECT_EQ(lyrics->getAbsoluteFilePath(), "/tmp/test.lrc");
visited = true;
});
EXPECT_TRUE(visited);
{
bool visited{};
TrackLyrics::find(session, TrackLyrics::FindParameters{}.setTrack(track.getId()), [&](const TrackLyrics::pointer& lyrics) {
EXPECT_EQ(lyrics->getAbsoluteFilePath(), "/tmp/test.lrc");
visited = true;
});
EXPECT_TRUE(visited);
}
{
bool visited{};
TrackLyrics::find(session, TrackLyrics::FindParameters{}.setExternal(true), [&](const TrackLyrics::pointer& lyrics) {
EXPECT_EQ(lyrics->getAbsoluteFilePath(), "/tmp/test.lrc");
visited = true;
});
EXPECT_TRUE(visited);
}
{
bool visited{};
TrackLyrics::find(session, TrackLyrics::FindParameters{}.setExternal(false), [&](const TrackLyrics::pointer&) {
visited = true;
});
EXPECT_FALSE(visited);
}
{
bool visited{};
TrackLyrics::find(session, TrackLyrics::FindParameters{}.setSortMethod(TrackLyricsSortMethod::EmbeddedFirst), [&](const TrackLyrics::pointer&) {
visited = true;
});
EXPECT_TRUE(visited);
}
{
bool visited{};
TrackLyrics::find(session, TrackLyrics::FindParameters{}.setSortMethod(TrackLyricsSortMethod::ExternalFirst), [&](const TrackLyrics::pointer&) {
visited = true;
});
EXPECT_TRUE(visited);
}
}
}
} // namespace lms::db::tests