Display recent, starred, and contact groups in compose

This commit is contained in:
moezbhatti
2019-10-27 22:04:43 -04:00
committed by Moez Bhatti
parent 8f67de736a
commit a91643e882
14 changed files with 411 additions and 164 deletions
@@ -29,4 +29,4 @@ class ContactFilter @Inject constructor(private val phoneNumberFilter: PhoneNumb
item.numbers.map { it.address }.any { address -> phoneNumberFilter.filter(address, query) } // Number
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.filter
import com.moez.QKSMS.extensions.removeAccents
import com.moez.QKSMS.model.ContactGroup
import javax.inject.Inject
class ContactGroupFilter @Inject constructor(private val contactFilter: ContactFilter) : Filter<ContactGroup>() {
override fun filter(item: ContactGroup, query: CharSequence): Boolean {
return item.title.removeAccents().contains(query, true) || // Name
item.contacts.any { contact -> contactFilter.filter(contact, query) } // Contacts
}
}
@@ -25,10 +25,13 @@ import android.provider.ContactsContract
import android.provider.ContactsContract.CommonDataKinds.Email
import android.provider.ContactsContract.CommonDataKinds.Phone
import com.moez.QKSMS.extensions.asFlowable
import com.moez.QKSMS.extensions.asObservable
import com.moez.QKSMS.extensions.mapNotNull
import com.moez.QKSMS.model.Contact
import com.moez.QKSMS.model.ContactGroup
import com.moez.QKSMS.util.Preferences
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
@@ -70,55 +73,68 @@ class ContactRepositoryImpl @Inject constructor(
.findAll()
}
override fun getUnmanagedContacts(): Flowable<List<Contact>> {
override fun getUnmanagedContacts(starred: Boolean): Observable<List<Contact>> {
val realm = Realm.getDefaultInstance()
val mobileLabel by lazy {
Phone.getTypeLabel(context.resources, Phone.TYPE_MOBILE, "Mobile").toString()
val mobileOnly = prefs.mobileOnly.get()
val mobileLabel by lazy { Phone.getTypeLabel(context.resources, Phone.TYPE_MOBILE, "Mobile").toString() }
var query = realm.where(Contact::class.java)
if (mobileOnly) {
query = query.contains("numbers.type", mobileLabel)
}
val contactsFlowable = when (prefs.mobileOnly.get()) {
true -> realm.where(Contact::class.java)
.contains("numbers.type", mobileLabel)
.findAllAsync()
.asFlowable()
.filter { it.isLoaded }
.filter { it.isValid }
.map { realm.copyFromRealm(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.map { contacts ->
if (starred) {
query = query.equalTo("starred", true)
}
return query
.findAllAsync()
.asObservable()
.filter { it.isLoaded }
.filter { it.isValid }
.map { realm.copyFromRealm(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.map { contacts ->
if (mobileOnly) {
contacts.map { contact ->
val filteredNumbers = contact.numbers.filter { number -> number.type == mobileLabel }
contact.numbers.clear()
contact.numbers.addAll(filteredNumbers)
contact
}
} else {
contacts
}
false -> realm.where(Contact::class.java)
.findAllAsync()
.asFlowable()
.filter { it.isLoaded }
.filter { it.isValid }
.map { realm.copyFromRealm(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
}
return contactsFlowable.map { contacts ->
contacts.sortedWith(Comparator { c1, c2 ->
val initial = c1.name.firstOrNull()
val other = c2.name.firstOrNull()
if (initial?.isLetter() == true && other?.isLetter() != true) {
-1
} else if (initial?.isLetter() != true && other?.isLetter() == true) {
1
} else {
c1.name.compareTo(c2.name, ignoreCase = true)
}
})
}
.map { contacts ->
contacts.sortedWith(Comparator { c1, c2 ->
val initial = c1.name.firstOrNull()
val other = c2.name.firstOrNull()
if (initial?.isLetter() == true && other?.isLetter() != true) {
-1
} else if (initial?.isLetter() != true && other?.isLetter() == true) {
1
} else {
c1.name.compareTo(c2.name, ignoreCase = true)
}
})
}
}
override fun getUnmanagedContactGroups(): Observable<List<ContactGroup>> {
val realm = Realm.getDefaultInstance()
return realm.where(ContactGroup::class.java)
.isNotEmpty("contacts")
.findAllAsync()
.asObservable()
.filter { it.isLoaded }
.filter { it.isValid }
.map { realm.copyFromRealm(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
}
}
@@ -23,6 +23,7 @@ import android.content.Context
import android.provider.Telephony
import com.moez.QKSMS.compat.TelephonyCompat
import com.moez.QKSMS.extensions.anyOf
import com.moez.QKSMS.extensions.asObservable
import com.moez.QKSMS.extensions.map
import com.moez.QKSMS.extensions.removeAccents
import com.moez.QKSMS.filter.ConversationFilter
@@ -35,6 +36,9 @@ import com.moez.QKSMS.model.Recipient
import com.moez.QKSMS.model.SearchResult
import com.moez.QKSMS.util.PhoneNumberUtils
import com.moez.QKSMS.util.tryOrNull
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import io.realm.Case
import io.realm.Realm
import io.realm.RealmResults
@@ -183,6 +187,25 @@ class ConversationRepositoryImpl @Inject constructor(
.findAll()
}
override fun getUnmanagedConversations(): Observable<List<Conversation>> {
val realm = Realm.getDefaultInstance()
return realm.where(Conversation::class.java)
.sort("date", Sort.DESCENDING)
.notEqualTo("id", 0L)
.greaterThan("count", 0)
.equalTo("archived", false)
.equalTo("blocked", false)
.isNotEmpty("recipients")
.limit(5)
.findAllAsync()
.asObservable()
.filter { it.isLoaded }
.filter { it.isValid }
.map { realm.copyFromRealm(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
}
override fun getRecipient(recipientId: Long): Recipient? {
return Realm.getDefaultInstance()
.where(Recipient::class.java)