Display phone number type/label in contact view detail
This commit is contained in:
parent
ee9a843a6e
commit
e9abb5cef4
8 changed files with 54 additions and 15 deletions
|
@ -192,7 +192,7 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactViewModelInt
|
||||||
|
|
||||||
private fun updateNumbersAndAddresses() {
|
private fun updateNumbersAndAddresses() {
|
||||||
val phoneNumbers = arrayListOf<NumberOrAddressEditorViewModel>()
|
val phoneNumbers = arrayListOf<NumberOrAddressEditorViewModel>()
|
||||||
for (number in c?.phoneNumbers.orEmpty()) {
|
for (number in c?.rawPhoneNumbers.orEmpty()) {
|
||||||
phoneNumbers.add(NumberOrAddressEditorViewModel(number, false))
|
phoneNumbers.add(NumberOrAddressEditorViewModel(number, false))
|
||||||
}
|
}
|
||||||
if (phoneNumbers.isEmpty()) {
|
if (phoneNumbers.isEmpty()) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ContactNumberOrAddressViewModel(
|
||||||
val displayedValue: String,
|
val displayedValue: String,
|
||||||
val isSip: Boolean = true,
|
val isSip: Boolean = true,
|
||||||
val showSecureChat: Boolean = false,
|
val showSecureChat: Boolean = false,
|
||||||
|
val typeLabel: String = "",
|
||||||
private val listener: ContactNumberOrAddressClickListener
|
private val listener: ContactNumberOrAddressClickListener
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val showInvite = !hasPresence && !isSip
|
val showInvite = !hasPresence && !isSip
|
||||||
|
|
|
@ -175,14 +175,15 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont
|
||||||
val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener)
|
val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener)
|
||||||
list.add(noa)
|
list.add(noa)
|
||||||
}
|
}
|
||||||
for (number in contact.phoneNumbers) {
|
for (phoneNumber in contact.phoneNumbers) {
|
||||||
|
val number = phoneNumber.value
|
||||||
val presenceModel = contact.friend?.getPresenceModelForUriOrTel(number)
|
val presenceModel = contact.friend?.getPresenceModelForUriOrTel(number)
|
||||||
val hasPresence = presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open
|
val hasPresence = presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open
|
||||||
val contactAddress = presenceModel?.contact ?: number
|
val contactAddress = presenceModel?.contact ?: number
|
||||||
val address = coreContext.core.interpretUrl(contactAddress)
|
val address = coreContext.core.interpretUrl(contactAddress)
|
||||||
val isMe = if (address != null) coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false else false
|
val isMe = if (address != null) coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false else false
|
||||||
val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false
|
val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false
|
||||||
val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, listener = listener)
|
val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener)
|
||||||
list.add(noa)
|
list.add(noa)
|
||||||
}
|
}
|
||||||
numbersAndAddresses.value = list
|
numbersAndAddresses.value = list
|
||||||
|
|
|
@ -41,8 +41,8 @@ class AsyncContactsLoader(private val context: Context) :
|
||||||
ContactsContract.Contacts.STARRED,
|
ContactsContract.Contacts.STARRED,
|
||||||
ContactsContract.Contacts.LOOKUP_KEY,
|
ContactsContract.Contacts.LOOKUP_KEY,
|
||||||
"data1", // Company, Phone or SIP Address
|
"data1", // Company, Phone or SIP Address
|
||||||
"data2", // ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME
|
"data2", // ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE
|
||||||
"data3", // ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME
|
"data3", // ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.CommonDataKinds.Phone.LABEL, ContactsContract.CommonDataKinds.SipAddress.LABEL
|
||||||
"data4"
|
"data4"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ class AsyncContactsLoader(private val context: Context) :
|
||||||
contact.sipAddresses.clear()
|
contact.sipAddresses.clear()
|
||||||
contact.rawSipAddresses.clear()
|
contact.rawSipAddresses.clear()
|
||||||
contact.phoneNumbers.clear()
|
contact.phoneNumbers.clear()
|
||||||
|
contact.rawPhoneNumbers.clear()
|
||||||
androidContactsCache[contact.nativeId] = contact
|
androidContactsCache[contact.nativeId] = contact
|
||||||
nativeIds.add(contact.nativeId)
|
nativeIds.add(contact.nativeId)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,6 +33,12 @@ import org.linphone.core.PresenceBasicStatus
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.ImageUtils
|
import org.linphone.utils.ImageUtils
|
||||||
|
|
||||||
|
data class PhoneNumber(val value: String, val typeLabel: String) : Comparable<PhoneNumber> {
|
||||||
|
override fun compareTo(other: PhoneNumber): Int {
|
||||||
|
return value.compareTo(other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class Contact : Comparable<Contact> {
|
open class Contact : Comparable<Contact> {
|
||||||
var fullName: String? = null
|
var fullName: String? = null
|
||||||
var firstName: String? = null
|
var firstName: String? = null
|
||||||
|
@ -40,7 +46,8 @@ open class Contact : Comparable<Contact> {
|
||||||
var organization: String? = null
|
var organization: String? = null
|
||||||
var isStarred: Boolean = false
|
var isStarred: Boolean = false
|
||||||
|
|
||||||
var phoneNumbers = arrayListOf<String>()
|
var phoneNumbers = arrayListOf<PhoneNumber>()
|
||||||
|
var rawPhoneNumbers = arrayListOf<String>()
|
||||||
var sipAddresses = arrayListOf<Address>()
|
var sipAddresses = arrayListOf<Address>()
|
||||||
// Raw SIP addresses are only used for contact edition
|
// Raw SIP addresses are only used for contact edition
|
||||||
var rawSipAddresses = arrayListOf<String>()
|
var rawSipAddresses = arrayListOf<String>()
|
||||||
|
@ -53,7 +60,7 @@ open class Contact : Comparable<Contact> {
|
||||||
if (fn == otherFn) {
|
if (fn == otherFn) {
|
||||||
if (phoneNumbers.size == other.phoneNumbers.size && phoneNumbers.size > 0) {
|
if (phoneNumbers.size == other.phoneNumbers.size && phoneNumbers.size > 0) {
|
||||||
if (phoneNumbers != other.phoneNumbers) {
|
if (phoneNumbers != other.phoneNumbers) {
|
||||||
for (i in 0..phoneNumbers.size) {
|
for (i in 0 until phoneNumbers.size) {
|
||||||
val compare = phoneNumbers[i].compareTo(other.phoneNumbers[i])
|
val compare = phoneNumbers[i].compareTo(other.phoneNumbers[i])
|
||||||
if (compare != 0) return compare
|
if (compare != 0) return compare
|
||||||
}
|
}
|
||||||
|
@ -64,7 +71,7 @@ open class Contact : Comparable<Contact> {
|
||||||
|
|
||||||
if (sipAddresses.size == other.sipAddresses.size && sipAddresses.size > 0) {
|
if (sipAddresses.size == other.sipAddresses.size && sipAddresses.size > 0) {
|
||||||
if (sipAddresses != other.sipAddresses) {
|
if (sipAddresses != other.sipAddresses) {
|
||||||
for (i in 0..sipAddresses.size) {
|
for (i in 0 until sipAddresses.size) {
|
||||||
val compare = sipAddresses[i].asStringUriOnly().compareTo(other.sipAddresses[i].asStringUriOnly())
|
val compare = sipAddresses[i].asStringUriOnly().compareTo(other.sipAddresses[i].asStringUriOnly())
|
||||||
if (compare != 0) return compare
|
if (compare != 0) return compare
|
||||||
}
|
}
|
||||||
|
@ -89,7 +96,10 @@ open class Contact : Comparable<Contact> {
|
||||||
|
|
||||||
phoneNumbers.clear()
|
phoneNumbers.clear()
|
||||||
for (number in friend.phoneNumbers) {
|
for (number in friend.phoneNumbers) {
|
||||||
if (!phoneNumbers.contains(number)) phoneNumbers.add(number)
|
if (!rawPhoneNumbers.contains(number)) {
|
||||||
|
phoneNumbers.add(PhoneNumber(number, ""))
|
||||||
|
rawPhoneNumbers.add(number)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sipAddresses.clear()
|
sipAddresses.clear()
|
||||||
|
@ -151,7 +161,7 @@ open class Contact : Comparable<Contact> {
|
||||||
val presenceModel = friend?.getPresenceModelForUriOrTel(address.asStringUriOnly())
|
val presenceModel = friend?.getPresenceModelForUriOrTel(address.asStringUriOnly())
|
||||||
if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true
|
if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true
|
||||||
}
|
}
|
||||||
for (number in phoneNumbers) {
|
for (number in rawPhoneNumbers) {
|
||||||
val presenceModel = friend?.getPresenceModelForUriOrTel(number)
|
val presenceModel = friend?.getPresenceModelForUriOrTel(number)
|
||||||
if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true
|
if (presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open) return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,7 +345,7 @@ class ContactsManager(private val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storePresenceInNativeContact(contact: NativeContact) {
|
private fun storePresenceInNativeContact(contact: NativeContact) {
|
||||||
for (phoneNumber in contact.phoneNumbers) {
|
for (phoneNumber in contact.rawPhoneNumbers) {
|
||||||
val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber)
|
val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber)
|
||||||
if (sipAddress != null) {
|
if (sipAddress != null) {
|
||||||
Log.d("[Contacts Manager] Found presence information to store in native contact $contact under Linphone sync account")
|
Log.d("[Contacts Manager] Found presence information to store in native contact $contact under Linphone sync account")
|
||||||
|
|
|
@ -108,9 +108,24 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("[Native Contact] Found phone number $data1 ($data4)")
|
val labelColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL)
|
||||||
|
val label: String? = cursor.getString(labelColumnIndex)
|
||||||
|
val typeColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)
|
||||||
|
val type: Int = cursor.getInt(typeColumnIndex)
|
||||||
|
val typeLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel(
|
||||||
|
coreContext.context.resources,
|
||||||
|
type,
|
||||||
|
label
|
||||||
|
).toString()
|
||||||
|
|
||||||
val number = data4 ?: data1
|
val number = data4 ?: data1
|
||||||
if (number != null && number.isNotEmpty() && !phoneNumbers.contains(number)) phoneNumbers.add(number)
|
if (number != null && number.isNotEmpty()) {
|
||||||
|
Log.d("[Native Contact] Found phone number $data1 ($data4), type label is $typeLabel")
|
||||||
|
if (!rawPhoneNumbers.contains(number)) {
|
||||||
|
phoneNumbers.add(PhoneNumber(number, typeLabel))
|
||||||
|
rawPhoneNumbers.add(number)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
linphoneMime, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE -> {
|
linphoneMime, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE -> {
|
||||||
if (data1 == null) {
|
if (data1 == null) {
|
||||||
|
@ -119,7 +134,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("[Native Contact] Found SIP address $data1")
|
Log.d("[Native Contact] Found SIP address $data1")
|
||||||
if (phoneNumbers.contains(data1)) {
|
if (rawPhoneNumbers.contains(data1)) {
|
||||||
Log.d("[Native Contact] SIP address value already exists in phone numbers list, skipping")
|
Log.d("[Native Contact] SIP address value already exists in phone numbers list, skipping")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -131,6 +146,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val stringAddress = address.asStringUriOnly()
|
val stringAddress = address.asStringUriOnly()
|
||||||
|
Log.d("[Native Contact] Found SIP address $stringAddress")
|
||||||
if (!rawSipAddresses.contains(stringAddress)) {
|
if (!rawSipAddresses.contains(stringAddress)) {
|
||||||
sipAddresses.add(address)
|
sipAddresses.add(address)
|
||||||
rawSipAddresses.add(stringAddress)
|
rawSipAddresses.add(stringAddress)
|
||||||
|
@ -191,7 +207,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (address in sipAddresses) friend.addAddress(address)
|
for (address in sipAddresses) friend.addAddress(address)
|
||||||
for (number in phoneNumbers) friend.addPhoneNumber(number)
|
for (number in rawPhoneNumbers) friend.addPhoneNumber(number)
|
||||||
|
|
||||||
friend.done()
|
friend.done()
|
||||||
if (created) coreContext.core.defaultFriendList?.addFriend(friend)
|
if (created) coreContext.core.defaultFriendList?.addFriend(friend)
|
||||||
|
@ -220,6 +236,7 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null)
|
||||||
sipAddresses.clear()
|
sipAddresses.clear()
|
||||||
rawSipAddresses.clear()
|
rawSipAddresses.clear()
|
||||||
phoneNumbers.clear()
|
phoneNumbers.clear()
|
||||||
|
rawPhoneNumbers.clear()
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
syncValuesFromAndroidCursor(cursor)
|
syncValuesFromAndroidCursor(cursor)
|
||||||
|
|
|
@ -72,6 +72,15 @@
|
||||||
android:scrollHorizontally="true"
|
android:scrollHorizontally="true"
|
||||||
android:singleLine="true" />
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@{data.typeLabel}"
|
||||||
|
android:visibility="@{data.typeLabel.length() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="?attr/primarySubtextDarkColor"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
Loading…
Reference in a new issue