M module-apps/application-music-player/ApplicationMusicPlayer.cpp => module-apps/application-music-player/ApplicationMusicPlayer.cpp +2 -2
@@ 46,8 46,8 @@ namespace app
bus.channels.push_back(sys::BusChannel::ServiceAudioNotifications);
auto tagsFetcher = std::make_unique<app::music_player::ServiceAudioTagsFetcher>(this);
- auto songsRepository = std::make_unique<app::music_player::SongsRepository>(std::move(tagsFetcher));
- priv->songsModel = std::make_unique<app::music_player::SongsModel>(std::move(songsRepository));
+ auto songsRepository = std::make_unique<app::music_player::SongsRepository>(this, std::move(tagsFetcher));
+ priv->songsModel = std::make_unique<app::music_player::SongsModel>(this, std::move(songsRepository));
auto audioOperations = std::make_unique<app::AsyncAudioOperations>(this);
priv->songsPresenter =
std::make_unique<app::music_player::SongsPresenter>(priv->songsModel, std::move(audioOperations));
M module-apps/application-music-player/models/SongsModel.cpp => module-apps/application-music-player/models/SongsModel.cpp +71 -64
@@ 12,13 12,19 @@
namespace app::music_player
{
- SongsModel::SongsModel(std::shared_ptr<AbstractSongsRepository> songsRepository)
- : songsRepository{std::move(songsRepository)}
+ SongsListItemProvider::SongsListItemProvider(ApplicationCommon *app) : DatabaseModel(app)
+ {}
+
+ SongsModelInterface::SongsModelInterface(ApplicationCommon *app) : SongsListItemProvider(app)
+ {}
+
+ SongsModel::SongsModel(app::ApplicationCommon *app, std::shared_ptr<AbstractSongsRepository> songsRepository)
+ : SongsModelInterface(app), songsRepository{std::move(songsRepository)}
{}
auto SongsModel::requestRecordsCount() -> unsigned int
{
- return internalData.size();
+ return recordsCount;
}
auto SongsModel::getMinimalItemSpaceRequired() const -> unsigned int
@@ 28,48 34,65 @@ namespace app::music_player
void SongsModel::requestRecords(const uint32_t offset, const uint32_t limit)
{
- setupModel(offset, limit);
- list->onProviderDataUpdate();
+ songsRepository->getMusicFilesList(
+ offset,
+ limit,
+ [this](const std::vector<db::multimedia_files::MultimediaFilesRecord> &records,
+ unsigned int repoRecordsCount) { return onMusicListRetrieved(records, repoRecordsCount); });
}
auto SongsModel::getItem(gui::Order order) -> gui::ListItem *
{
- return getRecord(order);
- }
+ std::shared_ptr<db::multimedia_files::MultimediaFilesRecord> song = getRecord(order);
+ if (!song) {
+ return nullptr;
+ }
- void SongsModel::createData(OnShortReleaseCallback shortReleaseCallback,
- OnLongPressCallback longPressCallback,
- OnSetBottomBarTemporaryCallback bottomBarTemporaryMode,
- OnRestoreBottomBarTemporaryCallback bottomBarRestoreFromTemporaryMode)
- {
- songsRepository->scanMusicFilesList();
- auto songsList = songsRepository->getMusicFilesList();
- for (const auto &song : songsList) {
- auto item = new gui::SongItem(song.artist,
- song.title,
- utils::time::Duration(song.total_duration_s).str(),
- bottomBarTemporaryMode,
- bottomBarRestoreFromTemporaryMode);
-
- item->activatedCallback = [=](gui::Item &) {
- shortReleaseCallback(song.filePath);
+ auto item = new gui::SongItem(song->tags.album.artist,
+ song->tags.title,
+ utils::time::Duration(song->audioProperties.songLength).str(),
+ bottomBarTemporaryMode,
+ bottomBarRestoreFromTemporaryMode);
+
+ if (songContext.filePath == song->fileInfo.path) {
+ item->setState(songContext.isPlaying() ? gui::SongItem::ItemState::Playing
+ : (songContext.isPaused() ? gui::SongItem::ItemState::Paused
+ : gui::SongItem::ItemState::None));
+ }
+ else {
+ item->setState(gui::SongItem::ItemState::None);
+ }
+
+ item->activatedCallback = [this, song](gui::Item &) {
+ if (shortReleaseCallback != nullptr) {
+ shortReleaseCallback(song->fileInfo.path);
return true;
- };
+ }
+ return false;
+ };
- item->inputCallback = [longPressCallback](gui::Item &, const gui::InputEvent &event) {
- if (event.isLongRelease(gui::KeyCode::KEY_ENTER)) {
+ item->inputCallback = [=](gui::Item &, const gui::InputEvent &event) {
+ if (event.isLongRelease(gui::KeyCode::KEY_ENTER)) {
+ if (longPressCallback != nullptr) {
longPressCallback();
return true;
}
- return false;
- };
+ }
+ return false;
+ };
- internalData.push_back(item);
- }
+ return item;
+ }
- for (auto &item : internalData) {
- item->deleteByList = false;
- }
+ void SongsModel::createData(OnShortReleaseCallback shortReleaseCallback,
+ OnLongPressCallback longPressCallback,
+ OnSetBottomBarTemporaryCallback bottomBarTemporaryMode,
+ OnRestoreBottomBarTemporaryCallback bottomBarRestoreFromTemporaryMode)
+ {
+ this->shortReleaseCallback = shortReleaseCallback;
+ this->longPressCallback = longPressCallback;
+ this->bottomBarTemporaryMode = bottomBarTemporaryMode;
+ this->bottomBarRestoreFromTemporaryMode = bottomBarRestoreFromTemporaryMode;
}
bool SongsModel::isSongPlaying() const noexcept
@@ 80,7 103,6 @@ namespace app::music_player
void SongsModel::setCurrentSongState(SongState songState) noexcept
{
songContext.currentSongState = songState;
- updateCurrentItemState();
}
std::optional<audio::Token> SongsModel::getCurrentFileToken() const noexcept
@@ 112,50 134,35 @@ namespace app::music_player
void SongsModel::setCurrentSongContext(SongContext context)
{
using namespace gui;
- clearCurrentItemState();
-
songContext = context;
-
- updateCurrentItemState();
}
void SongsModel::clearCurrentSongContext()
{
- clearCurrentItemState();
songContext.clear();
}
- void SongsModel::clearCurrentItemState()
+ void SongsModel::clearData()
{
- using namespace gui;
- const auto songIndex = getCurrentIndex();
- if (songIndex < internalData.size()) {
- internalData[songIndex]->setState(SongItem::ItemState::None);
- }
+ list->reset();
}
- void SongsModel::updateCurrentItemState()
+ [[nodiscard]] bool SongsModel::updateRecords(std::vector<db::multimedia_files::MultimediaFilesRecord> records)
{
- using namespace gui;
- const auto songIndex = getCurrentIndex();
- if (songIndex >= internalData.size()) {
- return;
- }
-
- if (songContext.isPlaying()) {
- internalData[songIndex]->setState(SongItem::ItemState::Playing);
- }
- else if (songContext.isPaused()) {
- internalData[songIndex]->setState(SongItem::ItemState::Paused);
- }
- else {
- internalData[songIndex]->setState(SongItem::ItemState::None);
- }
+ DatabaseModel::updateRecords(std::move(records));
+ list->onProviderDataUpdate();
+ return true;
}
- void SongsModel::clearData()
+ bool SongsModel::onMusicListRetrieved(const std::vector<db::multimedia_files::MultimediaFilesRecord> &records,
+ unsigned int repoRecordsCount)
{
- list->reset();
- eraseInternalData();
+ if (recordsCount != repoRecordsCount) {
+ recordsCount = repoRecordsCount;
+ list->reSendLastRebuildRequest();
+ return false;
+ }
+ return updateRecords(records);
}
+
} // namespace app::music_player
M module-apps/application-music-player/models/SongsModel.hpp => module-apps/application-music-player/models/SongsModel.hpp +10 -3
@@ 16,7 16,7 @@ namespace app::music_player
class SongsModel : public SongsModelInterface
{
public:
- explicit SongsModel(std::shared_ptr<AbstractSongsRepository> songsRepository);
+ SongsModel(app::ApplicationCommon *app, std::shared_ptr<AbstractSongsRepository> songsRepository);
void createData(OnShortReleaseCallback shortReleaseCallback,
OnLongPressCallback longPressCallback,
@@ 46,10 46,17 @@ namespace app::music_player
void clearData() override;
private:
- void clearCurrentItemState();
- void updateCurrentItemState();
+ bool onMusicListRetrieved(const std::vector<db::multimedia_files::MultimediaFilesRecord> &records,
+ unsigned int repoRecordsCount);
+ [[nodiscard]] bool updateRecords(std::vector<db::multimedia_files::MultimediaFilesRecord> records) override;
+
SongContext songContext;
+ OnShortReleaseCallback shortReleaseCallback{nullptr};
+ OnLongPressCallback longPressCallback{nullptr};
+ OnSetBottomBarTemporaryCallback bottomBarTemporaryMode{nullptr};
+ OnRestoreBottomBarTemporaryCallback bottomBarRestoreFromTemporaryMode{nullptr};
+
std::shared_ptr<AbstractSongsRepository> songsRepository;
};
} // namespace app::music_player
M module-apps/application-music-player/models/SongsModelInterface.hpp => module-apps/application-music-player/models/SongsModelInterface.hpp +6 -3
@@ 6,20 6,22 @@
#include "SongContext.hpp"
#include <string>
#include <widgets/SongItem.hpp>
-#include <InternalModel.hpp>
#include <ListItemProvider.hpp>
#include <apps-common/ApplicationCommon.hpp>
+#include <apps-common/DatabaseModel.hpp>
+#include <module-db/Interface/MultimediaFilesRecord.hpp>
namespace app::music_player
{
- class SongsListItemProvider : public app::InternalModel<gui::SongItem *>, public gui::ListItemProvider
+ class SongsListItemProvider : public app::DatabaseModel<db::multimedia_files::MultimediaFilesRecord>,
+ public gui::ListItemProvider
{
public:
using OnShortReleaseCallback = std::function<bool(const std::string &fileName)>;
using OnLongPressCallback = std::function<void()>;
using OnSetBottomBarTemporaryCallback = std::function<void(const UTF8 &)>;
using OnRestoreBottomBarTemporaryCallback = std::function<void()>;
-
+ explicit SongsListItemProvider(app::ApplicationCommon *app);
virtual ~SongsListItemProvider() noexcept = default;
virtual void createData(OnShortReleaseCallback shortReleaseCallback,
@@ 33,6 35,7 @@ namespace app::music_player
class SongsModelInterface : public SongsListItemProvider
{
public:
+ explicit SongsModelInterface(app::ApplicationCommon *app);
virtual ~SongsModelInterface() noexcept = default;
virtual bool isSongPlaying() const noexcept = 0;
M module-apps/application-music-player/models/SongsRepository.cpp => module-apps/application-music-player/models/SongsRepository.cpp +28 -33
@@ 9,7 9,7 @@
#include <service-audio/AudioServiceName.hpp>
#include <time/ScopedTime.hpp>
#include <service-audio/AudioMessage.hpp>
-#include <tags_fetcher/TagsFetcher.hpp>
+#include <module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp>
#include <filesystem>
@@ 23,46 23,40 @@ namespace app::music_player
return tags::fetcher::fetchTags(filePath);
}
- SongsRepository::SongsRepository(std::unique_ptr<AbstractTagsFetcher> tagsFetcher, std::string musicFolderName)
- : tagsFetcher(std::move(tagsFetcher)), musicFolderName(std::move(musicFolderName))
+ SongsRepository::SongsRepository(ApplicationCommon *application, std::unique_ptr<AbstractTagsFetcher> tagsFetcher)
+ : app::AsyncCallbackReceiver{application}, application{application}, tagsFetcher(std::move(tagsFetcher))
{}
- void SongsRepository::scanMusicFilesList()
+ void SongsRepository::getMusicFilesList(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &callback)
{
- musicFiles.clear();
-
- LOG_INFO("Scanning music folder: %s", musicFolderName.c_str());
- {
- auto time = utils::time::Scoped("fetch tags time");
- for (const auto &entry : std::filesystem::directory_iterator(musicFolderName)) {
- if (!std::filesystem::is_directory(entry)) {
- const auto &filePath = entry.path();
- const auto fileTags = tagsFetcher->getFileTags(filePath);
- if (fileTags) {
- musicFiles.push_back(*fileTags);
- }
- else {
- LOG_ERROR("Scanned not an audio file, skipped");
- }
- }
+ auto query = std::make_unique<db::multimedia_files::query::GetLimited>(offset, limit);
+ auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::MultimediaFiles);
+
+ task->setCallback([this, callback](auto response) {
+ auto result = dynamic_cast<db::multimedia_files::query::GetLimitedResult *>(response);
+ musicFiles.clear();
+
+ if (result == nullptr) {
+ return false;
}
- std::sort(
- musicFiles.begin(), musicFiles.end(), [](const tags::fetcher::Tags &t1, const tags::fetcher::Tags &t2) {
- return t1.filePath < t2.filePath;
- });
- }
- LOG_INFO("Total number of music files found: %u", static_cast<unsigned int>(musicFiles.size()));
- }
- std::vector<tags::fetcher::Tags> SongsRepository::getMusicFilesList() const
- {
- return musicFiles;
+ if (callback) {
+ for (auto &record : result->getResult()) {
+ musicFiles.push_back(record);
+ }
+ callback(musicFiles, result->getCount());
+ }
+ return true;
+ });
+ task->execute(application, this);
}
std::size_t SongsRepository::getFileIndex(const std::string &filePath) const
{
auto it = std::find_if(musicFiles.begin(), musicFiles.end(), [filePath](const auto &musicFile) {
- return musicFile.filePath == filePath;
+ return musicFile.fileInfo.path == filePath;
});
if (it != musicFiles.end()) {
@@ 79,7 73,7 @@ namespace app::music_player
if (currentIndex == std::numeric_limits<size_t>::max() || currentIndex == musicFiles.size() - 1) {
return "";
}
- return musicFiles[currentIndex + 1].filePath;
+ return musicFiles[currentIndex + 1].fileInfo.path;
}
std::string SongsRepository::getPreviousFilePath(const std::string &filePath) const
@@ 89,6 83,7 @@ namespace app::music_player
if (currentIndex == std::numeric_limits<size_t>::max() || currentIndex == 0) {
return "";
}
- return musicFiles[currentIndex - 1].filePath;
+ return musicFiles[currentIndex - 1].fileInfo.path;
}
+
} // namespace app::music_player
M module-apps/application-music-player/models/SongsRepository.hpp => module-apps/application-music-player/models/SongsRepository.hpp +15 -12
@@ 5,7 5,7 @@
#include <apps-common/ApplicationCommon.hpp>
#include <tags_fetcher/TagsFetcher.hpp>
-#include <purefs/filesystem_paths.hpp>
+#include <module-db/Interface/MultimediaFilesRecord.hpp>
#include <memory>
#include <optional>
@@ 38,32 38,35 @@ namespace app::music_player
class AbstractSongsRepository
{
public:
+ using OnGetMusicFilesListCallback =
+ std::function<bool(const std::vector<db::multimedia_files::MultimediaFilesRecord> &, unsigned int)>;
+
virtual ~AbstractSongsRepository() noexcept = default;
- virtual void scanMusicFilesList() = 0;
- virtual std::vector<tags::fetcher::Tags> getMusicFilesList() const = 0;
+ virtual void getMusicFilesList(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &callback) = 0;
virtual std::size_t getFileIndex(const std::string &filePath) const = 0;
virtual std::string getNextFilePath(const std::string &filePath) const = 0;
virtual std::string getPreviousFilePath(const std::string &filePath) const = 0;
};
- class SongsRepository : public AbstractSongsRepository
+ class SongsRepository : public AbstractSongsRepository, public app::AsyncCallbackReceiver
{
- static constexpr auto musicSubfolderName = "music";
-
public:
- explicit SongsRepository(std::unique_ptr<AbstractTagsFetcher> tagsFetcher,
- std::string musicFolderName = purefs::dir::getUserDiskPath() / musicSubfolderName);
+ explicit SongsRepository(ApplicationCommon *application, std::unique_ptr<AbstractTagsFetcher> tagsFetcher);
- void scanMusicFilesList() override;
- std::vector<tags::fetcher::Tags> getMusicFilesList() const override;
+ void getMusicFilesList(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &callback) override;
std::size_t getFileIndex(const std::string &filePath) const override;
std::string getNextFilePath(const std::string &filePath) const override;
std::string getPreviousFilePath(const std::string &filePath) const override;
private:
+ ApplicationCommon *application;
+
std::unique_ptr<AbstractTagsFetcher> tagsFetcher;
- std::string musicFolderName;
- std::vector<tags::fetcher::Tags> musicFiles;
+ std::vector<db::multimedia_files::MultimediaFilesRecord> musicFiles;
};
} // namespace app::music_player
M module-apps/application-music-player/tests/CMakeLists.txt => module-apps/application-music-player/tests/CMakeLists.txt +0 -1
@@ 3,7 3,6 @@ add_gtest_executable(
app-music-player
SRCS
unittest.cpp
- unittest_songrepository.cpp
unittest_songsmodel.cpp
LIBS
application-music-player
M module-apps/application-music-player/tests/MockSongsRepository.hpp => module-apps/application-music-player/tests/MockSongsRepository.hpp +4 -2
@@ 17,8 17,10 @@ namespace testing::app::music_player
class MockSongsRepository : public ::app::music_player::AbstractSongsRepository
{
public:
- MOCK_METHOD(void, scanMusicFilesList, (), (override));
- MOCK_METHOD(std::vector<tags::fetcher::Tags>, getMusicFilesList, (), (const override));
+ MOCK_METHOD(void,
+ getMusicFilesList,
+ (std::uint32_t offset, std::uint32_t limit, const OnGetMusicFilesListCallback &callback),
+ (override));
MOCK_METHOD(std::size_t, getFileIndex, (const std::string &filePath), (const override));
MOCK_METHOD(std::string, getNextFilePath, (const std::string &filePath), (const override));
MOCK_METHOD(std::string, getPreviousFilePath, (const std::string &filePath), (const override));
D module-apps/application-music-player/tests/unittest_songrepository.cpp => module-apps/application-music-player/tests/unittest_songrepository.cpp +0 -154
@@ 1,154 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include "MockTagsFetcher.hpp"
-
-#include <models/SongsRepository.hpp>
-#include <tags_fetcher/TagsFetcher.hpp>
-#include <filesystem>
-#include <fstream>
-#include <stdexcept>
-
-using ::testing::Return;
-using ::testing::app::music_player::MockTagsFetcher;
-namespace fs = std::filesystem;
-
-constexpr auto testDir = "appmusic-test";
-constexpr auto emptyDir = "empty";
-constexpr auto musicDir = "music";
-constexpr auto bazDir = "bazdir";
-auto testDirPath = fs::path(testDir);
-auto emptyDirPath = testDirPath / emptyDir;
-auto musicDirPath = testDirPath / musicDir;
-auto bazDirPath = musicDirPath / bazDir;
-
-class SongsRepositoryFixture : public ::testing::Test
-{
- protected:
- static void SetUpTestSuite()
- {
- if (fs::exists(testDirPath)) {
- TearDownTestSuite();
- }
-
- fs::create_directory(testDirPath);
- fs::create_directory(emptyDirPath);
- fs::create_directory(musicDirPath);
-
- createFile(musicDirPath / "foo");
- createFile(musicDirPath / "bar");
-
- fs::create_directory(bazDirPath);
-
- createFile(bazDirPath / "baz");
-
- fs::create_directory(musicDirPath / "bazzinga");
- }
-
- static void createFile(const std::string &path)
- {
- std::ofstream file(path);
- file << "app music test file";
- }
-
- static void TearDownTestSuite()
- {
- fs::remove_all(testDir);
- }
-
- auto getMockedRepository(const std::string &directoryToScan)
- {
- return std::make_unique<app::music_player::SongsRepository>(std::make_unique<MockTagsFetcher>(),
- directoryToScan);
- }
-};
-
-TEST_F(SongsRepositoryFixture, LazyInit)
-{
- auto repo = getMockedRepository(testDir);
- auto musicFiles = repo->getMusicFilesList();
- EXPECT_EQ(musicFiles.size(), 0);
-}
-
-TEST_F(SongsRepositoryFixture, Empty)
-{
- auto repo = getMockedRepository(testDirPath / emptyDir);
- repo->scanMusicFilesList();
-
- auto musicFiles = repo->getMusicFilesList();
- EXPECT_EQ(musicFiles.size(), 0);
-}
-
-TEST_F(SongsRepositoryFixture, ScanEmptyFiles)
-{
- auto tagsFetcherMock = std::make_unique<MockTagsFetcher>();
- auto rawMock = tagsFetcherMock.get();
- auto repo = std::make_unique<app::music_player::SongsRepository>(std::move(tagsFetcherMock), musicDirPath);
-
- EXPECT_CALL(*rawMock, getFileTags).Times(2);
- repo->scanMusicFilesList();
-
- auto musicFiles = repo->getMusicFilesList();
- EXPECT_EQ(musicFiles.size(), 0);
-}
-
-TEST_F(SongsRepositoryFixture, ScanWithTagsReturn)
-{
- auto tagsFetcherMock = std::make_unique<MockTagsFetcher>();
- auto rawMock = tagsFetcherMock.get();
- auto repo = std::make_unique<app::music_player::SongsRepository>(std::move(tagsFetcherMock), musicDirPath);
-
- auto fooTags = tags::fetcher::Tags{"foo"};
- auto barTags = tags::fetcher::Tags{"foo"};
-
- ON_CALL(*rawMock, getFileTags(fs::path(musicDirPath / "foo").c_str())).WillByDefault(Return(fooTags));
- ON_CALL(*rawMock, getFileTags(fs::path(musicDirPath / "bar").c_str())).WillByDefault(Return(barTags));
- EXPECT_CALL(*rawMock, getFileTags).Times(2);
- repo->scanMusicFilesList();
-
- auto musicFiles = repo->getMusicFilesList();
- EXPECT_EQ(musicFiles.size(), 2);
-}
-
-TEST_F(SongsRepositoryFixture, FileIndex)
-{
- auto tagsFetcherMock = std::make_unique<MockTagsFetcher>();
- auto rawMock = tagsFetcherMock.get();
- auto repo = std::make_unique<app::music_player::SongsRepository>(std::move(tagsFetcherMock), musicDirPath);
-
- auto fooPath = musicDirPath / "foo";
- auto barPath = musicDirPath / "bar";
-
- auto fooTags = tags::fetcher::Tags(fooPath);
- auto barTags = tags::fetcher::Tags(barPath);
-
- ON_CALL(*rawMock, getFileTags(fs::path(musicDirPath / "foo").c_str())).WillByDefault(Return(fooTags));
- ON_CALL(*rawMock, getFileTags(fs::path(musicDirPath / "bar").c_str())).WillByDefault(Return(barTags));
- EXPECT_CALL(*rawMock, getFileTags).Times(2);
- repo->scanMusicFilesList();
-
- auto fooIndex = repo->getFileIndex(fooPath);
- auto barIndex = repo->getFileIndex(barPath);
-
- EXPECT_NE(fooIndex, static_cast<std::size_t>(-1));
- EXPECT_EQ(fooIndex, 1);
-
- EXPECT_NE(barIndex, static_cast<std::size_t>(-1));
- EXPECT_EQ(barIndex, 0);
-
- auto bazIndex = repo->getFileIndex("baz");
- EXPECT_EQ(bazIndex, static_cast<std::size_t>(-1));
-
- EXPECT_EQ(repo->getNextFilePath(barTags.filePath), fooTags.filePath);
- EXPECT_EQ(repo->getNextFilePath(fooTags.filePath), "");
- EXPECT_EQ(repo->getNextFilePath("rand"), "");
- EXPECT_EQ(repo->getNextFilePath(""), "");
-
- EXPECT_EQ(repo->getPreviousFilePath(barTags.filePath), "");
- EXPECT_EQ(repo->getPreviousFilePath(fooTags.filePath), barTags.filePath);
- EXPECT_EQ(repo->getPreviousFilePath("rand"), "");
- EXPECT_EQ(repo->getPreviousFilePath(""), "");
-}
M module-apps/application-music-player/tests/unittest_songsmodel.cpp => module-apps/application-music-player/tests/unittest_songsmodel.cpp +2 -13
@@ 17,16 17,15 @@ using ::testing::app::music_player::MockSongsRepository;
TEST(SongsModel, Init)
{
auto mockRepo = std::make_shared<MockSongsRepository>();
- auto model = SongsModel(mockRepo);
+ auto model = SongsModel(nullptr, mockRepo);
- EXPECT_EQ(model.requestRecordsCount(), 0);
EXPECT_FALSE(model.isSongPlaying());
}
TEST(SongsModel, EmptyContext)
{
auto mockRepo = std::make_shared<MockSongsRepository>();
- auto model = SongsModel(mockRepo);
+ auto model = SongsModel(nullptr, mockRepo);
auto ctx = model.getCurrentSongContext();
@@ 34,13 33,3 @@ TEST(SongsModel, EmptyContext)
EXPECT_TRUE(ctx.filePath.empty());
EXPECT_EQ(ctx.currentSongState, app::music_player::SongState::NotPlaying);
}
-
-TEST(SongsModel, createDataNoSongs)
-{
- auto mockRepo = std::make_shared<MockSongsRepository>();
- auto model = SongsModel(mockRepo);
-
- EXPECT_CALL(*mockRepo, scanMusicFilesList);
- EXPECT_CALL(*mockRepo, getMusicFilesList).WillRepeatedly(Return(std::vector<tags::fetcher::Tags>()));
- model.createData([](const std::string &) { return true; }, []() {}, [](const UTF8 &) {}, []() {});
-}
M module-apps/application-music-player/windows/MusicPlayerAllSongsWindow.cpp => module-apps/application-music-player/windows/MusicPlayerAllSongsWindow.cpp +0 -3
@@ 69,9 69,6 @@ namespace gui
void MusicPlayerAllSongsWindow::onBeforeShow([[maybe_unused]] ShowMode mode, [[maybe_unused]] SwitchData *data)
{
presenter->attach(this);
- auto index = presenter->getMusicPlayerItemProvider()->getCurrentIndex();
-
- songsList->rebuildList(listview::RebuildType::OnPageElement, index);
}
void MusicPlayerAllSongsWindow::updateSongsState()
M module-db/Interface/MultimediaFilesRecord.cpp => module-db/Interface/MultimediaFilesRecord.cpp +5 -5
@@ 137,7 137,7 @@ namespace db::multimedia_files
{
const auto records = database->files.getLimitOffset(query->offset, query->limit);
- auto response = std::make_unique<query::GetLimitedResult>(records);
+ auto response = std::make_unique<query::GetLimitedResult>(records, database->files.count());
response->setRequestQuery(query);
return response;
@@ 192,7 192,7 @@ namespace db::multimedia_files
{
const auto records = database->files.getArtistsLimitOffset(query->offset, query->limit);
- auto response = std::make_unique<query::GetArtistsLimitedResult>(records);
+ auto response = std::make_unique<query::GetArtistsLimitedResult>(records, database->files.countArtists());
response->setRequestQuery(query);
return response;
@@ 212,7 212,7 @@ namespace db::multimedia_files
{
const auto records = database->files.getAlbumsLimitOffset(query->offset, query->limit);
- auto response = std::make_unique<query::GetAlbumsLimitedResult>(records);
+ auto response = std::make_unique<query::GetAlbumsLimitedResult>(records, database->files.countAlbums());
response->setRequestQuery(query);
return response;
@@ 223,7 223,7 @@ namespace db::multimedia_files
{
const auto records = database->files.getLimitOffset(query->artist, query->offset, query->limit);
- auto response = std::make_unique<query::GetLimitedResult>(records);
+ auto response = std::make_unique<query::GetLimitedResult>(records, database->files.count());
response->setRequestQuery(query);
return response;
@@ 243,7 243,7 @@ namespace db::multimedia_files
{
const auto records = database->files.getLimitOffset(query->album, query->offset, query->limit);
- auto response = std::make_unique<query::GetLimitedResult>(records);
+ auto response = std::make_unique<query::GetLimitedResult>(records, database->files.count());
response->setRequestQuery(query);
return response;
M module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.cpp => module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.cpp +21 -3
@@ 31,7 31,8 @@ namespace db::multimedia_files::query
return std::string{"GetLimitedForAlbum"};
}
- GetLimitedResult::GetLimitedResult(std::vector<MultimediaFilesRecord> records) : records(std::move(records))
+ GetLimitedResult::GetLimitedResult(std::vector<MultimediaFilesRecord> records, unsigned int dbRecordsCount)
+ : records(std::move(records)), dbRecordsCount{dbRecordsCount}
{}
auto GetLimitedResult::getResult() const -> std::vector<MultimediaFilesRecord>
@@ 39,6 40,11 @@ namespace db::multimedia_files::query
return records;
}
+ auto GetLimitedResult::getCount() const noexcept -> unsigned int
+ {
+ return dbRecordsCount;
+ }
+
auto GetLimitedResult::debugInfo() const -> std::string
{
return std::string{"GetLimitedResult"};
@@ 53,7 59,8 @@ namespace db::multimedia_files::query
return std::string{"GetArtistsLimited"};
}
- GetArtistsLimitedResult::GetArtistsLimitedResult(std::vector<Artist> records) : records(std::move(records))
+ GetArtistsLimitedResult::GetArtistsLimitedResult(std::vector<Artist> records, unsigned int dbRecordsCount)
+ : records(std::move(records)), dbRecordsCount{dbRecordsCount}
{}
auto GetArtistsLimitedResult::getResult() const -> std::vector<Artist>
@@ 61,6 68,11 @@ namespace db::multimedia_files::query
return records;
}
+ auto GetArtistsLimitedResult::getCount() const noexcept -> unsigned int
+ {
+ return dbRecordsCount;
+ }
+
auto GetArtistsLimitedResult::debugInfo() const -> std::string
{
return std::string{"GetArtistsLimitedResult"};
@@ 75,7 87,8 @@ namespace db::multimedia_files::query
return std::string{"GetAlbumsLimited"};
}
- GetAlbumsLimitedResult::GetAlbumsLimitedResult(std::vector<Album> records) : records(std::move(records))
+ GetAlbumsLimitedResult::GetAlbumsLimitedResult(std::vector<Album> records, unsigned int dbRecordsCount)
+ : records(std::move(records)), dbRecordsCount{dbRecordsCount}
{}
auto GetAlbumsLimitedResult::getResult() const -> std::vector<Album>
@@ 83,6 96,11 @@ namespace db::multimedia_files::query
return records;
}
+ auto GetAlbumsLimitedResult::getCount() const noexcept -> unsigned int
+ {
+ return dbRecordsCount;
+ }
+
auto GetAlbumsLimitedResult::debugInfo() const -> std::string
{
return std::string{"GetAlbumsLimitedResult"};
M module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp => module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp +9 -6
@@ 48,11 48,12 @@ namespace db::multimedia_files::query
class GetLimitedResult : public QueryResult
{
const std::vector<MultimediaFilesRecord> records;
+ unsigned int dbRecordsCount;
public:
- explicit GetLimitedResult(std::vector<MultimediaFilesRecord> records);
+ explicit GetLimitedResult(std::vector<MultimediaFilesRecord> records, unsigned int dbRecordsCount);
[[nodiscard]] auto getResult() const -> std::vector<MultimediaFilesRecord>;
-
+ [[nodiscard]] auto getCount() const noexcept -> unsigned int;
[[nodiscard]] auto debugInfo() const -> std::string override;
};
@@ 69,11 70,12 @@ namespace db::multimedia_files::query
class GetArtistsLimitedResult : public QueryResult
{
const std::vector<Artist> records;
+ unsigned int dbRecordsCount;
public:
- explicit GetArtistsLimitedResult(std::vector<Artist> records);
+ explicit GetArtistsLimitedResult(std::vector<Artist> records, unsigned int dbRecordsCount);
[[nodiscard]] auto getResult() const -> std::vector<Artist>;
-
+ [[nodiscard]] auto getCount() const noexcept -> unsigned int;
[[nodiscard]] auto debugInfo() const -> std::string override;
};
@@ 90,11 92,12 @@ namespace db::multimedia_files::query
class GetAlbumsLimitedResult : public QueryResult
{
const std::vector<Album> records;
+ unsigned int dbRecordsCount;
public:
- explicit GetAlbumsLimitedResult(std::vector<Album> records);
+ explicit GetAlbumsLimitedResult(std::vector<Album> records, unsigned int dbRecordsCount);
[[nodiscard]] auto getResult() const -> std::vector<Album>;
-
+ [[nodiscard]] auto getCount() const noexcept -> unsigned int;
[[nodiscard]] auto debugInfo() const -> std::string override;
};
} // namespace db::multimedia_files::query