~aleteoryx/muditaos

d84671140f8915ab221eed4462dee5be84be6b49 — rrandomsky 2 years ago 9da6579
[MOS-1007] Fix for no popup when contact cannot be saved because of same nubers

Fix for fix. It add popup when user try to save contact witch practically
the same numners  (even if having a country code is only difference)
M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +2 -0
@@ 369,6 369,8 @@
    "app_phonebook_new_contact_email": "E-Mail",
    "app_phonebook_new_contact_first_name": "Vorname",
    "app_phonebook_new_contact_invalid_number": "<text>Dieser Kontakt kann nicht gespeichert werden.<br></br>Die von Ihnen eingegebene Telefonnummer<br></br>hat ein ung\u00fcltiges Format.</text>",
    "app_phonebook_new_contact_unable_to_save": "Kontakt nicht gespeichert",
    "app_phonebook_new_contact_same_numbers": "<text>Trotz der eingegebenen Landesvorwahl sind die Telefonnummern identisch.</text> <br></br><br></br> <text weight='bold' size='27'> Geben Sieeine weitere Nummer ein, um den Kontakt zu speichern.</text>",
    "app_phonebook_new_contact_last_name": "Nachname",
    "app_phonebook_new_contact_note": "Notiz",
    "app_phonebook_new_contact_number": "Nummer",

M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +2 -0
@@ 372,6 372,8 @@
    "app_phonebook_new_contact_email": "Email",
    "app_phonebook_new_contact_first_name": "First name",
    "app_phonebook_new_contact_invalid_number": "<text>Cannot save this contact.<br></br>The phone number you entered <br></br>is in an invalid format.</text>",
    "app_phonebook_new_contact_unable_to_save": "Unable to save contact",
    "app_phonebook_new_contact_same_numbers": "<text>Despite the country code entered,<br></br>the phone numbers are the same.</text> <br></br><br></br> <text weight='bold' size='27'>Enter another numbers to save <br></br>the contact.</text>",
    "app_phonebook_new_contact_last_name": "Last name",
    "app_phonebook_new_contact_note": "Note",
    "app_phonebook_new_contact_number": "Phone number",

M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +2 -0
@@ 368,6 368,8 @@
    "app_phonebook_new_contact_email": "Correo electr\u00f3nico",
    "app_phonebook_new_contact_first_name": "Nombre",
    "app_phonebook_new_contact_invalid_number": "<text>No se puede guardar este contacto.<br></br>El n\u00famero de tel\u00e9fono que ingres\u00f3 <br></br>tiene un formato no v\u00e1lido.</text>",
    "app_phonebook_new_contact_unable_to_save": "No se pudo guardar el contacto",
    "app_phonebook_new_contact_same_numbers": "<text>A pesar del c\u00f3digo de país ingresado, los n\u00fameros de tel\u00e9fono son los mismos.</text> <br></br><br></br> <text weight='bold' size='27'>Ingrese otros n\u00fameros para guardar el contacto.</text>",
    "app_phonebook_new_contact_last_name": "Apellido",
    "app_phonebook_new_contact_note": "Nota",
    "app_phonebook_new_contact_number": "N\u00famero",

M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +2 -0
@@ 336,6 336,8 @@
    "app_phonebook_new_contact_email": "Email",
    "app_phonebook_new_contact_first_name": "Pr\u00e9nom",
    "app_phonebook_new_contact_invalid_number": "<text>Impossible d'enregistrer ce contact.<br></br>Le num\u00e9ro de t\u00e9l\u00e9phone que vous avez entr\u00e9 <br></br>est dans un format invalide.</text>",
    "app_phonebook_new_contact_unable_to_save": "Impossible d'enreg. le contact",
    "app_phonebook_new_contact_same_numbers": "<text>Malgr\u00e9 l'indicatif du pays saisi, les num\u00e9ros de t\u00e9l\u00e9phone sont les m\u00eames.</text> <br></br><br></br> <text weight='bold' size='27'>Entrez un autre num\u00e9ro pour enregistrer le contact.</text>",
    "app_phonebook_new_contact_last_name": "Nom",
    "app_phonebook_new_contact_note": "Note",
    "app_phonebook_new_contact_number": "Num\u00e9ro",

