~aleteoryx/muditaos

48f7cf171d870f14f6732b17c98b4aef23825dc6 — Michał Kamoń 4 years ago 2e2ce20
[EGD-6755] Add updated notification icons

This PR adds/updates notification icons to latest version provided
by designs.

Also this PR provides new implementation for CallLogDetailsWindow.
The window was using one of the icons updated. To avoid making
temporary corrections on the icon's hardcoded (x,y,w,h) properties,
the entire window was redesign to use up-to-date ModuitaOS GUI
features.
A image/assets/images/alarm_notification_icon.vpi => image/assets/images/alarm_notification_icon.vpi +0 -0
A image/assets/images/calendar_notification_icon.vpi => image/assets/images/calendar_notification_icon.vpi +0 -0
A image/assets/images/calls_notification_icon.vpi => image/assets/images/calls_notification_icon.vpi +0 -0
A image/assets/images/messages_notification_icon.vpi => image/assets/images/messages_notification_icon.vpi +0 -0
A image/assets/images/now_playing_notification_icon.vpi => image/assets/images/now_playing_notification_icon.vpi +0 -0
D image/assets/images/phone.vpi => image/assets/images/phone.vpi +0 -0
M module-apps/Application.cpp => module-apps/Application.cpp +1 -2
@@ 927,8 927,7 @@ namespace app
    void Application::handleNotificationsChanged(std::unique_ptr<gui::SwitchData> notificationsParams)
    {
        if (auto window = getCurrentWindow()->getName(); window == gui::popup::window::phone_lock_window) {

            updateWindow(window, std::move(notificationsParams));
            switchWindow(window, std::move(notificationsParams));
        }
    }


M module-apps/application-calllog/data/CallLogStyle.hpp => module-apps/application-calllog/data/CallLogStyle.hpp +24 -99
@@ 14,113 14,38 @@ namespace callLogStyle
    // DETAILS WINDOW
    namespace detailsWindow
    {
        constexpr uint32_t default_x = style::window::default_left_margin;
        constexpr uint32_t default_w =
            style::window_width - style::window::default_left_margin - style::window::default_right_margin;
        namespace information
        {
            namespace label
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = 111;
                constexpr uint32_t w = default_w;
            } // namespace label
            namespace number
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = 174;
                constexpr uint32_t w = default_w;
            } // namespace number
            namespace imgs
            {
                constexpr uint32_t y = 162;
                constexpr uint32_t w = 55;
                constexpr uint32_t h = 55;
                namespace call
                {
                    constexpr uint32_t x = 317;
                    namespace icon
                    {
                        constexpr uint32_t x = 11;
                        constexpr uint32_t y = 12;
                    } // namespace icon
                }     // namespace call
                namespace sms
                {
                    constexpr uint32_t x = 389;
                    namespace icon
                    {
                        constexpr uint32_t x = 11;
                        constexpr uint32_t y = 12;
                    } // namespace icon
                }     // namespace sms
            }         // namespace imgs
        }             // namespace information
        namespace type
        constexpr inline auto x = style::window::bottomBar::leftMargin;
        constexpr inline auto y = style::header::height;
        constexpr inline auto w = style::window_width - 2 * x;
        constexpr inline auto h = style::window::default_body_height;

        namespace widget
        {
            namespace label
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = 222;
                constexpr uint32_t w = style::window_width / 2 - x;
            } // namespace label
            namespace img
            {
                const uint32_t x = default_x;
                const uint32_t y = 285;
            } // namespace img
            namespace data
            {
                constexpr uint32_t x = 70;
                constexpr uint32_t y = 285;
                constexpr uint32_t w = style::window_width / 2 - x;
            } // namespace data
        }     // namespace type
        namespace duration
            constexpr inline auto h      = style::widgets::h;
            constexpr inline auto smallH = style::window::label::small_h;
        } // namespace widget

        namespace callData
        {
            namespace label
            {
                constexpr uint32_t x = 281;
                constexpr uint32_t y = 222;
                constexpr uint32_t w = style::window_width - x - style::window::default_right_margin;
            } // namespace label
            namespace data
            {
                constexpr uint32_t x = 281;
                constexpr uint32_t y = 285;
                constexpr uint32_t w = style::window_width / 2 - style::window::default_right_margin;
            } // namespace data
        }     // namespace duration
            constexpr inline auto columns = 2;
            constexpr inline auto rows    = 2;
            constexpr inline auto h       = rows * widget::h;
        } // namespace callData

        namespace date
        {
            namespace label
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = 333;
                constexpr uint32_t w = default_w;
            } // namespace label
            namespace dataDay
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = 396;
                constexpr uint32_t w = default_w;
            } // namespace dataDay
            namespace dataDate
            {
                constexpr uint32_t x = default_x;
                constexpr uint32_t y = dataDay::y + style::window::label::small_h;
                constexpr uint32_t w = default_w;
            } // namespace dataDate
        }     // namespace date
    }         // namespace detailsWindow
            constexpr inline auto rows = 2;
            constexpr inline auto h    = rows * widget::smallH;
        } // namespace date
    }     // namespace detailsWindow

    // MAIN WINDOW
    namespace mainWindow
    {
        constexpr uint32_t x = style::window::default_left_margin;
        constexpr uint32_t y = style::header::height;
        constexpr uint32_t w = style::listview::body_width_with_scroll;
        constexpr uint32_t h = style::window_height - y - style::footer::height;
        constexpr inline uint32_t x = style::window::default_left_margin;
        constexpr inline uint32_t y = style::header::height;
        constexpr inline uint32_t w = style::listview::body_width_with_scroll;
        constexpr inline uint32_t h = style::window_height - y - style::footer::height;
    } // namespace mainWindow

} // namespace callLogStyle

