mirror of
https://github.com/SimpleMobileTools/Simple-Dialer.git
synced 2025-02-12 01:20:49 +01:00
Improved RecentCallsAdapter for onScroll loading
This commit is contained in:
parent
56d0a0ca07
commit
939cba30ea
@ -260,6 +260,7 @@ class RecentCallsAdapter(
|
||||
if (newItems.hashCode() != recentCalls.hashCode()) {
|
||||
recentCalls = newItems.clone() as ArrayList<RecentCall>
|
||||
textToHighlight = highlightText
|
||||
recyclerView.resetItemCount()
|
||||
notifyDataSetChanged()
|
||||
finishActMode()
|
||||
} else if (textToHighlight != highlightText) {
|
||||
|
@ -8,17 +8,23 @@ import com.simplemobiletools.commons.helpers.ContactsHelper
|
||||
import com.simplemobiletools.commons.helpers.MyContactsContentProvider
|
||||
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALL_LOG
|
||||
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
|
||||
import com.simplemobiletools.commons.models.contacts.Contact
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.dialer.R
|
||||
import com.simplemobiletools.dialer.activities.SimpleActivity
|
||||
import com.simplemobiletools.dialer.adapters.RecentCallsAdapter
|
||||
import com.simplemobiletools.dialer.extensions.config
|
||||
import com.simplemobiletools.dialer.helpers.MIN_RECENTS_THRESHOLD
|
||||
import com.simplemobiletools.dialer.helpers.RecentsHelper
|
||||
import com.simplemobiletools.dialer.interfaces.RefreshItemsListener
|
||||
import com.simplemobiletools.dialer.models.RecentCall
|
||||
import kotlinx.android.synthetic.main.fragment_recents.view.*
|
||||
import kotlinx.android.synthetic.main.fragment_recents.view.recents_list
|
||||
import kotlinx.android.synthetic.main.fragment_recents.view.recents_placeholder
|
||||
import kotlinx.android.synthetic.main.fragment_recents.view.recents_placeholder_2
|
||||
|
||||
class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshItemsListener {
|
||||
private var allRecentCalls = ArrayList<RecentCall>()
|
||||
private var recentsAdapter: RecentCallsAdapter? = null
|
||||
|
||||
override fun setupFragment() {
|
||||
val placeholderResId = if (context.hasPermission(PERMISSION_READ_CALL_LOG)) {
|
||||
@ -40,7 +46,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
recents_placeholder.setTextColor(textColor)
|
||||
recents_placeholder_2.setTextColor(properPrimaryColor)
|
||||
|
||||
(recents_list?.adapter as? RecentCallsAdapter)?.apply {
|
||||
recentsAdapter?.apply {
|
||||
initDrawables()
|
||||
updateTextColor(textColor)
|
||||
}
|
||||
@ -49,36 +55,14 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
override fun refreshItems(callback: (() -> Unit)?) {
|
||||
val privateCursor = context?.getMyContactsCursor(false, true)
|
||||
val groupSubsequentCalls = context?.config?.groupSubsequentCalls ?: false
|
||||
RecentsHelper(context).getRecentCalls(groupSubsequentCalls) { recents ->
|
||||
val querySize = allRecentCalls.size.coerceAtLeast(MIN_RECENTS_THRESHOLD)
|
||||
RecentsHelper(context).getRecentCalls(groupSubsequentCalls, querySize) { recents ->
|
||||
ContactsHelper(context).getContacts(showOnlyContactsWithNumbers = true) { contacts ->
|
||||
val privateContacts = MyContactsContentProvider.getContacts(context, privateCursor)
|
||||
|
||||
recents.filter { it.phoneNumber == it.name }.forEach { recent ->
|
||||
var wasNameFilled = false
|
||||
if (privateContacts.isNotEmpty()) {
|
||||
val privateContact = privateContacts.firstOrNull { it.doesContainPhoneNumber(recent.phoneNumber) }
|
||||
if (privateContact != null) {
|
||||
recent.name = privateContact.getNameToDisplay()
|
||||
wasNameFilled = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasNameFilled) {
|
||||
val contact = contacts.filter { it.phoneNumbers.isNotEmpty() }.firstOrNull { it.phoneNumbers.first().normalizedNumber == recent.phoneNumber }
|
||||
if (contact != null) {
|
||||
recent.name = contact.getNameToDisplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
allRecentCalls = recents
|
||||
|
||||
// hide private contacts from recent calls
|
||||
if (SMT_PRIVATE in context.baseConfig.ignoredContactSources) {
|
||||
allRecentCalls = recents.filterNot { recent ->
|
||||
val privateNumbers = privateContacts.flatMap { it.phoneNumbers }.map { it.value }
|
||||
recent.phoneNumber in privateNumbers
|
||||
} as ArrayList
|
||||
}
|
||||
.setNamesIfEmpty(contacts, privateContacts)
|
||||
.hidePrivateContacts(privateContacts, SMT_PRIVATE in context.baseConfig.ignoredContactSources)
|
||||
|
||||
activity?.runOnUiThread {
|
||||
gotRecents(allRecentCalls)
|
||||
@ -99,7 +83,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
|
||||
val currAdapter = recents_list.adapter
|
||||
if (currAdapter == null) {
|
||||
RecentCallsAdapter(activity as SimpleActivity, recents, recents_list, this, true) {
|
||||
recentsAdapter = RecentCallsAdapter(activity as SimpleActivity, recents, recents_list, this, true) {
|
||||
val recentCall = it as RecentCall
|
||||
if (context.config.showCallConfirmation) {
|
||||
CallConfirmationDialog(activity as SimpleActivity, recentCall.name) {
|
||||
@ -108,15 +92,43 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
} else {
|
||||
activity?.launchCallIntent(recentCall.phoneNumber)
|
||||
}
|
||||
}.apply {
|
||||
recents_list.adapter = this
|
||||
}
|
||||
|
||||
recents_list.adapter = recentsAdapter
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
recents_list.scheduleLayoutAnimation()
|
||||
}
|
||||
|
||||
recents_list.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener {
|
||||
override fun updateTop() {}
|
||||
|
||||
override fun updateBottom() {
|
||||
getMoreRecentCalls()
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
(currAdapter as RecentCallsAdapter).updateItems(recents)
|
||||
recentsAdapter?.updateItems(recents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMoreRecentCalls() {
|
||||
val privateCursor = context?.getMyContactsCursor(false, true)
|
||||
val groupSubsequentCalls = context?.config?.groupSubsequentCalls ?: false
|
||||
val querySize = allRecentCalls.size.plus(MIN_RECENTS_THRESHOLD)
|
||||
RecentsHelper(context).getRecentCalls(groupSubsequentCalls, querySize) { recents ->
|
||||
ContactsHelper(context).getContacts(showOnlyContactsWithNumbers = true) { contacts ->
|
||||
val privateContacts = MyContactsContentProvider.getContacts(context, privateCursor)
|
||||
|
||||
allRecentCalls = recents
|
||||
.setNamesIfEmpty(contacts, privateContacts)
|
||||
.hidePrivateContacts(privateContacts, SMT_PRIVATE in context.baseConfig.ignoredContactSources)
|
||||
|
||||
activity?.runOnUiThread {
|
||||
gotRecents(allRecentCalls)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +151,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
|
||||
override fun onSearchClosed() {
|
||||
recents_placeholder.beVisibleIf(allRecentCalls.isEmpty())
|
||||
(recents_list.adapter as? RecentCallsAdapter)?.updateItems(allRecentCalls)
|
||||
recentsAdapter?.updateItems(allRecentCalls)
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
@ -150,6 +162,39 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
||||
}.toMutableList() as ArrayList<RecentCall>
|
||||
|
||||
recents_placeholder.beVisibleIf(recentCalls.isEmpty())
|
||||
(recents_list.adapter as? RecentCallsAdapter)?.updateItems(recentCalls, text)
|
||||
recentsAdapter?.updateItems(recentCalls, text)
|
||||
}
|
||||
}
|
||||
|
||||
// hide private contacts from recent calls
|
||||
private fun List<RecentCall>.hidePrivateContacts(privateContacts: ArrayList<Contact>, shouldHide: Boolean): ArrayList<RecentCall> {
|
||||
return if (shouldHide) {
|
||||
filterNot { recent ->
|
||||
val privateNumbers = privateContacts.flatMap { it.phoneNumbers }.map { it.value }
|
||||
recent.phoneNumber in privateNumbers
|
||||
} as ArrayList
|
||||
} else {
|
||||
this as ArrayList
|
||||
}
|
||||
}
|
||||
|
||||
private fun ArrayList<RecentCall>.setNamesIfEmpty(contacts: ArrayList<Contact>, privateContacts: ArrayList<Contact>): ArrayList<RecentCall> {
|
||||
filter { it.phoneNumber == it.name }.forEach { recent ->
|
||||
var wasNameFilled = false
|
||||
if (privateContacts.isNotEmpty()) {
|
||||
val privateContact = privateContacts.firstOrNull { it.doesContainPhoneNumber(recent.phoneNumber) }
|
||||
if (privateContact != null) {
|
||||
recent.name = privateContact.getNameToDisplay()
|
||||
wasNameFilled = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasNameFilled) {
|
||||
val contact = contacts.filter { it.phoneNumbers.isNotEmpty() }.firstOrNull { it.phoneNumbers.first().normalizedNumber == recent.phoneNumber }
|
||||
if (contact != null) {
|
||||
recent.name = contact.getNameToDisplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
@ -28,3 +28,5 @@ const val ACCEPT_CALL = PATH + "accept_call"
|
||||
const val DECLINE_CALL = PATH + "decline_call"
|
||||
|
||||
const val DIALPAD_TONE_LENGTH_MS = 150L // The length of DTMF tones in milliseconds
|
||||
|
||||
const val MIN_RECENTS_THRESHOLD = 30
|
||||
|
@ -13,10 +13,10 @@ import com.simplemobiletools.dialer.models.RecentCall
|
||||
|
||||
class RecentsHelper(private val context: Context) {
|
||||
private val COMPARABLE_PHONE_NUMBER_LENGTH = 9
|
||||
private val QUERY_LIMIT = "200"
|
||||
private val QUERY_LIMIT = 200
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun getRecentCalls(groupSubsequentCalls: Boolean, callback: (ArrayList<RecentCall>) -> Unit) {
|
||||
fun getRecentCalls(groupSubsequentCalls: Boolean, maxSize: Int = QUERY_LIMIT, callback: (ArrayList<RecentCall>) -> Unit) {
|
||||
val privateCursor = context.getMyContactsCursor(false, true)
|
||||
ensureBackgroundThread {
|
||||
if (!context.hasPermission(PERMISSION_READ_CALL_LOG)) {
|
||||
@ -30,13 +30,13 @@ class RecentsHelper(private val context: Context) {
|
||||
contacts.addAll(privateContacts)
|
||||
}
|
||||
|
||||
getRecents(contacts, groupSubsequentCalls, callback)
|
||||
getRecents(contacts, groupSubsequentCalls, maxSize, callback = callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun getRecents(contacts: ArrayList<Contact>, groupSubsequentCalls: Boolean, callback: (ArrayList<RecentCall>) -> Unit) {
|
||||
private fun getRecents(contacts: ArrayList<Contact>, groupSubsequentCalls: Boolean, maxSize: Int, callback: (ArrayList<RecentCall>) -> Unit) {
|
||||
|
||||
var recentCalls = ArrayList<RecentCall>()
|
||||
var previousRecentCallFrom = ""
|
||||
@ -64,7 +64,7 @@ class RecentsHelper(private val context: Context) {
|
||||
val cursor = if (isNougatPlus()) {
|
||||
// https://issuetracker.google.com/issues/175198972?pli=1#comment6
|
||||
val limitedUri = uri.buildUpon()
|
||||
.appendQueryParameter(Calls.LIMIT_PARAM_KEY, QUERY_LIMIT)
|
||||
.appendQueryParameter(Calls.LIMIT_PARAM_KEY, QUERY_LIMIT.toString())
|
||||
.build()
|
||||
val sortOrder = "${Calls._ID} DESC"
|
||||
context.contentResolver.query(limitedUri, projection, null, null, sortOrder)
|
||||
@ -163,7 +163,7 @@ class RecentsHelper(private val context: Context) {
|
||||
}
|
||||
|
||||
previousRecentCallFrom = "$number$name$simID"
|
||||
} while (cursor.moveToNext())
|
||||
} while (cursor.moveToNext() && recentCalls.size < maxSize)
|
||||
}
|
||||
cursor?.close()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user