~aleteoryx/muditaos

b30212bede352ea78efd59819aafbd52cf15e97b — Lefucjusz 2 years ago feec59f
[MOS-896] Update low battery screen view

Updated low battery screen view by adding
info windows appearing when trying to
interact with phone having critical
charge level.
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +2 -0
@@ 283,6 283,8 @@
    "app_desktop_unread_messages": "<text>Ungelesene Nachrichten</text>",
    "app_desktop_unread_single_message": "<text>Ungelesene Nachricht</text>",
    "app_desktop_battery_too_hot": "<text>Batterie zu heiß, lädt nicht</text>",
    "app_desktop_too_low_battery": "<text>Ihr Batteriestand ist zu niedrig (<token>$VALUE</token>%). Um Pure weiterhin zu verwenden, schließen Sie das Ladegerät an.</text>",
    "app_desktop_too_low_battery_charging": "<text>Ihr Batteriestand ist zu niedrig (<token>$VALUE</token>%). Pure wird gestartet, wenn der Mindestladezustand erreicht ist (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_countdown_desc": "Beginnt in",
    "app_meditation_interval_chime": "Glocken-Intervall",

M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +2 -0
@@ 286,6 286,8 @@
    "app_desktop_unread_messages": "<text>Unread messages</text>",
    "app_desktop_unread_single_message": "<text>Unread message</text>",
    "app_desktop_battery_too_hot": "<text>Battery too hot, not charging</text>",
    "app_desktop_too_low_battery": "<text>Your battery level is too low (<token>$VALUE</token>%). To continue using Pure, connect it to the charger.</text>",
    "app_desktop_too_low_battery_charging": "<text>Your battery level is too low (<token>$VALUE</token>%). Pure will start when minimum charge level is reached (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_countdown_desc": "Starts in",
    "app_meditation_interval_chime": "Interval chime",

M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +2 -0
@@ 282,6 282,8 @@
    "app_desktop_unread_messages": "<text>Mensajes no le\u00eddos</text>",
    "app_desktop_unread_single_message": "<text>Mensaje no le\u00eddo</text>",
    "app_desktop_battery_too_hot": "<text>Batería caliente, no carga</text>",
    "app_desktop_too_low_battery": "<text>El nivel de tu batería es demasiado bajo (<token>$VALUE</token>%). Para seguir usando Pure, conecte el dispositivo al cargador.</text>",
    "app_desktop_too_low_battery_charging": "<text>El nivel de tu batería es demasiado bajo (<token>$VALUE</token>%). Pure comenzará cuando se alcance el nivel mínimo de carga (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_countdown_desc": "Empieza en",
    "app_meditation_interval_chime": "Campanilla de intervalo",

M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +2 -0
@@ 250,6 250,8 @@
    "app_desktop_unread_messages": "<text>Messages non lus</text>",
    "app_desktop_unread_single_message": "<text>Message non lu</text>",
    "app_desktop_battery_too_hot": "<text>Batterie chaude, pas de charge</text>",
    "app_desktop_too_low_battery": "<text>Le niveau de charge de votre batterie est trop faible (<token>$VALUE</token>%). Pour continuer à utiliser Pure, branchez-la au chargeur.</text>",
    "app_desktop_too_low_battery_charging": "<text>Le niveau de charge de votre batterie est trop faible (<token>$VALUE</token>%). Pure se lancera lorsque le niveau de charge minimum sera atteint (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_countdown_desc": "D\u00e9but dans",
    "app_meditation_interval_chime": "Carillon d'intervalle",

M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +2 -0
@@ 275,6 275,8 @@
    "app_desktop_unread_messages": "<text>Nowe wiadomo\u015bci</text>",
    "app_desktop_unread_single_message": "<text>Nowa wiadomo\u015b\u0107</text>",
    "app_desktop_battery_too_hot": "<text>Bateria zbyt gorąca, nie ładuje</text>",
    "app_desktop_too_low_battery": "<text>Poziom naładowania baterii jest zbyt niski (<token>$VALUE</token>%). Aby dalej korzystać z Pure, podłącz go do ładowarki.</text>",
    "app_desktop_too_low_battery_charging": "<text>Poziom naładowania baterii jest zbyt niski (<token>$VALUE</token>%). Pure uruchomi się po osiągnięciu minimalnego poziomu naładowania (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_countdown_desc": "Startuje za",
    "app_meditation_interval_chime": "Cykliczny d\u017awi\u0119k",