M module-apps/application-calllog/data/CallLogSwitchData.hpp => module-apps/application-calllog/data/CallLogSwitchData.hpp +7 -5
@@ 1,10 1,10 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// 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 "CalllogRecord.hpp"
#include "SwitchData.hpp"
#include <CalllogRecord.hpp>
#include <SwitchData.hpp>

namespace calllog
{


@@ 18,10 18,12 @@ namespace calllog

      public:
        CallLogSwitchData() = delete;
        CallLogSwitchData(CalllogRecord record) : SwitchData(CALLLOG_SWITCH_DATA_STR), record{record} {};
        explicit CallLogSwitchData(CalllogRecord record)
            : SwitchData(CALLLOG_SWITCH_DATA_STR), record{std::move(record)}
        {}
        virtual ~CallLogSwitchData() = default;

        const CalllogRecord &getRecord() const
        [[nodiscard]] auto getRecord() const noexcept -> const CalllogRecord &
        {
            return record;
        };

M module-apps/application-calllog/windows/CallLogDetailsWindow.cpp => module-apps/application-calllog/windows/CallLogDetailsWindow.cpp +160 -205
@@ 5,38 5,28 @@
#include <memory>
#include <functional>

#include "OptionsWindow.hpp"
#include <OptionsWindow.hpp>
#include <service-appmgr/model/ApplicationManager.hpp>
#include <service-appmgr/Controller.hpp>

#include "bsp/rtc/rtc.hpp"

#include "../ApplicationCallLog.hpp"
#include <application-calllog/ApplicationCallLog.hpp>
#include <application-calllog/data/CallLogInternals.hpp>
#include <application-calllog/data/CallLogSwitchData.hpp>
#include <application-calllog/windows/CallLogOptionsWindow.hpp>
#include <module-utils/time/DateAndTimeSettings.hpp>
#include <widgets/TextWithIconsWidget.hpp>
#include <widgets/ActiveIconFactory.hpp>

#include <i18n/i18n.hpp>

#include "../data/CallLogInternals.hpp" // TODO: alek: add easier paths
#include "../data/CallLogSwitchData.hpp"
#include "../windows/CallLogOptionsWindow.hpp"
#include "Label.hpp"
#include "Margins.hpp"
#include "application-call/ApplicationCall.hpp"
#include <application-call/data/CallSwitchData.hpp>
#include "time/time_conversion.hpp"
#include <time/time_conversion.hpp>
#include <Style.hpp>
#include <cassert>
#include <module-apps/application-messages/data/SMSdata.hpp>

using namespace calllog;
using namespace callLogStyle::detailsWindow;

namespace detailsWindow = callLogStyle::detailsWindow;
namespace gui
{

