// Copyright (c) 2017-2022, 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 #include #include #include #include #include SoundsModel::SoundsModel(std::shared_ptr 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 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(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::getSystemDiskPath() / "assets/audio/ringtone"; case audio::PlaybackType::TextMessageRingtone: return purefs::dir::getSystemDiskPath() / "assets/audio/sms"; case audio::PlaybackType::Notifications: return purefs::dir::getSystemDiskPath() / "assets/audio/alarm"; default: return purefs::dir::getSystemDiskPath() / "assets/audio"; } } void SoundsModel::applyItems(const std::vector &sounds, app::ApplicationCommon *app, audio_settings::AbstractAudioSettingsModel *model) { auto currentItemIndex = 0; auto selectedItemIndex = 0; std::string selectedSound = purefs::dir::getSystemDiskPath() / 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::getSystemDiskPath()); 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::getSystemDiskPath()); 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::getSystemDiskPath()); 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); }