~aleteoryx/muditaos

d9612efe7a702e82d3b9540d348fd7772a428575 — mkamonMdt 5 years ago 103af76
[EGD-4338] Fix menu notification dot

Each tile in Menu that uses notification dot
is be refreshed. It also solves missing dot
issue of EGD-4129 and lack of sound notification
on incoming text message.
M changelog.md => changelog.md +1 -0
@@ 22,6 22,7 @@

### Fixed

* Fix menu notification dot
* Fix absent notifications
* Fix newly added contact recognized as a duplicate of temporary contact.
* Fix default borderCallback navigation in GridLayout.

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +5 -2
@@ 203,7 203,11 @@ namespace app
             msg->interface == db::Interface::Name::SMS) &&
            msg->type != db::Query::Type::Read) {
            requestNotReadNotifications();
            windowsFactory.build(this, app::window::name::desktop_menu);
            if (auto menuWindow = dynamic_cast<gui::MenuWindow *>(getWindow(app::window::name::desktop_menu));
                menuWindow != nullptr) {
                menuWindow->refresh();
                return true;
            }
        }

        return false;


@@ 266,7 270,6 @@ namespace app
    {
        notifications.notRead.Calls = DBServiceAPI::CalllogGetCount(this, EntryState::UNREAD);
        notifications.notRead.SMS   = DBServiceAPI::ThreadGetCount(this, EntryState::UNREAD);

        return true;
    }


M module-apps/application-desktop/windows/MenuWindow.cpp => module-apps/application-desktop/windows/MenuWindow.cpp +71 -20
@@ 24,16 24,33 @@ namespace style::design
    inline const auto notify_dot_x = 80;
    inline const auto notify_dot_y = (64 - 50) / 2;
    inline const auto grid_offset  = 20;
}; // namespace style::design
} // namespace style::design

namespace
{
    static constexpr auto deepRefreshDot = "dot_12px_hard_alpha_W_G";
    static constexpr auto fastRefreshDot = "dot_12px_hard_alpha_W_M";

    gui::Image *buildThumbnail(gui::RefreshModes mode)
    {
        gui::Image *thumbnail =
            new gui::Image(mode == gui::RefreshModes::GUI_REFRESH_DEEP ? deepRefreshDot : fastRefreshDot);
        thumbnail->setPosition(style::design::notify_dot_x, style::design::notify_dot_y);
        return thumbnail;
    }
} // namespace

namespace gui
{
    inline const auto APP_SETTINGS_NEW = "ApplicationSettingsNew";
    Tile::Tile(UTF8 icon, std::string title, std::function<bool(Item &)> activatedCallback, unsigned int notifications)
    Tile::Tile(UTF8 icon,
               std::string title,
               std::function<bool(Item &)> activatedCallback,
               std::function<bool()> hasNotificationsCallback)
    {
        setSize(style::design::tile_w, style::design::tile_h);

        auto *it = new gui::Item();
        auto it = new gui::Item();
        it->setSize(style::design::tile_w, style::design::tile_h - 2 * style::design::tile_margin);
        it->setPosition(area().x, area().y + style::design::tile_margin);



@@ 48,10 65,21 @@ namespace gui
        desc->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Bottom));
        desc->setText(utils::localize.get(title));

        if (notifications > 0) {
            auto thumbnail = new gui::Image("dot_12px_hard_alpha_W_G");
            thumbnail->setPosition(style::design::notify_dot_x, style::design::notify_dot_y);
            it->addWidget(thumbnail);
        if (hasNotificationsCallback != nullptr) {
            onNotificationsChangeCallback =
                [this, it, hasNotifications = std::move(hasNotificationsCallback)](gui::RefreshModes mode) -> bool {
                if (hasNotifications() && notificationThumbnail == nullptr) {
                    notificationThumbnail = buildThumbnail(mode);
                    it->addWidget(notificationThumbnail);
                    return true;
                }
                else if (!hasNotifications() && notificationThumbnail != nullptr) {
                    it->erase(notificationThumbnail);
                    notificationThumbnail = nullptr;
                }
                return false;
            };
            onNotificationsChangeCallback(gui::RefreshModes::GUI_REFRESH_DEEP);
        }

        this->activatedCallback = activatedCallback;


@@ 59,9 87,16 @@ namespace gui
        this->setPenFocusWidth(style::window::default_border_focus_w);
        this->setEdges(RectangleEdge::Top | RectangleEdge::Bottom);
        addWidget(it);
    };
    }
    bool Tile::onNotificationsChange(gui::RefreshModes mode)
    {
        if (onNotificationsChangeCallback != nullptr) {
            return onNotificationsChangeCallback(mode);
        }
        return false;
    }

    MenuPage::MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles) : title(title)
    MenuPage::MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles) : title(std::move(title))
    {
        if (parent) {
            parent->addWidget(this);


@@ 83,6 118,17 @@ namespace gui
        }
    }

    bool MenuPage::refresh(gui::RefreshModes mode)
    {
        bool visibleStateChanged = false;
        for (auto child : children) {
            if (auto tile = dynamic_cast<Tile *>(child); tile != nullptr) {
                visibleStateChanged |= tile->onNotificationsChange(mode);
            }
        }
        return visibleStateChanged;
    }

    MenuWindow::MenuWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_menu)
    {
        buildInterface();


@@ 150,7 196,8 @@ namespace gui
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationCallLog"));
                              },
                              app->notifications.notRead.Calls},
                              [=]() { return app->notifications.notRead.Calls > 0; }},

                new gui::Tile("menu_contacts_W_G",
                              "app_desktop_menu_contacts",
                              [=](gui::Item &item) {


@@ 168,7 215,7 @@ namespace gui
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationMessages"));
                              },
                              app->notifications.notRead.SMS},
                              [=]() { return app->notifications.notRead.SMS > 0; }},
                new gui::Tile{"menu_music_player_W_G",
                              "app_desktop_menu_music",
                              [=](gui::Item &item) {


@@ 185,15 232,12 @@ namespace gui
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationMeditation"));
                              }},
                new gui::Tile{"menu_settings_W_G",
                              "app_desktop_menu_settings_new",
                              [=](gui::Item &item) {
                new gui::Tile{"menu_settings_W_G", "app_desktop_menu_settings_new", [=](gui::Item &item) {
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>(APP_SETTINGS_NEW));
                              }},
            });
                              }}});

        toolsMenu = new MenuPage(
            this,


@@ 254,9 298,6 @@ namespace gui
        toolsMenu = nullptr;
    }

    void MenuWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {}

    bool MenuWindow::onInput(const InputEvent &inputEvent)
    {
        if ((inputEvent.state == InputEvent::State::keyReleasedShort) && (inputEvent.keyCode == KeyCode::KEY_RF) &&


@@ 278,7 319,17 @@ namespace gui

        setTitle(page->title);
        setFocusItem(page);
        application->refreshWindow(gui::RefreshModes::GUI_REFRESH_DEEP);
    }

    void MenuWindow::refresh()
    {
        if (application->getCurrentWindow() == this) {
            if (mainMenu->refresh(RefreshModes::GUI_REFRESH_FAST)) {
                application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
            }
        }
        else {
            mainMenu->refresh(RefreshModes::GUI_REFRESH_DEEP);
        }
    }
} /* namespace gui */