M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +2 -0
@@ 362,6 362,8 @@
    "app_phonebook_new_contact_email": "E-mail",
    "app_phonebook_new_contact_first_name": "Imi\u0119",
    "app_phonebook_new_contact_invalid_number": "<text>Nie mo\u017cna zapisa\u0107 tego kontaktu.<br></br>Wprowadzony numer telefonu<br></br>ma nieprawid\u0142owy format.</text>",
    "app_phonebook_new_contact_unable_to_save": "Nie mo\u017cna zapisa\u0107 kontaktu",
    "app_phonebook_new_contact_same_numbers": "<text>Pomijaj\u0105c numery kierunkowe,<br></br>wprowad\u017aone numery s\u0105 takie same.</text> <br></br><br></br> <text weight='bold' size='27'>Wprowad\u017a inne numery <br></br>by zapisać kontakt.</text>",
    "app_phonebook_new_contact_last_name": "Nazwisko",
    "app_phonebook_new_contact_note": "Notatka",
    "app_phonebook_new_contact_number": "Numer",

M image/system_a/data/lang/Svenska.json => image/system_a/data/lang/Svenska.json +2 -0
@@ 227,6 227,8 @@
    "app_phonebook_new_contact_email": "Mail",
    "app_phonebook_new_contact_first_name": "F\u00f6rnamn",
    "app_phonebook_new_contact_invalid_number": "<text>Det g\u00e5r inte att spara den h\u00e4r kontakten.<br></br>Telefonnumret du angav<br></br>\u00e4r i ett ogiltigt format.</text>",
    "app_phonebook_new_contact_unable_to_save": "Kan inte spara kontakt",
    "app_phonebook_new_contact_same_numbers": "<text>Trots landskoden \u00e4r telefonnumren identiska.</text> <br></br><br></br> <text weight='bold' size='27'>Ange ett annat nummer för att sparakontakten.</text>",
    "app_phonebook_new_contact_last_name": "Efternamn",
    "app_phonebook_new_contact_note": "Anteckning",
    "app_phonebook_new_contact_number": "Nummer",

M module-apps/application-phonebook/windows/PhonebookNewContact.cpp => module-apps/application-phonebook/windows/PhonebookNewContact.cpp +17 -0
@@ 193,6 193,9 @@ namespace gui
            case DBServiceAPI::ContactVerificationResult::secondaryNumberDuplicate:
                showDialogDuplicatedNumber(contact->numbers[1].number, contact->ID);
                return false;
            case DBServiceAPI::ContactVerificationResult::primaryAndSecondaryNumberAreTheSame:
                showDialogPrimaryAndSecondaryNumberAreTheSame();
                return false;
            case DBServiceAPI::ContactVerificationResult::speedDialDuplicate:
                showDialogDuplicatedSpeedDialNumber();
                return false;


@@ 338,4 341,18 @@ namespace gui
        return newContactModel->isAnyUnsavedChange(contact);
    }

    void PhonebookNewContact::showDialogPrimaryAndSecondaryNumberAreTheSame()
    {
        auto metaData = std::make_unique<gui::DialogMetadataMessage>(
            gui::DialogMetadata{utils::translate("app_phonebook_new_contact_unable_to_save"),
                                "fail_128px_W_G",
                                utils::translate("app_phonebook_new_contact_same_numbers"),
                                "",
                                [=]() -> bool {
                                    application->returnToPreviousWindow();
                                    return true;
                                }});

        application->switchWindow(gui::window::name::dialog, std::move(metaData));
    }
} // namespace gui

M module-apps/application-phonebook/windows/PhonebookNewContact.hpp => module-apps/application-phonebook/windows/PhonebookNewContact.hpp +1 -0
@@ 38,6 38,7 @@ namespace gui
        void showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber,
                                        const std::uint32_t duplicatedNumberContactID = 0u);
        void showDialogDuplicatedSpeedDialNumber();
        void showDialogPrimaryAndSecondaryNumberAreTheSame();
        void showDialogUnsavedChanges(std::function<bool()> whereToGoOnYes = nullptr);
        void setSaveButtonVisible(bool visible);
        void showContactDeletedNotification();