    CallLogDetailsWindow::CallLogDetailsWindow(app::Application *app)
        : AppWindow(app, calllog::settings::DetailsWindowStr)
    {

        buildInterface();
    }



@@ 46,31 36,85 @@ namespace gui
        buildInterface();
    }

    Label *CallLogDetailsWindow::decorateLabel(Label *label)
    namespace
    {
        if (label == nullptr) {
            LOG_ERROR("label is nullptr");
            return label;
        Rect *decorate(Rect *rect)
        {
            Expects(rect != nullptr);
            rect->setEdges(RectangleEdge::None);
            rect->activeItem = false;
            return rect;
        }

        [[nodiscard]] auto createText(const std::string &text, const UTF8 &font)
        {
            auto textWidget = new gui::Text();
            textWidget->setEdges(RectangleEdge::None);
            textWidget->setMaximumSize(detailsWindow::w, detailsWindow::widget::h);
            textWidget->setMinimumSize(detailsWindow::widget::h, Axis::Y);
            textWidget->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
            textWidget->setFont(font);
            textWidget->setText(text);
            return textWidget;
        }
        style::window::decorate(label);
        label->setFont(style::window::font::small);
        label->setSize(label->widgetArea.w, style::window::label::big_h);
        label->setLineMode(true);

        return label;
        void addSnippetWithText(gui::Item *parent, const UTF8 &image, const std::string &text, const Margins &margins)
        {
            auto textHBox = decorate(new gui::HBox(parent, 0, 0, parent->getWidth(), detailsWindow::widget::h));
            textHBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));

            const auto font  = style::window::font::medium;
            auto imageWidget = new gui::Image(image);
            imageWidget->setMargins(margins);
            textHBox->addWidget(imageWidget);
            textHBox->addWidget(createText(text, font));
            parent->addWidget(new TextWithSnippet(text, font, image));
        }

        void addNextListHeader(gui::Item *parent, const std::string &text)
        {
            parent->addWidget(new TextWithSnippet(text, style::window::font::small));
        }
    } // namespace

    void CallLogDetailsWindow::buildNumberWidget(gui::Item *parent)
    {
        Expects(parent != nullptr);
        addNextListHeader(parent, utils::translate(style::strings::common::information));
        numberHBox = new TextWithIconsWidget(parent);
    }

    Label *CallLogDetailsWindow::decorateData(Label *label)
    void CallLogDetailsWindow::buildCallDataWidget(gui::Item *parent)
    {
        if (label == nullptr) {
            LOG_ERROR("label is nullptr");
            return label;
        }
        style::window::decorate(label);
        label->setFont(style::window::font::medium);
        label->setSize(label->widgetArea.w, style::window::label::small_h);
        Expects(parent != nullptr);
        auto callBox = decorate(
            new gui::VBox(parent, 0, 0, parent->getWidth() / detailsWindow::callData::columns, parent->getHeight()));
        addNextListHeader(callBox, utils::translate("app_calllog_type"));
        typeHBox = new gui::HBox(callBox, 0, 0, callBox->getWidth(), detailsWindow::widget::h);
        typeHBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        decorate(typeHBox);
    }

    void CallLogDetailsWindow::buildCallDurationWidget(gui::Item *parent)
    {
        Expects(parent != nullptr);
        auto durationBox = decorate(
            new gui::VBox(parent, 0, 0, parent->getWidth() / detailsWindow::callData::columns, parent->getHeight()));
        addNextListHeader(durationBox, utils::translate("app_calllog_duration"));
        durationData = createText("", style::window::font::medium);
        durationBox->addWidget(durationData);
    }

        return label;
    void CallLogDetailsWindow::buildDateWidgets(gui::Item *parent)
    {
        Expects(parent != nullptr);
        addNextListHeader(parent, utils::translate("app_calllog_date"));
        auto dateBox = decorate(new gui::VBox(parent, 0, 0, parent->getWidth(), detailsWindow::date::h));
        dateBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
        dateDay  = new Text(dateBox, 0, 0, dateBox->getWidth(), detailsWindow::widget::smallH);
        dateDate = new Text(dateBox, 0, 0, dateBox->getWidth(), detailsWindow::widget::smallH);
        dateDay->setFont(style::window::font::medium);
        dateDate->setFont(style::window::font::medium);
    }

    void CallLogDetailsWindow::buildInterface()


