~aleteoryx/muditaos

c0e13a83973fcb27e9fe99cd8044921a067fd89c — Maciej Gibowicz 1 year, 10 months ago e993435
[BH-1916] Add Error handling to the vertical list

Added error handling in case the file
selected in the vertical list is either
corrupted or deleted.
49 files changed, 618 insertions(+), 195 deletions(-)

M image/system_a/data/lang/Deutsch.json
M image/system_a/data/lang/English.json
M image/system_a/data/lang/Espanol.json
M image/system_a/data/lang/Francais.json
M image/system_a/data/lang/Polski.json
M module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp
M module-apps/apps-common/popups/Popups.cpp
M module-apps/apps-common/popups/Popups.hpp
R {products/BellHybrid/apps/application-bell-relaxation/data/RelaxationErrorData => module-apps/apps-common/popups/data/AudioErrorParams}.hpp
M products/BellHybrid/apps/Application.cpp
M products/BellHybrid/apps/application-bell-relaxation/ApplicationBellRelaxation.cpp
M products/BellHybrid/apps/application-bell-relaxation/CMakeLists.txt
M products/BellHybrid/apps/application-bell-relaxation/data/RelaxationStyle.hpp
M products/BellHybrid/apps/application-bell-relaxation/include/application-bell-relaxation/ApplicationBellRelaxation.hpp
D products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationErrorPresenter.cpp
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationMainWindow.cpp
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningLoopWindow.cpp
M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningProgressWindow.cpp
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp
M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt
A products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/AudioErrorModel.hpp
A products/BellHybrid/apps/application-bell-settings/models/AudioErrorModel.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp
M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.hpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.hpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp
M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.hpp
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.cpp
M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.hpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.cpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.hpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.cpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.hpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.cpp
M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.hpp
M products/BellHybrid/apps/common/CMakeLists.txt
R products/BellHybrid/apps/{application-bell-relaxation/presenter/RelaxationErrorPresenter => common/include/common/AudioErrorPresenter}.hpp
M products/BellHybrid/apps/common/include/common/BellCommonNames.hpp
R products/BellHybrid/apps/{application-bell-relaxation/windows/RelaxationErrorWindow => common/include/common/windows/AudioErrorWindow}.hpp
A products/BellHybrid/apps/common/src/AudioErrorPresenter.cpp
R products/BellHybrid/apps/{application-bell-relaxation/windows/RelaxationErrorWindow => common/src/windows/AudioErrorWindow}.cpp
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +3 -3
@@ 52,9 52,9 @@
    "app_bell_onboarding_shortcuts_step_restart": "F\u00fcr Ger\u00e4teneustart beide Seitenkn\u00f6pfe 10 Sek. dr\u00fccken",
    "app_bell_onboarding_shortcuts_step_rotate": "Zum Ausw\u00e4hlen drehen",
    "app_bell_onboarding_shortcuts_step_turn_off": "Zum Ausstellen des Ger\u00e4ts R\u00fcckseite 10 Sek. dr\u00fccken",
    "app_bell_relaxation_error_message": "Nicht unterst\u00fctztes Dateiformat",
    "app_bell_relaxation_file_deleted_message": "<text>Die Datei wurde gel\u00f6scht.</text>",
    "app_bell_relaxation_limit_error_message": "<text>Datenlimit \u00fcberschritten.<br />Es k\u00f6nnte zu Fehlern kommen.</text>",
    "app_bell_audio_error_message": "Nicht unterst\u00fctztes Dateiformat",
    "app_bell_audio_file_deleted_message": "<text>Die Datei wurde gel\u00f6scht.</text>",
    "app_bell_audio_limit_error_message": "<text>Datenlimit \u00fcberschritten.<br />Es k\u00f6nnte zu Fehlern kommen.</text>",
    "app_bell_relaxation_loop": "endlos",
    "app_bell_relaxation_loop_description": "der Titel wird abgespielt, bis Sie ihn ausschalten",
    "app_bell_relaxation_looped": "geschlungen",

M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +3 -3
@@ 85,9 85,9 @@
    "app_bell_onboarding_shortcuts_step_restart": "Press both side buttons for 10s to restart the device",
    "app_bell_onboarding_shortcuts_step_rotate": "Rotate to select",
    "app_bell_onboarding_shortcuts_step_turn_off": "Press back for 10s to turn off the device",
    "app_bell_relaxation_error_message": "Unsupported media type",
    "app_bell_relaxation_file_deleted_message": "<text>The file has been deleted.</text>",
    "app_bell_relaxation_limit_error_message": "<text>File limit exceeded.<br />Not all files may be displayed<br />correctly</text>",
    "app_bell_audio_error_message": "Unsupported media type",
    "app_bell_audio_file_deleted_message": "<text>The file has been deleted.</text>",
    "app_bell_audio_limit_error_message": "<text>File limit exceeded.<br />Not all files may be displayed<br />correctly</text>",
    "app_bell_relaxation_loop": "loop",
    "app_bell_relaxation_loop_description": "the song will play until you turn it off",
    "app_bell_relaxation_looped": "looped",

M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +3 -3
@@ 51,9 51,9 @@
    "app_bell_onboarding_shortcuts_step_restart": "Pulsa ambos botones laterales 10 s para reiniciar",
    "app_bell_onboarding_shortcuts_step_rotate": "Girar para seleccionar",
    "app_bell_onboarding_shortcuts_step_turn_off": "Pulsa Volver atr\u00e1s 10 s para apagar el dispositivo",
    "app_bell_relaxation_error_message": "Formato de archivo no admitido",
    "app_bell_relaxation_file_deleted_message": "<text>Se ha eliminado el archivo.</text>",
    "app_bell_relaxation_limit_error_message": "<text>L\u00edmite de archivos alcanzado,<br />pueden producirse errores.</text>",
    "app_bell_audio_error_message": "Formato de archivo no admitido",
    "app_bell_audio_file_deleted_message": "<text>Se ha eliminado el archivo.</text>",
    "app_bell_audio_limit_error_message": "<text>L\u00edmite de archivos alcanzado,<br />pueden producirse errores.</text>",
    "app_bell_relaxation_loop": "bucle",
    "app_bell_relaxation_loop_description": "la canci\u00f3n se reproducir\u00e1 hasta que la apagues",
    "app_bell_relaxation_looped": "en bucle",

M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +3 -3
@@ 53,9 53,9 @@
    "app_bell_onboarding_shortcuts_step_restart": "Pressez les boutons lat\u00e9raux pendant 10 sec pour red\u00e9marrer",
    "app_bell_onboarding_shortcuts_step_rotate": "Faites tourner pour s\u00e9lectionner",
    "app_bell_onboarding_shortcuts_step_turn_off": "Appuyez sur Retour pendant 10 sec pour \u00e9teindre l'appareil",
    "app_bell_relaxation_error_message": "<text>Format de fichier non pris en<br></br>charge</text>",
    "app_bell_relaxation_file_deleted_message": "<text>Le fichier a \u00e9t\u00e9 supprim\u00e9.</text>",
    "app_bell_relaxation_limit_error_message": "<text>Limite de fichiers exc\u00e9d\u00e9e.<br />Risque de probl\u00e8mes<br />d'affichage</text>",
    "app_bell_audio_error_message": "<text>Format de fichier non pris en<br></br>charge</text>",
    "app_bell_audio_file_deleted_message": "<text>Le fichier a \u00e9t\u00e9 supprim\u00e9.</text>",
    "app_bell_audio_limit_error_message": "<text>Limite de fichiers exc\u00e9d\u00e9e.<br />Risque de probl\u00e8mes<br />d'affichage</text>",
    "app_bell_relaxation_loop": "en boucle",
    "app_bell_relaxation_loop_description": "le morceau sera lu jusqu'\u00e0 ce que vous l'\u00e9teigniez",
    "app_bell_relaxation_looped": "en boucle",

M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +3 -3
@@ 52,9 52,9 @@
    "app_bell_onboarding_shortcuts_step_restart": "Przytrzymaj oba boczne przyciski przez 10s, aby zrestartowa\u0107 urz\u0105dzenie",
    "app_bell_onboarding_shortcuts_step_rotate": "Obr\u00f3\u0107, aby wybra\u0107",
    "app_bell_onboarding_shortcuts_step_turn_off": "Przytrzymaj przycisk wstecz przez 10s aby wy\u0142\u0105czy\u0107 urz\u0105dzenie",
    "app_bell_relaxation_error_message": "Nieobs\u0142ugiwany format pliku",
    "app_bell_relaxation_file_deleted_message": "<text>Plik zosta\u0142 usuni\u0119ty.</text>",
    "app_bell_relaxation_limit_error_message": "<text>Przekroczono limit plik\u00f3w.<br />Nie wszystkie pliki mog\u0105 by\u0107<br />wy\u015bwietlone poprawnie</text>",
    "app_bell_audio_error_message": "Nieobs\u0142ugiwany format pliku",
    "app_bell_audio_file_deleted_message": "<text>Plik zosta\u0142 usuni\u0119ty.</text>",
    "app_bell_audio_limit_error_message": "<text>Przekroczono limit plik\u00f3w.<br />Nie wszystkie pliki mog\u0105 by\u0107<br />wy\u015bwietlone poprawnie</text>",
    "app_bell_relaxation_loop": "w p\u0119tli",
    "app_bell_relaxation_loop_description": "utw\u00f3r b\u0119dzie odtwarzany do momentu wy\u0142\u0105czenia go",
    "app_bell_relaxation_looped": "zap\u0119tlony",

