/* * 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 . */ #include "Explore.hpp" #include #include #include #include "utils/Logger.hpp" #include "LmsApplication.hpp" #include "Filters.hpp" #include "ArtistsView.hpp" #include "ArtistView.hpp" #include "ReleasesView.hpp" #include "ReleaseView.hpp" #include "TracksView.hpp" namespace UserInterface { enum IdxRoot { IdxArtists = 0, IdxArtist, IdxReleases, IdxRelease, IdxTracks, }; static void handlePathChange(Wt::WStackedWidget* stack) { static const std::map indexes = { { "/artists", IdxArtists }, { "/artist", IdxArtist }, { "/releases", IdxReleases }, { "/release", IdxRelease }, { "/tracks", IdxTracks }, }; LMS_LOG(UI, DEBUG) << "Internal path changed to '" << wApp->internalPath() << "'"; for (auto index : indexes) { if (wApp->internalPathMatches(index.first)) { stack->setCurrentIndex(index.second); return; } } } Explore::Explore() : Wt::WTemplate(Wt::WString::tr("Lms.Explore.template")) { _filters = bindNew("filters"); // Contents Wt::WStackedWidget* stack = bindNew("contents"); auto artists = std::make_unique(_filters); auto artists_raw = artists.get(); artists->artistAdd.connect(this, &Explore::handleArtistAdd); artists->artistPlay.connect(this, &Explore::handleArtistPlay); stack->addWidget(std::move(artists)); auto artist = std::make_unique(_filters); artist->artistAdd.connect(this, &Explore::handleArtistAdd); artist->artistPlay.connect(this, &Explore::handleArtistPlay); artist->releaseAdd.connect(this, &Explore::handleReleaseAdd); artist->releasePlay.connect(this, &Explore::handleReleasePlay); stack->addWidget(std::move(artist)); auto releases = std::make_unique(_filters); auto releases_raw = releases.get(); releases->releaseAdd.connect(this, &Explore::handleReleaseAdd); releases->releasePlay.connect(this, &Explore::handleReleasePlay); stack->addWidget(std::move(releases)); auto release = std::make_unique(_filters); release->releaseAdd.connect(this, &Explore::handleReleaseAdd); release->releasePlay.connect(this, &Explore::handleReleasePlay); release->trackAdd.connect(this, &Explore::handleTrackAdd); release->trackPlay.connect(this, &Explore::handleTrackPlay); stack->addWidget(std::move(release)); _dbChanged.connect([=] { artists_raw->refreshRecentlyAdded(); releases_raw->refreshRecentlyAdded(); }); _trackPlayed.connect([=] { artists_raw->refreshMostPlayed(); releases_raw->refreshMostPlayed(); }); auto tracks = std::make_unique(_filters); tracks->trackAdd.connect(this, &Explore::handleTrackAdd); tracks->trackPlay.connect(this, &Explore::handleTrackPlay); tracks->tracksAdd.connect(this, &Explore::handleTracksAdd); tracks->tracksPlay.connect(this, &Explore::handleTracksPlay); stack->addWidget(std::move(tracks)); wApp->internalPathChanged().connect(std::bind([=] { handlePathChange(stack); })); handlePathChange(stack); } // TODO SQL this? static std::vector getArtistTracks(Wt::Dbo::Session& session, Database::IdType artistId, std::set clusters) { std::vector res; auto artist = Database::Artist::getById(session, artistId); if (!artist) return res; auto releases = artist->getReleases(clusters); for (auto release : releases) { auto tracks = release->getTracks(clusters); for (auto track : tracks) { if (track->getArtist() && track->getArtist().id() == artistId) res.push_back(track); } } return res; } static std::vector getReleaseTracks(Wt::Dbo::Session& session, Database::IdType releaseId, std::set clusters) { std::vector res; auto release = Database::Release::getById(session, releaseId); if (!release) return res; return release->getTracks(clusters); } static std::vector getTrack(Wt::Dbo::Session& session, Database::IdType trackId) { std::vector res; auto track = Database::Track::getById(session, trackId); if (track) res.push_back(track); return res; } void Explore::handleArtistAdd(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksAdd.emit(getArtistTracks(LmsApp->getDboSession(), id, _filters->getClusterIds())); } void Explore::handleArtistPlay(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksPlay.emit(getArtistTracks(LmsApp->getDboSession(), id, _filters->getClusterIds())); } void Explore::handleReleaseAdd(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksAdd.emit(getReleaseTracks(LmsApp->getDboSession(), id, _filters->getClusterIds())); } void Explore::handleReleasePlay(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksPlay.emit(getReleaseTracks(LmsApp->getDboSession(), id, _filters->getClusterIds())); } void Explore::handleTrackAdd(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksAdd.emit(getTrack(LmsApp->getDboSession(), id)); } void Explore::handleTrackPlay(Database::IdType id) { Wt::Dbo::Transaction transaction(LmsApp->getDboSession()); tracksPlay.emit(getTrack(LmsApp->getDboSession(), id)); } void Explore::handleTracksAdd(std::vector tracks) { tracksAdd.emit(tracks); } void Explore::handleTracksPlay(std::vector tracks) { tracksPlay.emit(tracks); } } // namespace UserInterface