Factorized sort mode, now using a more compact dropdown menu
This commit is contained in:
+23
-26
@@ -3,32 +3,9 @@
|
||||
<!--FORMS message blocks-->
|
||||
|
||||
<message id="Lms.Explore.Artists.template">
|
||||
<div class="mb-3">
|
||||
<ul class="nav nav-pills mb-2">
|
||||
<li class="nav-item">
|
||||
${random class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${starred class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${most-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-added class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${all class="nav-link"}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
${link-type class="form-select"}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
${link-type}
|
||||
${sort-mode}
|
||||
</div>
|
||||
${artists}
|
||||
</message>
|
||||
@@ -42,4 +19,24 @@
|
||||
${loading-indicator}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Artists.template.track-artist-link-type-selector">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
${link-type}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>${link-type-all class="dropdown-item"}</li>
|
||||
<li>${link-type-artist class="dropdown-item"}</li>
|
||||
<li>${link-type-releaseartist class="dropdown-item"}</li>
|
||||
<li>${link-type-composer class="dropdown-item"}</li>
|
||||
<li>${link-type-conductor class="dropdown-item"}</li>
|
||||
<li>${link-type-lyricist class="dropdown-item"}</li>
|
||||
<li>${link-type-mixer class="dropdown-item"}</li>
|
||||
<li>${link-type-performer class="dropdown-item"}</li>
|
||||
<li>${link-type-producer class="dropdown-item"}</li>
|
||||
<li>${link-type-remixer class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
|
||||
@@ -52,5 +52,20 @@
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.template.sort-mode-selector">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
${sort-mode}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>${random class="dropdown-item"}</li>
|
||||
<li>${starred class="dropdown-item"}</li>
|
||||
<li>${recently-played class="dropdown-item"}</li>
|
||||
<li>${most-played class="dropdown-item"}</li>
|
||||
<li>${recently-added class="dropdown-item"}</li>
|
||||
<li>${all class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
|
||||
+2
-21
@@ -3,27 +3,7 @@
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
|
||||
<message id="Lms.Explore.Releases.template">
|
||||
<div class="mb-3">
|
||||
<ul class="nav nav-pills mb-2">
|
||||
<li class="nav-item">
|
||||
${random class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${starred class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${most-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-added class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${all class="nav-link"}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="btn-group">
|
||||
${play-btn class="btn btn-primary"}
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
|
||||
@@ -33,6 +13,7 @@
|
||||
<li>${play-shuffled class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
${sort-mode}
|
||||
</div>
|
||||
${releases}
|
||||
</message>
|
||||
|
||||
+2
-4
@@ -20,10 +20,8 @@
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.Search.template.artists">
|
||||
<div class="row mb-3">
|
||||
<div class="col-lg-3">
|
||||
${link-type class="form-select"}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
${link-type}
|
||||
</div>
|
||||
${artists}
|
||||
</message>
|
||||
|
||||
+2
-21
@@ -4,27 +4,7 @@
|
||||
<!--FORMS message blocks-->
|
||||
|
||||
<message id="Lms.Explore.Tracks.template">
|
||||
<div class="mb-3">
|
||||
<ul class="nav nav-pills mb-2">
|
||||
<li class="nav-item">
|
||||
${random class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${starred class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${most-played class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${recently-added class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${all class="nav-link"}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="btn-group">
|
||||
${play-btn class="btn btn-primary"}
|
||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"/>
|
||||
@@ -34,6 +14,7 @@
|
||||
<li>${play-shuffled class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
${sort-mode}
|
||||
</div>
|
||||
${tracks}
|
||||
</message>
|
||||
|
||||
@@ -105,20 +105,6 @@ namespace lms::db
|
||||
});
|
||||
}
|
||||
|
||||
core::EnumSet<TrackArtistLinkType> TrackArtistLink::findUsedTypes(Session& session)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
const auto query{ session.getDboSession()->query<TrackArtistLinkType>("SELECT DISTINCT type from track_artist_link") };
|
||||
|
||||
core::EnumSet<TrackArtistLinkType> res;
|
||||
utils::forEachQueryResult(query, [&](TrackArtistLinkType linkType)
|
||||
{
|
||||
res.insert(linkType);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
core::EnumSet<TrackArtistLinkType> TrackArtistLink::findUsedTypes(Session& session, ArtistId artistId)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
@@ -66,7 +66,6 @@ namespace lms::db
|
||||
static void find(Session& session, const FindParameters& parameters, const std::function<void(const TrackArtistLink::pointer&)>&);
|
||||
static pointer find(Session& session, TrackArtistLinkId linkId);
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<Artist> artist, TrackArtistLinkType type, std::string_view subType = {});
|
||||
static core::EnumSet<TrackArtistLinkType> findUsedTypes(Session& session);
|
||||
static core::EnumSet<TrackArtistLinkType> findUsedTypes(Session& session, ArtistId _artist);
|
||||
|
||||
ObjectPtr<Track> getTrack() const { return _track; }
|
||||
|
||||
@@ -43,6 +43,8 @@ add_executable(lms
|
||||
ui/explore/ReleaseView.cpp
|
||||
ui/explore/ReleaseTypes.cpp
|
||||
ui/explore/SearchView.cpp
|
||||
ui/explore/SortModeSelector.cpp
|
||||
ui/explore/TrackArtistLinkTypeSelector.cpp
|
||||
ui/explore/TrackCollector.cpp
|
||||
ui/explore/TrackListHelpers.cpp
|
||||
ui/explore/TrackListView.cpp
|
||||
|
||||
@@ -18,62 +18,18 @@
|
||||
*/
|
||||
#include "ArtistListHelpers.hpp"
|
||||
|
||||
#include <Wt/WAnchor.h>
|
||||
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/TrackArtistLink.hpp"
|
||||
#include "core/EnumSet.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace lms::ui::ArtistListHelpers
|
||||
{
|
||||
std::unique_ptr<Wt::WTemplate>
|
||||
createEntry(const db::ObjectPtr<db::Artist>& artist)
|
||||
{
|
||||
auto res {std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artists.template.entry"))};
|
||||
res->bindWidget("name", utils::createArtistAnchor(artist));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::unique_ptr<ArtistLinkTypesModel>
|
||||
createArtistLinkTypesModel()
|
||||
{
|
||||
using namespace db;
|
||||
|
||||
std::unique_ptr<ArtistLinkTypesModel> linkTypesModel {std::make_unique<ArtistLinkTypesModel>()};
|
||||
|
||||
core::EnumSet<TrackArtistLinkType> usedLinkTypes;
|
||||
{
|
||||
auto transaction {LmsApp->getDbSession().createReadTransaction()};
|
||||
usedLinkTypes = TrackArtistLink::findUsedTypes(LmsApp->getDbSession());
|
||||
}
|
||||
|
||||
auto addTypeIfUsed {[&](TrackArtistLinkType linkType, std::string_view stringKey)
|
||||
{
|
||||
if (!usedLinkTypes.contains(linkType))
|
||||
return;
|
||||
|
||||
linkTypesModel->add(Wt::WString::trn(std::string {stringKey}, 2), linkType);
|
||||
}};
|
||||
|
||||
// add default one first (none)
|
||||
linkTypesModel->add(Wt::WString::tr("Lms.Explore.Artists.linktype-all"), std::nullopt);
|
||||
|
||||
// TODO: sort by translated strings
|
||||
addTypeIfUsed(TrackArtistLinkType::Artist, "Lms.Explore.Artists.linktype-artist");
|
||||
addTypeIfUsed(TrackArtistLinkType::ReleaseArtist, "Lms.Explore.Artists.linktype-releaseartist");
|
||||
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::Mixer, "Lms.Explore.Artists.linktype-mixer");
|
||||
addTypeIfUsed(TrackArtistLinkType::Performer, "Lms.Explore.Artists.linktype-performer");
|
||||
addTypeIfUsed(TrackArtistLinkType::Producer, "Lms.Explore.Artists.linktype-producer");
|
||||
addTypeIfUsed(TrackArtistLinkType::Remixer, "Lms.Explore.Artists.linktype-remixer");
|
||||
|
||||
return linkTypesModel;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<Wt::WTemplate> createEntry(const db::ObjectPtr<db::Artist>& artist)
|
||||
{
|
||||
auto res{ std::make_unique<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Artists.template.entry")) };
|
||||
res->bindWidget("name", utils::createArtistAnchor(artist));
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,6 @@ namespace lms::ui
|
||||
namespace ArtistListHelpers
|
||||
{
|
||||
std::unique_ptr<Wt::WTemplate> createEntry(const db::ObjectPtr<db::Artist>& artist);
|
||||
std::unique_ptr<ArtistLinkTypesModel> createArtistLinkTypesModel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,15 +21,17 @@
|
||||
|
||||
#include <Wt/WPushButton.h>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/TrackArtistLink.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
|
||||
#include "common/InfiniteScrollingContainer.hpp"
|
||||
#include "ArtistListHelpers.hpp"
|
||||
#include "Filters.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "SortModeSelector.hpp"
|
||||
#include "TrackArtistLinkTypeSelector.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
@@ -37,49 +39,22 @@ namespace lms::ui
|
||||
|
||||
Artists::Artists(Filters& filters)
|
||||
: Wt::WTemplate{ Wt::WString::tr("Lms.Explore.Artists.template") }
|
||||
, _artistCollector{ filters, _defaultMode, _maxCount }
|
||||
, _artistCollector{ filters, _defaultSortMode, _maxCount }
|
||||
{
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
|
||||
auto bindMenuItem{ [this](const std::string& var, const Wt::WString& title, ArtistCollector::Mode mode)
|
||||
{
|
||||
auto* menuItem {bindNew<Wt::WPushButton>(var, title)};
|
||||
menuItem->clicked().connect([=, this]
|
||||
SortModeSelector* sortModeSelector{ bindNew<SortModeSelector>("sort-mode", _defaultSortMode) };
|
||||
sortModeSelector->sortModeChanged.connect([this](ArtistCollector::Mode sortMode)
|
||||
{
|
||||
refreshView(mode);
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
refreshView(sortMode);
|
||||
});
|
||||
|
||||
if (mode == _defaultMode)
|
||||
TrackArtistLinkTypeSelector* linkTypeSelector{ bindNew<TrackArtistLinkTypeSelector>("link-type", _defaultLinkType) };
|
||||
linkTypeSelector->linkTypeChanged.connect([this](std::optional<TrackArtistLinkType> linkType)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("random", Wt::WString::tr("Lms.Explore.random"), ArtistCollector::Mode::Random);
|
||||
bindMenuItem("starred", Wt::WString::tr("Lms.Explore.starred"), ArtistCollector::Mode::Starred);
|
||||
bindMenuItem("recently-played", Wt::WString::tr("Lms.Explore.recently-played"), ArtistCollector::Mode::RecentlyPlayed);
|
||||
bindMenuItem("most-played", Wt::WString::tr("Lms.Explore.most-played"), ArtistCollector::Mode::MostPlayed);
|
||||
bindMenuItem("recently-added", Wt::WString::tr("Lms.Explore.recently-added"), ArtistCollector::Mode::RecentlyAdded);
|
||||
bindMenuItem("all", Wt::WString::tr("Lms.Explore.all"), ArtistCollector::Mode::All);
|
||||
|
||||
_linkType = bindNew<Wt::WComboBox>("link-type");
|
||||
_linkType->setModel(ArtistListHelpers::createArtistLinkTypesModel());
|
||||
_linkType->changed().connect([this]
|
||||
{
|
||||
const std::optional<TrackArtistLinkType> linkType{ static_cast<ArtistLinkTypesModel*>(_linkType->model().get())->getValue(_linkType->currentIndex()) };
|
||||
refreshView(linkType);
|
||||
});
|
||||
|
||||
LmsApp->getScannerEvents().scanComplete.connect(this, [this](const scanner::ScanStats& stats)
|
||||
{
|
||||
if (stats.nbChanges())
|
||||
_linkType->setModel(ArtistListHelpers::createArtistLinkTypesModel());
|
||||
});
|
||||
|
||||
_container = bindNew<InfiniteScrollingContainer>("artists", Wt::WString::tr("Lms.Explore.Artists.template.container"));
|
||||
_container->onRequestElements.connect([this]
|
||||
{
|
||||
|
||||
@@ -30,28 +30,28 @@
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
|
||||
class Artists : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
Artists(Filters& filters);
|
||||
class Artists : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
Artists(Filters& filters);
|
||||
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(ArtistCollector::Mode mode);
|
||||
void refreshView(std::optional<db::TrackArtistLinkType> linkType);
|
||||
void addSome();
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(ArtistCollector::Mode mode);
|
||||
void refreshView(std::optional<db::TrackArtistLinkType> linkType);
|
||||
void addSome();
|
||||
|
||||
static constexpr std::size_t _batchSize {30};
|
||||
static constexpr std::size_t _maxCount {8000};
|
||||
static constexpr std::size_t _batchSize{ 30 };
|
||||
static constexpr std::size_t _maxCount{ 8000 };
|
||||
|
||||
Wt::WWidget* _currentActiveItem {};
|
||||
InfiniteScrollingContainer* _container {};
|
||||
ArtistCollector _artistCollector;
|
||||
Wt::WComboBox* _linkType {};
|
||||
static constexpr ArtistCollector::Mode _defaultMode {ArtistCollector::Mode::Random};
|
||||
};
|
||||
Wt::WWidget* _currentLinkTypeActiveItem{};
|
||||
InfiniteScrollingContainer* _container{};
|
||||
ArtistCollector _artistCollector;
|
||||
static constexpr ArtistCollector::Mode _defaultSortMode{ ArtistCollector::Mode::Random };
|
||||
static constexpr std::optional<db::TrackArtistLinkType> _defaultLinkType;
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -32,97 +32,94 @@
|
||||
#include "TrackListsView.hpp"
|
||||
#include "TracksView.hpp"
|
||||
|
||||
namespace lms::ui {
|
||||
namespace lms::ui
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void handleContentsPathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
enum Idx
|
||||
{
|
||||
IdxArtists = 0,
|
||||
IdxArtist,
|
||||
IdxTrackLists,
|
||||
IdxTrackList,
|
||||
IdxReleases,
|
||||
IdxRelease,
|
||||
IdxSearch,
|
||||
IdxTracks,
|
||||
};
|
||||
|
||||
namespace {
|
||||
static const std::map<std::string, int> indexes =
|
||||
{
|
||||
{ "/artists", IdxArtists },
|
||||
{ "/artist", IdxArtist },
|
||||
{ "/tracklists", IdxTrackLists },
|
||||
{ "/tracklist", IdxTrackList },
|
||||
{ "/releases", IdxReleases },
|
||||
{ "/release", IdxRelease },
|
||||
{ "/search", IdxSearch },
|
||||
{ "/tracks", IdxTracks },
|
||||
};
|
||||
|
||||
void
|
||||
handleContentsPathChange(Wt::WStackedWidget* stack)
|
||||
{
|
||||
enum Idx
|
||||
{
|
||||
IdxArtists = 0,
|
||||
IdxArtist,
|
||||
IdxTrackLists,
|
||||
IdxTrackList,
|
||||
IdxReleases,
|
||||
IdxRelease,
|
||||
IdxSearch,
|
||||
IdxTracks,
|
||||
};
|
||||
for (const auto& index : indexes)
|
||||
{
|
||||
if (wApp->internalPathMatches(index.first))
|
||||
{
|
||||
stack->setCurrentIndex(index.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const std::map<std::string, int> indexes =
|
||||
{
|
||||
{ "/artists", IdxArtists },
|
||||
{ "/artist", IdxArtist },
|
||||
{ "/tracklists", IdxTrackLists },
|
||||
{ "/tracklist", IdxTrackList },
|
||||
{ "/releases", IdxReleases },
|
||||
{ "/release", IdxRelease },
|
||||
{ "/search", IdxSearch },
|
||||
{ "/tracks", IdxTracks },
|
||||
};
|
||||
} // namespace
|
||||
|
||||
for (const auto& index : indexes)
|
||||
{
|
||||
if (wApp->internalPathMatches(index.first))
|
||||
{
|
||||
stack->setCurrentIndex(index.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Explore::Explore(Filters& filters, PlayQueue& playQueue)
|
||||
: Wt::WTemplate{ Wt::WString::tr("Lms.Explore.template") }
|
||||
, _playQueueController{ filters, playQueue }
|
||||
{
|
||||
addFunction("tr", &Functions::tr);
|
||||
|
||||
} // namespace
|
||||
// Contents
|
||||
Wt::WStackedWidget* contentsStack{ bindNew<Wt::WStackedWidget>("contents") };
|
||||
contentsStack->setOverflow(Wt::Overflow::Visible); // wt makes it hidden by default
|
||||
|
||||
Explore::Explore(Filters& filters, PlayQueue& playQueue)
|
||||
: Wt::WTemplate {Wt::WString::tr("Lms.Explore.template")}
|
||||
, _playQueueController {filters, playQueue}
|
||||
{
|
||||
addFunction("tr", &Functions::tr);
|
||||
// same order as enum Idx
|
||||
auto artists = std::make_unique<Artists>(filters);
|
||||
contentsStack->addWidget(std::move(artists));
|
||||
|
||||
// Contents
|
||||
Wt::WStackedWidget* contentsStack {bindNew<Wt::WStackedWidget>("contents")};
|
||||
contentsStack->setOverflow(Wt::Overflow::Visible); // wt makes it hidden by default
|
||||
auto artist = std::make_unique<Artist>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(artist));
|
||||
|
||||
// same order as enum Idx
|
||||
auto artists = std::make_unique<Artists>(filters);
|
||||
contentsStack->addWidget(std::move(artists));
|
||||
auto trackLists{ std::make_unique<TrackLists>(filters) };
|
||||
auto trackList{ std::make_unique<TrackList>(filters, _playQueueController) };
|
||||
trackList->trackListDeleted.connect(trackLists.get(), &TrackLists::onTrackListDeleted);
|
||||
contentsStack->addWidget(std::move(trackLists));
|
||||
contentsStack->addWidget(std::move(trackList));
|
||||
|
||||
auto artist = std::make_unique<Artist>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(artist));
|
||||
auto releases = std::make_unique<Releases>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(releases));
|
||||
|
||||
auto trackLists {std::make_unique<TrackLists>(filters)};
|
||||
auto trackList {std::make_unique<TrackList>(filters, _playQueueController)};
|
||||
trackList->trackListDeleted.connect(trackLists.get(), &TrackLists::onTrackListDeleted);
|
||||
contentsStack->addWidget(std::move(trackLists));
|
||||
contentsStack->addWidget(std::move(trackList));
|
||||
auto release = std::make_unique<Release>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(release));
|
||||
|
||||
auto releases = std::make_unique<Releases>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(releases));
|
||||
auto search = std::make_unique<SearchView>(filters, _playQueueController);
|
||||
_search = search.get();
|
||||
contentsStack->addWidget(std::move(search));
|
||||
|
||||
auto release = std::make_unique<Release>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(release));
|
||||
auto tracks = std::make_unique<Tracks>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(tracks));
|
||||
|
||||
auto search = std::make_unique<SearchView>(filters, _playQueueController);
|
||||
_search = search.get();
|
||||
contentsStack->addWidget(std::move(search));
|
||||
wApp->internalPathChanged().connect(this, [contentsStack]
|
||||
{
|
||||
handleContentsPathChange(contentsStack);
|
||||
});
|
||||
|
||||
auto tracks = std::make_unique<Tracks>(filters, _playQueueController);
|
||||
contentsStack->addWidget(std::move(tracks));
|
||||
|
||||
wApp->internalPathChanged().connect(this, [=]
|
||||
{
|
||||
handleContentsPathChange(contentsStack);
|
||||
});
|
||||
|
||||
handleContentsPathChange(contentsStack);
|
||||
}
|
||||
|
||||
void
|
||||
Explore::search(const Wt::WString& searchText)
|
||||
{
|
||||
_search->refreshView(searchText);
|
||||
}
|
||||
handleContentsPathChange(contentsStack);
|
||||
}
|
||||
|
||||
void Explore::search(const Wt::WString& searchText)
|
||||
{
|
||||
_search->refreshView(searchText);
|
||||
}
|
||||
} // namespace lms::ui
|
||||
|
||||
@@ -20,25 +20,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "PlayQueueController.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class Filters;
|
||||
class SearchView;
|
||||
class PlayQueue;
|
||||
class Filters;
|
||||
class SearchView;
|
||||
class PlayQueue;
|
||||
|
||||
class Explore : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
Explore(Filters& filters, PlayQueue& playQueue);
|
||||
class Explore : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
Explore(Filters& filters, PlayQueue& playQueue);
|
||||
|
||||
void search(const Wt::WString& searchText);
|
||||
PlayQueueController& getPlayQueueController() { return _playQueueController; }
|
||||
void search(const Wt::WString& searchText);
|
||||
PlayQueueController& getPlayQueueController() { return _playQueueController; }
|
||||
|
||||
private:
|
||||
PlayQueueController _playQueueController;
|
||||
SearchView* _search {};
|
||||
};
|
||||
private:
|
||||
PlayQueueController _playQueueController;
|
||||
SearchView* _search{};
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "explore/PlayQueueController.hpp"
|
||||
#include "explore/ReleaseHelpers.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "SortModeSelector.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
@@ -43,31 +44,12 @@ namespace lms::ui
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
addFunction("id", &Wt::WTemplate::Functions::id);
|
||||
|
||||
auto bindMenuItem{ [this](const std::string& var, const Wt::WString& title, ReleaseCollector::Mode mode)
|
||||
{
|
||||
auto* menuItem {bindNew<Wt::WPushButton>(var, title)};
|
||||
menuItem->clicked().connect([this, mode, menuItem]
|
||||
SortModeSelector* sortMode{ bindNew<SortModeSelector>("sort-mode", _defaultMode) };
|
||||
sortMode->sortModeChanged.connect([this](ReleaseCollector::Mode sortMode)
|
||||
{
|
||||
refreshView(mode);
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
refreshView(sortMode);
|
||||
});
|
||||
|
||||
if (mode == _defaultMode)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("random", Wt::WString::tr("Lms.Explore.random"), ReleaseCollector::Mode::Random);
|
||||
bindMenuItem("starred", Wt::WString::tr("Lms.Explore.starred"), ReleaseCollector::Mode::Starred);
|
||||
bindMenuItem("recently-played", Wt::WString::tr("Lms.Explore.recently-played"), ReleaseCollector::Mode::RecentlyPlayed);
|
||||
bindMenuItem("most-played", Wt::WString::tr("Lms.Explore.most-played"), ReleaseCollector::Mode::MostPlayed);
|
||||
bindMenuItem("recently-added", Wt::WString::tr("Lms.Explore.recently-added"), ReleaseCollector::Mode::RecentlyAdded);
|
||||
bindMenuItem("all", Wt::WString::tr("Lms.Explore.all"), ReleaseCollector::Mode::All);
|
||||
|
||||
Wt::WPushButton* playBtn{ bindNew<Wt::WPushButton>("play-btn", Wt::WString::tr("Lms.Explore.play"), Wt::TextFormat::XHTML) };
|
||||
playBtn->clicked().connect([this]
|
||||
{
|
||||
|
||||
@@ -26,31 +26,30 @@
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class PlayQueueController;
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class PlayQueueController;
|
||||
|
||||
class Releases : public Template
|
||||
{
|
||||
public:
|
||||
Releases(Filters& filters, PlayQueueController& playQueueController);
|
||||
class Releases : public Template
|
||||
{
|
||||
public:
|
||||
Releases(Filters& filters, PlayQueueController& playQueueController);
|
||||
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(ReleaseCollector::Mode mode);
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(ReleaseCollector::Mode mode);
|
||||
|
||||
void addSome();
|
||||
std::vector<db::ReleaseId> getAllReleases();
|
||||
void addSome();
|
||||
std::vector<db::ReleaseId> getAllReleases();
|
||||
|
||||
static constexpr std::size_t _maxItemsPerLine {6};
|
||||
static constexpr std::size_t _batchSize {_maxItemsPerLine};
|
||||
static constexpr std::size_t _maxCount {_maxItemsPerLine * 500};
|
||||
static constexpr std::size_t _maxItemsPerLine{ 6 };
|
||||
static constexpr std::size_t _batchSize{ _maxItemsPerLine };
|
||||
static constexpr std::size_t _maxCount{ _maxItemsPerLine * 500 };
|
||||
|
||||
PlayQueueController& _playQueueController;
|
||||
Wt::WWidget* _currentActiveItem {};
|
||||
InfiniteScrollingContainer* _container {};
|
||||
ReleaseCollector _releaseCollector;
|
||||
static constexpr ReleaseCollector::Mode _defaultMode {ReleaseCollector::Mode::Random};
|
||||
};
|
||||
PlayQueueController& _playQueueController;
|
||||
InfiniteScrollingContainer* _container{};
|
||||
ReleaseCollector _releaseCollector;
|
||||
static constexpr ReleaseCollector::Mode _defaultMode{ ReleaseCollector::Mode::Random };
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Filters.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "ReleaseHelpers.hpp"
|
||||
#include "TrackArtistLinkTypeSelector.hpp"
|
||||
#include "TrackListHelpers.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
@@ -58,11 +59,9 @@ namespace lms::ui
|
||||
{
|
||||
Wt::WTemplate* artistResults{ _stack->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Explore.Search.template.artists")) };
|
||||
|
||||
_artistLinkType = artistResults->bindNew<Wt::WComboBox>("link-type");
|
||||
_artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel());
|
||||
_artistLinkType->changed().connect([this]
|
||||
TrackArtistLinkTypeSelector* linkTypeSelector{ artistResults->bindNew<TrackArtistLinkTypeSelector>("link-type", std::nullopt)};
|
||||
linkTypeSelector->linkTypeChanged.connect([this](std::optional<TrackArtistLinkType> linkType)
|
||||
{
|
||||
const std::optional<TrackArtistLinkType> linkType{ static_cast<ArtistLinkTypesModel*>(_artistLinkType->model().get())->getValue(_artistLinkType->currentIndex()) };
|
||||
refreshView(linkType);
|
||||
});
|
||||
|
||||
@@ -101,12 +100,6 @@ namespace lms::ui
|
||||
{
|
||||
refreshView();
|
||||
});
|
||||
|
||||
LmsApp->getScannerEvents().scanComplete.connect(this, [this](const scanner::ScanStats& stats)
|
||||
{
|
||||
if (stats.nbChanges())
|
||||
_artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel());
|
||||
});
|
||||
}
|
||||
|
||||
std::size_t SearchView::getBatchSize(Mode mode) const
|
||||
|
||||
@@ -85,8 +85,6 @@ namespace lms::ui
|
||||
InfiniteScrollingContainer* _artists{};
|
||||
InfiniteScrollingContainer* _releases{};
|
||||
InfiniteScrollingContainer* _tracks{};
|
||||
|
||||
Wt::WComboBox* _artistLinkType{};
|
||||
};
|
||||
|
||||
} // namespace lms::ui
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SortModeSelector.hpp"
|
||||
|
||||
#include <Wt/WPushButton.h>
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
SortModeSelector::SortModeSelector(DatabaseCollectorBase::Mode defaultMode)
|
||||
: Wt::WTemplate{ Wt::WString::tr("Lms.Explore.template.sort-mode-selector") }
|
||||
{
|
||||
auto* sortMode{ bindNew<Wt::WText>("sort-mode") };
|
||||
|
||||
auto bindMenuItem{ [this, sortMode, defaultMode](const std::string& var, const Wt::WString& title, DatabaseCollectorBase::Mode mode)
|
||||
{
|
||||
auto* menuItem {bindNew<Wt::WPushButton>(var, title)};
|
||||
menuItem->clicked().connect([this, mode, menuItem, sortMode, title]
|
||||
{
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
sortMode->setText(title);
|
||||
|
||||
sortModeChanged.emit(mode);
|
||||
});
|
||||
|
||||
if (mode == defaultMode)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
sortMode->setText(title);
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("random", Wt::WString::tr("Lms.Explore.random"), DatabaseCollectorBase::Mode::Random);
|
||||
bindMenuItem("starred", Wt::WString::tr("Lms.Explore.starred"), DatabaseCollectorBase::Mode::Starred);
|
||||
bindMenuItem("recently-played", Wt::WString::tr("Lms.Explore.recently-played"), DatabaseCollectorBase::Mode::RecentlyPlayed);
|
||||
bindMenuItem("most-played", Wt::WString::tr("Lms.Explore.most-played"), DatabaseCollectorBase::Mode::MostPlayed);
|
||||
bindMenuItem("recently-added", Wt::WString::tr("Lms.Explore.recently-added"), DatabaseCollectorBase::Mode::RecentlyAdded);
|
||||
bindMenuItem("all", Wt::WString::tr("Lms.Explore.all"), DatabaseCollectorBase::Mode::All);
|
||||
}
|
||||
} // namespace lms::ui
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WSignal.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "DatabaseCollectorBase.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class SortModeSelector : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
SortModeSelector(DatabaseCollectorBase::Mode defaultMode);
|
||||
|
||||
Wt::Signal<DatabaseCollectorBase::Mode> sortModeChanged;
|
||||
|
||||
private:
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TrackArtistLinkTypeSelector.hpp"
|
||||
|
||||
#include <Wt/WPushButton.h>
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
TrackArtistLinkTypeSelector::TrackArtistLinkTypeSelector(std::optional<db::TrackArtistLinkType> defaultLinkType)
|
||||
: Wt::WTemplate{ Wt::WString::tr("Lms.Explore.Artists.template.track-artist-link-type-selector") }
|
||||
{
|
||||
Wt::WText* linkTypeTxt{ bindNew<Wt::WText>("link-type") };
|
||||
|
||||
auto bindMenuItem{ [this, linkTypeTxt, defaultLinkType](const std::string& var, const Wt::WString& title, std::optional<db::TrackArtistLinkType> linkType)
|
||||
{
|
||||
auto* menuItem{ bindNew<Wt::WPushButton>(var, title) };
|
||||
menuItem->clicked().connect([=]
|
||||
{
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
linkTypeTxt->setText(title);
|
||||
|
||||
linkTypeChanged.emit(linkType);
|
||||
});
|
||||
|
||||
if (linkType == defaultLinkType)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
linkTypeTxt->setText(title);
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("link-type-all", Wt::WString::tr("Lms.Explore.Artists.linktype-all"), std::nullopt);
|
||||
bindMenuItem("link-type-artist", Wt::WString::trn("Lms.Explore.Artists.linktype-artist", 2), db::TrackArtistLinkType::Artist);
|
||||
bindMenuItem("link-type-releaseartist", Wt::WString::trn("Lms.Explore.Artists.linktype-releaseartist", 2), db::TrackArtistLinkType::ReleaseArtist);
|
||||
bindMenuItem("link-type-composer", Wt::WString::trn("Lms.Explore.Artists.linktype-composer", 2), db::TrackArtistLinkType::Composer);
|
||||
bindMenuItem("link-type-conductor", Wt::WString::trn("Lms.Explore.Artists.linktype-conductor", 2), db::TrackArtistLinkType::Conductor);
|
||||
bindMenuItem("link-type-lyricist", Wt::WString::trn("Lms.Explore.Artists.linktype-lyricist", 2), db::TrackArtistLinkType::Lyricist);
|
||||
bindMenuItem("link-type-mixer", Wt::WString::trn("Lms.Explore.Artists.linktype-mixer", 2), db::TrackArtistLinkType::Mixer);
|
||||
bindMenuItem("link-type-performer", Wt::WString::trn("Lms.Explore.Artists.linktype-performer", 2), db::TrackArtistLinkType::Performer);
|
||||
bindMenuItem("link-type-producer", Wt::WString::trn("Lms.Explore.Artists.linktype-producer", 2), db::TrackArtistLinkType::Producer);
|
||||
bindMenuItem("link-type-remixer", Wt::WString::trn("Lms.Explore.Artists.linktype-remixer", 2), db::TrackArtistLinkType::Remixer);
|
||||
}
|
||||
} // namespace lms::ui
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Wt/WSignal.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class TrackArtistLinkTypeSelector : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
TrackArtistLinkTypeSelector(std::optional<db::TrackArtistLinkType> defaultLinkType);
|
||||
|
||||
Wt::Signal<std::optional<db::TrackArtistLinkType>> linkTypeChanged;
|
||||
|
||||
private:
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "explore/PlayQueueController.hpp"
|
||||
#include "explore/TrackListHelpers.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "SortModeSelector.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
@@ -44,31 +45,12 @@ namespace lms::ui
|
||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||
addFunction("id", &Wt::WTemplate::Functions::id);
|
||||
|
||||
auto bindMenuItem{ [this](const std::string& var, const Wt::WString& title, TrackCollector::Mode mode)
|
||||
{
|
||||
auto* menuItem {bindNew<Wt::WPushButton>(var, title)};
|
||||
menuItem->clicked().connect([this, mode, menuItem]
|
||||
SortModeSelector* sortMode{ bindNew<SortModeSelector>("sort-mode", _defaultMode) };
|
||||
sortMode->sortModeChanged.connect([this](TrackCollector::Mode mode)
|
||||
{
|
||||
refreshView(mode);
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
});
|
||||
|
||||
if (mode == _defaultMode)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("random", Wt::WString::tr("Lms.Explore.random"), TrackCollector::Mode::Random);
|
||||
bindMenuItem("starred", Wt::WString::tr("Lms.Explore.starred"), TrackCollector::Mode::Starred);
|
||||
bindMenuItem("recently-played", Wt::WString::tr("Lms.Explore.recently-played"), TrackCollector::Mode::RecentlyPlayed);
|
||||
bindMenuItem("most-played", Wt::WString::tr("Lms.Explore.most-played"), TrackCollector::Mode::MostPlayed);
|
||||
bindMenuItem("recently-added", Wt::WString::tr("Lms.Explore.recently-added"), TrackCollector::Mode::RecentlyAdded);
|
||||
bindMenuItem("all", Wt::WString::tr("Lms.Explore.all"), TrackCollector::Mode::All);
|
||||
|
||||
bindNew<Wt::WPushButton>("play-btn", Wt::WString::tr("Lms.Explore.play"), Wt::TextFormat::XHTML)
|
||||
->clicked().connect([this]
|
||||
{
|
||||
|
||||
@@ -26,31 +26,30 @@
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class PlayQueueController;
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class PlayQueueController;
|
||||
|
||||
class Tracks : public Template
|
||||
{
|
||||
public:
|
||||
Tracks(Filters& filters, PlayQueueController& playQueueController);
|
||||
class Tracks : public Template
|
||||
{
|
||||
public:
|
||||
Tracks(Filters& filters, PlayQueueController& playQueueController);
|
||||
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(TrackCollector::Mode mode);
|
||||
void addSome();
|
||||
private:
|
||||
void refreshView();
|
||||
void refreshView(TrackCollector::Mode mode);
|
||||
void addSome();
|
||||
|
||||
std::vector<db::TrackId> getAllTracks();
|
||||
std::vector<db::TrackId> getAllTracks();
|
||||
|
||||
static constexpr TrackCollector::Mode _defaultMode {TrackCollector::Mode::Random};
|
||||
static constexpr std::size_t _batchSize {6};
|
||||
static constexpr std::size_t _maxCount {8000};
|
||||
static constexpr TrackCollector::Mode _defaultMode{ TrackCollector::Mode::Random };
|
||||
static constexpr std::size_t _batchSize{ 6 };
|
||||
static constexpr std::size_t _maxCount{ 8000 };
|
||||
|
||||
Filters& _filters;
|
||||
PlayQueueController& _playQueueController;
|
||||
Wt::WWidget* _currentActiveItem {};
|
||||
InfiniteScrollingContainer* _container {};
|
||||
TrackCollector _trackCollector;
|
||||
};
|
||||
Filters& _filters;
|
||||
PlayQueueController& _playQueueController;
|
||||
InfiniteScrollingContainer* _container{};
|
||||
TrackCollector _trackCollector;
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
Reference in New Issue
Block a user