~aleteoryx/muditaos

ref: 196c02686ae5b344e6814800b7cb8aa2473f15ea muditaos/module-apps/application-messages/models/SMSThreadModel.cpp -rw-r--r-- 3.8 KiB
196c0268 — Przemyslaw Brudny [EGD-2395] Added BottomTop orientation support for listView. Created SMSThreadViewWindow and SMSOutputWidget. MessagesStyle moved from global Style.hpp. Fixes in Text. ListView fixes, BoxLayout callback for requestedSize. Added smsInput into list. Drafts handling added. 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <module-services/service-db/messages/QueryMessage.hpp>
#include <module-services/service-db/api/DBServiceAPI.hpp>
#include <module-db/queries/messages/sms/QuerySMSGetCountByThreadID.hpp>
#include <module-db/queries/messages/sms/QuerySMSGetForList.hpp>

#include <application-messages/widgets/SMSOutputWidget.hpp>
#include <module-apps/application-messages/ApplicationMessages.hpp>
#include "application-messages/data/MessagesStyle.hpp"
#include "SMSThreadModel.hpp"
#include "ListView.hpp"

SMSThreadModel::SMSThreadModel(app::Application *app) : DatabaseModel(app)
{
    smsInput = new gui::SMSInputWidget(application);
}

SMSThreadModel::~SMSThreadModel()
{
    delete smsInput;
}

unsigned int SMSThreadModel::getMinimalItemHeight() const
{
    return style::messages::smsOutput::default_h;
}

gui::ListItem *SMSThreadModel::getItem(gui::Order order)
{
    std::shared_ptr<SMSRecord> sms = getRecord(order);

    if (sms == nullptr) {
        return nullptr;
    }

    // Small hack to trick current model logic -> adding empty row into query result for Input Widget
    if (sms->type == SMSType::INPUT) {
        addReturnNumber();
        return smsInput;
    }

    return new gui::SMSOutputWidget(application, sms);
}

unsigned int SMSThreadModel::requestRecordsCount()
{
    return recordsCount;
}

void SMSThreadModel::requestRecords(uint32_t offset, uint32_t limit)
{
    auto query = std::make_unique<db::query::SMSGetForList>(smsThreadID, offset, limit);
    query->setQueryListener(
        db::QueryCallback::fromFunction([this](auto response) { return handleQueryResponse(response); }));
    DBServiceAPI::GetQuery(application, db::Interface::Name::SMS, std::move(query));
}

bool SMSThreadModel::updateRecords(std::unique_ptr<std::vector<SMSRecord>> records)
{
    DatabaseModel::updateRecords(std::move(records));
    list->onProviderDataUpdate();
    return true;
}

auto SMSThreadModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
{
    auto msgResponse = dynamic_cast<db::query::SMSGetForListResult *>(queryResult);
    assert(msgResponse != nullptr);

    auto records_data = msgResponse->getResults();

    // If list record count has changed we need to rebuild list.
    if (recordsCount != (msgResponse->getCount() + 1)) {
        // Additional one element for SMSInputWidget.
        recordsCount = msgResponse->getCount() + 1;
        list->rebuildList(style::listview::RebuildType::Full, 0, true);
        return false;
    }

    resetInputWidget();

    if (msgResponse->getDraft().isValid()) {
        smsInput->draft = msgResponse->getDraft().type == SMSType::DRAFT
                              ? std::optional<SMSRecord>{msgResponse->getDraft()}
                              : std::nullopt;
        smsInput->displayDraftMessage();
    }

    auto records = std::make_unique<std::vector<SMSRecord>>(records_data.begin(), records_data.end());

    return this->updateRecords(std::move(records));
}

void SMSThreadModel::addReturnNumber()
{
    if (number != nullptr) {
        smsInput->number = std::move(number);
    }

    smsInput->activatedCallback = [this]([[maybe_unused]] gui::Item &item) {
        auto app = dynamic_cast<app::ApplicationMessages *>(application);
        assert(app != nullptr);
        assert(smsInput->number != nullptr);
        if (app->handleSendSmsFromThread(*smsInput->number, smsInput->inputText->getText())) {
            LOG_ERROR("handleSendSmsFromThread failed");
        }
        smsInput->inputText->clear();
        smsInput->clearDraftMessage();
        return true;
    };
}

void SMSThreadModel::handleDraftMessage()
{
    smsInput->handleDraftMessage();
}

void SMSThreadModel::resetInputWidget()
{
    smsInput->setFocus(false);
    smsInput->setVisible(true);
    smsInput->clearNavigationItem(gui::NavigationDirection::UP);
    smsInput->clearNavigationItem(gui::NavigationDirection::DOWN);
}