M image/system_a/data/lang/Svenska.json => image/system_a/data/lang/Svenska.json +2 -0
@@ 148,6 148,8 @@
    "app_desktop_unread_messages": "<text>Ol\u00e4sta meddelanden</text>",
    "app_desktop_unread_single_message": "<text>Ol\u00e4st meddelande</text>",
    "app_desktop_battery_too_hot": "<text>Batteri för varmt, laddas inte</text>",
    "app_desktop_too_low_battery": "<text>Din batterinivå är för låg (<token>$VALUE</token>%). För att fortsätta använda Pure, anslut den till laddaren.</text>",
    "app_desktop_too_low_battery_charging": "<text>Din batterinivå är för låg (<token>$VALUE</token>%). Pure startar när lägsta laddningsnivå har uppnåtts (5%).</text>",
    "app_emoji_input_window": "Emoji",
    "app_meditation_interval_chime": "Klinga d\u00e5 och d\u00e5",
    "app_meditation_interval_every_x_minutes": "Var %0:e minut",

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +8 -4
@@ 4,6 4,7 @@
#include "ApplicationDesktop.hpp"
#include "ChargingBatteryWindow.hpp"
#include "DeadBatteryWindow.hpp"
#include "DeadBatteryInfoWindow.hpp"
#include "DesktopMainWindow.hpp"
#include "ClosingWindow.hpp"
#include "MenuWindow.hpp"