M module-apps/application-desktop/windows/MenuWindow.hpp => module-apps/application-desktop/windows/MenuWindow.hpp +9 -2
@@ 22,7 22,13 @@ namespace gui
        Tile(UTF8 icon,
             std::string title,
             std::function<bool(Item &)> activatedCallback,
             unsigned int notifications = 0);
             std::function<bool()> hasNotificationsCallback = nullptr);

        bool onNotificationsChange(gui::RefreshModes);

      private:
        std::function<bool(gui::RefreshModes)> onNotificationsChangeCallback = nullptr;
        gui::Image *notificationThumbnail                                    = nullptr;
    };

    class MenuPage : public gui::GridLayout


@@ 36,6 42,7 @@ namespace gui
        MenuPage(gui::Item *parent, UTF8 title, std::vector<Tile *> tiles);
        /// set child which should be selected on start of desktop
        void setFirstTimeSelection();
        bool refresh(gui::RefreshModes mode);
    };

    class MenuWindow : public AppWindow


@@ 48,7 55,6 @@ namespace gui
      public:
        MenuWindow(app::Application *app);

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

        void rebuild() override;


@@ 56,6 62,7 @@ namespace gui
        void destroyInterface() override;

        void switchMenu(MenuPage *page);
        void refresh();

      private:
        void invalidate() noexcept;

M module-gui/gui/widgets/Item.cpp => module-gui/gui/widgets/Item.cpp +0 -5
@@ 515,11 515,6 @@ namespace gui
        return false;
    }

    bool Item::onContent()
    {
        return false;
    }

    auto Item::onTimer(Timer &timer) -> bool
    {
        if (timerCallback != nullptr) {

M module-gui/gui/widgets/Item.hpp => module-gui/gui/widgets/Item.hpp +0 -7
@@ 139,9 139,6 @@ namespace gui
        /// @param `this` item
        /// @param `InputEvent`
        std::function<bool(Item &, const InputEvent &inputEvent)> inputCallback;
        /// callback when element insides are changed
        /// @param `this` item
        std::function<bool(Item &)> contentCallback;
        /// callback when timer is called on Item and onTimer is executed
        /// @param `this` item
        /// @param `timer` which triggered this callback


@@ 183,10 180,6 @@ namespace gui
        /// calls: none, inconsistent api
        /// @note TODO should be fixed so that api would be consistent
        virtual bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim);
        /// (should be) called each time content in item was changed, added for gui::Text widget
        /// calls: none, inconsistent behaviour
        /// @note TODO should be fixed so that api would be consistent
        virtual bool onContent();
        /// called on Timer event in application, triggeres timerCallback
        /// @param timer timer element which triggered this action
        virtual bool onTimer(Timer &timer);

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +3 -0
@@ 1044,6 1044,9 @@ sys::MessagePointer ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl,
            if (auto response = dynamic_cast<db::query::SMSSearchByTypeResult *>(result.get())) {
                responseHandled = handle(response);
            }
            else if (result->hasListener()) {
                responseHandled = result->handle();
            }
        }
        if (responseHandled) {
            return std::make_shared<sys::ResponseMessage>();