@@ 78,113 122,17 @@ namespace gui
        AppWindow::buildInterface();

        bottomBar->setText(BottomBar::Side::LEFT, utils::translate(style::strings::common::options));
        bottomBar->setText(BottomBar::Side::CENTER, utils::translate(style::strings::common::call));
        bottomBar->setText(BottomBar::Side::RIGHT, utils::translate(style::strings::common::back));

        // NOTE: height of all labels is set using decorators

        // Information
        informationLabel = decorateLabel(new gui::Label(this,
                                                        information::label::x,
                                                        information::label::y,
                                                        information::label::w,
                                                        0,
                                                        utils::translate(style::strings::common::information)));
        number           = decorateData(
            new gui::Label(this, information::number::x, information::number::y, information::number::w, 0));
        number->setFont(style::window::font::mediumbold);

        for (uint32_t i = 0; i < 2; ++i) {
            rects[i] = new gui::Rect(this, 0, 0, information::imgs::w, information::imgs::h);
            rects[i]->setFilled(false);
            rects[i]->setEdges(RectangleEdge::Bottom | RectangleEdge::Top);
            rects[i]->setPenFocusWidth(style::window::default_border_focus_w);
            rects[i]->setPenWidth(style::window::default_border_no_focus_w);
        }
        auto vBox = new VBox(this, detailsWindow::x + 10, detailsWindow::y, detailsWindow::w, detailsWindow::h);
        vBox->setEdges(RectangleEdge::None);
        buildNumberWidget(vBox);

        rects[static_cast<uint32_t>(FocusRects::Call)]->setPosition(information::imgs::call::x, information::imgs::y);
        rects[static_cast<uint32_t>(FocusRects::Sms)]->setPosition(information::imgs::sms::x, information::imgs::y);

        // TODO: alek: phone ringing seems to be to small
        callImg = new gui::Image(rects[FocusRects::Call],
                                 information::imgs::call::icon::x,
                                 information::imgs::call::icon::y,
                                 0,
                                 0,
                                 "phonebook_phone_ringing");
        smsImg  = new gui::Image(
            rects[FocusRects::Sms], information::imgs::sms::icon::x, information::imgs::call::icon::y, 0, 0, "mail");

        // define navigation between labels
        rects[static_cast<uint32_t>(FocusRects::Call)]->setNavigationItem(
            NavigationDirection::LEFT, rects[static_cast<uint32_t>(FocusRects::Sms)]);
        rects[static_cast<uint32_t>(FocusRects::Call)]->setNavigationItem(
            NavigationDirection::RIGHT, rects[static_cast<uint32_t>(FocusRects::Sms)]);

        rects[static_cast<uint32_t>(FocusRects::Sms)]->setNavigationItem(
            NavigationDirection::LEFT, rects[static_cast<uint32_t>(FocusRects::Call)]);
        rects[static_cast<uint32_t>(FocusRects::Sms)]->setNavigationItem(
            NavigationDirection::RIGHT, rects[static_cast<uint32_t>(FocusRects::Call)]);

        // focus callbacks
        rects[static_cast<uint32_t>(FocusRects::Call)]->focusChangedCallback = [=](gui::Item &item) {
            bottomBar->setText(BottomBar::Side::CENTER, utils::translate(style::strings::common::call));
            return true;
        };
        auto callDataDurationBox = decorate(new gui::HBox(vBox, 0, 0, vBox->getWidth(), detailsWindow::callData::h));
        buildCallDataWidget(callDataDurationBox);
        buildCallDurationWidget(callDataDurationBox);

        rects[static_cast<uint32_t>(FocusRects::Sms)]->focusChangedCallback = [=](gui::Item &item) {
            bottomBar->setText(BottomBar::Side::CENTER, utils::translate(style::strings::common::send));
            return true;
        };

        // activated callbacks
        rects[FocusRects::Call]->activatedCallback = [=](gui::Item &item) {
            LOG_INFO("call %s", record.phoneNumber.getE164().c_str());
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::Dial,
                                                        std::make_unique<app::ExecuteCallData>(record.phoneNumber),
                                                        app::manager::OnSwitchBehaviour::RunInBackground);
        };

        rects[FocusRects::Sms]->activatedCallback = [=](gui::Item &item) {
            LOG_INFO("sms %s", record.phoneNumber.getE164().c_str());
            auto data                        = std::make_unique<SMSSendRequest>(record.phoneNumber, std::string{});
            data->ignoreCurrentWindowOnStack = true;
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::CreateSms,
                                                        std::move(data),
                                                        app::manager::OnSwitchBehaviour::RunInBackground);
        };

        // Type
        typeLabel = decorateLabel(new gui::Label(
            this, type::label::x, type::label::y, type::label::w, 0, utils::translate("app_calllog_type")));
        typeData  = decorateData(new gui::Label(this, type::data::x, type::data::y, type::data::w, 0));

        // TODO: alek: it is used in the code at least twice, possibly create one common function for this
        auto newImg = [=](const UTF8 imageName) -> gui::Image * {
            auto img = new gui::Image(this, type::img::x, type::img::y, 0, 0, imageName);
            img->setVisible(false);
            return img;
        };
        callTypeImg[calllog::CallLogCallType::IN]     = newImg("calllog_arrow_in");
        callTypeImg[calllog::CallLogCallType::OUT]    = newImg("calllog_arrow_out");
        callTypeImg[calllog::CallLogCallType::MISSED] = newImg("calllog_arrow_den");

        // Duration
        durationLabel = decorateLabel(new gui::Label(this,
                                                     duration::label::x,
                                                     duration::label::y,
                                                     duration::label::w,
                                                     0,
                                                     utils::translate("app_calllog_duration")));
        durationData  = decorateData(new gui::Label(this, duration::data::x, duration::data::y, duration::data::w, 0));

        // Date
        dateLabel = decorateLabel(new gui::Label(
            this, date::label::x, date::label::y, date::label::w, 0, utils::translate("app_calllog_date")));
        dateDay   = decorateData(new gui::Label(this, date::dataDay::x, date::dataDay::y, date::dataDay::w, 0));
        dateDate  = decorateData(new gui::Label(this, date::dataDate::x, date::dataDate::y, date::dataDate::w, 0));
        buildDateWidgets(vBox);
    }

    void CallLogDetailsWindow::destroyInterface()