@@ 148,14 149,17 @@ namespace app
        windowsFactory.attach(desktop_menu, [this](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::MenuWindow>(app, dbNotificationHandler);
        });
        windowsFactory.attach(dead_battery, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::DeadBatteryWindow>(app);
        });
        windowsFactory.attach(closing_window, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::ClosingWindow>(app);
        });
        windowsFactory.attach(dead_battery, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::DeadBatteryWindow>(app, name);
        });
        windowsFactory.attach(charging_battery, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::ChargingBatteryWindow>(app);
            return std::make_unique<gui::ChargingBatteryWindow>(app, name);
        });
        windowsFactory.attach(dead_battery_info, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::DeadBatteryInfoWindow>(app, name);
        });
        windowsFactory.attach(desktop_mmi_pull, [](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::MmiPullWindow>(app, name);

M module-apps/application-desktop/CMakeLists.txt => module-apps/application-desktop/CMakeLists.txt +2 -0
@@ 20,6 20,7 @@ target_sources(application-desktop
	PRIVATE
		ApplicationDesktop.cpp
		data/Mmi.hpp
		data/DeadBatteryInfoWindowData.hpp
		models/ActiveNotificationsListPresenter.cpp
		models/ActiveNotificationsListPresenter.hpp
		widgets/DBNotificationsHandler.cpp


@@ 29,6 30,7 @@ target_sources(application-desktop
		windows/ChargingBatteryWindow.hpp
		windows/DeadBatteryWindow.cpp
		windows/DeadBatteryWindow.hpp
		windows/DeadBatteryInfoWindow.cpp
		windows/DesktopMainWindow.cpp
		windows/DesktopMainWindow.hpp
		windows/ClosingWindow.cpp

A module-apps/application-desktop/data/DeadBatteryInfoWindowData.hpp => module-apps/application-desktop/data/DeadBatteryInfoWindowData.hpp +21 -0
@@ 0,0 1,21 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <SwitchData.hpp>

class DeadBatteryInfoWindowData : public gui::SwitchData
{
  public:
    explicit DeadBatteryInfoWindowData(const std::string &message) : message(message)
    {}

    std::string getMessageText()
    {
        return message;
    }

  private:
    const std::string message;
};

M module-apps/application-desktop/include/application-desktop/Names.hpp => module-apps/application-desktop/include/application-desktop/Names.hpp +2 -1
@@ 10,7 10,8 @@ namespace app::window::name
    inline constexpr auto desktop_main_window        = gui::name::window::main_window;
    inline constexpr auto desktop_menu               = "MenuWindow";
    inline constexpr auto dead_battery               = "DeadBatteryWindow";
    inline constexpr auto charging_battery           = "CharginBatteryWindow";
    inline constexpr auto dead_battery_info          = "DeadBatteryInfoWindow";
    inline constexpr auto charging_battery           = "ChargingBatteryWindow";
    inline constexpr auto closing_window             = "ClosingWindow";
    inline constexpr auto desktop_mmi_pull           = "MmiPullWindow";
    inline constexpr auto desktop_mmi_push           = "MmiPushWindow";

M module-apps/application-desktop/windows/ChargingBatteryWindow.cpp => module-apps/application-desktop/windows/ChargingBatteryWindow.cpp +20 -8
@@ 1,13 1,15 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ChargingBatteryWindow.hpp"
#include "InputEvent.hpp"
#include "Names.hpp"
#include "DeadBatteryInfoWindowData.hpp"

#include <gui/widgets/Image.hpp>
#include <log/log.hpp>
#include <service-appmgr/Controller.hpp>
#include <InputEvent.hpp>
#include <EventStore.hpp>
#include <FontManager.hpp>

namespace gui
{


@@ 15,10 17,20 @@ namespace gui
    {
        constexpr inline auto imgPositionX = 176;
        constexpr inline auto imgPositionY = 250;

        std::string getInfoText()
        {
            const auto &rawText     = utils::translate("app_desktop_too_low_battery_charging");
            const auto batteryLevel = static_cast<int>(Store::Battery::get().level);
            auto format             = TextFormat(FontManager::getInstance().getFont(style::window::font::medium));
            auto tokenMap           = text::RichTextParser::TokenMap({{"$VALUE", batteryLevel}});

            return text::RichTextParser().parse(rawText, &format, std::move(tokenMap))->getText();
        }
    } // namespace

    ChargingBatteryWindow::ChargingBatteryWindow(app::ApplicationCommon *app)
        : AppWindow(app, app::window::name::charging_battery)
    ChargingBatteryWindow::ChargingBatteryWindow(app::ApplicationCommon *app, const std::string &name)
        : AppWindow(app, name)
    {
        buildInterface();
        preventsAutoLock = true;


@@ 43,10 55,10 @@ namespace gui
        erase();
    }

    bool ChargingBatteryWindow::onInput(const InputEvent &inputEvent)
    bool ChargingBatteryWindow::onInput([[maybe_unused]] const InputEvent &inputEvent)
    {
        // Ignore all inputs
        auto data = std::make_unique<DeadBatteryInfoWindowData>(getInfoText());
        application->switchWindow(app::window::name::dead_battery_info, std::move(data));
        return true;
    }

} /* namespace gui */

M module-apps/application-desktop/windows/ChargingBatteryWindow.hpp => module-apps/application-desktop/windows/ChargingBatteryWindow.hpp +2 -5
@@ 1,22 1,19 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <AppWindow.hpp>

#include <vector>

namespace gui
{
    class ChargingBatteryWindow : public AppWindow
    {
      public:
        explicit ChargingBatteryWindow(app::ApplicationCommon *app);
        ChargingBatteryWindow(app::ApplicationCommon *app, const std::string &name);
        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
    };

} /* namespace gui */

A module-apps/application-desktop/windows/DeadBatteryInfoWindow.cpp => module-apps/application-desktop/windows/DeadBatteryInfoWindow.cpp +83 -0
@@ 0,0 1,83 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "DeadBatteryInfoWindow.hpp"
#include "DeadBatteryInfoWindowData.hpp"

#include <i18n/i18n.hpp>
#include <Image.hpp>

namespace
{
    using namespace std::chrono_literals;
    constexpr auto windowTimeout = 5s;
} // namespace

namespace gui
{
    DeadBatteryInfoWindow::DeadBatteryInfoWindow(app::ApplicationCommon *app, const std::string &name)
        : WindowWithTimer(app, name, windowTimeout)
    {
        buildInterface();
        preventsAutoLock = true;
    }

    DeadBatteryInfoWindow::~DeadBatteryInfoWindow()
    {
        destroyInterface();
    }

    status_bar::Configuration DeadBatteryInfoWindow::configureStatusBar(status_bar::Configuration appConfiguration)
    {
        appConfiguration.enable(status_bar::Indicator::Time);
        appConfiguration.disable(status_bar::Indicator::NetworkAccessTechnology);
        appConfiguration.disable(status_bar::Indicator::PhoneMode);
        appConfiguration.disable(status_bar::Indicator::Signal);
        return appConfiguration;
    }

    void DeadBatteryInfoWindow::rebuild()
    {
        destroyInterface();
        buildInterface();
    }

    void DeadBatteryInfoWindow::buildInterface()
    {
        AppWindow::buildInterface();

        navBar->setActive(nav_bar::Side::Left, false);
        navBar->setActive(nav_bar::Side::Center, false);
        navBar->setActive(nav_bar::Side::Right, false);

        icon = new Icon(this,
                        style::window::default_left_margin,
                        style::window::default_vertical_pos,
                        style::window::default_body_width,
                        style::window::default_body_height,
                        "info_128px_W_G",
                        "");
        icon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        icon->image->setMargins(Margins(0, icon::image_top_margin, 0, icon::image_bottom_margin));

        setTitle(utils::translate("app_desktop_info"));
    }

    void DeadBatteryInfoWindow::destroyInterface()
    {
        erase();
    }

    void DeadBatteryInfoWindow::onBeforeShow([[maybe_unused]] gui::ShowMode mode, gui::SwitchData *data)
    {
        WindowWithTimer::onBeforeShow(mode, data);
        if (const auto switchData = dynamic_cast<DeadBatteryInfoWindowData *>(data); switchData != nullptr) {
            icon->text->setText(switchData->getMessageText());
        }
    }

    bool DeadBatteryInfoWindow::onInput([[maybe_unused]] const gui::InputEvent &inputEvent)
    {
        return true; // Ignore all inputs
    }
} // namespace gui

A module-apps/application-desktop/windows/DeadBatteryInfoWindow.hpp => module-apps/application-desktop/windows/DeadBatteryInfoWindow.hpp +28 -0
@@ 0,0 1,28 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

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

namespace gui
{
    class DeadBatteryInfoWindow : public WindowWithTimer
    {
      public:
        DeadBatteryInfoWindow(app::ApplicationCommon *app, const std::string &name);
        ~DeadBatteryInfoWindow();

        status_bar::Configuration configureStatusBar(status_bar::Configuration appConfiguration) override;
        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;

        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onInput(const InputEvent &inputEvent) override;

      private:
        Icon *icon = nullptr;
    };
} // namespace gui

M module-apps/application-desktop/windows/DeadBatteryWindow.cpp => module-apps/application-desktop/windows/DeadBatteryWindow.cpp +19 -7
@@ 1,14 1,15 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "DeadBatteryWindow.hpp"
#include "Names.hpp"
#include "DeadBatteryInfoWindowData.hpp"

#include <gui/widgets/Image.hpp>
#include <Image.hpp>
#include <InputEvent.hpp>
#include <log/log.hpp>
#include <service-appmgr/Controller.hpp>
#include <InputEvent.hpp>
#include <EventStore.hpp>
#include <FontManager.hpp>

namespace gui
{


@@ 16,9 17,19 @@ namespace gui
    {
        constexpr inline auto imgPositionX = 176;
        constexpr inline auto imgPositionY = 250;

        std::string getInfoText()
        {
            const auto &rawText     = utils::translate("app_desktop_too_low_battery");
            const auto batteryLevel = static_cast<int>(Store::Battery::get().level);
            auto format             = TextFormat(FontManager::getInstance().getFont(style::window::font::medium));
            auto tokenMap           = text::RichTextParser::TokenMap({{"$VALUE", batteryLevel}});

            return text::RichTextParser().parse(rawText, &format, std::move(tokenMap))->getText();
        }
    } // namespace

    DeadBatteryWindow::DeadBatteryWindow(app::ApplicationCommon *app) : AppWindow(app, app::window::name::dead_battery)
    DeadBatteryWindow::DeadBatteryWindow(app::ApplicationCommon *app, const std::string &name) : AppWindow(app, name)
    {
        buildInterface();
        preventsAutoLock = true;


@@ 43,9 54,10 @@ namespace gui
        erase();
    }

    bool DeadBatteryWindow::onInput(const InputEvent &inputEvent)
    bool DeadBatteryWindow::onInput([[maybe_unused]] const InputEvent &inputEvent)
    {
        // Ignore all inputs
        auto data = std::make_unique<DeadBatteryInfoWindowData>(getInfoText());
        application->switchWindow(app::window::name::dead_battery_info, std::move(data));
        return true;
    }
} /* namespace gui */

M module-apps/application-desktop/windows/DeadBatteryWindow.hpp => module-apps/application-desktop/windows/DeadBatteryWindow.hpp +2 -5
@@ 1,23 1,20 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <AppWindow.hpp>

#include <vector>

namespace gui
{
    class Image;
    class DeadBatteryWindow : public AppWindow
    {
      public:
        explicit DeadBatteryWindow(app::ApplicationCommon *app);
        DeadBatteryWindow(app::ApplicationCommon *app, const std::string &name);
        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
    };

} /* namespace gui */

M module-gui/gui/widgets/StatusBar.cpp => module-gui/gui/widgets/StatusBar.cpp +7 -5
@@ 389,10 389,11 @@ namespace gui::status_bar

    void StatusBar::showPhoneMode(bool enabled)
    {
        showPhoneModeOrTethering(enabled, configuration.isEnabled(Indicator::Tethering));
        showPhoneModeOrTethering(
            configuration.isEnabled(Indicator::Signal), enabled, configuration.isEnabled(Indicator::Tethering));
    }

    void StatusBar::showPhoneModeOrTethering(bool phoneModeEnabled, bool tetheringEnabled)
    void StatusBar::showPhoneModeOrTethering(bool signalEnabled, bool phoneModeEnabled, bool tetheringEnabled)
    {
        if (tetheringEnabled && configuration.getTetheringState() != sys::phone_modes::Tethering::Off) {
            phoneMode->hide();


@@ 402,7 403,7 @@ namespace gui::status_bar
        }
        else {
            tethering->hide();
            signal->show();
            signalEnabled ? signal->show() : signal->hide();
            phoneModeEnabled ? phoneMode->show() : phoneMode->hide();
            showNetworkAccessTechnology(configuration.isEnabled(Indicator::NetworkAccessTechnology));
        }


@@ 425,7 426,7 @@ namespace gui::status_bar

    bool StatusBar::showTime(bool enabled)
    {
        const auto visibilityChanged = time->isVisible() == enabled ? false : true;
        const auto visibilityChanged = (time->isVisible() != enabled);
        time->update();
        if (enabled) {
            centralBox->setMinimumSize(boxes::center::maxX, this->drawArea.h);


@@ 473,7 474,8 @@ namespace gui::status_bar

    void StatusBar::showTethering(bool enabled)
    {
        showPhoneModeOrTethering(configuration.isEnabled(Indicator::PhoneMode), enabled);
        showPhoneModeOrTethering(
            configuration.isEnabled(Indicator::Signal), configuration.isEnabled(Indicator::PhoneMode), enabled);
    }

    void StatusBar::accept(GuiVisitor &visitor)

M module-gui/gui/widgets/StatusBar.hpp => module-gui/gui/widgets/StatusBar.hpp +1 -1
@@ 258,7 258,7 @@ namespace gui::status_bar
        void showTethering(bool enabled);

        /// Show/hide phone mode or tethering widget
        void showPhoneModeOrTethering(bool phoneModeEnabled, bool tetheringEnabled);
        void showPhoneModeOrTethering(bool signalEnabled, bool phoneModeEnabled, bool tetheringEnabled);

        /// Sets the status of the specified indicator on the Status bar
        /// @param indicator indicator id

M pure_changelog.md => pure_changelog.md +1 -0
@@ 9,6 9,7 @@
### Changed / Improved

* Disabled USB MTP protocol
* Changed UI flow on discharged device window.

### Fixed