M module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp => module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp +15 -1
@@ 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

#include "AppWindow.hpp"
#include "ApplicationCommon.hpp"
#include "data/AlarmPopupRequestParams.hpp"
#include "data/AudioErrorParams.hpp"
#include "service-db/Settings.hpp"
#include "service-db/agents/settings/SystemSettings.hpp"
#include "popups/data/PopupData.hpp"


@@ 133,6 134,19 @@ namespace app
                                  std::make_unique<gui::AlarmPopupRequestParams>(popupParams));
                return true;
            });

        auto audioErrorBlueprint = [&](gui::popup::ID id, std::unique_ptr<gui::PopupRequestParams> &params) {
            auto popupParams = dynamic_cast<gui::AudioErrorParams *>(params.get());
            if (popupParams == nullptr) {
                return false;
            }
            switchWindowPopup(gui::popup::resolveWindowName(id),
                              popupParams->getDisposition(),
                              std::make_unique<gui::AudioErrorParams>(popupParams),
                              SwitchReason::Popup);
            return true;
        };
        popupBlueprint.registerBlueprint(ID::AudioError, audioErrorBlueprint);
    }

    std::optional<gui::popup::Blueprint> ApplicationCommon::popupBlueprintFallback(gui::popup::ID id)

M module-apps/apps-common/popups/Popups.cpp => module-apps/apps-common/popups/Popups.cpp +3 -1
@@ 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 "Popups.hpp"


@@ 56,6 56,8 @@ namespace gui::popup
            return gui::popup::window::charging_notification_window;
        case ID::ChargingDoneNotification:
            return gui::popup::window::charging_done_notification_window;
        case ID::AudioError:
            return gui::popup::window::audio_error_window;
        case ID::AppTestPopup:
            return gui::popup::window::test_popup;
        case ID::Invalid:

M module-apps/apps-common/popups/Popups.hpp => module-apps/apps-common/popups/Popups.hpp +3 -1
@@ 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


@@ 34,6 34,7 @@ namespace gui
            BedtimeNotification,
            ChargingNotification,
            ChargingDoneNotification,
            AudioError,
            AppTestPopup,
            Invalid,
        };


@@ 65,6 66,7 @@ namespace gui
            inline constexpr auto bedtime_notification_window       = "BedtimeNotificationPopup";
            inline constexpr auto charging_notification_window      = "ChargingNotificationPopup";
            inline constexpr auto charging_done_notification_window = "ChargingDoneNotificationPopup";
            inline constexpr auto audio_error_window                = "AudioErrorPopup";
            inline constexpr auto test_popup                        = "test_popup";
        } // namespace window


R products/BellHybrid/apps/application-bell-relaxation/data/RelaxationErrorData.hpp => module-apps/apps-common/popups/data/AudioErrorParams.hpp +13 -8
@@ 2,12 2,12 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once
#include <SwitchData.hpp>

#include "PopupRequestParams.hpp"

namespace gui
{

    enum class RelaxationErrorType
    enum class AudioErrorType
    {
        UnsupportedMediaType,
        FilesLimitExceeded,


@@ 15,17 15,22 @@ namespace gui
        Unknown
    };

    class RelaxationErrorData : public SwitchData
    class AudioErrorParams : public PopupRequestParams
    {
        RelaxationErrorType errorType;

      public:
        explicit RelaxationErrorData(const RelaxationErrorType &relaxationErrorType) : errorType{relaxationErrorType}
        explicit AudioErrorParams(AudioErrorType errorType)
            : PopupRequestParams{popup::ID::AudioError}, errorType{errorType}
        {}

        [[nodiscard]] RelaxationErrorType getErrorType()
        explicit AudioErrorParams(AudioErrorParams *p) : PopupRequestParams{p->getPopupId()}, errorType(p->errorType)
        {}

        [[nodiscard]] AudioErrorType getErrorType()
        {
            return errorType;
        }

      private:
        AudioErrorType errorType;
    };
} // namespace gui

M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +9 -0
@@ 13,6 13,8 @@
#include <common/popups/BellRebootWindow.hpp>
#include <common/windows/BellTurnOffWindow.hpp>
#include <common/windows/BellWelcomeWindow.hpp>
#include <common/AudioErrorPresenter.hpp>
#include <common/windows/AudioErrorWindow.hpp>
#include <service-appmgr/ServiceApplicationManagerName.hpp>
#include <common/popups/BedtimeNotificationWindow.hpp>
#include <common/popups/ChargingNotificationWindow.hpp>


