~aleteoryx/muditaos

23a42d0e99f6c5be80c656b450c40622a69dd19e — Maciej Janicki 4 years ago ef46a48
[BH-922] Fix alarm activate popup

Fix activate popup to have proper alarm time
Change activate/deactivate popup to use alarm model
M image/assets/lang/English.json => image/assets/lang/English.json +1 -1
@@ 606,7 606,7 @@
  "app_bell_settings_alarm_settings_snooze_chime_volume": "Snooze chime volume",
  "app_bellmain_home_screen_bottom_desc": "Next alarm will ring",
  "app_bellmain_home_screen_bottom_desc_dp": "Deep press to activate",
  "app_bell_alarm_deactivated": "Alarm deactivated",
  "app_bell_alarm_deactivated": "<text>Alarm deactivated<br /></text>",
  "app_bell_alarm_set_not_active": "<text>Alarm set.<br />Deep press to activate.</text>",
  "app_bell_settings_advanced_frontlight": "Frontlight",
  "app_bell_settings_frontlight_top_message": "Frontlight intensity",

M module-apps/apps-common/ApplicationCommon.hpp => module-apps/apps-common/ApplicationCommon.hpp +3 -3
@@ 255,6 255,9 @@ namespace app
        ///@param ignoredWindowsNumber: defines how many windows will be skipped while going back on stack
        void returnToPreviousWindow(const uint32_t times = 1);

        /// Find and pop window from stack by window name
        void popWindow(const std::string &window);

        /// Pops the current window from the windows stack
        void popCurrentWindow();



@@ 354,9 357,6 @@ namespace app
        WindowsStack windowsStack;
        WindowsFactory windowsFactory;

        /// Find and pop window from stack by window name
        void popWindow(const std::string &window);

        /// Method used to attach popups windows to application
        virtual void attachPopups(const std::vector<gui::popup::ID> &popupsList);
        virtual void showPopup(gui::popup::ID id, const gui::PopupRequestParams *params);

M products/BellHybrid/apps/Application.cpp => products/BellHybrid/apps/Application.cpp +16 -8
@@ 2,6 2,10 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <Application.hpp>

#include <common/models/AlarmModel.hpp>

#include <common/popups/presenter/AlarmActivatedPresenter.hpp>
#include <common/popups/AlarmActivatedWindow.hpp>
#include <common/popups/AlarmDeactivatedWindow.hpp>



