Files
MuditaOS/module-apps/application-phonebook/models/PhonebookModel.cpp
Lefucjusz d90576e4e6 [MOS-972] Fixed missing contact entries when scrolling phonebook
Fix of the issue that in some cases contact entry
would not be displayed on any page in case it
was on the boundary of two pages.
2023-07-21 13:31:45 +02:00

183 lines
5.9 KiB
C++

// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <application-phonebook/ApplicationPhonebook.hpp>
#include <application-phonebook/windows/PhonebookContactDetails.hpp>
#include <AsyncTask.hpp>
#include "ListView.hpp"
#include "PhonebookModel.hpp"
#include <Common/Query.hpp>
#include <queries/phonebook/QueryContactGet.hpp>
#include <queries/RecordQuery.hpp>
#include <service-db/QueryMessage.hpp>
#include <service-db/DBServiceAPI.hpp>
#include <service-appmgr/Controller.hpp>
#include <application-call/data/CallSwitchData.hpp>
#include <string>
#include <utility>
namespace
{
constexpr auto phonebookModelTimeout = 1000;
}
PhonebookModel::PhonebookModel(app::ApplicationCommon *app) : DatabaseModel(app), app::AsyncCallbackReceiver{app}
{}
auto PhonebookModel::requestRecordsCount() -> unsigned int
{
auto dispMode = static_cast<ContactDisplayMode>(getDisplayMode());
if (dispMode == ContactDisplayMode::SortedByLetter) {
letterMap = requestLetterMap();
recordsCount = letterMap.itemCount;
return recordsCount;
}
auto [code, msg] = DBServiceAPI::GetQueryWithReply(
application,
db::Interface::Name::Contact,
std::make_unique<db::query::ContactGetSize>(queryFilter, queryGroupFilter, queryDisplayMode),
phonebookModelTimeout);
if (code == sys::ReturnCodes::Success && msg != nullptr) {
auto queryResponse = dynamic_cast<db::QueryResponse *>(msg.get());
assert(queryResponse != nullptr);
auto countResultResponse = queryResponse->getResult();
auto countResult = dynamic_cast<db::query::RecordsSizeQueryResult *>(countResultResponse.get());
assert(countResult != nullptr);
recordsCount = countResult->getSize();
}
return recordsCount;
}
void PhonebookModel::requestRecords(const std::uint32_t offset, const std::uint32_t limit)
{
auto query =
std::make_unique<db::query::ContactGet>(limit, offset, queryFilter, queryGroupFilter, queryDisplayMode);
auto task = app::AsyncQuery::createFromQuery(std::move(query), db::Interface::Name::Contact);
task->setCallback([this](auto response) { return handleQueryResponse(response); });
task->execute(application, this);
}
auto PhonebookModel::requestLetterMap() -> ContactsMapData
{
auto [code, msg] = DBServiceAPI::GetQueryWithReply(
application,
db::Interface::Name::Contact,
std::make_unique<db::query::ContactGetLetterMap>(queryFilter, queryGroupFilter, queryDisplayMode),
phonebookModelTimeout);
ContactsMapData contactMapData;
if (code == sys::ReturnCodes::Success && msg != nullptr) {
auto queryResponse = dynamic_cast<db::QueryResponse *>(msg.get());
if (queryResponse != nullptr) {
auto letterMapResultResponse = queryResponse->getResult();
auto letterMapResult = dynamic_cast<db::query::LetterMapResult *>(letterMapResultResponse.get());
if (letterMapResult != nullptr) {
contactMapData = letterMapResult->getLetterMap();
}
}
}
return contactMapData;
}
auto PhonebookModel::updateRecords(std::vector<ContactRecord> records) -> bool
{
DatabaseModel::updateRecords(std::move(records));
list->onProviderDataUpdate();
return true;
}
auto PhonebookModel::getMinimalItemSpaceRequired() const -> unsigned int
{
return phonebookStyle::contactItem::h;
}
auto PhonebookModel::getItem(gui::Order order) -> gui::ListItem *
{
const auto contact = getRecord(order);
if (contact == nullptr) {
return nullptr;
}
auto item = new gui::PhonebookItem();
item->setContact(contact);
item->setLabelMarkerDisplayMode(getLabelMarkerDisplayMode(contact->contactPosOnList));
item->activatedCallback = [this, item, contact](gui::Item &) {
if (customContactActivationCallback) {
return customContactActivationCallback(item);
}
application->switchWindow(gui::window::name::contact, std::make_unique<PhonebookItemData>(contact));
return true;
};
item->inputCallback = [this, item](gui::Item &, const gui::InputEvent &event) {
if (event.isShortRelease(gui::KeyCode::KEY_LF)) {
if (item->contact && !item->contact->numbers.empty()) {
const auto phoneNumber = item->contact->numbers.front().number;
return app::manager::Controller::sendAction(application,
app::manager::actions::Call,
std::make_unique<app::ExecuteCallData>(phoneNumber),
app::manager::OnSwitchBehaviour::RunInBackground);
}
}
return false;
};
return item;
}
auto PhonebookModel::getFilter() const -> const std::string &
{
return queryFilter;
}
void PhonebookModel::setDisplayMode(std::uint32_t displayMode)
{
queryDisplayMode = displayMode;
}
auto PhonebookModel::getDisplayMode() -> std::uint32_t
{
return queryDisplayMode;
}
auto PhonebookModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
{
auto contactsResponse = dynamic_cast<db::query::ContactGetResult *>(queryResult);
assert(contactsResponse != nullptr);
auto records = std::vector<ContactRecord>(contactsResponse->getRecords());
return this->updateRecords(std::move(records));
}
auto PhonebookModel::getLabelMarkerDisplayMode(uint32_t posOnList) -> LabelMarkerDisplayMode
{
if (posOnList < letterMap.favouritesCount) {
return LabelMarkerDisplayMode::IncludeFavourites;
}
return LabelMarkerDisplayMode::IgnoreFavourites;
}
void PhonebookModel::setFilter(std::string filter, const std::uint32_t groupFilter, const std::uint32_t displayMode)
{
queryFilter = std::move(filter);
queryGroupFilter = groupFilter;
queryDisplayMode = displayMode;
}