@@ 192,82 140,89 @@ namespace gui
        erase();
    }

    CallLogDetailsWindow::~CallLogDetailsWindow()
    void CallLogDetailsWindow::initNumberWidget()
    {
        destroyInterface();
        Expects(numberHBox != nullptr);
        numberHBox->erase();
        ActiveIconFactory factory(this->application);
        const auto &numberView = record.phoneNumber;
        if (record.presentation == PresentationType::PR_UNKNOWN) {
            numberHBox->addText(callLogStyle::strings::privateNumber, style::window::font::mediumbold);
        }
        else {
            numberHBox->addText(numberView.getFormatted(), style::window::font::mediumbold);
            numberHBox->addIcon(factory.makeCallIcon(numberView));
            numberHBox->addIcon(factory.makeSMSIcon(numberView));
            setFocusItem(numberHBox);
        }
    }

    void CallLogDetailsWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    void CallLogDetailsWindow::initCallDataWidget()
    {
        if (data != nullptr && data->getDescription() == calllog::CALLLOG_SWITCH_DATA_STR) {
            auto switchData = reinterpret_cast<calllog::CallLogSwitchData *>(data);
            record          = switchData->getRecord();
        Expects(typeHBox != nullptr);
        typeHBox->erase();
        UTF8 callIconName, callTypeStr;
        switch (record.type) {
        case CallType::CT_INCOMING:
            callTypeStr  = utils::translate("app_calllog_incoming_call");
            callIconName = "calllog_arrow_in";
            break;
        case CallType::CT_OUTGOING:
            callTypeStr  = utils::translate("app_calllog_outgoing_call");
            callIconName = "calllog_arrow_out";
            break;
        case CallType::CT_MISSED:
            callTypeStr  = utils::translate("app_calllog_missed_call");
            callIconName = "calllog_arrow_den";
            break;
        case CallType::CT_REJECTED:
            callTypeStr  = utils::translate("app_calllog_rejected_call");
            callIconName = "calllog_arrow_den";
            break;
        default:
            break;
        }
        addSnippetWithText(
            typeHBox, callIconName, callTypeStr, Margins(style::margins::big, 0, style::margins::big, 0));
    }

            setTitle(record.name);
    void CallLogDetailsWindow::initCallDurationWidget()
    {
        Expects(durationData != nullptr);
        durationData->setText(utils::time::Duration(record.duration).str());
    }

            auto callType = toCallLogCallType(record.type);
            for (auto &img : callTypeImg) {
                img->setVisible(false);
            }
            callTypeImg[callType]->setVisible(true);

            UTF8 callTypeStr;
            switch (record.type) {
            case CallType::CT_INCOMING:
                callTypeStr = utils::translate("app_calllog_incoming_call");
                break;
            case CallType::CT_OUTGOING:
                callTypeStr = utils::translate("app_calllog_outgoing_call");
                break;
            case CallType::CT_MISSED:
                callTypeStr = utils::translate("app_calllog_missed_call");
                break;
            case CallType::CT_REJECTED:
                callTypeStr = utils::translate("app_calllog_rejected_call");
                break;
            default:
                break;
            }
            typeData->setText(callTypeStr);

            durationData->setText(utils::time::Duration(record.duration).str());

            utils::time::Timestamp t(record.date);
            dateDay->setText(t.day() + ",");
            dateDate->setText(t.str(utils::translate("locale_date_full") + ", " +
                                    utils::translate("locale_12hour_min"))); // TODO: alek 12/24 h
        }
    void CallLogDetailsWindow::initDateWidgets()
    {
        Expects(dateDay != nullptr && dateDate != nullptr);
        using utils::time::Locale;
        utils::time::Timestamp t(record.date);
        dateDay->setText(t.day() + ",");

        if (mode == ShowMode::GUI_SHOW_INIT)
            setFocusItem(rects[static_cast<uint32_t>(FocusRects::Call)]);
        auto timeFormat = Locale::format(utils::dateAndTimeSettings.getTimeFormat());
        auto dateFormat = utils::translate("locale_date_full");

        if (record.presentation == PresentationType::PR_UNKNOWN) {
            rects[FocusRects::Call]->setVisible(false);
            rects[FocusRects::Call]->activatedCallback    = nullptr;
            rects[FocusRects::Call]->focusChangedCallback = nullptr;
            rects[FocusRects::Sms]->setVisible(false);
            rects[FocusRects::Sms]->activatedCallback    = nullptr;
            rects[FocusRects::Sms]->focusChangedCallback = nullptr;
            number->setText(utils::translate(callLogStyle::strings::privateNumber));
            bottomBar->setActive(BottomBar::Side::CENTER, false);
        }
        else {
            number->setText(record.phoneNumber.getFormatted());
        }
        dateDate->setText(t.str(dateFormat + ", " + timeFormat));
    }

    bool CallLogDetailsWindow::onInput(const InputEvent &inputEvent)
    void CallLogDetailsWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        // check if any of the lower inheritance onInput methods catch the event
        if (AppWindow::onInput(inputEvent)) {
            // refresh window only when key is other than enter
            if (!inputEvent.is(KeyCode::KEY_ENTER)) {
                application->render(RefreshModes::GUI_REFRESH_FAST);
            }
        if (mode == ShowMode::GUI_SHOW_RETURN) {
            return;
        }

            return true;
        if (auto switchData = dynamic_cast<calllog::CallLogSwitchData *>(data); data != nullptr) {
            record = switchData->getRecord();
            setTitle(record.name);
            initNumberWidget();
            initCallDataWidget();
            initCallDurationWidget();
            initDateWidgets();
        }
    }

    bool CallLogDetailsWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_LF)) {
            auto app = dynamic_cast<app::ApplicationCallLog *>(application);
            assert(app != nullptr);


@@ 276,8 231,8 @@ namespace gui

            return true;
        }

        return false;
        // check if any of the lower inheritance onInput methods catch the event
        return AppWindow::onInput(inputEvent);
    }

} /* namespace gui */

