Files
MuditaOS/module-apps/application-settings/models/apps/SoundsModel.cpp
Adam Dobrowolski 0ec9428917 [EGD-7773] Popups stack poc
Stack plus minimum tests added
Updated to master
Removed useless or adressed TODOS
Constants name applied
Renamed searchModel to searchRequestModel
Review applied
We should remove legacy window names
Bell names fixes
2022-01-04 13:01:23 +01:00

210 lines
7.5 KiB
C++

// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SoundsModel.hpp"
#include "AppWindow.hpp"
#include <application-settings/widgets/apps/SettingsSoundItem.hpp>
#include <module-gui/gui/input/InputEvent.hpp>
#include <ListView.hpp>
#include <purefs/filesystem_paths.hpp>
#include <service-audio/AudioServiceAPI.hpp>
#include <tags_fetcher/TagsFetcher.hpp>
SoundsModel::SoundsModel(std::shared_ptr<AbstractSoundsPlayer> soundsPlayer) : soundsPlayer{std::move(soundsPlayer)}
{}
unsigned int SoundsModel::requestRecordsCount()
{
return internalData.size();
}
unsigned int SoundsModel::getMinimalItemSpaceRequired() const
{
return style::window::label::big_h + style::margins::big;
}
void SoundsModel::requestRecords(const uint32_t offset, const uint32_t limit)
{
setupModel(offset, limit);
list->onProviderDataUpdate();
}
gui::ListItem *SoundsModel::getItem(gui::Order order)
{
return getRecord(order);
}
void SoundsModel::createData(app::ApplicationCommon *app, audio_settings::AbstractAudioSettingsModel *model)
{
assert(model);
assert(app);
// configure according to type
std::filesystem::path folder = getSoundPath(model);
// iterate through selected folder and collect all sounds names
std::vector<std::filesystem::path> sounds;
if (std::filesystem::is_directory(folder)) {
LOG_INFO("Scanning sound folder: %s", folder.c_str());
for (const auto &entry : std::filesystem::directory_iterator(folder)) {
if (std::filesystem::is_directory(entry)) {
continue;
}
const auto &filePath = entry.path();
if (filePath.extension() == ".mp3")
sounds.push_back(filePath);
}
LOG_INFO("Found %d sounds in folder %s", static_cast<int>(sounds.size()), folder.c_str());
}
else {
LOG_ERROR("Cannot find directory: %s", folder.c_str());
}
applyItems(sounds, app, model);
}
void SoundsModel::clearData()
{
list->reset();
eraseInternalData();
}
std::filesystem::path SoundsModel::getSoundPath(audio_settings::AbstractAudioSettingsModel *model)
{
assert(model);
switch (model->getPlaybackType()) {
case audio::PlaybackType::CallRingtone:
return purefs::dir::getCurrentOSPath() / "assets/audio/ringtone";
case audio::PlaybackType::TextMessageRingtone:
return purefs::dir::getCurrentOSPath() / "assets/audio/sms";
case audio::PlaybackType::Notifications:
return purefs::dir::getCurrentOSPath() / "assets/audio/alarm";
default:
return purefs::dir::getCurrentOSPath() / "assets/audio";
}
}
void SoundsModel::applyItems(const std::vector<std::filesystem::path> &sounds,
app::ApplicationCommon *app,
audio_settings::AbstractAudioSettingsModel *model)
{
auto currentItemIndex = 0;
auto selectedItemIndex = 0;
std::string selectedSound = purefs::dir::getCurrentOSPath() / model->getSound();
for (const auto &sound : sounds) {
bool isSelected = false;
if (sound == selectedSound) {
isSelected = true;
selectedItemIndex = currentItemIndex;
}
std::string itemTitle;
auto fileTags = tags::fetcher::fetchTags(sound);
itemTitle = fileTags.title;
if (itemTitle.empty()) {
itemTitle = sound.filename();
}
auto item = new gui::SettingsSoundItem(itemTitle, isSelected);
switch (model->getPlaybackType()) {
case audio::PlaybackType::CallRingtone:
case audio::PlaybackType::TextMessageRingtone:
case audio::PlaybackType::Notifications:
item->activatedCallback = [=](gui::Item &) {
auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
LOG_INFO("Setting sound to %s", fileRelativePath.c_str());
model->setSound(fileRelativePath);
soundsPlayer->stop();
app->returnToPreviousWindow();
return true;
};
// callback to handle preview of the sound
item->inputCallback = [=](gui::Item &item, const gui::InputEvent &event) {
auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
if (event.isShortRelease(gui::KeyCode::KEY_RF)) {
soundsPlayer->stop();
}
else if (event.isShortRelease(gui::KeyCode::KEY_LF)) {
if (!soundsPlayer->previouslyPlayed(fileRelativePath) ||
soundsPlayer->isInState(AbstractSoundsPlayer::State::Stopped)) {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::pause), gui::nav_bar::Side::Left, false);
return soundsPlayer->play(fileRelativePath, [=]() {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::play), gui::nav_bar::Side::Left, false);
});
}
else if (soundsPlayer->isInState(AbstractSoundsPlayer::State::Playing)) {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::play), gui::nav_bar::Side::Left, false);
return soundsPlayer->pause();
}
else if (soundsPlayer->isInState(AbstractSoundsPlayer::State::Paused)) {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::pause), gui::nav_bar::Side::Left, false);
return soundsPlayer->resume();
}
}
return false;
};
item->focusChangedCallback = [=](gui::Item &item) {
if (!item.focus) {
app->getCurrentWindow()->navBarRestoreFromTemporaryMode();
return true;
}
auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
if (!soundsPlayer->previouslyPlayed(fileRelativePath)) {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::play), gui::nav_bar::Side::Left, false);
return true;
}
if (soundsPlayer->isInState(AbstractSoundsPlayer::State::Playing)) {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::pause), gui::nav_bar::Side::Left, false);
return true;
}
else {
app->getCurrentWindow()->navBarTemporaryMode(
utils::translate(style::strings::common::play), gui::nav_bar::Side::Left, false);
return true;
}
};
break;
default:
item->activatedCallback = [=](gui::Item &) {
app->returnToPreviousWindow();
return true;
};
break;
}
internalData.push_back(item);
++currentItemIndex;
}
for (auto item : internalData) {
item->deleteByList = false;
}
list->rebuildList(gui::listview::RebuildType::OnPageElement, selectedItemIndex);
}