Add the default number indicator at the View Details too

This commit is contained in:
Pavel Poley 2022-05-27 12:14:51 +03:00
parent d83c14dab9
commit 82f01f8551
4 changed files with 158 additions and 34 deletions

View File

@ -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'

View File

@ -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<PhoneNumber?, PhoneNumber?>) {
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<PhoneNumber?, PhoneNumber?>,
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

View File

@ -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,10 @@ class ViewContactActivity : ContactActivity() {
private var contactSources = ArrayList<ContactSource>()
private var showFields = 0
private var fullContact: Contact? = null // contact with all fields filled from duplicates
private var duplicateInitialized = false
private val mergeDuplicate: Boolean by lazy {
config.mergeDuplicateContacts
}
private val COMPARABLE_PHONE_NUMBER_LENGTH = 9
@ -250,12 +255,9 @@ class ViewContactActivity : ContactActivity() {
contactSources = it
runOnUiThread {
setupContactDetails()
if (config.mergeDuplicateContacts) {
getDuplicateContacts {
if (duplicateContacts.isNotEmpty()) {
setupContactDetails()
}
}
getDuplicateContacts {
duplicateInitialized = true
setupContactDetails()
}
}
}
@ -282,6 +284,7 @@ class ViewContactActivity : ContactActivity() {
private fun launchEditContact(contact: Contact) {
wasEditLaunched = true
duplicateInitialized = false
editContact(contact)
}
@ -332,8 +335,32 @@ class ViewContactActivity : ContactActivity() {
private fun setupPhoneNumbers() {
var phoneNumbers = contact!!.phoneNumbers.toMutableSet() as LinkedHashSet<PhoneNumber>
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 +376,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 +392,8 @@ class ViewContactActivity : ContactActivity() {
startCallIntent(phoneNumber.value)
}
}
contact_number_holder.default_toggle_icon.isVisible = duplicateInitialized && phoneNumber.isPrimary
}
}
contact_numbers_image.beVisible()
@ -410,8 +438,11 @@ class ViewContactActivity : ContactActivity() {
private fun setupAddresses() {
var addresses = contact!!.addresses.toMutableSet() as LinkedHashSet<Address>
duplicateContacts.forEach {
addresses.addAll(it.addresses)
if (mergeDuplicate) {
duplicateContacts.forEach {
addresses.addAll(it.addresses)
}
}
addresses = addresses.sortedBy { it.type }.toMutableSet() as LinkedHashSet<Address>
@ -442,8 +473,11 @@ class ViewContactActivity : ContactActivity() {
private fun setupIMs() {
var IMs = contact!!.IMs.toMutableSet() as LinkedHashSet<IM>
duplicateContacts.forEach {
IMs.addAll(it.IMs)
if (mergeDuplicate) {
duplicateContacts.forEach {
IMs.addAll(it.IMs)
}
}
IMs = IMs.sortedBy { it.type }.toMutableSet() as LinkedHashSet<IM>
@ -470,8 +504,11 @@ class ViewContactActivity : ContactActivity() {
private fun setupEvents() {
var events = contact!!.events.toMutableSet() as LinkedHashSet<Event>
duplicateContacts.forEach {
events.addAll(it.events)
if (mergeDuplicate) {
duplicateContacts.forEach {
events.addAll(it.events)
}
}
events = events.sortedBy { it.type }.toMutableSet() as LinkedHashSet<Event>
@ -497,8 +534,11 @@ class ViewContactActivity : ContactActivity() {
private fun setupWebsites() {
var websites = contact!!.websites.toMutableSet() as LinkedHashSet<String>
duplicateContacts.forEach {
websites.addAll(it.websites)
if (mergeDuplicate) {
duplicateContacts.forEach {
websites.addAll(it.websites)
}
}
websites = websites.sorted().toMutableSet() as LinkedHashSet<String>
@ -528,8 +568,11 @@ class ViewContactActivity : ContactActivity() {
private fun setupGroups() {
var groups = contact!!.groups.toMutableSet() as LinkedHashSet<Group>
duplicateContacts.forEach {
groups.addAll(it.groups)
if (mergeDuplicate) {
duplicateContacts.forEach {
groups.addAll(it.groups)
}
}
groups = groups.sortedBy { it.title }.toMutableSet() as LinkedHashSet<Group>
@ -558,8 +601,11 @@ class ViewContactActivity : ContactActivity() {
if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) {
var sources = HashMap<Contact, String>()
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) {

View File

@ -1,20 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contact_number_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="46dp"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin">
android:paddingEnd="@dimen/normal_margin">
<ImageView
android:id="@+id/default_toggle_icon"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/contact_number_type"
android:padding="@dimen/tiny_margin"
android:visibility="gone"
app:srcCompat="@drawable/ic_star_vector" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/contact_number_type"
android:layout_toStartOf="@+id/default_toggle_icon"
android:lines="1"
android:maxLines="1"
android:singleLine="true"
@ -29,6 +38,7 @@
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:gravity="center"
android:minWidth="70dp"
android:paddingStart="@dimen/medium_margin"
android:paddingEnd="@dimen/medium_margin"
android:text="@string/mobile"