M module-apps/application-calllog/windows/CallLogDetailsWindow.hpp => module-apps/application-calllog/windows/CallLogDetailsWindow.hpp +20 -36
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 6,52 6,36 @@
#include <string>
#include <functional>

#include "AppWindow.hpp"
#include "gui/widgets/Text.hpp"
#include "gui/widgets/Label.hpp"
#include "gui/widgets/Image.hpp"
#include "gui/widgets/Window.hpp"
#include "gui/widgets/BottomBar.hpp"
#include "gui/widgets/ListView.hpp"

#include "../data/CallLogInternals.hpp"
#include <AppWindow.hpp>
#include <Text.hpp>
#include <CalllogRecord.hpp>

namespace gui
{
    class TextWithIconsWidget;

    class CallLogDetailsWindow : public AppWindow
    {

        enum FocusRects
        {
            Call,
            Sms,
            NumOfRects
        };

        Label *informationLabel                                                                     = nullptr;
        Label *number                                                                               = nullptr;
        gui::Rect *rects[static_cast<uint32_t>(FocusRects::NumOfRects)]                             = {nullptr};
        Image *callImg                                                                              = nullptr;
        Image *smsImg                                                                               = nullptr;
        gui::Image *callTypeImg[static_cast<uint32_t>(calllog::CallLogCallType::NUM_OF_CALL_TYPES)] = {
            nullptr, nullptr, nullptr};
        Label *typeLabel     = nullptr;
        Label *durationLabel = nullptr;
        Label *typeData      = nullptr;
        Label *durationData  = nullptr;
        Label *dateLabel     = nullptr;
        Label *dateDay       = nullptr;
        Label *dateDate      = nullptr;
        gui::TextWithIconsWidget *numberHBox = nullptr;
        Text *durationData                   = nullptr;
        Text *dateDay                        = nullptr;
        Text *dateDate                       = nullptr;
        gui::HBox *typeHBox                  = nullptr;