@@ 79,6 81,13 @@ namespace app
                        return std::make_unique<gui::AlarmDeactivatedWindow>(app, std::move(presenter));
                    });
                break;
            case ID::AudioError:
                windowsFactory.attach(
                    window::audio_error_window, [this](app::ApplicationCommon *app, const std::string &name) {
                        auto presenter = std::make_unique<gui::AudioErrorPresenter>(app);
                        return std::make_unique<gui::AudioErrorWindow>(app, name, std::move(presenter));
                    });
                break;
            case ID::PowerOff:
                windowsFactory.attach(window::power_off_window, [](ApplicationCommon *app, const std::string &name) {
                    return std::make_unique<gui::BellTurnOffOptionWindow>(

M products/BellHybrid/apps/application-bell-relaxation/ApplicationBellRelaxation.cpp => products/BellHybrid/apps/application-bell-relaxation/ApplicationBellRelaxation.cpp +10 -6
@@ 9,7 9,6 @@
#include "presenter/RelaxationVolumePresenter.hpp"
#include "presenter/RelaxationPausedPresenter.hpp"
#include "presenter/RelaxationEndedPresenter.hpp"
#include "presenter/RelaxationErrorPresenter.hpp"
#include "windows/RelaxationMainWindow.hpp"
#include "windows/RelaxationPausedWindow.hpp"
#include "windows/RelaxationRunningProgressWindow.hpp"


@@ 17,7 16,6 @@
#include "windows/RelaxationTimerSelectWindow.hpp"
#include "windows/RelaxationVolumeWindow.hpp"
#include "windows/RelaxationEndedWindow.hpp"
#include "windows/RelaxationErrorWindow.hpp"
#include "widgets/RelaxationPlayer.hpp"
#include <Paths.hpp>
#include <apps-common/messages/AppMessage.hpp>


@@ 28,6 26,9 @@
#include <common/models/AudioModel.hpp>
#include <common/models/SongsModel.hpp>
#include <common/windows/AppsBatteryStatusWindow.hpp>
#include <common/AudioErrorPresenter.hpp>
#include <common/windows/AudioErrorWindow.hpp>
#include <common/BellCommonNames.hpp>
#include <service-db/DBNotificationMessage.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>



@@ 147,10 148,13 @@ namespace app
                                  return std::make_unique<gui::AppsBatteryStatusWindow>(app, name);
                              });

        windowsFactory.attach(gui::window::name::relaxationError, [](ApplicationCommon *app, const std::string &name) {
            auto presenter = std::make_unique<relaxation::RelaxationErrorPresenter>(app);
            return std::make_unique<gui::RelaxationErrorWindow>(app, std::move(presenter));
        });
        windowsFactory.attach(gui::window::name::audioErrorWindow,
                              [this](ApplicationCommon *app, const std::string &name) {
                                  auto presenter      = std::make_unique<gui::AudioErrorPresenter>(app);
                                  auto onExitCallback = [this]() { switchWindow(gui::name::window::main_window); };
                                  return std::make_unique<gui::AudioErrorWindow>(
                                      app, name, std::move(presenter), std::move(onExitCallback));
                              });

        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,

M products/BellHybrid/apps/application-bell-relaxation/CMakeLists.txt => products/BellHybrid/apps/application-bell-relaxation/CMakeLists.txt +0 -5
@@ 20,7 20,6 @@ target_sources(application-bell-relaxation
        presenter/RelaxationVolumePresenter.cpp
        presenter/RelaxationPausedPresenter.cpp
        presenter/RelaxationEndedPresenter.cpp
        presenter/RelaxationErrorPresenter.cpp
        widgets/RelaxationPlayer.cpp
        windows/RelaxationMainWindow.cpp
        windows/RelaxationPausedWindow.cpp


@@ 29,13 28,11 @@ target_sources(application-bell-relaxation
        windows/RelaxationTimerSelectWindow.cpp
        windows/RelaxationVolumeWindow.cpp
        windows/RelaxationEndedWindow.cpp
        windows/RelaxationErrorWindow.cpp

        data/RelaxationCommon.hpp
        data/RelaxationStyle.hpp
        data/RelaxationAudioData.hpp
        data/RelaxationSwitchData.hpp
        data/RelaxationErrorData.hpp
        widgets/RelaxationPlayer.hpp
        windows/RelaxationMainWindow.hpp
        presenter/RelaxationMainWindowPresenter.hpp


@@ 45,7 42,6 @@ target_sources(application-bell-relaxation
        presenter/RelaxationVolumePresenter.hpp
        presenter/RelaxationPausedPresenter.hpp
        presenter/RelaxationEndedPresenter.hpp
        presenter/RelaxationErrorPresenter.cpp
        windows/RelaxationMainWindow.hpp
        windows/RelaxationPausedWindow.hpp
        windows/RelaxationRunningProgressWindow.hpp


@@ 53,7 49,6 @@ target_sources(application-bell-relaxation
        windows/RelaxationTimerSelectWindow.hpp
        windows/RelaxationVolumeWindow.hpp
        windows/RelaxationEndedWindow.hpp
        windows/RelaxationErrorWindow.hpp

        PUBLIC
        include/application-bell-relaxation/ApplicationBellRelaxation.hpp

M products/BellHybrid/apps/application-bell-relaxation/data/RelaxationStyle.hpp => products/BellHybrid/apps/application-bell-relaxation/data/RelaxationStyle.hpp +1 -7
@@ 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


@@ 70,10 70,4 @@ namespace gui::relaxationStyle
            inline constexpr auto maxSizeY  = 84U;
        } // namespace clock
    }     // namespace relStyle

    namespace error
    {
        inline constexpr auto imageMarginTop = 122U;
        inline constexpr auto textPaddingTop = 30U;
    } // namespace error
} // namespace gui::relaxationStyle

M products/BellHybrid/apps/application-bell-relaxation/include/application-bell-relaxation/ApplicationBellRelaxation.hpp => products/BellHybrid/apps/application-bell-relaxation/include/application-bell-relaxation/ApplicationBellRelaxation.hpp +0 -1
@@ 17,7 17,6 @@ namespace gui::window::name
    inline constexpr auto relaxationTimerSelect     = "RelaxationTimerSelectWindow";
    inline constexpr auto relaxationEnded           = "RelaxationEndedWindow";
    inline constexpr auto relaxationLowBattery      = "RelaxationLowBatteryWindow";
    inline constexpr auto relaxationError           = "RelaxationError";
} // namespace gui::window::name
namespace app
{

D products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationErrorPresenter.cpp => products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationErrorPresenter.cpp +0 -23
@@ 1,23 0,0 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "presenter/RelaxationErrorPresenter.hpp"
#include "ApplicationBellRelaxation.hpp"

#include <Application.hpp>
#include <service-appmgr/Controller.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>

namespace app::relaxation
{
    RelaxationErrorPresenter::RelaxationErrorPresenter(app::ApplicationCommon *app) : app{app}
    {}

    void RelaxationErrorPresenter::activate()
    {
        app::manager::Controller::sendAction(
            app,
            app::manager::actions::Launch,
            std::make_unique<app::ApplicationLaunchData>(app::applicationBellRelaxationName));
    }
} // namespace app::relaxation

M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationMainWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationMainWindow.cpp +4 -3
@@ 4,11 4,12 @@
#include "RelaxationMainWindow.hpp"

#include "data/RelaxationAudioData.hpp"
#include "data/RelaxationErrorData.hpp"

#include <ApplicationBellRelaxation.hpp>
#include <common/options/BellOptionsNavigation.hpp>
#include <common/options/OptionBellMenu.hpp>
#include <common/BellCommonNames.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <i18n/i18n.hpp>

namespace gui


@@ 60,8 61,8 @@ namespace gui

    void RelaxationMainWindow::handleError()
    {
        auto switchData = std::make_unique<RelaxationErrorData>(RelaxationErrorType::FilesLimitExceeded);
        application->switchWindow(gui::window::name::relaxationError, std::move(switchData));
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FilesLimitExceeded);
        application->switchWindow(gui::window::name::audioErrorWindow, std::move(switchData));
    }

    void RelaxationMainWindow::updateViewState()

M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningLoopWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningLoopWindow.cpp +6 -5
@@ 4,7 4,8 @@
#include "RelaxationRunningLoopWindow.hpp"
#include <data/RelaxationStyle.hpp>
#include <data/RelaxationSwitchData.hpp>
#include <data/RelaxationErrorData.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <common/BellCommonNames.hpp>

#include <ApplicationBellRelaxation.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>


@@ 232,13 233,13 @@ namespace gui

    void RelaxationRunningLoopWindow::handleError()
    {
        auto switchData = std::make_unique<RelaxationErrorData>(RelaxationErrorType::UnsupportedMediaType);
        application->switchWindow(gui::window::name::relaxationError, std::move(switchData));
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        application->switchWindow(gui::window::name::audioErrorWindow, std::move(switchData));
    }

    void RelaxationRunningLoopWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<RelaxationErrorData>(RelaxationErrorType::FileDeleted);
        application->switchWindow(gui::window::name::relaxationError, std::move(switchData));
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        application->switchWindow(gui::window::name::audioErrorWindow, std::move(switchData));
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningProgressWindow.cpp => products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationRunningProgressWindow.cpp +6 -6
@@ 4,8 4,8 @@
#include "RelaxationRunningProgressWindow.hpp"
#include <data/RelaxationStyle.hpp>
#include <data/RelaxationSwitchData.hpp>
#include <data/RelaxationErrorData.hpp>

#include <common/BellCommonNames.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <ApplicationBellRelaxation.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>


@@ 177,13 177,13 @@ namespace gui

    void RelaxationRunningProgressWindow::handleError()
    {
        auto switchData = std::make_unique<RelaxationErrorData>(RelaxationErrorType::UnsupportedMediaType);
        application->switchWindow(gui::window::name::relaxationError, std::move(switchData));
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        application->switchWindow(gui::window::name::audioErrorWindow, std::move(switchData));
    }

    void RelaxationRunningProgressWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<RelaxationErrorData>(RelaxationErrorType::FileDeleted);
        application->switchWindow(gui::window::name::relaxationError, std::move(switchData));
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        application->switchWindow(gui::window::name::audioErrorWindow, std::move(switchData));
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +22 -9
@@ 6,6 6,7 @@
#include "presenter/LayoutWindowPresenter.hpp"
#include "models/TemperatureUnitModel.hpp"
#include "models/AboutYourBellModel.hpp"
#include "models/AudioErrorModel.hpp"
#include "models/alarm_settings/AlarmSettingsListItemProvider.hpp"
#include "models/alarm_settings/PrewakeUpListItemProvider.hpp"
#include "models/alarm_settings/BedtimeSettingsListItemProvider.hpp"


@@ 132,10 133,11 @@ namespace app
                auto soundsRepository = std::make_unique<SoundsRepository>(this, pathSorting);
                auto songsModel       = std::make_unique<SongsModel>(this, std::move(soundsRepository));

                auto provider = std::make_shared<bell_settings::BedtimeSettingsListItemProvider>(bedtimeModel,
                auto provider        = std::make_unique<bell_settings::BedtimeSettingsListItemProvider>(bedtimeModel,
                                                                                                 std::move(songsModel));
                auto presenter =
                    std::make_unique<bell_settings::SettingsPresenter>(provider, bedtimeModel, *audioModel);
                auto audioErrorModel = std::make_unique<bell_settings::AudioErrorModel>();
                auto presenter       = std::make_unique<bell_settings::SettingsPresenter>(
                    std::move(provider), bedtimeModel, *audioModel, std::move(audioErrorModel));
                return std::make_unique<gui::BellSettingsBedtimeToneWindow>(app, std::move(presenter));
            });



@@ 188,8 190,13 @@ namespace app
                                                                                           std::move(songsModel));

                auto frontlightModel = std::make_unique<bell_settings::FrontlightModel>(app);
                auto presenter       = std::make_unique<bell_settings::PrewakeUpWindowPresenter>(
                    std::move(provider), std::move(prewakeUpSettingsModel), *audioModel, std::move(frontlightModel));
                auto audioErrorModel = std::make_unique<bell_settings::AudioErrorModel>();
                auto presenter =
                    std::make_unique<bell_settings::PrewakeUpWindowPresenter>(std::move(provider),
                                                                              std::move(prewakeUpSettingsModel),
                                                                              *audioModel,
                                                                              std::move(frontlightModel),
                                                                              std::move(audioErrorModel));
                return std::make_unique<gui::BellSettingsPrewakeUpWindow>(app, std::move(presenter));
            });



