M module-db/Interface/MultimediaFilesRecord.cpp => module-db/Interface/MultimediaFilesRecord.cpp +3 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "MultimediaFilesRecord.hpp"
@@ 257,7 257,8 @@ namespace db::multimedia_files
std::unique_ptr<db::multimedia_files::query::GetLimitedResult> MultimediaFilesRecordInterface::
runQueryImplGetLimited(const std::shared_ptr<db::multimedia_files::query::GetLimitedByPaths> &query)
{
- const auto records = database->files.getLimitOffsetByPaths(query->paths, query->offset, query->limit);
+ const auto records =
+ database->files.getLimitOffsetByPaths(query->paths, query->offset, query->limit, query->sorting);
auto response = std::make_unique<query::GetLimitedResult>(records, database->files.count(query->paths));
response->setRequestQuery(query);
M module-db/Tables/MultimediaFilesTable.cpp => module-db/Tables/MultimediaFilesTable.cpp +20 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "MultimediaFilesTable.hpp"
@@ 8,6 8,20 @@
#include <magic_enum.hpp>
#include <inttypes.h>
+namespace
+{
+ std::string getSorting(db::multimedia_files::SortingBy sorting)
+ {
+ switch (sorting) {
+ case db::multimedia_files::SortingBy::IdAscending:
+ return "_id ASC";
+ case db::multimedia_files::SortingBy::TitleAscending:
+ default:
+ return "title ASC";
+ }
+ }
+} // namespace
+
namespace db::multimedia_files
{
TableRow CreateTableRow(const QueryResult &result)
@@ 350,11 364,12 @@ namespace db::multimedia_files
}
auto MultimediaFilesTable::getLimitOffsetByPaths(const std::vector<std::string> &paths,
- uint32_t offset,
- uint32_t limit) -> std::vector<TableRow>
+ std::uint32_t offset,
+ std::uint32_t limit,
+ SortingBy sorting) -> std::vector<TableRow>
{
- const std::string query = "SELECT * FROM files WHERE " + constructMatchPattern(paths) +
- " ORDER BY title ASC LIMIT " + std::to_string(limit) + " OFFSET " +
+ const std::string query = "SELECT * FROM files WHERE " + constructMatchPattern(paths) + " ORDER BY " +
+ getSorting(sorting) + " LIMIT " + std::to_string(limit) + " OFFSET " +
std::to_string(offset) + ";";
std::unique_ptr<QueryResult> retQuery = db->query(query.c_str());
return retQueryUnpack(std::move(retQuery));
M module-db/Tables/MultimediaFilesTable.hpp => module-db/Tables/MultimediaFilesTable.hpp +11 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 70,6 70,12 @@ namespace db::multimedia_files
channels
};
+ enum class SortingBy
+ {
+ TitleAscending,
+ IdAscending
+ };
+
class MultimediaFilesTable : public Table<TableRow, TableFields>
{
public:
@@ 101,8 107,10 @@ namespace db::multimedia_files
auto getLimitOffset(const Album &album, uint32_t offset, uint32_t limit) -> std::vector<TableRow>;
auto count(const Album &album) -> uint32_t;
- auto getLimitOffsetByPaths(const std::vector<std::string> &paths, uint32_t offset, uint32_t limit)
- -> std::vector<TableRow>;
+ auto getLimitOffsetByPaths(const std::vector<std::string> &paths,
+ std::uint32_t offset,
+ std::uint32_t limit,
+ SortingBy sorting = SortingBy::TitleAscending) -> std::vector<TableRow>;
auto count(const std::vector<std::string> &paths) -> uint32_t;
TableRow getByPath(std::string path);
M module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.cpp => module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.cpp +6 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "QueryMultimediaFilesGetLimited.hpp"
@@ 106,8 106,11 @@ namespace db::multimedia_files::query
return std::string{"GetAlbumsLimitedResult"};
}
- GetLimitedByPaths::GetLimitedByPaths(const std::vector<std::string> &paths, uint32_t offset, uint32_t limit)
- : Query(Query::Type::Read), paths{paths}, offset(offset), limit(limit)
+ GetLimitedByPaths::GetLimitedByPaths(const std::vector<std::string> &paths,
+ std::uint32_t offset,
+ std::uint32_t limit,
+ SortingBy sorting)
+ : Query(Query::Type::Read), paths{paths}, offset{offset}, limit{limit}, sorting{sorting}
{}
auto GetLimitedByPaths::debugInfo() const -> std::string
M module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp => module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp +6 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 104,11 104,15 @@ namespace db::multimedia_files::query
class GetLimitedByPaths : public Query
{
public:
- GetLimitedByPaths(const std::vector<std::string> &paths, uint32_t offset, uint32_t limit);
+ GetLimitedByPaths(const std::vector<std::string> &paths,
+ std::uint32_t offset,
+ std::uint32_t limit,
+ SortingBy sorting = SortingBy::TitleAscending);
[[nodiscard]] auto debugInfo() const -> std::string override;
const std::vector<std::string> paths;
const uint32_t offset = 0;
const uint32_t limit = 0;
+ const SortingBy sorting = SortingBy::TitleAscending;
};
} // namespace db::multimedia_files::query
M products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp => products/BellHybrid/alarms/src/actions/PlayAudioActions.hpp +2 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 33,7 33,7 @@ namespace alarms
sys::Service &service;
sys::TimerHandle timer;
- SoundsRepository soundsRepository;
+ SimpleSoundsRepository soundsRepository;
const std::string toneSetting;
const std::optional<std::string> durationSetting;
const audio::PlaybackType playbackType;
M products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp => products/BellHybrid/apps/application-bell-powernap/ApplicationBellPowerNap.cpp +1 -1
@@ 62,7 62,7 @@ namespace app
auto timeModel = std::make_unique<app::TimeModel>();
auto frontlightModel = std::make_unique<powernap::PowerNapFrontlightModel>(this, powerNapAlarmDuration);
auto soundsRepository =
- std::make_unique<SoundsRepository>(paths::audio::proprietary() / paths::audio::alarm());
+ std::make_unique<SimpleSoundsRepository>(paths::audio::proprietary() / paths::audio::alarm());
auto presenter = std::make_unique<powernap::PowerNapProgressPresenter>(app,
settings.get(),
std::move(soundsRepository),
M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp +9 -8
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "PowerNapProgressPresenter.hpp"
@@ 18,13 18,14 @@ namespace
namespace app::powernap
{
- PowerNapProgressPresenter::PowerNapProgressPresenter(app::ApplicationCommon *app,
- settings::Settings *settings,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository,
- AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractTimeModel> timeModel,
- std::unique_ptr<PowerNapFrontlightModel> frontlightModel,
- const std::chrono::seconds &powerNapAlarmDuration)
+ PowerNapProgressPresenter::PowerNapProgressPresenter(
+ app::ApplicationCommon *app,
+ settings::Settings *settings,
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository,
+ AbstractAudioModel &audioModel,
+ std::unique_ptr<AbstractTimeModel> timeModel,
+ std::unique_ptr<PowerNapFrontlightModel> frontlightModel,
+ const std::chrono::seconds &powerNapAlarmDuration)
: app{app}, settings{settings}, soundsRepository{std::move(soundsRepository)},
audioModel{audioModel}, timeModel{std::move(timeModel)}, frontlightModel{std::move(frontlightModel)},
napAlarmTimer{sys::TimerFactory::createSingleShotTimer(
M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 66,7 66,7 @@ namespace app::powernap
{
app::ApplicationCommon *app{};
settings::Settings *settings{};
- std::unique_ptr<AbstractSoundsRepository> soundsRepository;
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository;
AbstractAudioModel &audioModel;
std::unique_ptr<app::TimerWithCallbacks> timer;
std::unique_ptr<AbstractTimeModel> timeModel;
@@ 79,7 79,7 @@ namespace app::powernap
public:
PowerNapProgressPresenter(app::ApplicationCommon *app,
settings::Settings *settings,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository,
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository,
AbstractAudioModel &audioModel,
std::unique_ptr<AbstractTimeModel> timeModel,
std::unique_ptr<PowerNapFrontlightModel> frontlightModel,
M products/BellHybrid/apps/application-bell-relaxation/ApplicationBellRelaxation.cpp => products/BellHybrid/apps/application-bell-relaxation/ApplicationBellRelaxation.cpp +11 -4
@@ 22,6 22,7 @@
#include <Paths.hpp>
#include <apps-common/messages/AppMessage.hpp>
#include <apps-common/models/SongsRepository.hpp>
+#include <common/SoundsRepository.hpp>
#include <common/models/TimeModel.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/AudioModel.hpp>
@@ 85,13 86,19 @@ namespace app
void ApplicationBellRelaxation::createUserInterface()
{
windowsFactory.attach(gui::name::window::main_window, [](ApplicationCommon *app, const std::string &name) {
- const auto paths = std::map<relaxation::MusicType, std::string>{
+ const auto pathsTypeMap = std::map<relaxation::MusicType, std::string>{
{relaxation::MusicType::Relaxation, paths::audio::proprietary() / paths::audio::relaxation()},
{relaxation::MusicType::ColorsOfNoise, paths::audio::proprietary() / paths::audio::colorOfNoises()},
{relaxation::MusicType::User, paths::audio::userApp() / paths::audio::relaxation()}};
-
- auto soundsRepository = std::make_unique<relaxation::RelaxationSongsRepository>(app, paths);
- auto songsModel = std::make_unique<relaxation::RelaxationSongsModel>(app, std::move(soundsRepository));
+ const auto pathsSortingVector = std::vector<SoundsRepository::PathSorting>{
+ {paths::audio::proprietary() / paths::audio::relaxation(), SoundsRepository::SortingBy::TitleAscending},
+ {paths::audio::proprietary() / paths::audio::colorOfNoises(),
+ SoundsRepository::SortingBy::TitleAscending},
+ {paths::audio::userApp() / paths::audio::relaxation(), SoundsRepository::SortingBy::TitleAscending}};
+
+ auto soundsRepository = std::make_unique<SoundsRepository>(app, pathsSortingVector);
+ auto songsModel =
+ std::make_unique<relaxation::RelaxationSongsModel>(app, std::move(soundsRepository), pathsTypeMap);
auto presenter = std::make_unique<relaxation::RelaxationMainWindowPresenter>(std::move(songsModel));
return std::make_unique<gui::RelaxationMainWindow>(app, std::move(presenter));
});
M products/BellHybrid/apps/application-bell-relaxation/CMakeLists.txt => products/BellHybrid/apps/application-bell-relaxation/CMakeLists.txt +0 -2
@@ 62,8 62,6 @@ target_sources(application-bell-relaxation
windows/RelaxationErrorWindow.hpp
model/RelaxationSongsModel.hpp
model/RelaxationSongsModel.cpp
- model/RelaxationSongsRepository.hpp
- model/RelaxationSongsRepository.cpp
PUBLIC
include/application-bell-relaxation/ApplicationBellRelaxation.hpp
M products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsModel.cpp => products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsModel.cpp +24 -27
@@ 1,31 1,20 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "RelaxationSongsModel.hpp"
#include "common/options/OptionBellMenu.hpp"
#include "widgets/RelaxationOption.hpp"
-namespace
-{
- app::relaxation::MusicType getTypeFromPath(const std::string &path,
- const std::map<app::relaxation::MusicType, std::string> &pathPrefixes)
- {
- for (const auto &[type, pathPrefix] : pathPrefixes) {
- if (path.find(pathPrefix) != std::string::npos) {
- return type;
- }
- }
- return app::relaxation::MusicType::Relaxation;
- }
-} // namespace
namespace app::relaxation
{
RelaxationSongsProvider::RelaxationSongsProvider(ApplicationCommon *app) : DatabaseModel(app)
{}
- RelaxationSongsModel::RelaxationSongsModel(
- ApplicationCommon *application, std::unique_ptr<app::relaxation::RelaxationSongsRepository> soundsRepository)
- : RelaxationSongsProvider(application), application(application), songsRepository{std::move(soundsRepository)}
+ RelaxationSongsModel::RelaxationSongsModel(ApplicationCommon *application,
+ std::unique_ptr<AbstractSoundsRepository> soundsRepository,
+ const std::map<MusicType, std::string> &pathPrefixes)
+ : RelaxationSongsProvider(application),
+ application(application), songsRepository{std::move(soundsRepository)}, pathPrefixes{pathPrefixes}
{}
void RelaxationSongsModel::createData(OnActivateCallback callback)
@@ 42,7 31,7 @@ namespace app::relaxation
unsigned int RelaxationSongsModel::requestRecordsCount()
{
- return songsRepository->getRecordsCount();
+ return songsRepository->getFilesCount();
}
unsigned int RelaxationSongsModel::getMinimalItemSpaceRequired() const
{
@@ 64,15 53,14 @@ namespace app::relaxation
if (!sound) {
return nullptr;
}
- auto item =
- gui::option::RelaxationOption{getTypeFromPath(sound->fileInfo.path, songsRepository->getPathPrefixes()),
- sound->tags.title,
- [=]([[maybe_unused]] gui::Item &item) {
- activateCallback(*sound);
- return true;
- },
- [=]([[maybe_unused]] gui::Item &item) { return true; },
- nullptr};
+ auto item = gui::option::RelaxationOption{getTypeFromPath(sound->fileInfo.path),
+ sound->tags.title,
+ [=]([[maybe_unused]] gui::Item &item) {
+ activateCallback(*sound);
+ return true;
+ },
+ []([[maybe_unused]] gui::Item &item) { return true; },
+ nullptr};
return item.build();
}
@@ 100,4 88,13 @@ namespace app::relaxation
list->onProviderDataUpdate();
return true;
}
+ MusicType RelaxationSongsModel::getTypeFromPath(const std::string &path)
+ {
+ for (const auto &[type, pathPrefix] : pathPrefixes) {
+ if (path.find(pathPrefix) != std::string::npos) {
+ return type;
+ }
+ }
+ return MusicType::Relaxation;
+ }
} // namespace app::relaxation
M products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsModel.hpp => products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsModel.hpp +9 -5
@@ 1,9 1,10 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
-#include "RelaxationSongsRepository.hpp"
+#include "data/RelaxationCommon.hpp"
+#include <common/SoundsRepository.hpp>
#include <apps-common/models/SongsModelInterface.hpp>
#include <gui/widgets/ListItemProvider.hpp>
@@ 25,18 26,21 @@ namespace app::relaxation
{
private:
ApplicationCommon *application;
- std::unique_ptr<RelaxationSongsRepository> songsRepository;
+ std::unique_ptr<AbstractSoundsRepository> songsRepository;
+ std::map<MusicType, std::string> pathPrefixes;
OnActivateCallback activateCallback{nullptr};
bool onMusicListRetrieved(const std::vector<db::multimedia_files::MultimediaFilesRecord> &records,
unsigned int repoRecordsCount);
[[nodiscard]] bool updateRecords(std::vector<db::multimedia_files::MultimediaFilesRecord> records) override;
+ MusicType getTypeFromPath(const std::string &path);
public:
virtual ~RelaxationSongsModel() = default;
- explicit RelaxationSongsModel(ApplicationCommon *application,
- std::unique_ptr<RelaxationSongsRepository> soundsRepository);
+ RelaxationSongsModel(ApplicationCommon *application,
+ std::unique_ptr<AbstractSoundsRepository> soundsRepository,
+ const std::map<MusicType, std::string> &pathPrefixes);
unsigned int requestRecordsCount() override;
D products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsRepository.cpp => products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsRepository.cpp +0 -145
@@ 1,145 0,0 @@
-// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "RelaxationSongsRepository.hpp"
-#include <module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp>
-#include <module-db/queries/multimedia_files/QueryMultimediaFilesCount.hpp>
-#include <AsyncTask.hpp>
-#include <vector>
-
-namespace
-{
- std::uint32_t calculateOffset(std::uint32_t offset, std::uint32_t filesCount)
- {
- if (offset >= filesCount) {
- return offset - filesCount;
- }
- return offset;
- }
- std::pair<std::uint32_t, std::uint32_t> calculateNewOffsetAndLimit(std::uint32_t offset,
- std::uint32_t limit,
- std::uint32_t loadedFiles)
- {
- const auto newLimit = limit - loadedFiles;
- const auto newOffset = offset + loadedFiles;
- return {newOffset, newLimit};
- }
-} // namespace
-namespace app::relaxation
-{
-
- RelaxationSongsRepository::RelaxationSongsRepository(ApplicationCommon *application,
- const std::map<MusicType, std::string> &pathPrefixes)
- : app::AsyncCallbackReceiver{application}, application{application}, pathPrefixes{pathPrefixes}
- {}
-
- void RelaxationSongsRepository::init()
- {
- updateFilesCount();
- }
-
- void RelaxationSongsRepository::updateFilesCount()
- {
- for (const auto &[musicType, musicPath] : pathPrefixes) {
- updateFilesCount(musicType, musicPath);
- }
- }
-
- void RelaxationSongsRepository::updateFilesCount(const MusicType &type, const std::string &path)
- {
- auto query = std::make_unique<db::multimedia_files::query::GetCountForPath>(path);
- auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::MultimediaFiles);
- task->setCallback([this, &type](auto response) {
- auto result = dynamic_cast<db::multimedia_files::query::GetCountResult *>(response);
- if (result == nullptr) {
- return false;
- }
- return updateCountCallback(type, result->getCount());
- });
- task->execute(application, this);
- }
-
- bool RelaxationSongsRepository::updateCountCallback(const MusicType &type, std::uint32_t count)
- {
- filesPerType[type] = count;
- return true;
- }
-
- void RelaxationSongsRepository::getMusicFiles(
- const MusicType &musicType,
- std::uint32_t offset,
- std::uint32_t limit,
- const RelaxationSongsRepository::OnGetMusicFilesListCallback &viewUpdateCallback)
- {
- auto taskCallback = [this, viewUpdateCallback, offset](auto response) {
- auto result = dynamic_cast<db::multimedia_files::query::GetLimitedResult *>(response);
- if (result == nullptr) {
- return false;
- }
- for (auto &record : result->getResult()) {
- musicFilesViewCache.records.push_back(record);
- }
- musicFilesViewCache.recordsOffset = offset;
- musicFilesViewCache.recordsCount = getRecordsCount();
-
- if (viewUpdateCallback) {
- viewUpdateCallback(musicFilesViewCache.records, musicFilesViewCache.recordsCount);
- }
- return true;
- };
-
- auto query = std::make_unique<db::multimedia_files::query::GetLimitedByPaths>(
- std::vector<std::string>{pathPrefixes[musicType]}, offset, limit);
- auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::MultimediaFiles);
- task->setCallback(taskCallback);
- task->execute(application, this);
- }
-
- std::uint32_t RelaxationSongsRepository::getRecordsCount()
- {
- return std::accumulate(filesPerType.begin(),
- filesPerType.end(),
- 0,
- [](const std::uint32_t sum, const auto &record) { return sum + record.second; });
- }
-
- void RelaxationSongsRepository::getMusicFiles(
- std::uint32_t offset,
- std::uint32_t limit,
- const RelaxationSongsRepository::OnGetMusicFilesListCallback &callback)
- {
- const auto skipViewUpdate = []([[maybe_unused]] const auto &sound, [[maybe_unused]] auto count) {
- return true;
- };
- musicFilesViewCache.records.clear();
- std::uint32_t totalFilesCount{0};
- const auto lastFileIndex = offset + limit;
- if (filesPerType.empty()) {
- getMusicFiles(MusicType::Relaxation, offset, limit, callback);
- }
-
- for (const auto &[type, filesCount] : filesPerType) {
- if (filesCount == 0) {
- continue;
- }
- totalFilesCount += filesCount;
- if (const auto newOffset = calculateOffset(offset, filesCount); newOffset != offset) {
- offset = newOffset;
- }
- else if (lastFileIndex <= totalFilesCount) {
- getMusicFiles(type, offset, limit, callback);
- break;
- }
- else {
- const auto filesToLoad = filesCount - offset;
- getMusicFiles(type, offset, filesToLoad, skipViewUpdate);
- std::tie(offset, limit) = calculateNewOffsetAndLimit(offset, limit, filesToLoad);
- offset = calculateOffset(offset, filesCount);
- }
- }
- }
- std::map<MusicType, std::string> &RelaxationSongsRepository::getPathPrefixes()
- {
- return pathPrefixes;
- }
-
-} // namespace app::relaxation
D products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsRepository.hpp => products/BellHybrid/apps/application-bell-relaxation/model/RelaxationSongsRepository.hpp +0 -41
@@ 1,41 0,0 @@
-// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include "data/RelaxationCommon.hpp"
-#include <apps-common/models/SongsRepository.hpp>
-#include <memory>
-namespace app::relaxation
-{
-
- class RelaxationSongsRepository : public app::AsyncCallbackReceiver
- {
- public:
- using OnGetMusicFilesListCallback =
- std::function<bool(const std::vector<db::multimedia_files::MultimediaFilesRecord> &, std::uint32_t)>;
-
- explicit RelaxationSongsRepository(ApplicationCommon *application,
- const std::map<MusicType, std::string> &pathPrefixes);
- void init();
- void getMusicFiles(std::uint32_t offset,
- std::uint32_t limit,
- const OnGetMusicFilesListCallback &viewUpdateCallback);
-
- std::uint32_t getRecordsCount();
- void updateFilesCount();
- std::map<MusicType, std::string> &getPathPrefixes();
-
- private:
- ApplicationCommon *application;
- std::map<MusicType, std::string> pathPrefixes;
- std::map<MusicType, std::uint32_t> filesPerType;
- music::FilesCache musicFilesViewCache;
- void updateFilesCount(const MusicType &type, const std::string &path);
- bool updateCountCallback(const MusicType &type, std::uint32_t count);
- void getMusicFiles(const MusicType &musicType,
- std::uint32_t offset,
- std::uint32_t limit,
- const OnGetMusicFilesListCallback &viewUpdateCallback);
- };
-} // namespace app::relaxation
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +7 -5
@@ 127,8 127,8 @@ namespace app
windowsFactory.attach(
gui::window::name::bellSettingsBedtimeTone, [this](ApplicationCommon *app, const std::string &name) {
auto bedtimeModel = std::make_shared<bell_bedtime::BedtimeModel>(app, *audioModel);
- auto soundsRepository =
- std::make_unique<SoundsRepository>(paths::audio::proprietary() / paths::audio::bedtimeReminder());
+ auto soundsRepository = std::make_unique<SimpleSoundsRepository>(paths::audio::proprietary() /
+ paths::audio::bedtimeReminder());
auto provider = std::make_shared<bell_settings::BedtimeSettingsListItemProvider>(
bedtimeModel, soundsRepository->getSongTitles());
auto presenter = std::make_unique<bell_settings::SettingsPresenter>(
@@ 174,7 174,8 @@ namespace app
std::move(prewakeUpChimeVolumeModel),
std::move(prewakeUpLightDurationModel),
std::move(prewakeUpFrontlightModel));
- auto soundsRepository = std::make_unique<SoundsRepository>(paths::audio::proprietary() / paths::audio::preWakeup());
+ auto soundsRepository =
+ std::make_unique<SimpleSoundsRepository>(paths::audio::proprietary() / paths::audio::preWakeup());
auto provider = std::make_unique<bell_settings::PrewakeUpListItemProvider>(
*prewakeUpSettingsModel, soundsRepository->getSongTitles());
auto frontlightModel = std::make_unique<bell_settings::FrontlightModel>(app);
@@ 206,7 207,7 @@ namespace app
std::move(snoozeChimeToneModel),
std::move(snoozeChimeVolumeModel));
auto soundsRepository =
- std::make_unique<SoundsRepository>(paths::audio::proprietary() / paths::audio::snooze());
+ std::make_unique<SimpleSoundsRepository>(paths::audio::proprietary() / paths::audio::snooze());
auto provider = std::make_shared<bell_settings::SnoozeListItemProvider>(
*snoozeSettingsModel, soundsRepository->getSongTitles());
auto presenter = std::make_unique<bell_settings::SnoozePresenter>(
@@ 226,7 227,8 @@ namespace app
std::move(alarmFadeOnOffModel),
std::move(alarmLightOnOffModel),
std::move(alarmFrontlightModel));
- auto soundsRepository = std::make_unique<SoundsRepository>(paths::audio::proprietary() / paths::audio::alarm());
+ auto soundsRepository =
+ std::make_unique<SimpleSoundsRepository>(paths::audio::proprietary() / paths::audio::alarm());
auto frontlightModel = std::make_unique<bell_settings::FrontlightModel>(app);
auto provider = std::make_unique<bell_settings::AlarmSettingsListItemProvider>(
*alarmSettingsModel, soundsRepository->getSongTitles());
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp +1 -1
@@ 8,7 8,7 @@ namespace app::bell_settings
SettingsPresenter::SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
std::shared_ptr<AbstractBedtimeModel> model,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository)
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository)
: provider(std::move(provider)),
model(std::move(model)), audioModel{audioModel}, soundsRepository{std::move(soundsRepository)}
{
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 45,7 45,7 @@ namespace app::bell_settings
SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
std::shared_ptr<AbstractBedtimeModel> model,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository);
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository);
auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
auto saveData() -> void override;
@@ 59,7 59,7 @@ namespace app::bell_settings
std::shared_ptr<BedtimeSettingsListItemProvider> provider;
std::shared_ptr<AbstractBedtimeModel> model;
AbstractAudioModel &audioModel;
- std::unique_ptr<AbstractSoundsRepository> soundsRepository;
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository;
UTF8 currentSoundPath;
};
} // namespace app::bell_settings
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp +1 -1
@@ 9,7 9,7 @@ namespace app::bell_settings
AlarmSettingsPresenter::AlarmSettingsPresenter(std::unique_ptr<AlarmSettingsListItemProvider> &&provider,
std::unique_ptr<AbstractAlarmSettingsModel> &&settingsModel,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> &&soundsRepository,
+ std::unique_ptr<AbstractSimpleSoundsRepository> &&soundsRepository,
std::unique_ptr<AbstractFrontlightModel> &&frontlight)
: provider{std::move(provider)}, settingsModel{std::move(settingsModel)}, audioModel{audioModel},
soundsRepository{std::move(soundsRepository)}, frontlight{std::move(frontlight)}
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 49,7 49,7 @@ namespace app::bell_settings
AlarmSettingsPresenter(std::unique_ptr<AlarmSettingsListItemProvider> &&provider,
std::unique_ptr<AbstractAlarmSettingsModel> &&settingsModel,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> &&soundsRepository,
+ std::unique_ptr<AbstractSimpleSoundsRepository> &&soundsRepository,
std::unique_ptr<AbstractFrontlightModel> &&frontlight);
auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
@@ 65,7 65,7 @@ namespace app::bell_settings
std::shared_ptr<AlarmSettingsListItemProvider> provider;
std::unique_ptr<AbstractAlarmSettingsModel> settingsModel;
AbstractAudioModel &audioModel;
- std::unique_ptr<AbstractSoundsRepository> soundsRepository;
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository;
std::unique_ptr<AbstractFrontlightModel> frontlight;
};
} // namespace app::bell_settings
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp +6 -5
@@ 6,11 6,12 @@
namespace app::bell_settings
{
- PrewakeUpWindowPresenter::PrewakeUpWindowPresenter(std::unique_ptr<PrewakeUpListItemProvider> &&provider,
- std::unique_ptr<AbstractPrewakeUpSettingsModel> &&model,
- AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> &&soundsRepository,
- std::unique_ptr<AbstractFrontlightModel> &&frontlight)
+ PrewakeUpWindowPresenter::PrewakeUpWindowPresenter(
+ std::unique_ptr<PrewakeUpListItemProvider> &&provider,
+ std::unique_ptr<AbstractPrewakeUpSettingsModel> &&model,
+ AbstractAudioModel &audioModel,
+ std::unique_ptr<AbstractSimpleSoundsRepository> &&soundsRepository,
+ std::unique_ptr<AbstractFrontlightModel> &&frontlight)
: provider{std::move(provider)}, model{std::move(model)}, audioModel{audioModel},
soundsRepository{std::move(soundsRepository)}, frontlight{std::move(frontlight)}
{
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 48,7 48,7 @@ namespace app::bell_settings
PrewakeUpWindowPresenter(std::unique_ptr<PrewakeUpListItemProvider> &&provider,
std::unique_ptr<AbstractPrewakeUpSettingsModel> &&model,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> &&soundsRepository,
+ std::unique_ptr<AbstractSimpleSoundsRepository> &&soundsRepository,
std::unique_ptr<AbstractFrontlightModel> &&frontlight);
auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
@@ 63,7 63,7 @@ namespace app::bell_settings
std::shared_ptr<PrewakeUpListItemProvider> provider;
std::unique_ptr<AbstractPrewakeUpSettingsModel> model;
AbstractAudioModel &audioModel;
- std::unique_ptr<AbstractSoundsRepository> soundsRepository;
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository;
std::unique_ptr<AbstractFrontlightModel> frontlight;
UTF8 currentSoundPath;
};
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp +1 -1
@@ 9,7 9,7 @@ namespace app::bell_settings
SnoozePresenter::SnoozePresenter(std::shared_ptr<SnoozeListItemProvider> provider,
std::unique_ptr<AbstractSnoozeSettingsModel> snoozeSettingsModel,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository)
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository)
: provider{provider}, snoozeSettingsModel{std::move(snoozeSettingsModel)}, audioModel{audioModel},
soundsRepository{std::move(soundsRepository)}
{
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 42,7 42,7 @@ namespace app::bell_settings
SnoozePresenter(std::shared_ptr<SnoozeListItemProvider> provider,
std::unique_ptr<AbstractSnoozeSettingsModel> snoozeSettingsModel,
AbstractAudioModel &audioModel,
- std::unique_ptr<AbstractSoundsRepository> soundsRepository);
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository);
auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
void saveData() override;
void loadData() override;
@@ 55,7 55,7 @@ namespace app::bell_settings
std::shared_ptr<SnoozeListItemProvider> provider;
std::unique_ptr<AbstractSnoozeSettingsModel> snoozeSettingsModel;
AbstractAudioModel &audioModel;
- std::unique_ptr<AbstractSoundsRepository> soundsRepository;
+ std::unique_ptr<AbstractSimpleSoundsRepository> soundsRepository;
UTF8 currentSoundPath;
};
} // namespace app::bell_settings
M products/BellHybrid/apps/common/include/common/SoundsRepository.hpp => products/BellHybrid/apps/common/include/common/SoundsRepository.hpp +69 -5
@@ 1,28 1,29 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <module-audio/tags_fetcher/TagsFetcher.hpp>
+#include <apps-common/models/SongsRepository.hpp>
#include <utf8/UTF8.hpp>
#include <filesystem>
#include <optional>
#include <vector>
-class AbstractSoundsRepository
+class AbstractSimpleSoundsRepository
{
public:
- virtual ~AbstractSoundsRepository() = default;
+ virtual ~AbstractSimpleSoundsRepository() = default;
virtual std::optional<std::filesystem::path> titleToPath(const UTF8 &title) const = 0;
virtual std::optional<UTF8> pathToTitle(std::filesystem::path) const = 0;
virtual std::vector<UTF8> getSongTitles() = 0;
};
-class SoundsRepository : public AbstractSoundsRepository
+class SimpleSoundsRepository : public AbstractSimpleSoundsRepository
{
public:
- explicit SoundsRepository(std::filesystem::path dirToScan);
+ explicit SimpleSoundsRepository(std::filesystem::path dirToScan);
std::optional<std::filesystem::path> titleToPath(const UTF8 &title) const override;
std::optional<UTF8> pathToTitle(std::filesystem::path path) const override;
@@ 33,3 34,66 @@ class SoundsRepository : public AbstractSoundsRepository
std::vector<tags::fetcher::Tags> samples;
};
+
+class AbstractSoundsRepository
+{
+ public:
+ using OnGetMusicFilesListCallback =
+ std::function<bool(const std::vector<db::multimedia_files::MultimediaFilesRecord> &, std::uint32_t)>;
+
+ virtual ~AbstractSoundsRepository() noexcept = default;
+
+ virtual void init() = 0;
+ virtual void getMusicFiles(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &callback) = 0;
+
+ virtual std::uint32_t getFilesCount() = 0;
+ virtual void updateFilesCount() = 0;
+};
+
+class SoundsRepository : public AbstractSoundsRepository, public app::AsyncCallbackReceiver
+{
+ public:
+ enum class SortingBy
+ {
+ IdAscending,
+ TitleAscending
+ };
+ struct PathSorting
+ {
+ std::string prefix;
+ SortingBy sorting;
+ };
+
+ SoundsRepository(app::ApplicationCommon *application, const PathSorting &path);
+ SoundsRepository(app::ApplicationCommon *application, const std::vector<PathSorting> &pathsVector);
+ void init() override;
+ void getMusicFiles(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &viewUpdateCallback) override;
+
+ std::uint32_t getFilesCount() override;
+ void updateFilesCount() override;
+
+ private:
+ struct PathDetails
+ {
+ std::uint32_t id;
+ std::uint32_t count;
+ SortingBy sorting;
+ std::string prefix;
+ };
+
+ app::ApplicationCommon *application;
+ std::vector<PathDetails> paths;
+ app::music::FilesCache musicFilesViewCache;
+
+ void updateFilesCount(const std::uint32_t id, const std::string &path);
+ bool updateCountCallback(const std::uint32_t id, const std::uint32_t count);
+ void getMusicFiles(const std::string &path,
+ const SortingBy sorting,
+ const std::uint32_t offset,
+ const std::uint32_t limit,
+ const OnGetMusicFilesListCallback &viewUpdateCallback);
+};
M products/BellHybrid/apps/common/src/SoundsRepository.cpp => products/BellHybrid/apps/common/src/SoundsRepository.cpp +157 -6
@@ 1,8 1,11 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SoundsRepository.hpp"
+#include <module-db/queries/multimedia_files/QueryMultimediaFilesGetLimited.hpp>
+#include <module-db/queries/multimedia_files/QueryMultimediaFilesCount.hpp>
+#include <AsyncTask.hpp>
#include <algorithm>
namespace fs = std::filesystem;
@@ 10,9 13,35 @@ namespace fs = std::filesystem;
namespace
{
constexpr auto allowedExtensions = {".wav", ".mp3", ".flac"};
+
+ constexpr std::uint32_t calculateOffset(std::uint32_t offset, std::uint32_t filesCount)
+ {
+ if (offset >= filesCount) {
+ return offset - filesCount;
+ }
+ return offset;
+ }
+ constexpr std::pair<std::uint32_t, std::uint32_t> calculateNewOffsetAndLimit(std::uint32_t offset,
+ std::uint32_t limit,
+ std::uint32_t loadedFiles)
+ {
+ const auto newLimit = limit - loadedFiles;
+ const auto newOffset = offset + loadedFiles;
+ return {newOffset, newLimit};
+ }
+ db::multimedia_files::SortingBy transformSorting(SoundsRepository::SortingBy sorting)
+ {
+ switch (sorting) {
+ case SoundsRepository::SortingBy::IdAscending:
+ return db::multimedia_files::SortingBy::IdAscending;
+ case SoundsRepository::SortingBy::TitleAscending:
+ default:
+ return db::multimedia_files::SortingBy::TitleAscending;
+ }
+ }
} // namespace
-SoundsRepository::SoundsRepository(std::filesystem::path dirToScan)
+SimpleSoundsRepository::SimpleSoundsRepository(std::filesystem::path dirToScan)
{
for (auto const &entry : std::filesystem::directory_iterator(dirToScan)) {
processEntry(entry);
@@ 21,7 50,7 @@ SoundsRepository::SoundsRepository(std::filesystem::path dirToScan)
/// Sort entries by track ID
std::sort(samples.begin(), samples.end(), [](const auto &a, const auto &b) { return a.track < b.track; });
}
-std::optional<std::filesystem::path> SoundsRepository::titleToPath(const UTF8 &title) const
+std::optional<std::filesystem::path> SimpleSoundsRepository::titleToPath(const UTF8 &title) const
{
const auto res =
std::find_if(samples.begin(), samples.end(), [title](const auto &e) { return e.title == title.c_str(); });
@@ 30,7 59,7 @@ std::optional<std::filesystem::path> SoundsRepository::titleToPath(const UTF8 &t
}
return {};
}
-std::optional<UTF8> SoundsRepository::pathToTitle(std::filesystem::path path) const
+std::optional<UTF8> SimpleSoundsRepository::pathToTitle(std::filesystem::path path) const
{
const auto res =
std::find_if(samples.begin(), samples.end(), [&path](const auto &e) { return e.filePath == path; });
@@ 40,14 69,14 @@ std::optional<UTF8> SoundsRepository::pathToTitle(std::filesystem::path path) co
return {};
}
-std::vector<UTF8> SoundsRepository::getSongTitles()
+std::vector<UTF8> SimpleSoundsRepository::getSongTitles()
{
std::vector<UTF8> ret;
std::transform(samples.begin(), samples.end(), std::back_inserter(ret), [](const auto &e) { return e.title; });
return ret;
}
-void SoundsRepository::processEntry(const std::filesystem::recursive_directory_iterator::value_type &entry)
+void SimpleSoundsRepository::processEntry(const std::filesystem::recursive_directory_iterator::value_type &entry)
{
if (fs::is_regular_file(entry)) {
for (const auto &ext : allowedExtensions) {
@@ 57,3 86,125 @@ void SoundsRepository::processEntry(const std::filesystem::recursive_directory_i
}
}
}
+
+SoundsRepository::SoundsRepository(app::ApplicationCommon *application, const PathSorting &path)
+ : app::AsyncCallbackReceiver{application}, application{application}
+{
+ paths.push_back({0, 0, path.sorting, path.prefix});
+}
+
+SoundsRepository::SoundsRepository(app::ApplicationCommon *application, const std::vector<PathSorting> &pathsVector)
+ : app::AsyncCallbackReceiver{application}, application{application}
+{
+ std::uint32_t id = 0;
+ for (const auto &[path, sorting] : pathsVector) {
+ paths.push_back({id, 0, sorting, path});
+ id++;
+ }
+}
+
+void SoundsRepository::init()
+{
+ updateFilesCount();
+}
+
+void SoundsRepository::getMusicFiles(std::uint32_t offset,
+ std::uint32_t limit,
+ const OnGetMusicFilesListCallback &viewUpdateCallback)
+{
+ const auto skipViewUpdate = []([[maybe_unused]] const auto &sound, [[maybe_unused]] auto count) { return true; };
+ musicFilesViewCache.records.clear();
+ std::uint32_t totalFilesCount{0};
+ const auto lastFileIndex = offset + limit;
+ if (getFilesCount() == 0 && !paths.empty()) {
+ getMusicFiles(paths[0].prefix, paths[0].sorting, offset, limit, viewUpdateCallback);
+ }
+
+ for (const auto &[id, filesCount, sorting, path] : paths) {
+ if (filesCount == 0) {
+ continue;
+ }
+ totalFilesCount += filesCount;
+ if (const auto newOffset = calculateOffset(offset, filesCount); newOffset != offset) {
+ offset = newOffset;
+ }
+ else if (lastFileIndex <= totalFilesCount) {
+ getMusicFiles(path, sorting, offset, limit, viewUpdateCallback);
+ break;
+ }
+ else {
+ const auto filesToLoad = filesCount - offset;
+ getMusicFiles(path, sorting, offset, filesToLoad, skipViewUpdate);
+ std::tie(offset, limit) = calculateNewOffsetAndLimit(offset, limit, filesToLoad);
+ offset = calculateOffset(offset, filesCount);
+ }
+ }
+}
+
+void SoundsRepository::getMusicFiles(const std::string &path,
+ const SortingBy sorting,
+ const std::uint32_t offset,
+ const std::uint32_t limit,
+ const OnGetMusicFilesListCallback &viewUpdateCallback)
+{
+ auto taskCallback = [this, viewUpdateCallback, offset](auto response) {
+ auto result = dynamic_cast<db::multimedia_files::query::GetLimitedResult *>(response);
+ if (result == nullptr) {
+ return false;
+ }
+ for (auto &record : result->getResult()) {
+ musicFilesViewCache.records.push_back(record);
+ }
+ musicFilesViewCache.recordsOffset = offset;
+ musicFilesViewCache.recordsCount = getFilesCount();
+
+ if (viewUpdateCallback) {
+ viewUpdateCallback(musicFilesViewCache.records, musicFilesViewCache.recordsCount);
+ }
+ return true;
+ };
+
+ const auto sortBy = transformSorting(sorting);
+ auto query = std::make_unique<db::multimedia_files::query::GetLimitedByPaths>(
+ std::vector<std::string>{path}, offset, limit, sortBy);
+ auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::MultimediaFiles);
+ task->setCallback(taskCallback);
+ task->execute(application, this);
+}
+
+std::uint32_t SoundsRepository::getFilesCount()
+{
+ return std::accumulate(
+ paths.begin(), paths.end(), 0, [](const std::uint32_t sum, const auto &record) { return sum + record.count; });
+}
+
+void SoundsRepository::updateFilesCount()
+{
+ for (const auto &path : paths) {
+ updateFilesCount(path.id, path.prefix);
+ }
+}
+
+void SoundsRepository::updateFilesCount(const std::uint32_t id, const std::string &path)
+{
+ auto query = std::make_unique<db::multimedia_files::query::GetCountForPath>(path);
+ auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::MultimediaFiles);
+ task->setCallback([this, id](auto response) {
+ auto result = dynamic_cast<db::multimedia_files::query::GetCountResult *>(response);
+ if (result == nullptr) {
+ return false;
+ }
+ return updateCountCallback(id, result->getCount());
+ });
+ task->execute(application, this);
+}
+
+bool SoundsRepository::updateCountCallback(const std::uint32_t id, const std::uint32_t count)
+{
+ const auto it = std::find_if(paths.begin(), paths.end(), [id](auto path) { return path.id == id; });
+ if (it != paths.end()) {
+ (*it).count = count;
+ return true;
+ }
+ return false;
+}