        CalllogRecord record;

        Label *decorateLabel(Label *);
        Label *decorateData(Label *);
        void buildNumberWidget(gui::Item *parent);
        void buildCallDataWidget(gui::Item *parent);
        void buildCallDurationWidget(gui::Item *parent);
        void buildDateWidgets(gui::Item *parent);

        void initNumberWidget();
        void initCallDataWidget();
        void initCallDurationWidget();
        void initDateWidgets();

      public:
        CallLogDetailsWindow(app::Application *app);
        virtual ~CallLogDetailsWindow();
        explicit CallLogDetailsWindow(app::Application *app);

        // virtual methods
        bool onInput(const InputEvent &inputEvent) override;

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +1 -2
@@ 207,8 207,7 @@ namespace app
    {
        if (auto window = getCurrentWindow()->getName();
            window == app::window::name::desktop_main_window || window == gui::popup::window::phone_lock_window) {

            updateWindow(window, std::move(notificationsParams));
            switchWindow(window, std::move(notificationsParams));
        }
    }


M module-apps/notifications/NotificationData.hpp => module-apps/notifications/NotificationData.hpp +0 -1
@@ 12,7 12,6 @@ namespace notifications
{
    enum class NotificationType
    {
        Unknown,
        NotSeenSms,
        NotSeenCall,
        Tethering

M module-apps/notifications/NotificationListItem.cpp => module-apps/notifications/NotificationListItem.cpp +2 -3
@@ 83,9 83,8 @@ namespace
    }

    std::map<notifications::NotificationType, UTF8> typeToIcon{
        {notifications::NotificationType::Unknown, "phone"},
        {notifications::NotificationType::NotSeenSms, "mail"},
        {notifications::NotificationType::NotSeenCall, "phone"},
        {notifications::NotificationType::NotSeenSms, "messages_notification_icon"},
        {notifications::NotificationType::NotSeenCall, "calls_notification_icon"},
        {notifications::NotificationType::Tethering, "tethering_notification_icon"}};
} // namespace


M module-apps/notifications/NotificationListItem.hpp => module-apps/notifications/NotificationListItem.hpp +1 -1
@@ 19,7 19,7 @@ namespace gui
    class NotificationListItem : public ListItem
    {
        using NotificationType      = notifications::NotificationType;
        const NotificationType type = NotificationType::Unknown;
        const NotificationType type = NotificationType::NotSeenSms;
        bool dismissible            = false;