@@ 220,9 227,10 @@ namespace app
                auto songsModel       = std::make_unique<SongsModel>(this, std::move(soundsRepository));
                auto provider         = std::make_unique<bell_settings::SnoozeListItemProvider>(*snoozeSettingsModel,
                                                                                        std::move(songsModel));
                auto audioErrorModel  = std::make_unique<bell_settings::AudioErrorModel>();

                auto presenter = std::make_unique<bell_settings::SnoozePresenter>(
                    std::move(provider), std::move(snoozeSettingsModel), *audioModel);
                    std::move(provider), std::move(snoozeSettingsModel), *audioModel, std::move(audioErrorModel));
                return std::make_unique<gui::BellSettingsAlarmSettingsSnoozeWindow>(app, std::move(presenter));
            });
        windowsFactory.attach(


@@ 254,8 262,12 @@ namespace app
                auto frontlightModel = std::make_unique<bell_settings::FrontlightModel>(app);
                auto provider  = std::make_unique<bell_settings::AlarmSettingsListItemProvider>(*alarmSettingsModel,
                                                                                               std::move(songsModel));
                auto presenter = std::make_unique<bell_settings::AlarmSettingsPresenter>(
                    std::move(provider), std::move(alarmSettingsModel), *audioModel, std::move(frontlightModel));
                auto audioErrorModel = std::make_unique<bell_settings::AudioErrorModel>();
                auto presenter       = std::make_unique<bell_settings::AlarmSettingsPresenter>(std::move(provider),
                                                                                         std::move(alarmSettingsModel),
                                                                                         *audioModel,
                                                                                         std::move(frontlightModel),
                                                                                         std::move(audioErrorModel));
                return std::make_unique<gui::BellSettingsAlarmSettingsWindow>(app, std::move(presenter));
            });



@@ 279,7 291,8 @@ namespace app
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification,
                      gui::popup::ID::ChargingNotification,
                      gui::popup::ID::ChargingDoneNotification});
                      gui::popup::ID::ChargingDoneNotification,
                      gui::popup::ID::AudioError});
    }

    sys::MessagePointer ApplicationBellSettings::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt => products/BellHybrid/apps/application-bell-settings/CMakeLists.txt +2 -0
@@ 27,6 27,7 @@ target_sources(application-bell-settings
        models/AboutYourBellModel.cpp
        models/FrontlightListItemProvider.cpp
        models/FrontlightModel.cpp
        models/AudioErrorModel.cpp
        models/alarm_settings/AlarmSettingsListItemProvider.cpp
        models/alarm_settings/AlarmSettingsModel.cpp
        models/alarm_settings/BedtimeSettingsListItemProvider.cpp


@@ 119,6 120,7 @@ target_sources(application-bell-settings

    PUBLIC
        include/application-bell-settings/models/DateTimeUnitsModel.hpp
        include/application-bell-settings/models/AudioErrorModel.hpp
        include/application-bell-settings/presenter/TimeUnitsPresenter.hpp
        include/application-bell-settings/windows/BellSettingsTimeUnitsWindow.hpp
        include/application-bell-settings/ApplicationBellSettings.hpp

A products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/AudioErrorModel.hpp => products/BellHybrid/apps/application-bell-settings/include/application-bell-settings/models/AudioErrorModel.hpp +28 -0
@@ 0,0 1,28 @@
// 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 <memory>
#include <utf8/UTF8.hpp>
#include <popups/data/AudioErrorParams.hpp>

namespace app::bell_settings
{
    class AudioErrorModel
    {
      public:
        struct ErrorPaths
        {
            UTF8 path;
            gui::AudioErrorType type;
        };

        bool isPathOnErrorList(const UTF8 &path) const;
        void addPathToErrorList(const UTF8 &path, gui::AudioErrorType errorType);
        std::optional<gui::AudioErrorType> getErrorType(const UTF8 &path) const;

      private:
        std::vector<ErrorPaths> errorPaths;
    };
} // namespace app::bell_settings

A products/BellHybrid/apps/application-bell-settings/models/AudioErrorModel.cpp => products/BellHybrid/apps/application-bell-settings/models/AudioErrorModel.cpp +29 -0
@@ 0,0 1,29 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "models/AudioErrorModel.hpp"

namespace app::bell_settings
{
    bool AudioErrorModel::isPathOnErrorList(const UTF8 &path) const
    {
        const auto res =
            std::find_if(errorPaths.begin(), errorPaths.end(), [&path](auto err) { return err.path == path; });
        return res != errorPaths.end();
    }

    void AudioErrorModel::addPathToErrorList(const UTF8 &path, gui::AudioErrorType errorType)
    {
        errorPaths.emplace_back(ErrorPaths{path, errorType});
    }

    std::optional<gui::AudioErrorType> AudioErrorModel::getErrorType(const UTF8 &path) const
    {
        const auto res =
            std::find_if(errorPaths.begin(), errorPaths.end(), [&path](auto err) { return err.path == path; });
        if (res != errorPaths.end()) {
            return (*res).type;
        }
        return std::nullopt;
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/AlarmSettingsListItemProvider.cpp +6 -0
@@ 51,6 51,12 @@ namespace app::bell_settings
                onToneExit(currentSoundPath);
            }
        };
        alarmTone->onProceed = [this]() {
            if (onToneProceed) {
                return onToneProceed(currentSoundPath);
            }
            return false;
        };
        internalData.emplace_back(alarmTone);

        constexpr auto volumeStep = 1U;

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/BedtimeSettingsListItemProvider.cpp +6 -0
@@ 42,6 42,12 @@ namespace app::bell_settings
                onToneExit(currentSoundPath);
            }
        };
        chimeTone->onProceed = [this]() {
            if (onToneProceed) {
                return onToneProceed(currentSoundPath);
            }
            return false;
        };
        internalData.emplace_back(chimeTone);

        constexpr auto volumeStep = 1U;

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/PrewakeUpListItemProvider.cpp +6 -0
@@ 70,6 70,12 @@ namespace app::bell_settings
                onToneExit(currentSoundPath);
            }
        };
        chimeTone->onProceed = [this]() {
            if (onToneProceed) {
                return onToneProceed(currentSoundPath);
            }
            return false;
        };
        internalData.emplace_back(chimeTone);

        constexpr auto volumeStep = 1U;

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SettingsListItemProvider.hpp +2 -0
@@ 15,6 15,7 @@ namespace app::bell_settings
      public:
        /// Val contains currently chosen tone
        using ToneCallback = std::function<void(const UTF8 &val)>;
        using ToneProceedCallback = std::function<bool(const UTF8 &val)>;
        /// Val contains currently chosen volume (1-10 range)
        using VolumeCallback      = std::function<void(const uint32_t &val)>;
        using VolumeEnterCallback = ToneCallback;


@@ 39,6 40,7 @@ namespace app::bell_settings
        ToneCallback onToneEnter;
        ToneCallback onToneExit;
        ToneCallback onToneChange;
        ToneProceedCallback onToneProceed;

        VolumeEnterCallback onVolumeEnter;
        VolumeCallback onVolumeExit;

M products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp => products/BellHybrid/apps/application-bell-settings/models/alarm_settings/SnoozeListItemProvider.cpp +6 -0
@@ 149,6 149,12 @@ namespace app::bell_settings
                onToneExit(currentSoundPath);
            }
        };
        snoozeChimeTone->onProceed = [this]() {
            if (onToneProceed) {
                return onToneProceed(currentSoundPath);
            }
            return false;
        };
        internalData.emplace_back(snoozeChimeTone);

        constexpr auto volumeStep = 1U;

M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.cpp +55 -6
@@ 5,21 5,38 @@

namespace app::bell_settings
{
    SettingsPresenter::SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
    SettingsPresenter::SettingsPresenter(std::unique_ptr<BedtimeSettingsListItemProvider> &&provider,
                                         std::shared_ptr<AbstractBedtimeModel> model,
                                         AbstractAudioModel &audioModel)
        : provider(std::move(provider)), model(std::move(model)), audioModel{audioModel}
                                         AbstractAudioModel &audioModel,
                                         std::unique_ptr<AudioErrorModel> &&audioErrorModel)
        : provider{std::move(provider)}, model{std::move(model)}, audioModel{audioModel}, audioErrorModel{std::move(
                                                                                              audioErrorModel)}
    {
        auto playSound = [this](const UTF8 &val) {
            auto onStartCallback = [this, val](audio::RetCode retCode) {
                if (retCode != audio::RetCode::Success) {
                    handleAudioError(val, gui::AudioErrorType::UnsupportedMediaType);
                }
            };

            auto onFinishedCallback = [this, val](AbstractAudioModel::PlaybackFinishStatus status) {
                if (status == AbstractAudioModel::PlaybackFinishStatus::Error) {
                    handleAudioError(val, gui::AudioErrorType::FileDeleted);
                }
            };

            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Bedtime);
            this->audioModel.play(currentSoundPath, AbstractAudioModel::PlaybackType::Bedtime, {});
            this->audioModel.setPlaybackFinishedCb(std::move(onFinishedCallback));
            this->audioModel.play(
                currentSoundPath, AbstractAudioModel::PlaybackType::Bedtime, std::move(onStartCallback));
        };

        this->provider->onExit = [this]() { getView()->exit(); };

        this->provider->onToneEnter  = playSound;
        this->provider->onToneChange = playSound;
        this->provider->onToneProceed = [this](const auto &path) { return validatePath(path); };

        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { this->stopSound(); };


