From 03061045337e6cea5a8eeaef7484009f74f149d2 Mon Sep 17 00:00:00 2001 From: Alex Styl <1665273+alexstyl@users.noreply.github.com> Date: Fri, 31 Dec 2021 22:19:33 +0000 Subject: [PATCH] Add support for Relation --- ...ValuesToExistingContactContactStoreTest.kt | 24 +++++ .../ContactStoreInsertContactTest.kt | 20 +++++ .../contactstore/ContactStoreTestBase.kt | 4 +- .../EqualContentsContactMatcher.kt | 16 ++++ .../java/com/alexstyl/contactstore/Contact.kt | 7 ++ .../alexstyl/contactstore/ContactColumn.kt | 6 ++ .../alexstyl/contactstore/ContactEquality.kt | 1 + .../alexstyl/contactstore/ContactQueries.kt | 33 +++++++ .../alexstyl/contactstore/ContactStoreDSL.kt | 1 + .../com/alexstyl/contactstore/DataClasses.kt | 4 +- .../ExistingContactOperationsFactory.kt | 21 +++++ .../java/com/alexstyl/contactstore/Label.kt | 13 +++ .../alexstyl/contactstore/MutableContact.kt | 5 ++ .../contactstore/MutableContactBuilder.kt | 8 ++ .../NewContactOperationsFactory.kt | 90 ++++++++++++++++++- .../alexstyl/contactstore/PartialContact.kt | 5 +- 16 files changed, 253 insertions(+), 5 deletions(-) diff --git a/library/src/androidTest/java/com/alexstyl/contactstore/AddValuesToExistingContactContactStoreTest.kt b/library/src/androidTest/java/com/alexstyl/contactstore/AddValuesToExistingContactContactStoreTest.kt index 0d45fc9c..596123a5 100644 --- a/library/src/androidTest/java/com/alexstyl/contactstore/AddValuesToExistingContactContactStoreTest.kt +++ b/library/src/androidTest/java/com/alexstyl/contactstore/AddValuesToExistingContactContactStoreTest.kt @@ -8,7 +8,9 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses +import com.alexstyl.contactstore.Label.RelationManager import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking import org.junit.Test @@ -211,4 +213,26 @@ class AddValuesToExistingContactContactStoreTest : ContactStoreTestBase() { assertContactUpdatedNoId(expected) } + + @Test + fun updatesRelation(): Unit = runBlocking { + val contact = buildStoreContact(Names, Relations) { + firstName = "Paolo" + lastName = "Melendez" + } + + val expected = contact.mutableCopy().apply { + relations.add( + LabeledValue( + Relation(name = "Maria"), + RelationManager + ) + ) + } + store.execute { + update(expected) + } + + assertContactUpdatedNoId(expected) + } } diff --git a/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreInsertContactTest.kt b/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreInsertContactTest.kt index 1d059f0e..96c2683b 100644 --- a/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreInsertContactTest.kt +++ b/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreInsertContactTest.kt @@ -8,6 +8,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses import com.alexstyl.contactstore.Label.DateBirthday import com.alexstyl.contactstore.Label.LocationHome @@ -287,4 +288,23 @@ class ContactStoreInsertContactTest : ContactStoreTestBase() { assertOnlyContact(actual = actual, expected = expected) } + + @Test + fun insertsContactWithRelation(): Unit = runBlocking { + store.execute { + insert { + relation(name = "Person", label = Label.PhoneNumberAssistant) + } + } + + val actual = store.fetchContacts(columnsToFetch = listOf(Relations)).first() + val expected = contact( + relations = listOf( + LabeledValue(Relation(name = "Person"), Label.PhoneNumberAssistant) + ), + columns = listOf(Relations) + ) + + assertOnlyContact(actual = actual, expected = expected) + } } diff --git a/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreTestBase.kt b/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreTestBase.kt index e785090b..b14ec2bd 100644 --- a/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreTestBase.kt +++ b/library/src/androidTest/java/com/alexstyl/contactstore/ContactStoreTestBase.kt @@ -70,6 +70,7 @@ abstract class ContactStoreTestBase { events: List> = emptyList(), webAddresses: List> = emptyList(), imAddresses: List> = emptyList(), + relations : List> = emptyList(), note: Note? = null, prefix: String? = null, middleName: String? = null, @@ -94,7 +95,8 @@ abstract class ContactStoreTestBase { imAddresses = imAddresses, phones = phones, mails = mails, - isStarred = false + isStarred = false, + relations = relations ) } diff --git a/library/src/androidTest/java/com/alexstyl/contactstore/EqualContentsContactMatcher.kt b/library/src/androidTest/java/com/alexstyl/contactstore/EqualContentsContactMatcher.kt index 38342b06..ce2f3760 100644 --- a/library/src/androidTest/java/com/alexstyl/contactstore/EqualContentsContactMatcher.kt +++ b/library/src/androidTest/java/com/alexstyl/contactstore/EqualContentsContactMatcher.kt @@ -10,6 +10,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses import org.hamcrest.Description import org.hamcrest.Matcher @@ -62,6 +63,10 @@ class EqualContentsContactMatcher( putCommaIfNeeded() append("nickname = $nickname") } + if (containsColumn(Relations)) { + putCommaIfNeeded() + append("relations = ${labeledValues(relations)}") + } if (containsColumn(WebAddresses)) { putCommaIfNeeded() append("webAddresses = ${labeledValues(webAddresses)}") @@ -145,6 +150,10 @@ class EqualContentsContactMatcher( mismatchDescription.appendText("note was ${actual.note}") false } + relationsAreDifferent(actual) ->{ + mismatchDescription.appendText("relations were ${actual.relations}") + false + } displayName != expected.displayName -> { mismatchDescription.appendText("display name was '${actual.displayName}'") false @@ -154,6 +163,13 @@ class EqualContentsContactMatcher( } } + private fun relationsAreDifferent(actual: Contact): Boolean { + if(expected.containsColumn(Relations).not()) { + return false + } + return areLabeledValuesDifferentIgnoringId(actual.relations, expected.relations) + } + private fun imAreDifferent(actual: Contact): Boolean { if (expected.containsColumn(ImAddresses).not()) { return false diff --git a/library/src/main/java/com/alexstyl/contactstore/Contact.kt b/library/src/main/java/com/alexstyl/contactstore/Contact.kt index a3a8298d..d70eee1e 100644 --- a/library/src/main/java/com/alexstyl/contactstore/Contact.kt +++ b/library/src/main/java/com/alexstyl/contactstore/Contact.kt @@ -21,6 +21,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses interface Contact { @@ -146,6 +147,11 @@ interface Contact { */ val organization: String? + /** + * Requires: [ContactColumn.Relations] + */ + val relations: List> + /** * Requires: [ContactColumn.Organization] */ @@ -189,6 +195,7 @@ fun Contact.mutableCopy(): MutableContact { else mutableListOf(), imAddresses = if (containsColumn(ImAddresses)) imAddresses.toMutableList() else mutableListOf(), + relations = if(containsColumn(Relations)) relations.toMutableList() else mutableListOf(), note = if (containsColumn(Note)) note else null, columns = columns, middleName = if (containsColumn(Names)) middleName else null, diff --git a/library/src/main/java/com/alexstyl/contactstore/ContactColumn.kt b/library/src/main/java/com/alexstyl/contactstore/ContactColumn.kt index 32931d46..ed1cd3fe 100644 --- a/library/src/main/java/com/alexstyl/contactstore/ContactColumn.kt +++ b/library/src/main/java/com/alexstyl/contactstore/ContactColumn.kt @@ -71,6 +71,11 @@ sealed class ContactColumn { * A column that will populate the [Contact.imAddresses] field of all queried contacts when requested. */ object ImAddresses : ContactColumn() + + /** + * A column that will populate the [Contact.relations] field of all queried contacts when requested. + */ + object Relations : ContactColumn() } fun standardColumns(): List { @@ -87,5 +92,6 @@ fun standardColumns(): List { ContactColumn.Organization, ContactColumn.GroupMemberships, ContactColumn.ImAddresses, + ContactColumn.Relations, ) } diff --git a/library/src/main/java/com/alexstyl/contactstore/ContactEquality.kt b/library/src/main/java/com/alexstyl/contactstore/ContactEquality.kt index d7c32df8..ef838dea 100644 --- a/library/src/main/java/com/alexstyl/contactstore/ContactEquality.kt +++ b/library/src/main/java/com/alexstyl/contactstore/ContactEquality.kt @@ -1,6 +1,7 @@ package com.alexstyl.contactstore import com.alexstyl.contactstore.ContactColumn.Events +import com.alexstyl.contactstore.ContactColumn.ImAddresses import com.alexstyl.contactstore.ContactColumn.Image import com.alexstyl.contactstore.ContactColumn.Mails import com.alexstyl.contactstore.ContactColumn.Names diff --git a/library/src/main/java/com/alexstyl/contactstore/ContactQueries.kt b/library/src/main/java/com/alexstyl/contactstore/ContactQueries.kt index 3341f2dc..247f708d 100644 --- a/library/src/main/java/com/alexstyl/contactstore/ContactQueries.kt +++ b/library/src/main/java/com/alexstyl/contactstore/ContactQueries.kt @@ -9,6 +9,7 @@ import android.provider.ContactsContract.CommonDataKinds.Note as NoteColumns import android.provider.ContactsContract.CommonDataKinds.Organization as OrganizationColumns import android.provider.ContactsContract.CommonDataKinds.Phone as PhoneColumns import android.provider.ContactsContract.CommonDataKinds.Photo as PhotoColumns +import android.provider.ContactsContract.CommonDataKinds.Relation as RelationColumns import android.provider.ContactsContract.CommonDataKinds.StructuredName as NameColumns import android.provider.ContactsContract.CommonDataKinds.StructuredPostal as PostalColumns import android.provider.ContactsContract.CommonDataKinds.Website as WebColumns @@ -229,6 +230,7 @@ internal class ContactQueries( val webAddresses = mutableSetOf>() val events = mutableSetOf>() val imAddresses = mutableSetOf>() + val relations = mutableSetOf>() val postalAddresses = mutableSetOf>() var organization: String? = null var jobTitle: String? = null @@ -367,6 +369,14 @@ internal class ContactQueries( ) } } + RelationColumns.CONTENT_ITEM_TYPE -> { + val name = row[RelationColumns.NAME] + val id = row[RelationColumns._ID].toLongOrNull() + if (name.isNotBlank() && id != null) { + val label = relationLabel(row) + relations.add(LabeledValue(Relation(name), label, id)) + } + } else -> { val mimeType = linkedAccountMimeTypes[mimetype] if (mimeType != null) { @@ -415,10 +425,32 @@ internal class ContactQueries( groups = groupIds.toList(), linkedAccountValues = linkedAccountValues.toList(), imAddresses = imAddresses.toList(), + relations = relations.toList() ) } } + private fun relationLabel(row: Cursor): Label { + return when (row[RelationColumns.TYPE].toIntOrNull()) { + RelationColumns.TYPE_ASSISTANT -> Label.PhoneNumberAssistant + RelationColumns.TYPE_BROTHER -> Label.RelationBrother + RelationColumns.TYPE_CHILD -> Label.RelationChild + RelationColumns.TYPE_DOMESTIC_PARTNER -> Label.RelationDomesticPartner + RelationColumns.TYPE_FATHER -> Label.RelationFather + RelationColumns.TYPE_FRIEND -> Label.RelationFriend + RelationColumns.TYPE_MANAGER -> Label.RelationManager + RelationColumns.TYPE_MOTHER -> Label.RelationMother + RelationColumns.TYPE_PARENT -> Label.RelationParent + RelationColumns.TYPE_PARTNER -> Label.RelationPartner + RelationColumns.TYPE_REFERRED_BY -> Label.RelationReferredBy + RelationColumns.TYPE_RELATIVE -> Label.RelationRelative + RelationColumns.TYPE_SISTER -> Label.RelationSister + RelationColumns.TYPE_SPOUSE -> Label.RelationSpouse + RelationColumns.TYPE_CUSTOM -> Label.Custom(row[RelationColumns.LABEL]) + else -> Label.Other + } + } + private fun getImProtocol(fromCursor: Cursor): String { // starting from Android 31, type will always be PROTOCOL_CUSTOM according to docs // the else covers legacy versions @@ -458,6 +490,7 @@ internal class ContactQueries( Nickname -> NicknameColumns.CONTENT_ITEM_TYPE GroupMemberships -> GroupColumns.CONTENT_ITEM_TYPE ImAddresses -> ImColumns.CONTENT_ITEM_TYPE + Relations -> RelationColumns.CONTENT_ITEM_TYPE is LinkedAccountValues -> error("Tried to map a LinkedAccountColumn as standard column") } diff --git a/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt b/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt index 607c043a..9bb3d297 100644 --- a/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt +++ b/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt @@ -33,6 +33,7 @@ fun SaveRequest.insert(builder: MutableContactBuilder.() -> Unit) { postalAddresses.addAll(values.postalAddresses) webAddresses.addAll(values.webAddresses) groups.addAll(values.groupMemberships) + relations.addAll(values.relations) imAddresses.addAll(values.imAddresses) }) } diff --git a/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt b/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt index 96e3a7fc..7da32767 100644 --- a/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt +++ b/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt @@ -65,4 +65,6 @@ internal fun GroupMembership.requireId(): Long { return requireNotNull(_id) } -data class LookupKey(val value: String) \ No newline at end of file +data class LookupKey(val value: String) + +data class Relation(val name: String) \ No newline at end of file diff --git a/library/src/main/java/com/alexstyl/contactstore/ExistingContactOperationsFactory.kt b/library/src/main/java/com/alexstyl/contactstore/ExistingContactOperationsFactory.kt index dded3c90..c0053be3 100644 --- a/library/src/main/java/com/alexstyl/contactstore/ExistingContactOperationsFactory.kt +++ b/library/src/main/java/com/alexstyl/contactstore/ExistingContactOperationsFactory.kt @@ -11,6 +11,7 @@ import android.provider.ContactsContract.CommonDataKinds.Photo as PhotoColumns import android.provider.ContactsContract.CommonDataKinds.StructuredName as NameColumns import android.provider.ContactsContract.CommonDataKinds.StructuredPostal as PostalColumns import android.provider.ContactsContract.CommonDataKinds.Website as WebAddressColumns +import android.provider.ContactsContract.CommonDataKinds.Relation as RelationColumns import android.content.ContentProviderOperation import android.content.ContentProviderOperation.newDelete import android.content.ContentProviderOperation.newInsert @@ -31,6 +32,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses import com.alexstyl.contactstore.utils.get import com.alexstyl.contactstore.utils.runQuery @@ -62,6 +64,7 @@ internal class ExistingContactOperationsFactory( updateGroupMembership(newContact = contact, oldContact = existingContact) + updatePostalAddresses(newContact = contact, oldContact = existingContact) + updateImAddresses(newContact = contact, oldContact = existingContact) + + updateRelations(newContact = contact, oldContact = existingContact) + replaceWebAddresses(newContact = contact, oldContact = existingContact) } @@ -307,6 +310,24 @@ internal class ExistingContactOperationsFactory( } } + private fun updateRelations( + newContact: MutableContact, + oldContact: Contact + ): List { + if (newContact.containsColumn(Relations).not()) { + return emptyList() + } + return buildOperations( + forContactId = newContact.contactId, + oldValues = oldContact.relations, + newValues = newContact.relations, + mimeType = RelationColumns.CONTENT_ITEM_TYPE, + ) { labeledValue -> + withValue(RelationColumns.NAME, labeledValue.value.name) + .withRelationLabel(labeledValue.label) + } + } + private fun buildOperations( forContactId: Long, mimeType: String, diff --git a/library/src/main/java/com/alexstyl/contactstore/Label.kt b/library/src/main/java/com/alexstyl/contactstore/Label.kt index d8448ad9..0db4ccdf 100644 --- a/library/src/main/java/com/alexstyl/contactstore/Label.kt +++ b/library/src/main/java/com/alexstyl/contactstore/Label.kt @@ -33,4 +33,17 @@ sealed class Label { data class Custom(val label: String) : Label() object Other : Label() + object RelationBrother : Label() + object RelationChild : Label() + object RelationDomesticPartner : Label() + object RelationFather : Label() + object RelationFriend : Label() + object RelationManager : Label() + object RelationMother : Label() + object RelationParent : Label() + object RelationPartner : Label() + object RelationReferredBy : Label() + object RelationRelative : Label() + object RelationSister : Label() + object RelationSpouse : Label() } diff --git a/library/src/main/java/com/alexstyl/contactstore/MutableContact.kt b/library/src/main/java/com/alexstyl/contactstore/MutableContact.kt index 84ebf047..a5042df5 100644 --- a/library/src/main/java/com/alexstyl/contactstore/MutableContact.kt +++ b/library/src/main/java/com/alexstyl/contactstore/MutableContact.kt @@ -11,6 +11,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses class MutableContact internal constructor( @@ -40,6 +41,7 @@ class MutableContact internal constructor( groups: MutableList, linkedAccountValues: List, imAddresses: MutableList>, + relations: MutableList>, override val columns: List, ) : Contact { @@ -61,6 +63,8 @@ class MutableContact internal constructor( override val groups: MutableList by requireColumn(GroupMemberships, groups) + override val relations: MutableList> by requireColumn(Relations, relations) + override var organization: String? by readWriteField(Organization, organization) override var jobTitle: String? by readWriteField(Organization, jobTitle) override var firstName: String? by readWriteField(Names, firstName) @@ -83,6 +87,7 @@ class MutableContact internal constructor( events = mutableListOf(), postalAddresses = mutableListOf(), webAddresses = mutableListOf(), + relations = mutableListOf(), note = null, isStarred = false, firstName = null, diff --git a/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt b/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt index 5b925b31..1ea3a3cd 100644 --- a/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt +++ b/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt @@ -47,6 +47,10 @@ data class MutableContactBuilder( val groupMemberships: List get() = _groups.toList() + private val _relations: MutableList> = mutableListOf() + val relations: List> + get() = _relations.toList() + fun phone( number: String, label: Label @@ -117,4 +121,8 @@ data class MutableContactBuilder( LabeledValue(ImAddress(raw = address, protocol = protocol), label) ) } + + fun relation(name: String, label: Label) { + _relations.add(LabeledValue(Relation(name = name), label)) + } } diff --git a/library/src/main/java/com/alexstyl/contactstore/NewContactOperationsFactory.kt b/library/src/main/java/com/alexstyl/contactstore/NewContactOperationsFactory.kt index a86960c5..df03c5c2 100644 --- a/library/src/main/java/com/alexstyl/contactstore/NewContactOperationsFactory.kt +++ b/library/src/main/java/com/alexstyl/contactstore/NewContactOperationsFactory.kt @@ -2,16 +2,18 @@ package com.alexstyl.contactstore import android.provider.ContactsContract.CommonDataKinds.Email as EmailColumns import android.provider.ContactsContract.CommonDataKinds.Event as EventColumns +import android.provider.ContactsContract.CommonDataKinds.Im as ImColumns import android.provider.ContactsContract.CommonDataKinds.Note as NoteColumns import android.provider.ContactsContract.CommonDataKinds.Organization as OrganizationColumns import android.provider.ContactsContract.CommonDataKinds.Phone as PhoneColumns import android.provider.ContactsContract.CommonDataKinds.Photo as PhotoColumns +import android.provider.ContactsContract.CommonDataKinds.Relation as RelationColumns import android.provider.ContactsContract.CommonDataKinds.StructuredName as NameColumns import android.provider.ContactsContract.CommonDataKinds.StructuredPostal as PostalColumns import android.provider.ContactsContract.CommonDataKinds.Website as WebsiteColumns -import android.provider.ContactsContract.CommonDataKinds.Im as ImColumns import android.content.ContentProviderOperation import android.content.ContentProviderOperation.newInsert +import android.os.Build import android.provider.ContactsContract.CommonDataKinds.Contactables import android.provider.ContactsContract.Data import android.provider.ContactsContract.FullNameStyle @@ -33,6 +35,7 @@ internal class NewContactOperationsFactory { contact.postalAddresses.forEach { add(insertPostalOperation(it)) } contact.note?.run { add(insertNoteOperation(this)) } contact.imAddresses.forEach { add(insertImOperation(it)) } + contact.relations.forEach { add(insertRelationOperation(it)) } if (hasOrganizationDetails(contact)) { add(insertOrganization(contact)) @@ -134,6 +137,14 @@ internal class NewContactOperationsFactory { .build() } + private fun insertRelationOperation(labeledValue: LabeledValue): ContentProviderOperation { + return newInsert(Data.CONTENT_URI) + .withValueBackReference(Data.RAW_CONTACT_ID, NEW_CONTACT_INDEX) + .withValue(Data.MIMETYPE, RelationColumns.CONTENT_ITEM_TYPE) + .withValue(RelationColumns.NAME, labeledValue.value.name) + .withRelationLabel(labeledValue.label) + .build() + } private fun insertLocalRawAccountOperation(contact: MutableContact): ContentProviderOperation { return newInsert(RawContacts.CONTENT_URI) @@ -350,7 +361,7 @@ internal class NewContactOperationsFactory { private fun ContentProviderOperation.Builder.withImLabel( label: Label ): ContentProviderOperation.Builder { - return when(label){ + return when (label) { Label.LocationHome -> withValue( Contactables.TYPE, ImColumns.TYPE_HOME @@ -405,3 +416,78 @@ internal class NewContactOperationsFactory { const val NEW_CONTACT_INDEX = 0 } } + +fun ContentProviderOperation.Builder.withRelationLabel( + label: Label +): ContentProviderOperation.Builder { + return when (label) { + Label.PhoneNumberAssistant -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_ASSISTANT + ) + Label.RelationBrother -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_BROTHER + ) + Label.RelationDomesticPartner -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_DOMESTIC_PARTNER + ) + Label.RelationChild -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_CHILD + ) + Label.RelationFather -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_FATHER + ) + Label.RelationMother -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_MOTHER + ) + Label.RelationManager -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_MANAGER + ) + Label.RelationFriend -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_FRIEND + ) + Label.RelationParent -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_PARENT + ) + Label.RelationPartner -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_PARTNER + ) + Label.RelationReferredBy -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_REFERRED_BY + ) + Label.RelationSister -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_SISTER + ) + Label.RelationSpouse -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_SPOUSE + ) + Label.RelationRelative -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_RELATIVE + ) + Label.Other -> withValue( + Contactables.TYPE, + RelationColumns.TYPE_CHILD + ) + is Label.Custom -> { + withValue( + Contactables.TYPE, + Contactables.TYPE_CUSTOM + ) + .withValue(Contactables.LABEL, label.label) + } + else -> error("Unsupported Postal Label $label") + } +} diff --git a/library/src/main/java/com/alexstyl/contactstore/PartialContact.kt b/library/src/main/java/com/alexstyl/contactstore/PartialContact.kt index a751e33c..776734d0 100644 --- a/library/src/main/java/com/alexstyl/contactstore/PartialContact.kt +++ b/library/src/main/java/com/alexstyl/contactstore/PartialContact.kt @@ -12,6 +12,7 @@ import com.alexstyl.contactstore.ContactColumn.Note import com.alexstyl.contactstore.ContactColumn.Organization import com.alexstyl.contactstore.ContactColumn.Phones import com.alexstyl.contactstore.ContactColumn.PostalAddresses +import com.alexstyl.contactstore.ContactColumn.Relations import com.alexstyl.contactstore.ContactColumn.WebAddresses class PartialContact constructor( @@ -42,7 +43,8 @@ class PartialContact constructor( phoneticNameStyle: Int = ContactsContract.PhoneticNameStyle.UNDEFINED, groups: List = emptyList(), imAddresses: List> = emptyList(), - linkedAccountValues: List = emptyList() + linkedAccountValues: List = emptyList(), + relations: List> = emptyList() ) : Contact { override val prefix by requireColumn(Names, prefix) override val firstName by requireColumn(Names, firstName) @@ -67,6 +69,7 @@ class PartialContact constructor( override val jobTitle by requireColumn(Organization, jobTitle) override val linkedAccountValues by requireAnyLinkedAccountColumn(linkedAccountValues) override val groups: List by requireColumn(GroupMemberships, groups) + override val relations: List> by requireColumn(Relations, relations) override fun equals(other: Any?): Boolean { return equalContacts(other as? Contact)