      protected:

M module-apps/widgets/ActiveIconFactory.cpp => module-apps/widgets/ActiveIconFactory.cpp +1 -1
@@ 41,7 41,7 @@ auto ActiveIconFactory::makeCustomIcon(const UTF8 &image,
auto ActiveIconFactory::makeSMSIcon(const utils::PhoneNumber::View &number) -> ImageBox *
{
    return makeCustomIcon(
        "mail",
        "messages_notification_icon",
        [application = app, number](gui::Item &item) {
            auto data                        = std::make_unique<SMSSendRequest>(number, std::string{});
            data->ignoreCurrentWindowOnStack = true;

M module-apps/widgets/TextWithIconsWidget.cpp => module-apps/widgets/TextWithIconsWidget.cpp +38 -11
@@ 5,7 5,7 @@
#include <Style.hpp>
#include <TextFixedSize.hpp>
#include <Image.hpp>
#include "Application.hpp"
#include <Application.hpp>

using namespace gui;



@@ 25,16 25,43 @@ void TextWithIconsWidget::addIcon(ImageBox *icon)
    icons.push_back(icon);
}

namespace
{
    [[nodiscard]] auto createText(const std::string &text, const UTF8 &font)
    {
        auto textFixedSize = new TextFixedSize(nullptr, 0, 0, 0, 0);
        textFixedSize->setUnderline(false);
        textFixedSize->setMaximumSize(style::window::default_body_width, style::widgets::h);
        textFixedSize->setFont(font);
        textFixedSize->setEdges(gui::RectangleEdge::None);
        textFixedSize->setEditMode(EditMode::Browse);
        textFixedSize->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        textFixedSize->setMargins(Margins(style::widgets::leftMargin, 0, 0, 0));
        textFixedSize->setText(text);
        textFixedSize->activeItem = false;
        return textFixedSize;
    }

    [[nodiscard]] auto createSnippet(const UTF8 &snippetName)
    {
        auto snippet = new gui::Image(snippetName);
        snippet->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        snippet->activeItem = false;
        return snippet;
    }
} // namespace

void TextWithIconsWidget::addText(const std::string &text, const UTF8 &font)
{
    auto numberText = new TextFixedSize(this, 0, 0, 0, 0);
    numberText->setUnderline(false);
    numberText->setMaximumSize(style::window::default_body_width, style::widgets::h);
    numberText->setFont(font);
    numberText->setEdges(gui::RectangleEdge::None);
    numberText->setEditMode(EditMode::Browse);
    numberText->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
    numberText->setMargins(Margins(style::widgets::leftMargin, 0, 0, 0));
    numberText->setRichText(text);
    numberText->activeItem = false;
    addWidget(createText(text, font));
}

TextWithSnippet::TextWithSnippet(const std::string &text, const UTF8 &font, const UTF8 &snippet)
{
    setMinimumSize(style::window::default_body_width, style::widgets::h);
    setEdges(gui::RectangleEdge::None);
    setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));

    addWidget(createSnippet(snippet));
    addWidget(createText(text, font));
}

M module-apps/widgets/TextWithIconsWidget.hpp => module-apps/widgets/TextWithIconsWidget.hpp +8 -0
@@ 26,4 26,12 @@ namespace gui
        std::vector<ImageBox *> icons;
    };

    class TextWithSnippet : public HBox
    {
        constexpr static auto defaultSnippet = "Rectangle";

      public:
        TextWithSnippet(const std::string &text, const UTF8 &font, const UTF8 &snippet = defaultSnippet);
    };

} /* namespace gui */