@@ 56,13 73,45 @@ namespace app::bell_settings
        provider->clearData();
    }

    void SettingsPresenter::stopSound()
    auto SettingsPresenter::stopSound() -> void
    {
        this->audioModel.stopPlayedByThis({});
    }
    void SettingsPresenter::exitWithoutSave()

    auto SettingsPresenter::exitWithoutSave() -> void
    {
        this->stopSound();
        model->getBedtimeVolume().restoreDefault();
    }

    auto SettingsPresenter::handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void
    {
        const bool validPath = !audioErrorModel->isPathOnErrorList(path);
        if (validPath) {
            audioErrorModel->addPathToErrorList(path, errorType);
            showAudioError(errorType);
        }
    }

    auto SettingsPresenter::validatePath(const UTF8 &path) const -> bool
    {
        const auto errorType = audioErrorModel->getErrorType(path);
        if (errorType.has_value()) {
            showAudioError(errorType.value());
            return true;
        }
        return false;
    }

    auto SettingsPresenter::showAudioError(gui::AudioErrorType errorType) const -> void
    {
        switch (errorType) {
        case gui::AudioErrorType::FileDeleted:
            getView()->handleDeletedFile();
            break;
        default:
            getView()->handleError();
            break;
        }
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/BedtimeSettingsPresenter.hpp +15 -7
@@ 3,6 3,7 @@

#pragma once

#include "models/AudioErrorModel.hpp"
#include "models/alarm_settings/BedtimeSettingsListItemProvider.hpp"
#include <common/models/AbstractAudioModel.hpp>
#include <common/SoundsRepository.hpp>


@@ 23,8 24,10 @@ namespace app::bell_settings
        class View
        {
          public:
            virtual ~View() noexcept = default;
            virtual void exit()      = 0;
            virtual ~View() noexcept                 = default;
            virtual auto exit() -> void              = 0;
            virtual auto handleError() -> void       = 0;
            virtual auto handleDeletedFile() -> void = 0;
        };

        class Presenter : public BasePresenter<View>


@@ 35,29 38,34 @@ namespace app::bell_settings
            virtual auto saveData() -> void                                                 = 0;
            virtual auto loadData() -> void                                                 = 0;
            virtual auto eraseProviderData() -> void                                        = 0;
            virtual void exitWithoutSave()                                                  = 0;
            virtual auto exitWithoutSave() -> void                                          = 0;
        };
    };

    class SettingsPresenter : public BedtimeSettingsWindowContract::Presenter
    {
      public:
        SettingsPresenter(std::shared_ptr<BedtimeSettingsListItemProvider> provider,
        SettingsPresenter(std::unique_ptr<BedtimeSettingsListItemProvider> &&provider,
                          std::shared_ptr<AbstractBedtimeModel> model,
                          AbstractAudioModel &audioModel);
                          AbstractAudioModel &audioModel,
                          std::unique_ptr<AudioErrorModel> &&audioErrorModel);

        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        auto saveData() -> void override;
        auto loadData() -> void override;
        auto eraseProviderData() -> void override;
        void exitWithoutSave() override;
        auto exitWithoutSave() -> void override;

      private:
        void stopSound();
        auto stopSound() -> void;
        auto handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void;
        auto showAudioError(gui::AudioErrorType errorType) const -> void;
        auto validatePath(const UTF8 &path) const -> bool;

        std::shared_ptr<BedtimeSettingsListItemProvider> provider;
        std::shared_ptr<AbstractBedtimeModel> model;
        AbstractAudioModel &audioModel;
        std::unique_ptr<AudioErrorModel> audioErrorModel;
        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 +50 -3
@@ 9,15 9,30 @@ namespace app::bell_settings
    AlarmSettingsPresenter::AlarmSettingsPresenter(std::unique_ptr<AlarmSettingsListItemProvider> &&provider,
                                                   std::unique_ptr<AbstractAlarmSettingsModel> &&settingsModel,
                                                   AbstractAudioModel &audioModel,
                                                   std::unique_ptr<AbstractFrontlightModel> &&frontlight)
                                                   std::unique_ptr<AbstractFrontlightModel> &&frontlight,
                                                   std::unique_ptr<AudioErrorModel> &&audioErrorModel)
        : provider{std::move(provider)}, settingsModel{std::move(settingsModel)}, audioModel{audioModel},
          frontlight{std::move(frontlight)}
          frontlight{std::move(frontlight)}, audioErrorModel{std::move(audioErrorModel)}
    {

        auto playSound = [this](const UTF8 &val) {
            auto onStartCallback = [this, val](audio::RetCode retCode) {
                if (retCode != audio::RetCode::Success) {
                    handleAudioError(val, gui::AudioErrorType::UnsupportedMediaType);
                }
            };

            auto onFinishedCallback = [this, val](AbstractAudioModel::PlaybackFinishStatus status) {
                if (status == AbstractAudioModel::PlaybackFinishStatus::Error) {
                    handleAudioError(val, gui::AudioErrorType::FileDeleted);
                }
            };

            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Alarm);
            this->audioModel.play(currentSoundPath, AbstractAudioModel::PlaybackType::Alarm, {});
            this->audioModel.setPlaybackFinishedCb(std::move(onFinishedCallback));
            this->audioModel.play(
                currentSoundPath, AbstractAudioModel::PlaybackType::Alarm, std::move(onStartCallback));
        };

        this->provider->onExit = [this]() { getView()->exit(); };


@@ 25,6 40,7 @@ namespace app::bell_settings
        this->provider->onToneEnter  = playSound;
        this->provider->onToneExit   = [this](const auto &) { stopSound(); };
        this->provider->onToneChange = playSound;
        this->provider->onToneProceed = [this](const auto &path) { return validatePath(path); };

        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { stopSound(); };


@@ 90,4 106,35 @@ namespace app::bell_settings
        settingsModel->getAlarmVolume().restoreDefault();
        eraseProviderData();
    }

    auto AlarmSettingsPresenter::handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void
    {
        const bool validPath = !audioErrorModel->isPathOnErrorList(path);
        if (validPath) {
            audioErrorModel->addPathToErrorList(path, errorType);
            showAudioError(errorType);
        }
    }

    auto AlarmSettingsPresenter::validatePath(const UTF8 &path) const -> bool
    {
        const auto errorType = audioErrorModel->getErrorType(path);
        if (errorType.has_value()) {
            showAudioError(errorType.value());
            return true;
        }
        return false;
    }

    auto AlarmSettingsPresenter::showAudioError(gui::AudioErrorType errorType) const -> void
    {
        switch (errorType) {
        case gui::AudioErrorType::FileDeleted:
            getView()->handleDeletedFile();
            break;
        default:
            getView()->handleError();
            break;
        }
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/AlarmSettingsPresenter.hpp +9 -1
@@ 3,6 3,7 @@

#pragma once

#include "models/AudioErrorModel.hpp"
#include <apps-common/BasePresenter.hpp>
#include <apps-common/AudioOperations.hpp>
#include <common/models/AbstractAudioModel.hpp>


@@ 28,6 29,8 @@ namespace app::bell_settings
          public:
            virtual ~View() noexcept = default;
            virtual void exit()      = 0;
            virtual void handleError()       = 0;
            virtual void handleDeletedFile() = 0;
        };

        class Presenter : public BasePresenter<View>


@@ 49,7 52,8 @@ namespace app::bell_settings
        AlarmSettingsPresenter(std::unique_ptr<AlarmSettingsListItemProvider> &&provider,
                               std::unique_ptr<AbstractAlarmSettingsModel> &&settingsModel,
                               AbstractAudioModel &audioModel,
                               std::unique_ptr<AbstractFrontlightModel> &&frontlight);
                               std::unique_ptr<AbstractFrontlightModel> &&frontlight,
                               std::unique_ptr<AudioErrorModel> &&audioErrorModel);

        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        auto loadData() -> void override;


@@ 60,11 64,15 @@ namespace app::bell_settings

      private:
        auto stopSound() -> void;
        auto handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void;
        auto showAudioError(gui::AudioErrorType errorType) const -> void;
        auto validatePath(const UTF8 &path) const -> bool;

        std::shared_ptr<AlarmSettingsListItemProvider> provider;
        std::unique_ptr<AbstractAlarmSettingsModel> settingsModel;
        AbstractAudioModel &audioModel;
        std::unique_ptr<AbstractFrontlightModel> frontlight;
        std::unique_ptr<AudioErrorModel> audioErrorModel;
        UTF8 currentSoundPath;
    };
} // 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 +53 -6
@@ 9,14 9,29 @@ namespace app::bell_settings
    PrewakeUpWindowPresenter::PrewakeUpWindowPresenter(std::unique_ptr<PrewakeUpListItemProvider> &&provider,
                                                       std::unique_ptr<AbstractPrewakeUpSettingsModel> &&model,
                                                       AbstractAudioModel &audioModel,
                                                       std::unique_ptr<AbstractFrontlightModel> &&frontlight)
        : provider{std::move(provider)}, model{std::move(model)}, audioModel{audioModel}, frontlight{
                                                                                              std::move(frontlight)}
                                                       std::unique_ptr<AbstractFrontlightModel> &&frontlight,
                                                       std::unique_ptr<AudioErrorModel> &&audioErrorModel)
        : provider{std::move(provider)}, model{std::move(model)}, audioModel{audioModel},
          frontlight{std::move(frontlight)}, audioErrorModel{std::move(audioErrorModel)}
    {
        auto playSound = [this](const UTF8 &val) {
            auto onStartCallback = [this, val](audio::RetCode retCode) {
                if (retCode != audio::RetCode::Success) {
                    handleAudioError(val, gui::AudioErrorType::UnsupportedMediaType);
                }
            };

            auto onFinishedCallback = [this, val](AbstractAudioModel::PlaybackFinishStatus status) {
                if (status == AbstractAudioModel::PlaybackFinishStatus::Error) {
                    handleAudioError(val, gui::AudioErrorType::FileDeleted);
                }
            };

            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::PreWakeup);
            this->audioModel.play(currentSoundPath, AbstractAudioModel::PlaybackType::PreWakeup, {});
            this->audioModel.setPlaybackFinishedCb(std::move(onFinishedCallback));
            this->audioModel.play(
                currentSoundPath, AbstractAudioModel::PlaybackType::PreWakeup, std::move(onStartCallback));
        };

        this->provider->onExit = [this]() { getView()->exit(); };


