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
@@ 160,6 160,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;
@@ 302,4 305,18 @@ namespace gui
contactByID->front().numbers.empty();
}
+ 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 setSaveButtonVisible(bool visible);
void showContactDeletedNotification();
bool checkIfContactWasDeletedDuringEditProcess() const;
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
@@ 35,6 35,7 @@
* Fixed missing tethering icon on "Tethering is on" window
* Fixed showing "Copy text" option in empty note
* Fixed "Copy" option missing from the options list in "New message" 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,