Reuse path router for main view

This commit is contained in:
emeric
2026-06-03 22:30:45 +02:00
parent 0162c9a99e
commit 98369c9219
3 changed files with 36 additions and 63 deletions
+22 -62
View File
@@ -56,6 +56,7 @@
#include "admin/About.hpp" #include "admin/About.hpp"
#include "admin/AdminView.hpp" #include "admin/AdminView.hpp"
#include "admin/InitWizardView.hpp" #include "admin/InitWizardView.hpp"
#include "common/PathRouter.hpp"
#include "common/Template.hpp" #include "common/Template.hpp"
#include "explore/Explore.hpp" #include "explore/Explore.hpp"
#include "explore/Filters.hpp" #include "explore/Filters.hpp"
@@ -128,55 +129,6 @@ namespace lms::ui
return locale; return locale;
} }
enum IdxRoot
{
IdxExplore = 0,
IdxPlayQueue,
IdxSettings,
IdxAdmin,
};
void handlePathChange(Wt::WStackedWidget& stack, bool isAdmin)
{
static const struct
{
std::string path;
int index;
bool admin;
std::optional<Wt::WString> title;
} views[] = {
{ "/artists", IdxExplore, false, Wt::WString::tr("Lms.Explore.artists") },
{ "/artist", IdxExplore, false, std::nullopt },
{ "/releases", IdxExplore, false, Wt::WString::tr("Lms.Explore.releases") },
{ "/release", IdxExplore, false, std::nullopt },
{ "/tracks", IdxExplore, false, Wt::WString::tr("Lms.Explore.tracks") },
{ "/tracklists", IdxExplore, false, Wt::WString::tr("Lms.Explore.tracklists") },
{ "/tracklist", IdxExplore, false, std::nullopt },
{ "/playqueue", IdxPlayQueue, false, Wt::WString::tr("Lms.PlayQueue.playqueue") },
{ "/settings", IdxSettings, false, std::nullopt },
{ "/admin", IdxAdmin, true, std::nullopt },
};
LMS_LOG(UI, DEBUG, "Internal path changed to '" << wApp->internalPath() << "'");
for (const auto& view : views)
{
if (wApp->internalPathMatches(view.path))
{
if (view.admin && !isAdmin)
break;
stack.setCurrentIndex(view.index);
if (view.title)
LmsApp->setTitle(*view.title);
LmsApp->doJavaScript(LmsApp->javaScriptClass() + ".updateActiveNav('" + wApp->internalPath() + "')");
return;
}
}
wApp->setInternalPath(defaultPath, true);
}
} // namespace } // namespace
std::unique_ptr<Wt::WApplication> LmsApplication::create(const Wt::WEnvironment& env, db::IDb& db, LmsApplicationManager& appManager, AuthenticationBackend authBackend) std::unique_ptr<Wt::WApplication> LmsApplication::create(const Wt::WEnvironment& env, db::IDb& db, LmsApplicationManager& appManager, AuthenticationBackend authBackend)
@@ -490,19 +442,22 @@ namespace lms::ui
} }
} }
// Contents PathRouter* mainRouter{ main->bindNew<PathRouter>("contents") };
// Order is important in mainStack, see IdxRoot!
Wt::WStackedWidget* mainStack{ main->bindNew<Wt::WStackedWidget>("contents") };
mainStack->setOverflow(Wt::Overflow::Visible); // wt makes it hidden by default
std::unique_ptr<PlayQueue> playQueue{ std::make_unique<PlayQueue>() }; _playQueue = mainRouter->add<PlayQueue>("/playqueue", Wt::WString::tr("Lms.PlayQueue.playqueue"));
Explore* explore{ mainStack->addNew<Explore>(*filters, *playQueue) };
_playQueue = mainStack->addWidget(std::move(playQueue)); Explore* explore{ mainRouter->add<Explore>("/artists", Wt::WString::tr("Lms.Explore.artists"), *filters, *_playQueue) };
mainStack->addNew<SettingsView>(); mainRouter->addRoute("/artist", std::nullopt, explore);
mainRouter->addRoute("/releases", Wt::WString::tr("Lms.Explore.releases"), explore);
mainRouter->addRoute("/release", std::nullopt, explore);
mainRouter->addRoute("/tracks", Wt::WString::tr("Lms.Explore.tracks"), explore);
mainRouter->addRoute("/tracklists", Wt::WString::tr("Lms.Explore.tracklists"), explore);
mainRouter->addRoute("/tracklist", std::nullopt, explore);
mainRouter->add<SettingsView>("/settings", std::nullopt);
// Admin stuff
if (getUserType() == db::UserType::ADMIN) if (getUserType() == db::UserType::ADMIN)
mainStack->addNew<AdminView>(); mainRouter->add<AdminView>("/admin", std::nullopt);
explore->getPlayQueueController().setMaxTrackCountToEnqueue(_playQueue->getCapacity()); explore->getPlayQueueController().setMaxTrackCountToEnqueue(_playQueue->getCapacity());
@@ -560,11 +515,16 @@ namespace lms::ui
}); });
} }
internalPathChanged().connect(mainStack, [=] { internalPathChanged().connect([this] {
handlePathChange(*mainStack, isAdmin); LMS_LOG(UI, DEBUG, "Internal path changed to '" << wApp->internalPath() << "'");
doJavaScript(javaScriptClass() + ".updateActiveNav('" + wApp->internalPath() + "')");
}); });
handlePathChange(*mainStack, isAdmin); mainRouter->noMatch().connect([] {
wApp->setInternalPath(defaultPath, true);
});
mainRouter->activate();
} }
void LmsApplication::notify(const Wt::WEvent& event) void LmsApplication::notify(const Wt::WEvent& event)
+6
View File
@@ -31,6 +31,11 @@ namespace lms::ui
_stack->setOverflow(Wt::Overflow::Visible); _stack->setOverflow(Wt::Overflow::Visible);
} }
void PathRouter::addRoute(std::string_view path, std::optional<Wt::WString> title, Wt::WWidget* widget)
{
_routes.emplace_back(Route{ std::string{ path }, widget, std::move(title) });
}
void PathRouter::activate() void PathRouter::activate()
{ {
handlePathChange(); handlePathChange();
@@ -52,5 +57,6 @@ namespace lms::ui
return; return;
} }
} }
_noMatchSignal.emit();
} }
} // namespace lms::ui } // namespace lms::ui
+8 -1
View File
@@ -25,6 +25,7 @@
#include <vector> #include <vector>
#include <Wt/WContainerWidget.h> #include <Wt/WContainerWidget.h>
#include <Wt/WSignal.h>
#include <Wt/WStackedWidget.h> #include <Wt/WStackedWidget.h>
#include <Wt/WString.h> #include <Wt/WString.h>
@@ -39,10 +40,15 @@ namespace lms::ui
T* add(std::string_view path, std::optional<Wt::WString> title, Args&&... args) T* add(std::string_view path, std::optional<Wt::WString> title, Args&&... args)
{ {
T* widget{ _stack->addNew<T>(std::forward<Args>(args)...) }; T* widget{ _stack->addNew<T>(std::forward<Args>(args)...) };
_routes.emplace_back(Route{ std::string{ path }, widget, std::move(title) }); addRoute(path, std::move(title), widget);
return widget; return widget;
} }
void addRoute(std::string_view path, std::optional<Wt::WString> title, Wt::WWidget* widget);
// Emitted when no registered route matches the current internal path.
Wt::Signal<>& noMatch() { return _noMatchSignal; }
// Call once after all routes are registered — performs initial routing and starts listening to path changes. // Call once after all routes are registered — performs initial routing and starts listening to path changes.
void activate(); void activate();
@@ -50,6 +56,7 @@ namespace lms::ui
void handlePathChange(); void handlePathChange();
Wt::WStackedWidget* _stack{}; Wt::WStackedWidget* _stack{};
Wt::Signal<> _noMatchSignal;
struct Route struct Route
{ {