@@ 24,6 39,7 @@ namespace app::bell_settings
        this->provider->onToneEnter  = playSound;
        this->provider->onToneExit   = [this](const auto &) { stopSound(); };
        this->provider->onToneChange = playSound;
        this->provider->onToneProceed = [this](const auto &path) { return validatePath(path); };

        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { stopSound(); };


@@ 72,13 88,44 @@ namespace app::bell_settings
        provider->clearData();
    }

    void PrewakeUpWindowPresenter::stopSound()
    auto PrewakeUpWindowPresenter::stopSound() -> void
    {
        this->audioModel.stopPlayedByThis({});
    }

    void PrewakeUpWindowPresenter::exitWithoutSave()
    auto PrewakeUpWindowPresenter::exitWithoutSave() -> void
    {
        model->getChimeVolume().restoreDefault();
    }

    auto PrewakeUpWindowPresenter::handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void
    {
        const bool validPath = !audioErrorModel->isPathOnErrorList(path);
        if (validPath) {
            audioErrorModel->addPathToErrorList(path, errorType);
            showAudioError(errorType);
        }
    }

    auto PrewakeUpWindowPresenter::validatePath(const UTF8 &path) const -> bool
    {
        const auto errorType = audioErrorModel->getErrorType(path);
        if (errorType.has_value()) {
            showAudioError(errorType.value());
            return true;
        }
        return false;
    }

    auto PrewakeUpWindowPresenter::showAudioError(gui::AudioErrorType errorType) const -> void
    {
        switch (errorType) {
        case gui::AudioErrorType::FileDeleted:
            getView()->handleDeletedFile();
            break;
        default:
            getView()->handleError();
            break;
        }
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/PrewakeUpPresenter.hpp +14 -6
@@ 3,6 3,7 @@

#pragma once

#include "models/AudioErrorModel.hpp"
#include <apps-common/BasePresenter.hpp>
#include <apps-common/AudioOperations.hpp>
#include <models/alarm_settings/AbstractPrewakeUpSettingsModel.hpp>


@@ 25,8 26,10 @@ namespace app::bell_settings
        class View
        {
          public:
            virtual ~View() noexcept = default;
            virtual void exit()      = 0;
            virtual ~View() noexcept                 = default;
            virtual auto exit() -> void              = 0;
            virtual auto handleError() -> void       = 0;
            virtual auto handleDeletedFile() -> void = 0;
        };

        class Presenter : public BasePresenter<View>


@@ 37,7 40,7 @@ namespace app::bell_settings
            virtual auto saveData() -> void                                                 = 0;
            virtual auto loadData() -> void                                                 = 0;
            virtual auto eraseProviderData() -> void                                        = 0;
            virtual void exitWithoutSave()                                                  = 0;
            virtual auto exitWithoutSave() -> void                                          = 0;
        };
    };



@@ 47,21 50,26 @@ namespace app::bell_settings
        PrewakeUpWindowPresenter(std::unique_ptr<PrewakeUpListItemProvider> &&provider,
                                 std::unique_ptr<AbstractPrewakeUpSettingsModel> &&model,
                                 AbstractAudioModel &audioModel,
                                 std::unique_ptr<AbstractFrontlightModel> &&frontlight);
                                 std::unique_ptr<AbstractFrontlightModel> &&frontlight,
                                 std::unique_ptr<AudioErrorModel> &&audioErrorModel);

        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        auto saveData() -> void override;
        auto loadData() -> void override;
        auto eraseProviderData() -> void override;
        void exitWithoutSave() override;
        auto exitWithoutSave() -> void override;

      private:
        void stopSound();
        auto stopSound() -> void;
        auto handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void;
        auto showAudioError(gui::AudioErrorType errorType) const -> void;
        auto validatePath(const UTF8 &path) const -> bool;

        std::shared_ptr<PrewakeUpListItemProvider> provider;
        std::unique_ptr<AbstractPrewakeUpSettingsModel> model;
        AbstractAudioModel &audioModel;
        std::unique_ptr<AbstractFrontlightModel> frontlight;
        std::unique_ptr<AudioErrorModel> audioErrorModel;
        UTF8 currentSoundPath;
    };
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.cpp +56 -8
@@ 8,13 8,29 @@ namespace app::bell_settings
{
    SnoozePresenter::SnoozePresenter(std::unique_ptr<SnoozeListItemProvider> &&provider,
                                     std::unique_ptr<AbstractSnoozeSettingsModel> &&snoozeSettingsModel,
                                     AbstractAudioModel &audioModel)
        : provider{std::move(provider)}, snoozeSettingsModel{std::move(snoozeSettingsModel)}, audioModel{audioModel}
                                     AbstractAudioModel &audioModel,
                                     std::unique_ptr<AudioErrorModel> &&audioErrorModel)
        : provider{std::move(provider)}, snoozeSettingsModel{std::move(snoozeSettingsModel)}, audioModel{audioModel},
          audioErrorModel{std::move(audioErrorModel)}
    {
        auto playSound = [this](const UTF8 &val) {
            auto onStartCallback = [this, val](audio::RetCode retCode) {
                if (retCode != audio::RetCode::Success) {
                    handleAudioError(val, gui::AudioErrorType::UnsupportedMediaType);
                }
            };

            auto onFinishedCallback = [this, val](AbstractAudioModel::PlaybackFinishStatus status) {
                if (status == AbstractAudioModel::PlaybackFinishStatus::Error) {
                    handleAudioError(val, gui::AudioErrorType::FileDeleted);
                }
            };

            currentSoundPath = val;
            this->audioModel.setVolume(this->provider->getCurrentVolume(), AbstractAudioModel::PlaybackType::Snooze);
            this->audioModel.play(currentSoundPath, AbstractAudioModel::PlaybackType::Snooze, {});
            this->audioModel.setPlaybackFinishedCb(std::move(onFinishedCallback));
            this->audioModel.play(
                currentSoundPath, AbstractAudioModel::PlaybackType::Snooze, std::move(onStartCallback));
        };

        this->provider->onExit = [this]() { getView()->exit(); };


@@ 22,6 38,7 @@ namespace app::bell_settings
        this->provider->onToneEnter  = playSound;
        this->provider->onToneExit   = [this](const auto &) { stopSound(); };
        this->provider->onToneChange = playSound;
        this->provider->onToneProceed = [this](const auto &path) { return validatePath(path); };

        this->provider->onVolumeEnter  = playSound;
        this->provider->onVolumeExit   = [this](const auto &) { stopSound(); };


@@ 34,7 51,7 @@ namespace app::bell_settings
        };
    }

    void SnoozePresenter::saveData()
    auto SnoozePresenter::saveData() -> void
    {
        stopSound();
        for (const auto &item : provider->getListItems()) {


@@ 42,7 59,7 @@ namespace app::bell_settings
        }
    }

    void SnoozePresenter::loadData()
    auto SnoozePresenter::loadData() -> void
    {
        for (const auto &item : provider->getListItems()) {
            item->setValue();


@@ 54,18 71,49 @@ namespace app::bell_settings
        return provider;
    }

    void SnoozePresenter::stopSound()
    auto SnoozePresenter::stopSound() -> void
    {
        audioModel.stopPlayedByThis({});
    }

    void SnoozePresenter::eraseProviderData()
    auto SnoozePresenter::eraseProviderData() -> void
    {
        provider->clearData();
    }

    void SnoozePresenter::exitWithoutSave()
    auto SnoozePresenter::exitWithoutSave() -> void
    {
        snoozeSettingsModel->getSnoozeChimeVolume().restoreDefault();
    }

    auto SnoozePresenter::handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void
    {
        const bool validPath = !audioErrorModel->isPathOnErrorList(path);
        if (validPath) {
            audioErrorModel->addPathToErrorList(path, errorType);
            showAudioError(errorType);
        }
    }

    auto SnoozePresenter::validatePath(const UTF8 &path) const -> bool
    {
        const auto errorType = audioErrorModel->getErrorType(path);
        if (errorType.has_value()) {
            showAudioError(errorType.value());
            return true;
        }
        return false;
    }

    auto SnoozePresenter::showAudioError(gui::AudioErrorType errorType) const -> void
    {
        switch (errorType) {
        case gui::AudioErrorType::FileDeleted:
            getView()->handleDeletedFile();
            break;
        default:
            getView()->handleError();
            break;
        }
    }
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/alarm_settings/SnoozePresenter.hpp +20 -12
@@ 3,6 3,7 @@

#pragma once

#include "models/AudioErrorModel.hpp"
#include <apps-common/BasePresenter.hpp>
#include <models/alarm_settings/AbstractSnoozeSettingsModel.hpp>
#include <common/models/AbstractAudioModel.hpp>


@@ 21,8 22,10 @@ namespace app::bell_settings
    class View
    {
      public:
        virtual ~View() noexcept = default;
        virtual void exit()      = 0;
        virtual ~View() noexcept                 = default;
        virtual auto exit() -> void              = 0;
        virtual auto handleError() -> void       = 0;
        virtual auto handleDeletedFile() -> void = 0;
    };

    class AbstractSnoozePresenter : public BasePresenter<View>


@@ 30,10 33,10 @@ namespace app::bell_settings
      public:
        virtual ~AbstractSnoozePresenter()                                              = default;
        virtual auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> = 0;
        virtual void saveData()                                                         = 0;
        virtual void loadData()                                                         = 0;
        virtual void eraseProviderData()                                                = 0;
        virtual void exitWithoutSave()                                                  = 0;
        virtual auto saveData() -> void                                                 = 0;
        virtual auto loadData() -> void                                                 = 0;
        virtual auto eraseProviderData() -> void                                        = 0;
        virtual auto exitWithoutSave() -> void                                          = 0;
    };

    class SnoozePresenter : public AbstractSnoozePresenter


