#329 - Sync contact after adding

This commit is contained in:
Moez Bhatti
2018-09-03 14:39:32 -04:00
parent 0de41ce661
commit 14399e057d
6 changed files with 116 additions and 1 deletions
@@ -0,0 +1,54 @@
package com.moez.QKSMS.listener
import android.content.Context
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.provider.ContactsContract
import com.moez.QKSMS.repository.SyncRepository
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.subjects.PublishSubject
import javax.inject.Inject
/**
* Listens for a contact being added, and then syncs it to Realm
*
* TODO: Stop listening automatically. Currently, this will only happen if the contact is added
*/
class ContactAddedListenerImpl @Inject constructor(
private val context: Context,
private val syncRepo: SyncRepository
) : ContactAddedListener {
companion object {
private val URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
}
override fun listen(address: String): Single<*> {
val observable = ContactContentObserver(context).observable
.filter { syncRepo.syncContact(address) }
return Single.fromObservable(observable)
}
private class ContactContentObserver(context: Context) : ContentObserver(Handler()) {
private val subject = PublishSubject.create<Unit>()
val observable: Observable<Unit> = subject
.doOnSubscribe { context.contentResolver.registerContentObserver(URI, true, this) }
.doOnDispose { context.contentResolver.unregisterContentObserver(this) }
.share()
override fun onChange(selfChange: Boolean) {
this.onChange(selfChange, null)
}
override fun onChange(selfChange: Boolean, uri: Uri?) {
subject.onNext(Unit)
}
}
}
@@ -26,6 +26,7 @@ import android.telephony.PhoneNumberUtils
import com.f2prateek.rx.preferences2.RxSharedPreferences
import com.moez.QKSMS.extensions.insertOrUpdate
import com.moez.QKSMS.extensions.map
import com.moez.QKSMS.filter.PhoneNumberFilter
import com.moez.QKSMS.manager.KeyManager
import com.moez.QKSMS.mapper.CursorToContact
import com.moez.QKSMS.mapper.CursorToConversation
@@ -54,6 +55,7 @@ class SyncRepositoryImpl @Inject constructor(
private val cursorToRecipient: CursorToRecipient,
private val cursorToContact: CursorToContact,
private val keys: KeyManager,
private val phoneNumberFilter: PhoneNumberFilter,
private val rxPrefs: RxSharedPreferences
) : SyncRepository {
@@ -239,6 +241,30 @@ class SyncRepositoryImpl @Inject constructor(
}
}
override fun syncContact(address: String): Boolean {
// See if there's a contact that matches this phone number
var contact = getContacts().firstOrNull {
it.numbers.any { number -> PhoneNumberUtils.compare(number.address, address) }
} ?: return false
Realm.getDefaultInstance().use { realm ->
val recipients = realm.where(Recipient::class.java).findAll()
realm.executeTransaction {
contact = realm.copyToRealm(contact)
// Update all the matching recipients with the new contact
val updatedRecipients = recipients
.filter { recipient -> contact.numbers.any { number -> PhoneNumberUtils.compare(recipient.address, number.address) } }
.map { recipient -> recipient.apply { this.contact = contact } }
realm.insertOrUpdate(updatedRecipients)
}
}
return true
}
private fun getContacts(): List<Contact> {
return cursorToContact.getContactsCursor()
?.map { cursor -> cursorToContact.map(cursor) }