@@ 14,16 18,20 @@ namespace app
        for (auto popup : popupsList) {
            switch (popup) {
            case ID::AlarmActivated:
                windowsFactory.attach(window::alarm_activated_window,
                                      [](app::ApplicationCommon *app, const std::string &name) {
                                          return std::make_unique<gui::AlarmActivatedWindow>(app);
                                      });
                windowsFactory.attach(
                    window::alarm_activated_window, [](app::ApplicationCommon *app, const std::string &name) {
                        auto alarmModel = std::make_shared<app::AlarmModel>(app);
                        auto presenter  = std::make_unique<app::popup::AlarmActivatedPresenter>(alarmModel);
                        return std::make_unique<gui::AlarmActivatedWindow>(app, std::move(presenter));
                    });
                break;
            case ID::AlarmDeactivated:
                windowsFactory.attach(window::alarm_deactivated_window,
                                      [](app::ApplicationCommon *app, const std::string &name) {
                                          return std::make_unique<gui::AlarmDeactivatedWindow>(app);
                                      });
                windowsFactory.attach(
                    window::alarm_deactivated_window, [](app::ApplicationCommon *app, const std::string &name) {
                        auto alarmModel = std::make_shared<app::AlarmModel>(app);
                        auto presenter  = std::make_unique<app::popup::AlarmActivatedPresenter>(alarmModel);
                        return std::make_unique<gui::AlarmDeactivatedWindow>(app, std::move(presenter));
                    });
                break;
            default:
                break;

M products/BellHybrid/apps/application-bell-alarm/include/application-bell-alarm/ApplicationBellAlarm.hpp => products/BellHybrid/apps/application-bell-alarm/include/application-bell-alarm/ApplicationBellAlarm.hpp +1 -6
@@ 3,14 3,9 @@

#pragma once

#include "ApplicationBellAlarmNames.hpp"
#include <Application.hpp>

namespace gui::window::name
{
    inline constexpr auto bellAlarm    = "BellAlarm";
    inline constexpr auto bellAlarmSet = "BellAlarmSet";
} // namespace gui::window::name

namespace app
{
    namespace internal

A products/BellHybrid/apps/application-bell-alarm/include/application-bell-alarm/ApplicationBellAlarmNames.hpp => products/BellHybrid/apps/application-bell-alarm/include/application-bell-alarm/ApplicationBellAlarmNames.hpp +10 -0
@@ 0,0 1,10 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

namespace gui::window::name
{
    inline constexpr auto bellAlarm    = "BellAlarm";
    inline constexpr auto bellAlarmSet = "BellAlarmSet";
} // namespace gui::window::name

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +4 -1
@@ 15,6 15,7 @@ target_sources(application-bell-common
        src/BellFinishedWindow.cpp
        src/BellSideListItemWithCallbacks.cpp
        src/TimeUtils.cpp
        src/popups/presenter/AlarmActivatedPresenter.cpp
        src/popups/AlarmActivatedWindow.cpp
        src/popups/AlarmDeactivatedWindow.cpp
        src/widgets/ListItems.cpp


@@ 28,6 29,7 @@ target_sources(application-bell-common
        include/common/models/AbstractSettingsModel.hpp
        include/common/models/AlarmModel.hpp
        include/common/models/TimeModel.hpp
        include/common/popups/presenter/AlarmActivatedPresenter.hpp
        include/common/popups/AlarmActivatedWindow.hpp
        include/common/popups/AlarmDeactivatedWindow.hpp
        include/common/widgets/BellSideListItemWithCallbacks.hpp


@@ 42,7 44,8 @@ target_link_libraries(application-bell-common
        service-db

    PRIVATE
        bell::db
        bell::app-main
        bell::app-alarm 
        module-gui
        service-time
        bell::db

M products/BellHybrid/apps/common/include/common/popups/AlarmActivatedWindow.hpp => products/BellHybrid/apps/common/include/common/popups/AlarmActivatedWindow.hpp +6 -6
@@ 3,8 3,9 @@

#pragma once

#include "presenter/AlarmActivatedPresenter.hpp"

#include <apps-common/popups/WindowWithTimer.hpp>
#include <AsyncTask.hpp>

struct AlarmEventRecord;



@@ 12,19 13,18 @@ namespace gui
{
    class Icon;

    class AlarmActivatedWindow : public WindowWithTimer, public app::AsyncCallbackReceiver
    class AlarmActivatedWindow : public WindowWithTimer, app::popup::AlarmActivatedContract::View
    {
      public:
        explicit AlarmActivatedWindow(app::ApplicationCommon *app);
        AlarmActivatedWindow(app::ApplicationCommon *app,
                             std::shared_ptr<app::popup::AlarmActivatedPresenter> presenter);

      private:
        bool onInput(const InputEvent &inputEvent) override;
        void buildInterface() override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        void activateAlarm(AlarmEventRecord &alarmEvent);
        bool onAlarmResponseMessage(sys::ResponseMessage *response, ShowMode mode);
        void showAlarmTime(ShowMode mode, time_t alarmTime);
        void returnToPreviousWindow();
        void setAlarmTime(time_t alarmTime);

        Icon *icon{};
    };

M products/BellHybrid/apps/common/include/common/popups/AlarmDeactivatedWindow.hpp => products/BellHybrid/apps/common/include/common/popups/AlarmDeactivatedWindow.hpp +5 -5
@@ 3,25 3,25 @@

#pragma once

#include "presenter/AlarmActivatedPresenter.hpp"

#include <apps-common/popups/WindowWithTimer.hpp>
#include <AsyncTask.hpp>

struct AlarmEventRecord;

namespace gui
{
    class Icon;
    class AlarmDeactivatedWindow : public WindowWithTimer, public app::AsyncCallbackReceiver
    class AlarmDeactivatedWindow : public WindowWithTimer, app::popup::AlarmActivatedContract::View
    {
      public:
        explicit AlarmDeactivatedWindow(app::ApplicationCommon *app);
        AlarmDeactivatedWindow(app::ApplicationCommon *app,
                               std::shared_ptr<app::popup::AlarmActivatedPresenter> presenter);

      private:
        bool onInput(const InputEvent &inputEvent) override;
        void buildInterface() override;
        void returnToPreviousWindow();
        void deactivateAlarm(AlarmEventRecord &alarmEvent);
        bool onAlarmResponseMessage(sys::ResponseMessage *response);

        Icon *icon{};
    };

A products/BellHybrid/apps/common/include/common/popups/presenter/AlarmActivatedPresenter.hpp => products/BellHybrid/apps/common/include/common/popups/presenter/AlarmActivatedPresenter.hpp +61 -0
@@ 0,0 1,61 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/BasePresenter.hpp>
#include <common/models/AbstractAlarmModel.hpp>

#include <memory>

namespace app::popup
{
    class AlarmActivatedContract
    {
      public:
        class Presenter;

        class View
        {
          private:
            std::shared_ptr<Presenter> presenter;

          protected:
            std::shared_ptr<Presenter> getPresenter()
            {
                return presenter;
            }

          public:
            explicit View(std::shared_ptr<Presenter> presenter) : presenter(std::move(presenter))
            {}

            virtual ~View() = default;
        };
        class Presenter : public BasePresenter<AlarmActivatedContract::View>
        {
          public:
            virtual ~Presenter() noexcept                                  = default;
            virtual void updateAlarmModel(AlarmModelReadyHandler callback) = 0;
            virtual time_t getAlarmTime() const noexcept                   = 0;
            virtual bool isAlarmActive() const noexcept                    = 0;
            virtual void activate()                                        = 0;
            virtual void deactivate()                                      = 0;
        };
    };

    class AlarmActivatedPresenter : public AlarmActivatedContract::Presenter
    {
      public:
        AlarmActivatedPresenter(std::shared_ptr<AbstractAlarmModel> alarmModel);

        void updateAlarmModel(AlarmModelReadyHandler callback);
        time_t getAlarmTime() const noexcept;
        bool isAlarmActive() const noexcept;
        void activate();
        void deactivate();

      private:
        std::shared_ptr<AbstractAlarmModel> alarmModel;
    };
} // namespace app::popup

M products/BellHybrid/apps/common/src/popups/AlarmActivatedWindow.cpp => products/BellHybrid/apps/common/src/popups/AlarmActivatedWindow.cpp +35 -50
@@ 11,66 11,29 @@
#include <service-appmgr/Controller.hpp>
#include <service-time/AlarmMessage.hpp>
#include <service-time/Constants.hpp>
#include <application-bell-alarm/ApplicationBellAlarmNames.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>

namespace gui
{
    AlarmActivatedWindow::AlarmActivatedWindow(app::ApplicationCommon *app)
        : WindowWithTimer(app, popup::window::alarm_activated_window), app::AsyncCallbackReceiver{app}
    AlarmActivatedWindow::AlarmActivatedWindow(app::ApplicationCommon *app,
                                               std::shared_ptr<app::popup::AlarmActivatedPresenter> presenter)
        : WindowWithTimer(app, popup::window::alarm_activated_window), app::popup::AlarmActivatedContract::View(
                                                                           std::move(presenter))
    {
        getPresenter()->attach(this);
        buildInterface();
        getPresenter()->updateAlarmModel([&]() {
            setAlarmTime(getPresenter()->getAlarmTime());
            getPresenter()->activate();
        });

        timerCallback = [this](Item &, sys::Timer &) {
            returnToPreviousWindow();
            return true;
        };
    }

    void AlarmActivatedWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        WindowWithTimer::onBeforeShow(mode, data);
        auto task = app::AsyncRequest::createFromMessage(
            std::make_unique<alarms::AlarmGetFirstNextSingleEventRequestMessage>(), service::name::service_time);

        auto onResponseCallback = [this, mode](auto response) { return onAlarmResponseMessage(response, mode); };
        task->execute(this->application, this, onResponseCallback);
    }

    void AlarmActivatedWindow::activateAlarm(AlarmEventRecord &alarmEvent)
    {
        alarmEvent.enabled = true;
        auto task          = app::AsyncRequest::createFromMessage(
            std::make_unique<alarms::AlarmUpdateRequestMessage>(alarmEvent), service::name::service_time);

        task->execute(application, this);
    }

    bool AlarmActivatedWindow::onAlarmResponseMessage(sys::ResponseMessage *response, ShowMode mode)
    {
        auto result = dynamic_cast<alarms::AlarmGetFirstNextSingleEventResponseMessage *>(response);
        if (result == nullptr || result->retCode != sys::ReturnCodes::Success) {
            LOG_WARN("Get next single event request failed!");
            return false;
        }
        const auto &singleEventRecord = result->singleEvent;
        const auto &startDate         = singleEventRecord.startDate;
        LOG_DEBUG("Alarm time: %s", TimePointToString(startDate).c_str());
        const auto alarmTime = std::chrono::system_clock::to_time_t(startDate);
        showAlarmTime(mode, alarmTime);

        auto alarmEventRecord = dynamic_cast<AlarmEventRecord *>(singleEventRecord.parent.get());
        if (alarmEventRecord == nullptr) {
            LOG_WARN("Getting alarm event record failed!");
            return false;
        }
        activateAlarm(*alarmEventRecord);

        return true;
    }

    void AlarmActivatedWindow::showAlarmTime(ShowMode, time_t alarmTime)
    {
        icon->text->setRichText(utils::time::getBottomDescription(
            utils::time::calculateTimeDifference(alarmTime, utils::time::getCurrentTime())));
    }
    void AlarmActivatedWindow::buildInterface()
    {
        WindowWithTimer::buildInterface();


@@ 82,14 45,30 @@ namespace gui
        icon = new Icon(this, 0, 0, style::window_width, style::window_height, "big_alarm", {});
        icon->text->setFont(style::window::font::verybiglight);
    }

    void AlarmActivatedWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        WindowWithTimer::onBeforeShow(mode, data);
    }

    void AlarmActivatedWindow::returnToPreviousWindow()
    {
        app::manager::Controller::sendAction(
            application,
            app::manager::actions::AbortPopup,
            std::make_unique<gui::PopupRequestParams>(gui::popup::ID::AlarmDeactivated));
        application->returnToPreviousWindow();

        if (application->getPrevWindow() == gui::window::name::bellAlarmSet) {
            app::manager::Controller::sendAction(
                application,
                app::manager::actions::Launch,
                std::make_unique<app::ApplicationLaunchData>(app::applicationBellName));
        }
        else {
            application->returnToPreviousWindow();
        }
    }

    bool AlarmActivatedWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {


@@ 98,4 77,10 @@ namespace gui
        }
        return false;
    }

    void AlarmActivatedWindow::setAlarmTime(time_t alarmTime)
    {
        icon->text->setRichText(utils::time::getBottomDescription(
            utils::time::calculateTimeDifference(alarmTime, utils::time::getCurrentTime())));
    }
} /* namespace gui */

M products/BellHybrid/apps/common/src/popups/AlarmDeactivatedWindow.cpp => products/BellHybrid/apps/common/src/popups/AlarmDeactivatedWindow.cpp +16 -31
@@ 12,13 12,20 @@
#include <service-appmgr/Controller.hpp>
#include <service-time/AlarmMessage.hpp>
#include <service-time/Constants.hpp>
#include <application-bell-alarm/ApplicationBellAlarmNames.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>

namespace gui
{
    AlarmDeactivatedWindow::AlarmDeactivatedWindow(app::ApplicationCommon *app)
        : WindowWithTimer(app, popup::window::alarm_deactivated_window), app::AsyncCallbackReceiver{app}
    AlarmDeactivatedWindow::AlarmDeactivatedWindow(app::ApplicationCommon *app,
                                                   std::shared_ptr<app::popup::AlarmActivatedPresenter> presenter)
        : WindowWithTimer(app, popup::window::alarm_deactivated_window), app::popup::AlarmActivatedContract::View(
                                                                             std::move(presenter))
    {
        getPresenter()->attach(this);
        buildInterface();
        getPresenter()->updateAlarmModel([&]() { getPresenter()->deactivate(); });

        timerCallback = [this](Item &, sys::Timer &) {
            returnToPreviousWindow();
            return true;


@@ 37,11 44,6 @@ namespace gui
    void AlarmDeactivatedWindow::buildInterface()
    {
        WindowWithTimer::buildInterface();
        auto task = app::AsyncRequest::createFromMessage(
            std::make_unique<alarms::AlarmGetFirstNextSingleEventRequestMessage>(), service::name::service_time);

        auto onResponseCallback = [this](auto response) { return onAlarmResponseMessage(response); };
        task->execute(application, this, onResponseCallback);

        statusBar->setVisible(false);
        header->setTitleVisibility(false);


@@ 62,32 64,15 @@ namespace gui
        app::manager::Controller::sendAction(application,
                                             app::manager::actions::AbortPopup,
                                             std::make_unique<gui::PopupRequestParams>(gui::popup::ID::AlarmActivated));
        application->returnToPreviousWindow();
    }

    void AlarmDeactivatedWindow::deactivateAlarm(AlarmEventRecord &alarmEvent)
    {
        alarmEvent.enabled = false;
        auto task          = app::AsyncRequest::createFromMessage(
            std::make_unique<alarms::AlarmUpdateRequestMessage>(alarmEvent), service::name::service_time);

        task->execute(this->application, this);
    }

    bool AlarmDeactivatedWindow::onAlarmResponseMessage(sys::ResponseMessage *response)
    {
        auto result = dynamic_cast<alarms::AlarmGetFirstNextSingleEventResponseMessage *>(response);
        if (result == nullptr || result->retCode != sys::ReturnCodes::Success) {
            LOG_WARN("Get next single event request failed!");
            return false;
        if (application->getPrevWindow() == gui::window::name::bellAlarmSet) {
            app::manager::Controller::sendAction(
                application,
                app::manager::actions::Launch,
                std::make_unique<app::ApplicationLaunchData>(app::applicationBellName));
        }
        auto alarmEventRecord = dynamic_cast<AlarmEventRecord *>(result->singleEvent.parent.get());
        if (alarmEventRecord == nullptr) {
            LOG_WARN("Getting alarm event record failed!");
            return false;
        else {
            application->returnToPreviousWindow();
        }

        deactivateAlarm(*alarmEventRecord);
        return true;
    }
} /* namespace gui */

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

#include <common/popups/presenter/AlarmActivatedPresenter.hpp>

#include <Timers/TimerFactory.hpp>
#include <service-appmgr/Controller.hpp>

namespace app::popup
{
    AlarmActivatedPresenter ::AlarmActivatedPresenter(std::shared_ptr<AbstractAlarmModel> alarmModel)
        : alarmModel{std::move(alarmModel)}
    {}

    bool AlarmActivatedPresenter::isAlarmActive() const noexcept
    {
        return alarmModel->isActive();
    }

    time_t AlarmActivatedPresenter::getAlarmTime() const noexcept
    {
        return alarmModel->getAlarmTime();
    }

    void AlarmActivatedPresenter::activate()
    {
        return alarmModel->activate(true);
    }

    void AlarmActivatedPresenter::deactivate()
    {
        return alarmModel->activate(false);
    }

    void AlarmActivatedPresenter::updateAlarmModel(AlarmModelReadyHandler callback)
    {
        alarmModel->update(callback);
    }
} // namespace app::popup