@@ 41,19 44,24 @@ namespace app::bell_settings
      public:
        SnoozePresenter(std::unique_ptr<SnoozeListItemProvider> &&provider,
                        std::unique_ptr<AbstractSnoozeSettingsModel> &&snoozeSettingsModel,
                        AbstractAudioModel &audioModel);
                        AbstractAudioModel &audioModel,
                        std::unique_ptr<AudioErrorModel> &&audioErrorModel);
        auto getPagesProvider() const -> std::shared_ptr<gui::ListItemProvider> override;
        void saveData() override;
        void loadData() override;
        void eraseProviderData() override;
        void exitWithoutSave() override;
        auto saveData() -> void override;
        auto loadData() -> void override;
        auto eraseProviderData() -> void override;
        auto exitWithoutSave() -> void override;

      private:
        void stopSound();
        auto stopSound() -> void;
        auto handleAudioError(const UTF8 &path, gui::AudioErrorType errorType) -> void;
        auto showAudioError(gui::AudioErrorType errorType) const -> void;
        auto validatePath(const UTF8 &path) const -> bool;

        std::shared_ptr<SnoozeListItemProvider> provider;
        std::unique_ptr<AbstractSnoozeSettingsModel> snoozeSettingsModel;
        AbstractAudioModel &audioModel;
        std::unique_ptr<AudioErrorModel> audioErrorModel;
        UTF8 currentSoundPath;
    };
} // namespace app::bell_settings

M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.cpp +16 -1
@@ 1,12 1,15 @@
// 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 "BellSettingsBedtimeToneWindow.hpp"
#include "application-bell-settings/ApplicationBellSettings.hpp"
#include "BellSettingsStyle.hpp"

#include <common/windows/BellFinishedWindow.hpp>
#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/SideListView.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <service-appmgr/Controller.hpp>

namespace gui
{


@@ 75,4 78,16 @@ namespace gui
            presenter->eraseProviderData();
        }
    }

    void BellSettingsBedtimeToneWindow::handleError()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }

    void BellSettingsBedtimeToneWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }
} /* namespace gui */

M products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/BellSettingsBedtimeToneWindow.hpp +3 -1
@@ 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


@@ 25,6 25,8 @@ namespace gui
        bool onInput(const InputEvent &inputEvent) override;
        void rebuild() override;
        void exit() override;
        void handleError() override;
        void handleDeletedFile() override;

      private:
        SideListView *sidelistview{};

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.cpp +16 -1
@@ 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

#include "BellSettingsAlarmSettingsSnoozeWindow.hpp"


@@ 9,6 9,8 @@

#include <apps-common/ApplicationCommon.hpp>
#include <common/windows/BellFinishedWindow.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <service-appmgr/Controller.hpp>
#include <gui/input/InputEvent.hpp>
#include <widgets/SideListView.hpp>



@@ 74,10 76,23 @@ namespace gui
            window::bell_finished::defaultName,
            BellFinishedWindowData::Factory::create("circle_success_big", BellSettingsAlarmSettingsMenuWindow::name));
    }

    void BellSettingsAlarmSettingsSnoozeWindow::onClose(Window::CloseReason reason)
    {
        if (reason != CloseReason::Popup) {
            presenter->eraseProviderData();
        }
    }

    void BellSettingsAlarmSettingsSnoozeWindow::handleError()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }

    void BellSettingsAlarmSettingsSnoozeWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsSnoozeWindow.hpp +3 -1
@@ 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


@@ 25,6 25,8 @@ namespace gui
        void onClose(CloseReason reason) override;
        void rebuild() override;
        void exit() override;
        void handleError() override;
        void handleDeletedFile() override;

      private:
        SideListView *listView{};

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.cpp +15 -1
@@ 5,8 5,10 @@
#include "BellSettingsAlarmSettingsMenuWindow.hpp"
#include "BellSettingsAlarmSettingsWindow.hpp"
#include "BellSettingsStyle.hpp"
#include <common/windows/BellFinishedWindow.hpp>

#include <common/windows/BellFinishedWindow.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <service-appmgr/Controller.hpp>
#include <apps-common/options/OptionStyle.hpp>
#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/SideListView.hpp>


@@ 79,4 81,16 @@ namespace gui
    {
        setFocusItem(sidelistview);
    }

    void BellSettingsAlarmSettingsWindow::handleError()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }

    void BellSettingsAlarmSettingsWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }
} /* namespace gui */

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsAlarmSettingsWindow.hpp +3 -1
@@ 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


@@ 27,6 27,8 @@ namespace gui
        bool onInput(const InputEvent &inputEvent) override;
        void rebuild() override;
        void exit() override;
        void handleError() override;
        void handleDeletedFile() override;

      private:
        SideListView *sidelistview{};

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.cpp +16 -2
@@ 1,12 1,14 @@
// 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 "application-bell-settings/ApplicationBellSettings.hpp"
#include "BellSettingsAlarmSettingsMenuWindow.hpp"
#include "BellSettingsPrewakeUpWindow.hpp"
#include "BellSettingsStyle.hpp"
#include <common/windows/BellFinishedWindow.hpp>

#include <common/windows/BellFinishedWindow.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <service-appmgr/Controller.hpp>
#include <apps-common/options/OptionStyle.hpp>
#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/SideListView.hpp>


@@ 78,4 80,16 @@ namespace gui
            presenter->eraseProviderData();
        }
    }

    void BellSettingsPrewakeUpWindow::handleError()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::UnsupportedMediaType);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }

    void BellSettingsPrewakeUpWindow::handleDeletedFile()
    {
        auto switchData = std::make_unique<AudioErrorParams>(AudioErrorType::FileDeleted);
        app::manager::Controller::sendAction(application, app::manager::actions::ShowPopup, std::move(switchData));
    }
} /* namespace gui */

M products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.hpp => products/BellHybrid/apps/application-bell-settings/windows/alarm_settings/BellSettingsPrewakeUpWindow.hpp +3 -1
@@ 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


