~aleteoryx/muditaos

9b339ecf5b451e5178297008ca96fed28759c23f — Lefucjusz 2 years ago faa48e5
[MOS-1003] Fix automatically marking new message as read

Fix of the issue that after entering messages
app, opening one of the threads and returning
to main messages app window, new messages in
this thread were automatically marked as read.
M module-apps/application-messages/models/SMSThreadModel.cpp => module-apps/application-messages/models/SMSThreadModel.cpp +2 -3
@@ 53,7 53,7 @@ unsigned int SMSThreadModel::requestRecordsCount()
    return recordsCount;
}

void SMSThreadModel::requestRecords(uint32_t offset, uint32_t limit)
void SMSThreadModel::requestRecords(std::uint32_t offset, std::uint32_t limit)
{
    auto query = std::make_unique<db::query::SMSGetForList>(smsThreadID, offset, limit, numberID);
    auto task  = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::SMS);


@@ 80,8 80,6 @@ auto SMSThreadModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
        // Additional one element for SMSInputWidget.
        recordsCount = msgResponse->getCount() + 1;
        list->reSendLastRebuildRequest();

        markCurrentThreadAsRead();
        return false;
    }



@@ 129,6 127,7 @@ void SMSThreadModel::resetInputWidget()
    smsInput->clearNavigationItem(gui::NavigationDirection::UP);
    smsInput->clearNavigationItem(gui::NavigationDirection::DOWN);
}

