Playlists: now use a dropdown menu for selecting the sort mode
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@
|
||||
<message id="Lms.Explore.Artists.template.track-artist-link-type-selector">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
${link-type}
|
||||
${selected-item}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>${link-type-all class="dropdown-item"}</li>
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@
|
||||
<message id="Lms.Explore.template.sort-mode-selector">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
${sort-mode}
|
||||
${selected-item}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>${random class="dropdown-item"}</li>
|
||||
|
||||
+14
-9
@@ -3,19 +3,24 @@
|
||||
<messages xmlns:if="Wt.WTemplate.conditions">
|
||||
|
||||
<message id="Lms.Explore.TrackLists.template">
|
||||
<div class="mb-3">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
${recently-modified class="nav-link"}
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
${all class="nav-link"}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="d-flex flex-row-reverse">
|
||||
${sort-mode}
|
||||
</div>
|
||||
${tracklists}
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.TrackLists.template.sort-mode">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
${selected-item}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>${all class="dropdown-item"}</li>
|
||||
<li>${recently-modified class="dropdown-item"}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</message>
|
||||
|
||||
<message id="Lms.Explore.TrackLists.template.entry">
|
||||
${name class="text-decoration-none link-secondary"}
|
||||
</message>
|
||||
|
||||
@@ -42,8 +42,6 @@ add_executable(lms
|
||||
ui/explore/ReleasesView.cpp
|
||||
ui/explore/ReleaseView.cpp
|
||||
ui/explore/ReleaseTypes.cpp
|
||||
ui/explore/SortModeSelector.cpp
|
||||
ui/explore/TrackArtistLinkTypeSelector.cpp
|
||||
ui/explore/TrackCollector.cpp
|
||||
ui/explore/TrackListHelpers.cpp
|
||||
ui/explore/TrackListView.cpp
|
||||
|
||||
@@ -52,13 +52,13 @@ namespace lms::ui
|
||||
});
|
||||
|
||||
SortModeSelector* sortModeSelector{ bindNew<SortModeSelector>("sort-mode", _defaultSortMode) };
|
||||
sortModeSelector->sortModeChanged.connect([this](ArtistCollector::Mode sortMode)
|
||||
sortModeSelector->itemSelected.connect([this](ArtistCollector::Mode sortMode)
|
||||
{
|
||||
refreshView(sortMode);
|
||||
});
|
||||
|
||||
TrackArtistLinkTypeSelector* linkTypeSelector{ bindNew<TrackArtistLinkTypeSelector>("link-type", _defaultLinkType) };
|
||||
linkTypeSelector->linkTypeChanged.connect([this](std::optional<TrackArtistLinkType> linkType)
|
||||
linkTypeSelector->itemSelected.connect([this](std::optional<TrackArtistLinkType> linkType)
|
||||
{
|
||||
refreshView(linkType);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <Wt/WPushButton.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WSignal.h>
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
template <typename ItemType>
|
||||
class DropDownMenuSelector : public Wt::WTemplate
|
||||
{
|
||||
public:
|
||||
// text is the template of the dropdown menu
|
||||
// "selected-item" is the key for the currently selected entry
|
||||
DropDownMenuSelector(const Wt::WString& text, ItemType defaultItem)
|
||||
: Wt::WTemplate{ text }
|
||||
, _defaultItem{ defaultItem }
|
||||
{
|
||||
_selectedItem = bindNew<Wt::WText>("selected-item");
|
||||
}
|
||||
|
||||
void bindItem(const std::string& var, const Wt::WString& title, ItemType item)
|
||||
{
|
||||
auto* menuItem{ bindNew<Wt::WPushButton>(var, title) };
|
||||
menuItem->clicked().connect([=]
|
||||
{
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
_selectedItem->setText(title);
|
||||
|
||||
itemSelected.emit(item);
|
||||
});
|
||||
|
||||
if (item == _defaultItem)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
_selectedItem->setText(title);
|
||||
}
|
||||
}
|
||||
|
||||
Wt::Signal<ItemType> itemSelected;
|
||||
|
||||
private:
|
||||
const ItemType _defaultItem;
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
Wt::WText* _selectedItem{};
|
||||
};
|
||||
}
|
||||
@@ -48,12 +48,13 @@ namespace lms::ui
|
||||
{
|
||||
auto typeModel{ std::make_unique<TypeModel>() };
|
||||
|
||||
auto transaction{ LmsApp->getDbSession().createReadTransaction() };
|
||||
|
||||
db::ClusterType::find(LmsApp->getDbSession(), [&](const db::ClusterType::pointer& clusterType)
|
||||
{
|
||||
typeModel->add(Wt::WString::fromUTF8(std::string{ clusterType->getName() }), clusterType->getId());
|
||||
});
|
||||
{
|
||||
auto transaction{ LmsApp->getDbSession().createReadTransaction() };
|
||||
db::ClusterType::find(LmsApp->getDbSession(), [&](const db::ClusterType::pointer& clusterType)
|
||||
{
|
||||
typeModel->add(Wt::WString::fromUTF8(std::string{ clusterType->getName() }), clusterType->getId());
|
||||
});
|
||||
}
|
||||
|
||||
typeModel->add(Wt::WString::tr("Lms.Explore.media-library"), MediaLibraryTag{});
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace lms::ui
|
||||
});
|
||||
|
||||
SortModeSelector* sortMode{ bindNew<SortModeSelector>("sort-mode", _defaultMode) };
|
||||
sortMode->sortModeChanged.connect([this](ReleaseCollector::Mode sortMode)
|
||||
sortMode->itemSelected.connect([this](ReleaseCollector::Mode sortMode)
|
||||
{
|
||||
refreshView(sortMode);
|
||||
});
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -19,22 +19,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WSignal.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
#include "DropDownMenuSelector.hpp"
|
||||
|
||||
#include "DatabaseCollectorBase.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class SortModeSelector : public Wt::WTemplate
|
||||
class SortModeSelector : public DropDownMenuSelector<DatabaseCollectorBase::Mode>
|
||||
{
|
||||
public:
|
||||
SortModeSelector(DatabaseCollectorBase::Mode defaultMode);
|
||||
|
||||
Wt::Signal<DatabaseCollectorBase::Mode> sortModeChanged;
|
||||
|
||||
private:
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
SortModeSelector(DatabaseCollectorBase::Mode defaultMode)
|
||||
: DropDownMenuSelector<DatabaseCollectorBase::Mode>{ Wt::WString::tr("Lms.Explore.template.sort-mode-selector"), defaultMode }
|
||||
{
|
||||
bindItem("random", Wt::WString::tr("Lms.Explore.random"), DatabaseCollectorBase::Mode::Random);
|
||||
bindItem("starred", Wt::WString::tr("Lms.Explore.starred"), DatabaseCollectorBase::Mode::Starred);
|
||||
bindItem("recently-played", Wt::WString::tr("Lms.Explore.recently-played"), DatabaseCollectorBase::Mode::RecentlyPlayed);
|
||||
bindItem("most-played", Wt::WString::tr("Lms.Explore.most-played"), DatabaseCollectorBase::Mode::MostPlayed);
|
||||
bindItem("recently-added", Wt::WString::tr("Lms.Explore.recently-added"), DatabaseCollectorBase::Mode::RecentlyAdded);
|
||||
bindItem("all", Wt::WString::tr("Lms.Explore.all"), DatabaseCollectorBase::Mode::All);
|
||||
}
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
@@ -21,22 +21,27 @@
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <Wt/WSignal.h>
|
||||
#include <Wt/WTemplate.h>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
#include "DropDownMenuSelector.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class TrackArtistLinkTypeSelector : public Wt::WTemplate
|
||||
class TrackArtistLinkTypeSelector : public DropDownMenuSelector<std::optional<db::TrackArtistLinkType>>
|
||||
{
|
||||
public:
|
||||
TrackArtistLinkTypeSelector(std::optional<db::TrackArtistLinkType> defaultLinkType);
|
||||
|
||||
Wt::Signal<std::optional<db::TrackArtistLinkType>> linkTypeChanged;
|
||||
|
||||
private:
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
TrackArtistLinkTypeSelector(std::optional<db::TrackArtistLinkType> defaultLinkType)
|
||||
: DropDownMenuSelector{Wt::WString::tr("Lms.Explore.Artists.template.track-artist-link-type-selector") , defaultLinkType}
|
||||
{
|
||||
bindItem("link-type-all", Wt::WString::tr("Lms.Explore.Artists.linktype-all"), std::nullopt);
|
||||
bindItem("link-type-artist", Wt::WString::trn("Lms.Explore.Artists.linktype-artist", 2), db::TrackArtistLinkType::Artist);
|
||||
bindItem("link-type-releaseartist", Wt::WString::trn("Lms.Explore.Artists.linktype-releaseartist", 2), db::TrackArtistLinkType::ReleaseArtist);
|
||||
bindItem("link-type-composer", Wt::WString::trn("Lms.Explore.Artists.linktype-composer", 2), db::TrackArtistLinkType::Composer);
|
||||
bindItem("link-type-conductor", Wt::WString::trn("Lms.Explore.Artists.linktype-conductor", 2), db::TrackArtistLinkType::Conductor);
|
||||
bindItem("link-type-lyricist", Wt::WString::trn("Lms.Explore.Artists.linktype-lyricist", 2), db::TrackArtistLinkType::Lyricist);
|
||||
bindItem("link-type-mixer", Wt::WString::trn("Lms.Explore.Artists.linktype-mixer", 2), db::TrackArtistLinkType::Mixer);
|
||||
bindItem("link-type-performer", Wt::WString::trn("Lms.Explore.Artists.linktype-performer", 2), db::TrackArtistLinkType::Performer);
|
||||
bindItem("link-type-producer", Wt::WString::trn("Lms.Explore.Artists.linktype-producer", 2), db::TrackArtistLinkType::Producer);
|
||||
bindItem("link-type-remixer", Wt::WString::trn("Lms.Explore.Artists.linktype-remixer", 2), db::TrackArtistLinkType::Remixer);
|
||||
}
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Filters.hpp"
|
||||
#include "LmsApplication.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "DropDownMenuSelector.hpp"
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
@@ -41,27 +42,16 @@ 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, Mode mode)
|
||||
using SortModeSelector = DropDownMenuSelector<TrackLists::Mode>;
|
||||
SortModeSelector* sortModeSelector{ bindNew<SortModeSelector>("sort-mode", Wt::WString::tr("Lms.Explore.TrackLists.template.sort-mode"), _mode) };
|
||||
sortModeSelector->bindEntry("recently-modified", Wt::WString::tr("Lms.Explore.recently-modified"), Mode::RecentlyModified);
|
||||
sortModeSelector->bindEntry("all", Wt::WString::tr("Lms.Explore.all"), Mode::All);
|
||||
|
||||
sortModeSelector->entrySelected.connect(this, [this](TrackLists::Mode mode)
|
||||
{
|
||||
auto* menuItem {bindNew<Wt::WPushButton>(var, title)};
|
||||
menuItem->clicked().connect([this, mode, menuItem]
|
||||
{
|
||||
_mode = mode;
|
||||
refreshView();
|
||||
_currentActiveItem->removeStyleClass("active");
|
||||
menuItem->addStyleClass("active");
|
||||
_currentActiveItem = menuItem;
|
||||
});
|
||||
|
||||
if (mode == _mode)
|
||||
{
|
||||
_currentActiveItem = menuItem;
|
||||
_currentActiveItem->addStyleClass("active");
|
||||
}
|
||||
} };
|
||||
|
||||
bindMenuItem("recently-modified", Wt::WString::tr("Lms.Explore.recently-modified"), Mode::RecentlyModified);
|
||||
bindMenuItem("all", Wt::WString::tr("Lms.Explore.all"), Mode::All);
|
||||
_mode = mode;
|
||||
refreshView();
|
||||
});
|
||||
|
||||
_container = bindNew<InfiniteScrollingContainer>("tracklists", Wt::WString::tr("Lms.Explore.TrackLists.template.container"));
|
||||
_container->onRequestElements.connect([this]
|
||||
@@ -75,67 +65,67 @@ namespace lms::ui
|
||||
});
|
||||
|
||||
refreshView();
|
||||
}
|
||||
|
||||
void TrackLists::onTrackListDeleted(db::TrackListId trackListId)
|
||||
{
|
||||
auto itTrackList{ _trackListWidgets.find(trackListId) };
|
||||
if (itTrackList == std::end(_trackListWidgets))
|
||||
return;
|
||||
|
||||
_container->remove(*itTrackList->second);
|
||||
_trackListWidgets.erase(itTrackList);
|
||||
}
|
||||
|
||||
void TrackLists::refreshView()
|
||||
{
|
||||
_container->reset();
|
||||
_trackListWidgets.clear();
|
||||
}
|
||||
|
||||
void TrackLists::addSome()
|
||||
{
|
||||
const Range range{ static_cast<std::size_t>(_container->getCount()), _batchSize };
|
||||
|
||||
Session& session{ LmsApp->getDbSession() };
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
TrackList::FindParameters params;
|
||||
params.setClusters(_filters.getClusters());
|
||||
params.setMediaLibrary(_filters.getMediaLibrary());
|
||||
params.setUser(LmsApp->getUserId());
|
||||
params.setType(TrackListType::Playlist);
|
||||
params.setRange(range);
|
||||
switch (_mode)
|
||||
{
|
||||
case Mode::All:
|
||||
params.setSortMethod(TrackListSortMethod::Name);
|
||||
break;
|
||||
case Mode::RecentlyModified:
|
||||
params.setSortMethod(TrackListSortMethod::LastModifiedDesc);
|
||||
break;
|
||||
}
|
||||
|
||||
const auto trackListIds{ TrackList::find(session, params) };
|
||||
for (const TrackListId trackListId : trackListIds.results)
|
||||
void TrackLists::onTrackListDeleted(db::TrackListId trackListId)
|
||||
{
|
||||
if (const TrackList::pointer trackList{ TrackList::find(LmsApp->getDbSession(), trackListId) })
|
||||
addTracklist(trackList);
|
||||
auto itTrackList{ _trackListWidgets.find(trackListId) };
|
||||
if (itTrackList == std::end(_trackListWidgets))
|
||||
return;
|
||||
|
||||
_container->remove(*itTrackList->second);
|
||||
_trackListWidgets.erase(itTrackList);
|
||||
}
|
||||
|
||||
_container->setHasMore(trackListIds.moreResults);
|
||||
}
|
||||
void TrackLists::refreshView()
|
||||
{
|
||||
_container->reset();
|
||||
_trackListWidgets.clear();
|
||||
}
|
||||
|
||||
void TrackLists::addTracklist(const ObjectPtr<TrackList>& trackList)
|
||||
{
|
||||
const TrackListId trackListId{ trackList->getId() };
|
||||
void TrackLists::addSome()
|
||||
{
|
||||
const Range range{ static_cast<std::size_t>(_container->getCount()), _batchSize };
|
||||
|
||||
WTemplate* entry{ _container->addNew<Template>(Wt::WString::tr("Lms.Explore.TrackLists.template.entry")) };
|
||||
entry->bindWidget("name", utils::createTrackListAnchor(trackList));
|
||||
Session& session{ LmsApp->getDbSession() };
|
||||
auto transaction{ session.createReadTransaction() };
|
||||
|
||||
assert(_trackListWidgets.find(trackListId) == std::cend(_trackListWidgets));
|
||||
_trackListWidgets.emplace(trackListId, entry);
|
||||
}
|
||||
TrackList::FindParameters params;
|
||||
params.setClusters(_filters.getClusters());
|
||||
params.setMediaLibrary(_filters.getMediaLibrary());
|
||||
params.setUser(LmsApp->getUserId());
|
||||
params.setType(TrackListType::Playlist);
|
||||
params.setRange(range);
|
||||
switch (_mode)
|
||||
{
|
||||
case Mode::All:
|
||||
params.setSortMethod(TrackListSortMethod::Name);
|
||||
break;
|
||||
case Mode::RecentlyModified:
|
||||
params.setSortMethod(TrackListSortMethod::LastModifiedDesc);
|
||||
break;
|
||||
}
|
||||
|
||||
} // namespace lms::ui
|
||||
const auto trackListIds{ TrackList::find(session, params) };
|
||||
for (const TrackListId trackListId : trackListIds.results)
|
||||
{
|
||||
if (const TrackList::pointer trackList{ TrackList::find(LmsApp->getDbSession(), trackListId) })
|
||||
addTracklist(trackList);
|
||||
}
|
||||
|
||||
_container->setHasMore(trackListIds.moreResults);
|
||||
}
|
||||
|
||||
void TrackLists::addTracklist(const ObjectPtr<TrackList>& trackList)
|
||||
{
|
||||
const TrackListId trackListId{ trackList->getId() };
|
||||
|
||||
WTemplate* entry{ _container->addNew<Template>(Wt::WString::tr("Lms.Explore.TrackLists.template.entry")) };
|
||||
entry->bindWidget("name", utils::createTrackListAnchor(trackList));
|
||||
|
||||
assert(_trackListWidgets.find(trackListId) == std::cend(_trackListWidgets));
|
||||
_trackListWidgets.emplace(trackListId, entry);
|
||||
}
|
||||
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -30,40 +30,40 @@
|
||||
|
||||
namespace lms::db
|
||||
{
|
||||
class TrackList;
|
||||
class TrackList;
|
||||
}
|
||||
|
||||
namespace lms::ui
|
||||
{
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
class Filters;
|
||||
class InfiniteScrollingContainer;
|
||||
|
||||
class TrackLists : public Template
|
||||
{
|
||||
public:
|
||||
TrackLists(Filters& filters);
|
||||
class TrackLists : public Template
|
||||
{
|
||||
public:
|
||||
TrackLists(Filters& filters);
|
||||
|
||||
void onTrackListDeleted(db::TrackListId trackListId);
|
||||
void onTrackListDeleted(db::TrackListId trackListId);
|
||||
|
||||
private:
|
||||
enum class Mode
|
||||
{
|
||||
RecentlyModified,
|
||||
All,
|
||||
};
|
||||
private:
|
||||
enum class Mode
|
||||
{
|
||||
RecentlyModified,
|
||||
All,
|
||||
};
|
||||
|
||||
void refreshView();
|
||||
void addSome();
|
||||
void addTracklist(const db::ObjectPtr<db::TrackList>& trackList);
|
||||
void refreshView();
|
||||
void addSome();
|
||||
void addTracklist(const db::ObjectPtr<db::TrackList>& trackList);
|
||||
|
||||
static constexpr std::size_t _batchSize {30};
|
||||
static constexpr std::size_t _maxCount {500};
|
||||
static constexpr std::size_t _batchSize{ 30 };
|
||||
static constexpr std::size_t _maxCount{ 500 };
|
||||
|
||||
Mode _mode {Mode::RecentlyModified};
|
||||
Filters& _filters;
|
||||
Wt::WWidget* _currentActiveItem {};
|
||||
InfiniteScrollingContainer* _container {};
|
||||
std::unordered_map<db::TrackListId, Wt::WWidget*> _trackListWidgets;
|
||||
};
|
||||
Mode _mode{ Mode::RecentlyModified };
|
||||
Filters& _filters;
|
||||
Wt::WWidget* _currentActiveItem{};
|
||||
InfiniteScrollingContainer* _container{};
|
||||
std::unordered_map<db::TrackListId, Wt::WWidget*> _trackListWidgets;
|
||||
};
|
||||
} // namespace lms::ui
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace lms::ui
|
||||
});
|
||||
|
||||
SortModeSelector* sortMode{ bindNew<SortModeSelector>("sort-mode", _defaultMode) };
|
||||
sortMode->sortModeChanged.connect([this](TrackCollector::Mode mode)
|
||||
sortMode->itemSelected.connect([this](TrackCollector::Mode mode)
|
||||
{
|
||||
refreshView(mode);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user