@@ 26,6 26,8 @@ namespace gui
        bool onInput(const InputEvent &inputEvent) override;
        void rebuild() override;
        void exit() override;
        void handleError() override;
        void handleDeletedFile() override;

      private:
        SideListView *sidelistview{};

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +4 -0
@@ 27,6 27,7 @@ target_sources(application-bell-common
        src/SoundsProvider.cpp
        src/BellSideListItemWithCallbacks.cpp
        src/TimeUtils.cpp
        src/AudioErrorPresenter.cpp

        src/windows/BellFactoryReset.cpp
        src/windows/BellFinishedWindow.cpp


@@ 36,6 37,7 @@ target_sources(application-bell-common
        src/windows/ShortcutsWindow.cpp
        src/windows/BellBatteryStatusWindow.cpp
        src/windows/AppsBatteryStatusWindow.cpp
        src/windows/AudioErrorWindow.cpp

        src/models/SettingsModel.cpp
        src/models/BedtimeModel.cpp


@@ 93,6 95,7 @@ target_sources(application-bell-common
        include/common/SoundsRepository.hpp
        include/common/BellPowerOffPresenter.hpp
        include/common/BellFactoryResetPresenter.hpp
        include/common/AudioErrorPresenter.hpp
        include/common/windows/BellFactoryReset.hpp
        include/common/windows/BellFinishedWindow.hpp
        include/common/windows/BellTurnOffWindow.hpp


@@ 102,6 105,7 @@ target_sources(application-bell-common
        include/common/windows/ShortcutsWindow.hpp
        include/common/windows/BellBatteryStatusWindow.hpp
        include/common/windows/AppsBatteryStatusWindow.hpp
        include/common/windows/AudioErrorWindow.hpp
        include/common/TimeUtils.hpp

        include/common/data/BatteryUtils.hpp

R products/BellHybrid/apps/application-bell-relaxation/presenter/RelaxationErrorPresenter.hpp => products/BellHybrid/apps/common/include/common/AudioErrorPresenter.hpp +6 -6
@@ 10,9 10,9 @@ namespace app
    class ApplicationCommon;
}

namespace app::relaxation
namespace gui
{
    class RelaxationErrorContract
    class AudioErrorContract
    {
      public:
        class View


@@ 20,19 20,19 @@ namespace app::relaxation
          public:
            virtual ~View() = default;
        };
        class Presenter : public BasePresenter<RelaxationErrorContract::View>
        class Presenter : public app::BasePresenter<AudioErrorContract::View>
        {
          public:
            virtual void activate() = 0;
        };
    };

    class RelaxationErrorPresenter : public RelaxationErrorContract::Presenter
    class AudioErrorPresenter : public AudioErrorContract::Presenter
    {
        app::ApplicationCommon *app{};
        void activate() override;

      public:
        explicit RelaxationErrorPresenter(app::ApplicationCommon *app);
        explicit AudioErrorPresenter(app::ApplicationCommon *app);
    };
} // namespace app::relaxation
} // namespace gui

M products/BellHybrid/apps/common/include/common/BellCommonNames.hpp => products/BellHybrid/apps/common/include/common/BellCommonNames.hpp +2 -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

#pragma once


@@ 6,5 6,5 @@
namespace gui::window::name
{
    inline constexpr auto shortcutsWindow = "BellShortcuts";

    inline constexpr auto audioErrorWindow = "AudioError";
} // namespace gui::window::name

R products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationErrorWindow.hpp => products/BellHybrid/apps/common/include/common/windows/AudioErrorWindow.hpp +15 -12
@@ 1,32 1,35 @@
// 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 "presenter/RelaxationErrorPresenter.hpp"
#include "common/AudioErrorPresenter.hpp"
#include <apps-common/popups/WindowWithTimer.hpp>
#include <data/RelaxationErrorData.hpp>
#include <popups/data/AudioErrorParams.hpp>
#include <gui/widgets/Icon.hpp>
#include <memory>

namespace gui
{
    class BellBaseLayout;
    class RelaxationErrorWindow : public WindowWithTimer
    class AudioErrorWindow : public WindowWithTimer
    {
      public:
        explicit RelaxationErrorWindow(
            app::ApplicationCommon *app,
            std::unique_ptr<app::relaxation::RelaxationErrorContract::Presenter> &&presenter);
        using OnExitCallback = std::function<void()>;

        AudioErrorWindow(app::ApplicationCommon *app,
                         const std::string &name,
                         std::unique_ptr<AudioErrorContract::Presenter> &&presenter,
                         OnExitCallback callback = nullptr);

      private:
        std::unique_ptr<app::relaxation::RelaxationErrorContract::Presenter> presenter;
        std::unique_ptr<AudioErrorContract::Presenter> presenter;
        std::string errorText;
        gui::Icon *icon               = nullptr;
        RelaxationErrorType errorType = RelaxationErrorType::Unknown;
        Icon *icon{nullptr};
        AudioErrorType errorType{AudioErrorType::Unknown};
        OnExitCallback onExitCallback;

        void buildInterface() override;
        bool onInput(const gui::InputEvent &inputEvent) override;
        bool onInput(const InputEvent &inputEvent) override;
        void registerCallbacks();
        void buildLayout();
        void onBeforeShow(ShowMode mode, SwitchData *data) override;

A products/BellHybrid/apps/common/src/AudioErrorPresenter.cpp => products/BellHybrid/apps/common/src/AudioErrorPresenter.cpp +19 -0
@@ 0,0 1,19 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AudioErrorPresenter.hpp"

#include <Application.hpp>
#include <service-appmgr/Controller.hpp>

namespace gui
{
    AudioErrorPresenter::AudioErrorPresenter(app::ApplicationCommon *app) : app{app}
    {}

    void AudioErrorPresenter::activate()
    {
        app::manager::Controller::sendAction(
            app, app::manager::actions::Launch, std::make_unique<app::ApplicationLaunchData>(app->GetName()));
    }
} // namespace gui

R products/BellHybrid/apps/application-bell-relaxation/windows/RelaxationErrorWindow.cpp => products/BellHybrid/apps/common/src/windows/AudioErrorWindow.cpp +33 -26
@@ 1,77 1,83 @@
// 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 "RelaxationErrorWindow.hpp"
#include <data/RelaxationStyle.hpp>
#include <ApplicationBellRelaxation.hpp>
#include "windows/AudioErrorWindow.hpp"

#include <Application.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>

namespace
{
    constexpr auto unsupportedMediaMessage   = "app_bell_relaxation_error_message";
    constexpr auto exceededFilesLimitMessage = "app_bell_relaxation_limit_error_message";
    constexpr auto fileDeletedMessage        = "app_bell_relaxation_file_deleted_message";
    constexpr auto windowTimeout             = std::chrono::seconds{6};
    constexpr auto unsupportedMediaMessage   = "app_bell_audio_error_message";
    constexpr auto exceededFilesLimitMessage = "app_bell_audio_limit_error_message";
    constexpr auto fileDeletedMessage        = "app_bell_audio_file_deleted_message";
    constexpr auto emptyErrorMessage         = "";

    constexpr auto imageMarginTop = 122U;
    constexpr auto textPaddingTop = 30U;
} // namespace

namespace gui
{
    RelaxationErrorWindow::RelaxationErrorWindow(
        app::ApplicationCommon *app, std::unique_ptr<app::relaxation::RelaxationErrorContract::Presenter> &&presenter)
        : WindowWithTimer(app, gui::window::name::relaxationError, std::chrono::seconds{6}), presenter{
                                                                                                 std::move(presenter)}
    AudioErrorWindow::AudioErrorWindow(app::ApplicationCommon *app,
                                       const std::string &name,
                                       std::unique_ptr<AudioErrorContract::Presenter> &&presenter,
                                       OnExitCallback callback)
        : WindowWithTimer(app, name, windowTimeout), presenter{std::move(presenter)}, onExitCallback{
                                                                                          std::move(callback)}
    {
        if (onExitCallback == nullptr) {
            onExitCallback = [this]() { application->returnToPreviousWindow(); };
        }
        buildInterface();
    }

    void RelaxationErrorWindow::buildInterface()
    void AudioErrorWindow::buildInterface()
    {
        AppWindow::buildInterface();
        buildLayout();
        registerCallbacks();
    }

    void RelaxationErrorWindow::buildLayout()
    void AudioErrorWindow::buildLayout()
    {
        statusBar->setVisible(false);

        icon = new Icon(
            this, 0, 0, style::window_width, style::window_height, "big_information", "", ImageTypeSpecifier::W_G);
        icon->image->setMargins({0, gui::relaxationStyle::error::imageMarginTop, 0, 0});
        icon->image->setMargins({0, imageMarginTop, 0, 0});
        icon->text->setFont(style::window::font::verybiglight);
        const auto textPadding = icon->text->getPadding();
        icon->text->setPadding(
            {textPadding.left, gui::relaxationStyle::error::textPaddingTop, textPadding.right, textPadding.bottom});
        icon->text->setPadding({textPadding.left, textPaddingTop, textPadding.right, textPadding.bottom});
        icon->text->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        icon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        icon->resizeItems();
    }

    void RelaxationErrorWindow::registerCallbacks()
    void AudioErrorWindow::registerCallbacks()
    {
        timerCallback = [this](Item &, sys::Timer &timer) {
            application->switchWindow(gui::name::window::main_window);
            onExitCallback();
            return true;
        };
    }

    void RelaxationErrorWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    void AudioErrorWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        if (data && typeid(*data) == typeid(RelaxationErrorData)) {
            auto *errorData = static_cast<RelaxationErrorData *>(data);
        if (data && typeid(*data) == typeid(AudioErrorParams)) {
            auto *errorData = static_cast<AudioErrorParams *>(data);
            errorType       = errorData->getErrorType();
            switch (errorType) {
            case RelaxationErrorType::UnsupportedMediaType: {
            case AudioErrorType::UnsupportedMediaType: {
                icon->text->setRichText(utils::translate(unsupportedMediaMessage));
                break;
            }
            case RelaxationErrorType::FilesLimitExceeded: {
            case AudioErrorType::FilesLimitExceeded: {
                icon->text->setRichText(utils::translate(exceededFilesLimitMessage));
                break;
            }
            case RelaxationErrorType::FileDeleted: {
            case AudioErrorType::FileDeleted: {
                icon->text->setRichText(utils::translate(fileDeletedMessage));
                break;
            }


@@ 82,10 88,11 @@ namespace gui
        WindowWithTimer::onBeforeShow(mode, data);
    }

    bool RelaxationErrorWindow::onInput(const InputEvent &inputEvent)
    bool AudioErrorWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            application->switchWindow(gui::name::window::main_window);
            detachTimerIfExists();
            onExitCallback();
            return true;
        }
        return true;