void SMSThreadModel::markCurrentThreadAsRead()
{
    const auto [code, msg] = DBServiceAPI::GetQueryWithReply(application,

M module-apps/application-messages/models/SMSThreadModel.hpp => module-apps/application-messages/models/SMSThreadModel.hpp +1 -1
@@ 32,7 32,7 @@ class SMSThreadModel : public app::DatabaseModel<SMSRecord>,

    unsigned int requestRecordsCount() override;
    bool updateRecords(std::vector<SMSRecord> records) override;
    void requestRecords(uint32_t offset, uint32_t limit) override;
    void requestRecords(std::uint32_t offset, std::uint32_t limit) override;
    unsigned int getMinimalItemSpaceRequired() const override;
    gui::ListItem *getItem(gui::Order order) override;
};

M module-apps/application-messages/windows/SMSThreadViewWindow.cpp => module-apps/application-messages/windows/SMSThreadViewWindow.cpp +27 -24
@@ 15,11 15,8 @@
#include <Style.hpp>
#include <TextBubble.hpp>

#include <cassert>

namespace gui
{

    SMSThreadViewWindow::SMSThreadViewWindow(app::ApplicationCommon *app)
        : AppWindow(app, name::window::thread_view), app::AsyncCallbackReceiver{app},
          smsModel{std::make_shared<SMSThreadModel>(app)}


@@ 62,24 59,23 @@ namespace gui
    void SMSThreadViewWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        if (mode == ShowMode::GUI_SHOW_RETURN) {
            smsModel->markCurrentThreadAsRead();
            smsList->rebuildList();
        }

        if (auto pdata = dynamic_cast<SMSThreadData *>(data); pdata) {
        if (const auto pdata = dynamic_cast<SMSThreadData *>(data); pdata != nullptr) {
            LOG_INFO("Thread data received: %" PRIu32, pdata->thread->ID);
            saveInfoAboutPreviousAppForProperSwitchBack(data);
            requestContact(pdata->thread->numberID);

            // Mark thread as Read
            if (pdata->thread->isUnread()) {
                auto app = dynamic_cast<app::ApplicationMessages *>(application);
                assert(app != nullptr);
                if (application->getCurrentWindow() == this) {
                    app->markSmsThreadAsRead(pdata->thread.get());
                }
            }

            smsModel->numberID    = pdata->thread->numberID;
            smsModel->smsThreadID = pdata->thread->ID;
            requestContact(smsModel->numberID);

            // Mark thread as read
            if (pdata->thread->isUnread() && (this == application->getCurrentWindow())) {
                smsModel->markCurrentThreadAsRead();
            }

            smsList->rebuildList();
        }
        else if (smsModel->numberID != DB_ID_NONE) {


@@ 125,20 121,27 @@ namespace gui
    bool SMSThreadViewWindow::onDatabaseMessage(sys::Message *msgl)
    {
        const auto msg = dynamic_cast<db::NotificationMessage *>(msgl);
        if (msg != nullptr) {
            if ((msg->interface == db::Interface::Name::SMS) && msg->dataModified()) {
                rebuild();
                return true;
            }
            if ((msg->interface == db::Interface::Name::SMSThread) && (msg->type == db::Query::Type::Delete) &&
                (this == application->getCurrentWindow())) {
        if (msg == nullptr) {
            return false;
        }

        if ((msg->interface == db::Interface::Name::SMS) && msg->dataModified()) {
            rebuild();
            return true;
        }

        if ((msg->interface == db::Interface::Name::SMSThread) && (this == application->getCurrentWindow())) {
            if (msg->type == db::Query::Type::Delete) {
                application->switchWindow(gui::name::window::main_window);
            }
            else {
                smsModel->markCurrentThreadAsRead();
            }
        }
        return false;
    }

    auto SMSThreadViewWindow::requestContact(unsigned int numberID) -> void
    void SMSThreadViewWindow::requestContact(unsigned int numberID)
    {
        auto query = std::make_unique<db::query::ContactGetByNumberID>(numberID);
        auto task  = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact);


@@ 152,7 155,7 @@ namespace gui
        task->execute(application, this);
    }

    auto SMSThreadViewWindow::handleContactQueryResponse(db::QueryResult *queryResult) -> bool
    bool SMSThreadViewWindow::handleContactQueryResponse(db::QueryResult *queryResult)
    {
        auto msgResponse = dynamic_cast<db::query::ContactGetByNumberIDResult *>(queryResult);
        if (msgResponse == nullptr) {


@@ 173,7 176,7 @@ namespace gui
        task->execute(application, this);
    }

    auto SMSThreadViewWindow::handleNumberQueryResponse(db::QueryResult *queryResult) -> bool
    bool SMSThreadViewWindow::handleNumberQueryResponse(db::QueryResult *queryResult)
    {
        auto msgResponse = dynamic_cast<db::query::NumberGetByIDResult *>(queryResult);
        if (msgResponse == nullptr) {

M module-apps/application-messages/windows/SMSThreadViewWindow.hpp => module-apps/application-messages/windows/SMSThreadViewWindow.hpp +3 -3
@@ 22,10 22,10 @@ namespace gui
        std::shared_ptr<SMSThreadModel> smsModel;
        gui::ListView *smsList = nullptr;

        auto requestContact(unsigned int numberID) -> void;
        auto handleContactQueryResponse(db::QueryResult *) -> bool;
        void requestContact(unsigned int numberID);
        bool handleContactQueryResponse(db::QueryResult *);
        void requestNumber(unsigned int numberID);
        auto handleNumberQueryResponse(db::QueryResult *) -> bool;
        bool handleNumberQueryResponse(db::QueryResult *);

      public:
        explicit SMSThreadViewWindow(app::ApplicationCommon *app);

M module-db/Interface/ThreadRecord.hpp => module-db/Interface/ThreadRecord.hpp +13 -13
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, 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


@@ 13,14 13,15 @@
#include <utf8/UTF8.hpp>

#include <cstdint>

struct ThreadRecord : Record
{
    uint32_t date           = 0;
    uint32_t msgCount       = 0;
    uint32_t unreadMsgCount = 0;
    std::uint32_t date           = 0;
    std::uint32_t msgCount       = 0;
    std::uint32_t unreadMsgCount = 0;
    UTF8 snippet;
    SMSType type      = SMSType::UNKNOWN;
    uint32_t numberID = DB_ID_NONE;
    std::uint32_t numberID = DB_ID_NONE;

    ThreadRecord() = default;
    ThreadRecord(const ThreadsTableRow &rec)


@@ 47,19 48,18 @@ class ThreadRecordInterface : public RecordInterface<ThreadRecord, ThreadRecordF
    ~ThreadRecordInterface() = default;

    bool Add(const ThreadRecord &rec) override final;
    bool RemoveByID(uint32_t id) override final;
    bool RemoveByID(std::uint32_t id) override final;
    bool Update(const ThreadRecord &rec) override final;
    ThreadRecord GetByID(uint32_t id) override final;
    ThreadRecord GetByContact(uint32_t contact_id);
    ThreadRecord GetByID(std::uint32_t id) override final;
    ThreadRecord GetByNumber(const utils::PhoneNumber::View &phoneNumber);

    uint32_t GetCount() override final;
    uint32_t GetCount(EntryState state);
    std::uint32_t GetCount() override final;
    std::uint32_t GetCount(EntryState state);

    std::unique_ptr<std::vector<ThreadRecord>> GetLimitOffset(uint32_t offset, uint32_t limit) override final;
    std::unique_ptr<std::vector<ThreadRecord>> GetLimitOffset(std::uint32_t offset, std::uint32_t limit) override final;

    std::unique_ptr<std::vector<ThreadRecord>> GetLimitOffsetByField(uint32_t offset,
                                                                     uint32_t limit,
    std::unique_ptr<std::vector<ThreadRecord>> GetLimitOffsetByField(std::uint32_t offset,
                                                                     std::uint32_t limit,
                                                                     ThreadRecordField field,
                                                                     const char *str) override final;