diff --git a/app/build.gradle b/app/build.gradle index e1e969cc..7e8e38bb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,7 +63,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:1bc50d636c' + implementation 'com.github.SimpleMobileTools:Simple-Commons:2752395357' implementation 'com.googlecode.ez-vcard:ez-vcard:0.11.3' implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt index 8642b7ac..2d0aa70b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt @@ -70,6 +70,10 @@ class EditContactActivity : ContactActivity() { private var emailViewToColor: EditText? = null private var originalContactSource = "" + enum class PrimaryNumberStatus { + UNCHANGED, STARRED, UNSTARRED + } + override fun onCreate(savedInstanceState: Bundle?) { showTransparentTop = true super.onCreate(savedInstanceState) @@ -1024,8 +1028,14 @@ class EditContactActivity : ContactActivity() { } } + val contactValues = fillContactValues() + val oldPhotoUri = contact!!.photoUri - contact = fillContactValues() + val oldPrimary = contact!!.phoneNumbers.find { it.isPrimary } + val newPrimary = contactValues.phoneNumbers.find { it.isPrimary } + val primaryState = Pair(oldPrimary, newPrimary) + + contact = contactValues ensureBackgroundThread { config.lastUsedContactSource = contact!!.source @@ -1034,7 +1044,7 @@ class EditContactActivity : ContactActivity() { originalContactSource != contact!!.source -> insertNewContact(true) else -> { val photoUpdateStatus = getPhotoUpdateStatus(oldPhotoUri, contact!!.photoUri) - updateContact(photoUpdateStatus) + updateContact(photoUpdateStatus, primaryState) } } } @@ -1199,17 +1209,75 @@ class EditContactActivity : ContactActivity() { } } - private fun updateContact(photoUpdateStatus: Int) { + private fun updateContact(photoUpdateStatus: Int, primaryState: Pair) { isSaving = true if (ContactsHelper(this@EditContactActivity).updateContact(contact!!, photoUpdateStatus)) { - setResult(Activity.RESULT_OK) - hideKeyboard() - finish() + val status = getPrimaryNumberStatus(primaryState.first, primaryState.second) + if (status != PrimaryNumberStatus.UNCHANGED) { + updateDefaultNumberForDuplicateContacts(primaryState, status) { + setResult(Activity.RESULT_OK) + hideKeyboard() + finish() + } + } else { + setResult(Activity.RESULT_OK) + hideKeyboard() + finish() + } } else { toast(R.string.unknown_error_occurred) } } + private fun updateDefaultNumberForDuplicateContacts( + toggleState: Pair, + primaryStatus: PrimaryNumberStatus, + callback: () -> Unit + ) { + val contactsHelper = ContactsHelper(this) + + contactsHelper.getDuplicatesOfContact(contact!!, false) { contacts -> + ensureBackgroundThread { + val displayContactSources = getVisibleContactSources() + contacts.filter { displayContactSources.contains(it.source) }.forEach { contact -> + val duplicate = contactsHelper.getContactWithId(contact.id, contact.isPrivate()) + if (duplicate != null) { + if (primaryStatus == PrimaryNumberStatus.UNSTARRED) { + val number = duplicate.phoneNumbers.find { it.normalizedNumber == toggleState.first!!.normalizedNumber } + number?.isPrimary = false + } else if (primaryStatus == PrimaryNumberStatus.STARRED) { + val number = duplicate.phoneNumbers.find { it.normalizedNumber == toggleState.second!!.normalizedNumber } + if (number != null) { + duplicate.phoneNumbers.forEach { + it.isPrimary = false + } + number.isPrimary = true + } + } + + contactsHelper.updateContact(duplicate, PHOTO_UNCHANGED) + } + } + + runOnUiThread { + callback.invoke() + } + } + } + } + + private fun getPrimaryNumberStatus(oldPrimary: PhoneNumber?, newPrimary: PhoneNumber?): PrimaryNumberStatus { + return if (oldPrimary != null && newPrimary != null && oldPrimary != newPrimary) { + PrimaryNumberStatus.STARRED + } else if (oldPrimary == null && newPrimary != null) { + PrimaryNumberStatus.STARRED + } else if (oldPrimary != null && newPrimary == null) { + PrimaryNumberStatus.UNSTARRED + } else { + PrimaryNumberStatus.UNCHANGED + } + } + private fun getPhotoUpdateStatus(oldUri: String, newUri: String): Int { return if (oldUri.isEmpty() && newUri.isNotEmpty()) { PHOTO_ADDED diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt index faded3f9..81a61875 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt @@ -12,6 +12,7 @@ import android.view.View import android.view.WindowInsetsController import android.view.WindowManager import android.widget.RelativeLayout +import androidx.core.view.isVisible import com.bumptech.glide.Glide import com.bumptech.glide.load.resource.bitmap.FitCenter import com.bumptech.glide.load.resource.bitmap.RoundedCorners @@ -45,6 +46,8 @@ class ViewContactActivity : ContactActivity() { private var contactSources = ArrayList() private var showFields = 0 private var fullContact: Contact? = null // contact with all fields filled from duplicates + private var duplicateInitialized = false + private val mergeDuplicate: Boolean get() = config.mergeDuplicateContacts private val COMPARABLE_PHONE_NUMBER_LENGTH = 9 @@ -250,15 +253,13 @@ class ViewContactActivity : ContactActivity() { contactSources = it runOnUiThread { setupContactDetails() - if (config.mergeDuplicateContacts) { - getDuplicateContacts { - if (duplicateContacts.isNotEmpty()) { - setupContactDetails() - } - } - } } } + + getDuplicateContacts { + duplicateInitialized = true + setupContactDetails() + } } private fun setupContactDetails() { @@ -282,6 +283,7 @@ class ViewContactActivity : ContactActivity() { private fun launchEditContact(contact: Contact) { wasEditLaunched = true + duplicateInitialized = false editContact(contact) } @@ -332,8 +334,32 @@ class ViewContactActivity : ContactActivity() { private fun setupPhoneNumbers() { var phoneNumbers = contact!!.phoneNumbers.toMutableSet() as LinkedHashSet - duplicateContacts.forEach { - phoneNumbers.addAll(it.phoneNumbers) + + if (mergeDuplicate) { + duplicateContacts.forEach { + phoneNumbers.addAll(it.phoneNumbers) + } + } + + if (duplicateInitialized) { + val contactDefaultsNumbers = contact!!.phoneNumbers.filter { it.isPrimary } + val duplicateContactsDefaultNumbers = duplicateContacts.flatMap { it.phoneNumbers }.filter { it.isPrimary } + val defaultNumbers = (contactDefaultsNumbers + duplicateContactsDefaultNumbers).toSet() + + if (defaultNumbers.size > 1) { + phoneNumbers.forEach { it.isPrimary = false } + } else if (defaultNumbers.size == 1) { + if (mergeDuplicate) { + val defaultNumber = defaultNumbers.first() + val candidate = phoneNumbers.find { it.normalizedNumber == defaultNumber.normalizedNumber && !it.isPrimary } + candidate?.isPrimary = true + } else { + duplicateContactsDefaultNumbers.forEach { defaultNumber -> + val candidate = phoneNumbers.find { it.normalizedNumber == defaultNumber.normalizedNumber && !it.isPrimary } + candidate?.isPrimary = true + } + } + } } phoneNumbers = phoneNumbers.distinctBy { @@ -349,9 +375,8 @@ class ViewContactActivity : ContactActivity() { contact_numbers_holder.removeAllViews() if (phoneNumbers.isNotEmpty() && showFields and SHOW_PHONE_NUMBERS_FIELD != 0) { - phoneNumbers.forEach { + phoneNumbers.forEach { phoneNumber -> layoutInflater.inflate(R.layout.item_view_phone_number, contact_numbers_holder, false).apply { - val phoneNumber = it contact_numbers_holder.addView(this) contact_number.text = phoneNumber.value contact_number_type.text = getPhoneNumberTypeText(phoneNumber.type, phoneNumber.label) @@ -366,6 +391,8 @@ class ViewContactActivity : ContactActivity() { startCallIntent(phoneNumber.value) } } + + contact_number_holder.default_toggle_icon.isVisible = phoneNumber.isPrimary } } contact_numbers_image.beVisible() @@ -410,8 +437,11 @@ class ViewContactActivity : ContactActivity() { private fun setupAddresses() { var addresses = contact!!.addresses.toMutableSet() as LinkedHashSet
- duplicateContacts.forEach { - addresses.addAll(it.addresses) + + if (mergeDuplicate) { + duplicateContacts.forEach { + addresses.addAll(it.addresses) + } } addresses = addresses.sortedBy { it.type }.toMutableSet() as LinkedHashSet
@@ -442,8 +472,11 @@ class ViewContactActivity : ContactActivity() { private fun setupIMs() { var IMs = contact!!.IMs.toMutableSet() as LinkedHashSet - duplicateContacts.forEach { - IMs.addAll(it.IMs) + + if (mergeDuplicate) { + duplicateContacts.forEach { + IMs.addAll(it.IMs) + } } IMs = IMs.sortedBy { it.type }.toMutableSet() as LinkedHashSet @@ -470,8 +503,11 @@ class ViewContactActivity : ContactActivity() { private fun setupEvents() { var events = contact!!.events.toMutableSet() as LinkedHashSet - duplicateContacts.forEach { - events.addAll(it.events) + + if (mergeDuplicate) { + duplicateContacts.forEach { + events.addAll(it.events) + } } events = events.sortedBy { it.type }.toMutableSet() as LinkedHashSet @@ -497,8 +533,11 @@ class ViewContactActivity : ContactActivity() { private fun setupWebsites() { var websites = contact!!.websites.toMutableSet() as LinkedHashSet - duplicateContacts.forEach { - websites.addAll(it.websites) + + if (mergeDuplicate) { + duplicateContacts.forEach { + websites.addAll(it.websites) + } } websites = websites.sorted().toMutableSet() as LinkedHashSet @@ -528,8 +567,11 @@ class ViewContactActivity : ContactActivity() { private fun setupGroups() { var groups = contact!!.groups.toMutableSet() as LinkedHashSet - duplicateContacts.forEach { - groups.addAll(it.groups) + + if (mergeDuplicate) { + duplicateContacts.forEach { + groups.addAll(it.groups) + } } groups = groups.sortedBy { it.title }.toMutableSet() as LinkedHashSet @@ -558,8 +600,11 @@ class ViewContactActivity : ContactActivity() { if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) { var sources = HashMap() sources[contact!!] = getPublicContactSourceSync(contact!!.source, contactSources) - duplicateContacts.forEach { - sources[it] = getPublicContactSourceSync(it.source, contactSources) + + if (mergeDuplicate) { + duplicateContacts.forEach { + sources[it] = getPublicContactSourceSync(it.source, contactSources) + } } if (sources.size > 1) { diff --git a/app/src/main/res/layout/item_view_phone_number.xml b/app/src/main/res/layout/item_view_phone_number.xml index 26f267b8..34e2a7ad 100644 --- a/app/src/main/res/layout/item_view_phone_number.xml +++ b/app/src/main/res/layout/item_view_phone_number.xml @@ -1,20 +1,29 @@ + android:paddingEnd="@dimen/normal_margin"> + +