M module-db/Interface/ContactRecord.hpp => module-db/Interface/ContactRecord.hpp +2 -2
@@ 225,6 225,8 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco

    auto GetNumbersIdsByContact(std::uint32_t contactId) -> std::vector<std::uint32_t>;

    auto hasContactRecordSameNumbers(const ContactRecord &rec) -> bool;

    /**
     * @brief Merge contacts list with overriding the duplicates in contacts DB
     *


@@ 319,6 321,4 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco
     */
    auto changeNumberRecordInPlaceIfCountryCodeIsOnlyDifferent(const std::vector<std::uint32_t> &oldNumberIDs,
                                                               std::vector<ContactRecord::Number> &newNumbers) -> bool;

    auto hasContactRecordSameNumbers(const ContactRecord &rec) -> bool;
};

M module-services/service-db/DBServiceAPI.cpp => module-services/service-db/DBServiceAPI.cpp +23 -0
@@ 157,6 157,10 @@ auto DBServiceAPI::verifyContact(sys::Service *serv, const ContactRecord &rec)
        return ContactVerificationResult::speedDialDuplicate;
    }

    if (rec.numbers.size() >= 2 && hasContactSameNumbers(serv, rec)) {
        return ContactVerificationResult::primaryAndSecondaryNumberAreTheSame;
    }

    if (rec.numbers.size() > 0 && rec.numbers[0].number.getEntered().size() > 0) {
        auto retPhone1 = MatchContactByPhoneNumber(serv, rec.numbers[0].number, rec.ID);
        if (retPhone1) {


@@ 306,3 310,22 @@ void DBServiceAPI::InformLanguageChanged(sys::Service *serv)
    auto query = std::make_unique<Quotes::Messages::InformLanguageChangeRequest>();
    DBServiceAPI::GetQuery(serv, db::Interface::Name::Quotes, std::move(query));
}

auto DBServiceAPI::hasContactSameNumbers(sys::Service *serv, const ContactRecord &rec) -> bool
{
    std::shared_ptr<DBContactMessage> msg =
        std::make_shared<DBContactMessage>(MessageType::DBCheckContactNumbersIsSame, rec);

    auto ret             = serv->bus.sendUnicastSync(msg, service::name::db, constants::DefaultTimeoutInMs);
    auto contactResponse = dynamic_cast<DBResponseMessage *>(ret.second.get());
    if (contactResponse == nullptr) {
        LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
        return false; // Assumption that the numbers in the contact are not the same
    }
    if (ret.first == sys::ReturnCodes::Success) {
        return contactResponse->retCode;
    }

    LOG_ERROR("Checking if contact has same numbers failed");
    return false; // Assumption that the numbers in the contact are not the same
}

M module-services/service-db/include/service-db/DBServiceAPI.hpp => module-services/service-db/include/service-db/DBServiceAPI.hpp +3 -1
@@ 35,13 35,13 @@ namespace sys
class DBServiceAPI
{
  public:

    enum class ContactVerificationResult
    {
        emptyContact,
        temporaryContactExists,
        primaryNumberDuplicate,
        secondaryNumberDuplicate,
        primaryAndSecondaryNumberAreTheSame,
        speedDialDuplicate,
        success
    };


@@ 114,6 114,8 @@ class DBServiceAPI

    static auto IsContactInFavourites(sys::Service *serv, const utils::PhoneNumber::View &numberView) -> bool;
    static auto IsContactInEmergency(sys::Service *serv, const utils::PhoneNumber::View &numberView) -> bool;

    static auto hasContactSameNumbers(sys::Service *serv, const ContactRecord &rec) -> bool;
    /**
     * @brief Add sms via DBService interface
     *

M products/PurePhone/services/db/ServiceDB.cpp => products/PurePhone/services/db/ServiceDB.cpp +43 -34
@@ 83,10 83,10 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
         */

    case MessageType::DBContactAdd: {
        auto time             = utils::time::Scoped("DBContactAdd");
        auto msg              = static_cast<DBContactMessage *>(msgl);
        auto ret              = contactRecordInterface->Add(msg->record);
        auto record           = std::make_unique<std::vector<ContactRecord>>();
        auto time   = utils::time::Scoped("DBContactAdd");
        auto msg    = static_cast<DBContactMessage *>(msgl);
        auto ret    = contactRecordInterface->Add(msg->record);
        auto record = std::make_unique<std::vector<ContactRecord>>();
        record->push_back(msg->record);
        LOG_DEBUG("Last ID %" PRIu32, msg->record.ID);
        responseMsg = std::make_shared<DBContactResponseMessage>(std::move(record), ret);


@@ 94,21 94,21 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
    } break;

    case MessageType::DBContactGetByID: {
        auto time             = utils::time::Scoped("DBContactGetByID");
        auto msg              = static_cast<DBContactMessage *>(msgl);
        auto ret              = (msg->withTemporary ? contactRecordInterface->GetByIdWithTemporary(msg->record.ID)
                                                    : contactRecordInterface->GetByID(msg->record.ID));
        auto records          = std::make_unique<std::vector<ContactRecord>>();
        auto time    = utils::time::Scoped("DBContactGetByID");
        auto msg     = static_cast<DBContactMessage *>(msgl);
        auto ret     = (msg->withTemporary ? contactRecordInterface->GetByIdWithTemporary(msg->record.ID)
                                           : contactRecordInterface->GetByID(msg->record.ID));
        auto records = std::make_unique<std::vector<ContactRecord>>();
        records->push_back(ret);
        responseMsg = std::make_shared<DBContactResponseMessage>(
            std::move(records), true, msg->limit, msg->offset, msg->favourite, 1, MessageType::DBContactGetByID);
    } break;

    case MessageType::DBContactGetBySpeedDial: {
        auto time             = utils::time::Scoped("DBContactGetBySpeedDial");
        auto msg              = static_cast<DBContactMessage *>(msgl);
        auto ret              = contactRecordInterface->GetBySpeedDial(msg->record.speeddial);
        responseMsg           = std::make_shared<DBContactResponseMessage>(std::move(ret),
        auto time   = utils::time::Scoped("DBContactGetBySpeedDial");
        auto msg    = static_cast<DBContactMessage *>(msgl);
        auto ret    = contactRecordInterface->GetBySpeedDial(msg->record.speeddial);
        responseMsg = std::make_shared<DBContactResponseMessage>(std::move(ret),
                                                                 true,
                                                                 msg->limit,
                                                                 msg->offset,


@@ 150,6 150,15 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
        }
    } break;

    case MessageType::DBCheckContactNumbersIsSame: {
        auto time   = utils::time::Scoped("DBCheckContactNumbersIsSame");
        auto msg    = static_cast<DBContactMessage *>(msgl);
        auto ret    = contactRecordInterface->hasContactRecordSameNumbers(msg->record);
        auto record = std::make_unique<std::vector<ContactRecord>>();
        LOG_DEBUG("Has contact same numbers: %d" PRIu32, ret);
        responseMsg = std::make_shared<DBResponseMessage>(ret, 0, MessageType::MessageTypeUninitialized);
    } break;

    case MessageType::DBContactMatchByNumberID: {
        auto time = utils::time::Scoped("DBContactMatchByNumberID");
        auto msg  = static_cast<DBMatchContactByNumberIDMessage *>(msgl);


@@ 164,18 173,18 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
    } break;

    case MessageType::DBContactRemove: {
        auto time             = utils::time::Scoped("DBContactRemove");
        auto msg              = static_cast<DBContactMessage *>(msgl);
        auto ret              = contactRecordInterface->RemoveByID(msg->id);
        responseMsg           = std::make_shared<DBContactResponseMessage>(nullptr, ret);
        auto time   = utils::time::Scoped("DBContactRemove");
        auto msg    = static_cast<DBContactMessage *>(msgl);
        auto ret    = contactRecordInterface->RemoveByID(msg->id);
        responseMsg = std::make_shared<DBContactResponseMessage>(nullptr, ret);
        sendUpdateNotification(db::Interface::Name::Contact, db::Query::Type::Delete, msg->id);
    } break;

    case MessageType::DBContactUpdate: {
        auto time             = utils::time::Scoped("DBContactUpdate");
        auto msg              = static_cast<DBContactMessage *>(msgl);
        auto ret              = contactRecordInterface->Update(msg->record);
        responseMsg           = std::make_shared<DBContactResponseMessage>(nullptr, ret);
        auto time   = utils::time::Scoped("DBContactUpdate");
        auto msg    = static_cast<DBContactMessage *>(msgl);
        auto ret    = contactRecordInterface->Update(msg->record);
        responseMsg = std::make_shared<DBContactResponseMessage>(nullptr, ret);
        sendUpdateNotification(db::Interface::Name::Contact, db::Query::Type::Update, msg->record.ID);
    } break;



@@ 184,11 193,11 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
         */

    case MessageType::DBCalllogAdd: {
        auto time             = utils::time::Scoped("DBCalllogAdd");
        auto msg              = static_cast<DBCalllogMessage *>(msgl);
        auto record           = std::make_unique<std::vector<CalllogRecord>>();
        msg->record.ID        = DB_ID_NONE;
        auto ret              = calllogRecordInterface->Add(msg->record);
        auto time      = utils::time::Scoped("DBCalllogAdd");
        auto msg       = static_cast<DBCalllogMessage *>(msgl);
        auto record    = std::make_unique<std::vector<CalllogRecord>>();
        msg->record.ID = DB_ID_NONE;
        auto ret       = calllogRecordInterface->Add(msg->record);
        if (ret) {
            // return the newly added record
            msg->record = calllogRecordInterface->GetByID(calllogRecordInterface->GetLastID());


@@ 200,18 209,18 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
    } break;

    case MessageType::DBCalllogRemove: {
        auto time             = utils::time::Scoped("DBCalllogRemove");
        auto msg              = static_cast<DBCalllogMessage *>(msgl);
        auto ret              = calllogRecordInterface->RemoveByID(msg->id);
        responseMsg           = std::make_shared<DBCalllogResponseMessage>(nullptr, ret);
        auto time   = utils::time::Scoped("DBCalllogRemove");
        auto msg    = static_cast<DBCalllogMessage *>(msgl);
        auto ret    = calllogRecordInterface->RemoveByID(msg->id);
        responseMsg = std::make_shared<DBCalllogResponseMessage>(nullptr, ret);
        sendUpdateNotification(db::Interface::Name::Calllog, db::Query::Type::Delete, msg->id);
    } break;

    case MessageType::DBCalllogUpdate: {
        auto time             = utils::time::Scoped("DBCalllogUpdate");
        auto msg              = static_cast<DBCalllogMessage *>(msgl);
        auto ret              = calllogRecordInterface->Update(msg->record);
        responseMsg           = std::make_shared<DBCalllogResponseMessage>(nullptr, ret);
        auto time   = utils::time::Scoped("DBCalllogUpdate");
        auto msg    = static_cast<DBCalllogMessage *>(msgl);
        auto ret    = calllogRecordInterface->Update(msg->record);
        responseMsg = std::make_shared<DBCalllogResponseMessage>(nullptr, ret);
        sendUpdateNotification(db::Interface::Name::Calllog, db::Query::Type::Update, msg->record.ID);
    } break;


M pure_changelog.md => pure_changelog.md +1 -0
@@ 40,6 40,7 @@
* Fixed losing unsaved data on go back
* Fixed disabled screen autolock in meditation app
* Fixed multiple issues with input fields in "New alarm" window
* Fixed the ability to create a contact with the same primary and secondary phone number, which resulted in mismatching

## [1.7.2 2023-07-28]


M source/MessageType.hpp => source/MessageType.hpp +7 -4
@@ 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


@@ 29,9 29,12 @@ enum class MessageType
    DBMatchContactNumberBesidesOfContactID
    [[deprecated]], ///< used to best match with a single contact using a phone number (primary or secondary)
                    ///< but witch omitting specific contact ID
    DBContactAdd [[deprecated]],    ///< Add contact record
    DBContactRemove [[deprecated]], ///< Remove contact remove
    DBContactUpdate [[deprecated]], ///< Update contact remove
    DBCheckContactNumbersIsSame [[deprecated]], ///< used to check if a contact have 2 or more same numbers according to
                                                ///< internal rules of number the similarity when the numbers are
                                                ///< practically the same e.g. having a country code is only difference
    DBContactAdd [[deprecated]],                ///< Add contact record
    DBContactRemove [[deprecated]],             ///< Remove contact remove
    DBContactUpdate [[deprecated]],             ///< Update contact remove

    DBQuery,