227 lines
8.8 KiB
Kotlin
227 lines
8.8 KiB
Kotlin
package com.simplemobiletools.dialer.fragments
|
|
|
|
import android.content.Context
|
|
import android.util.AttributeSet
|
|
import com.google.gson.Gson
|
|
import com.reddit.indicatorfastscroll.FastScrollItemIndicator
|
|
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
|
import com.simplemobiletools.commons.dialogs.CallConfirmationDialog
|
|
import com.simplemobiletools.commons.extensions.*
|
|
import com.simplemobiletools.commons.helpers.*
|
|
import com.simplemobiletools.commons.models.contacts.Contact
|
|
import com.simplemobiletools.commons.views.MyGridLayoutManager
|
|
import com.simplemobiletools.commons.views.MyLinearLayoutManager
|
|
import com.simplemobiletools.dialer.R
|
|
import com.simplemobiletools.dialer.activities.SimpleActivity
|
|
import com.simplemobiletools.dialer.adapters.ContactsAdapter
|
|
import com.simplemobiletools.dialer.databinding.FragmentFavoritesBinding
|
|
import com.simplemobiletools.dialer.databinding.FragmentLettersLayoutBinding
|
|
import com.simplemobiletools.dialer.extensions.config
|
|
import com.simplemobiletools.dialer.helpers.Converters
|
|
import com.simplemobiletools.dialer.interfaces.RefreshItemsListener
|
|
import java.util.Locale
|
|
|
|
class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment<MyViewPagerFragment.LettersInnerBinding>(context, attributeSet),
|
|
RefreshItemsListener {
|
|
private lateinit var binding: FragmentLettersLayoutBinding
|
|
private var allContacts = ArrayList<Contact>()
|
|
|
|
override fun onFinishInflate() {
|
|
super.onFinishInflate()
|
|
binding = FragmentLettersLayoutBinding.bind(FragmentFavoritesBinding.bind(this).favoritesFragment)
|
|
innerBinding = LettersInnerBinding(binding)
|
|
}
|
|
|
|
override fun setupFragment() {
|
|
val placeholderResId = if (context.hasPermission(PERMISSION_READ_CONTACTS)) {
|
|
R.string.no_contacts_found
|
|
} else {
|
|
R.string.could_not_access_contacts
|
|
}
|
|
|
|
binding.fragmentPlaceholder.text = context.getString(placeholderResId)
|
|
binding.fragmentPlaceholder2.beGone()
|
|
}
|
|
|
|
override fun setupColors(textColor: Int, primaryColor: Int, properPrimaryColor: Int) {
|
|
binding.apply {
|
|
fragmentPlaceholder.setTextColor(textColor)
|
|
(fragmentList.adapter as? MyRecyclerViewAdapter)?.updateTextColor(textColor)
|
|
|
|
letterFastscroller.textColor = textColor.getColorStateList()
|
|
letterFastscroller.pressedTextColor = properPrimaryColor
|
|
letterFastscrollerThumb.setupWithFastScroller(letterFastscroller)
|
|
letterFastscrollerThumb.textColor = properPrimaryColor.getContrastColor()
|
|
letterFastscrollerThumb.thumbColor = properPrimaryColor.getColorStateList()
|
|
}
|
|
}
|
|
|
|
override fun refreshItems(callback: (() -> Unit)?) {
|
|
ContactsHelper(context).getContacts(showOnlyContactsWithNumbers = true) { contacts ->
|
|
allContacts = contacts
|
|
|
|
if (SMT_PRIVATE !in context.baseConfig.ignoredContactSources) {
|
|
val privateCursor = context?.getMyContactsCursor(true, true)
|
|
val privateContacts = MyContactsContentProvider.getContacts(context, privateCursor).map {
|
|
it.copy(starred = 1)
|
|
}
|
|
if (privateContacts.isNotEmpty()) {
|
|
allContacts.addAll(privateContacts)
|
|
allContacts.sort()
|
|
}
|
|
}
|
|
val favorites = contacts.filter { it.starred == 1 } as ArrayList<Contact>
|
|
|
|
allContacts = if (activity!!.config.isCustomOrderSelected) {
|
|
sortByCustomOrder(favorites)
|
|
} else {
|
|
favorites
|
|
}
|
|
|
|
activity?.runOnUiThread {
|
|
gotContacts(allContacts)
|
|
callback?.invoke()
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun gotContacts(contacts: ArrayList<Contact>) {
|
|
setupLetterFastScroller(contacts)
|
|
binding.apply {
|
|
if (contacts.isEmpty()) {
|
|
fragmentPlaceholder.beVisible()
|
|
fragmentList.beGone()
|
|
} else {
|
|
fragmentPlaceholder.beGone()
|
|
fragmentList.beVisible()
|
|
|
|
updateListAdapter()
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun updateListAdapter() {
|
|
val viewType = context.config.viewType
|
|
setViewType(viewType)
|
|
|
|
val currAdapter = binding.fragmentList.adapter as ContactsAdapter?
|
|
if (currAdapter == null) {
|
|
ContactsAdapter(
|
|
activity = activity as SimpleActivity,
|
|
contacts = allContacts,
|
|
recyclerView = binding.fragmentList,
|
|
refreshItemsListener = this,
|
|
viewType = viewType,
|
|
showDeleteButton = false,
|
|
enableDrag = true,
|
|
) {
|
|
if (context.config.showCallConfirmation) {
|
|
CallConfirmationDialog(activity as SimpleActivity, (it as Contact).getNameToDisplay()) {
|
|
activity?.apply {
|
|
initiateCall(it) { launchCallIntent(it) }
|
|
}
|
|
}
|
|
} else {
|
|
activity?.apply {
|
|
initiateCall(it as Contact) { launchCallIntent(it) }
|
|
}
|
|
}
|
|
}.apply {
|
|
binding.fragmentList.adapter = this
|
|
|
|
onDragEndListener = {
|
|
val adapter = binding.fragmentList.adapter
|
|
if (adapter is ContactsAdapter) {
|
|
val items = adapter.contacts
|
|
saveCustomOrderToPrefs(items)
|
|
setupLetterFastScroller(items)
|
|
}
|
|
}
|
|
|
|
onSpanCountListener = { newSpanCount ->
|
|
context.config.contactsGridColumnCount = newSpanCount
|
|
}
|
|
}
|
|
|
|
if (context.areSystemAnimationsEnabled) {
|
|
binding.fragmentList.scheduleLayoutAnimation()
|
|
}
|
|
} else {
|
|
currAdapter.viewType = viewType
|
|
currAdapter.updateItems(allContacts)
|
|
}
|
|
}
|
|
|
|
fun columnCountChanged() {
|
|
(binding.fragmentList.layoutManager as MyGridLayoutManager).spanCount = context!!.config.contactsGridColumnCount
|
|
binding.fragmentList.adapter?.apply {
|
|
notifyItemRangeChanged(0, allContacts.size)
|
|
}
|
|
}
|
|
|
|
private fun sortByCustomOrder(favorites: List<Contact>): ArrayList<Contact> {
|
|
val favoritesOrder = activity!!.config.favoritesContactsOrder
|
|
|
|
if (favoritesOrder.isEmpty()) {
|
|
return ArrayList(favorites)
|
|
}
|
|
|
|
val orderList = Converters().jsonToStringList(favoritesOrder)
|
|
val map = orderList.withIndex().associate { it.value to it.index }
|
|
val sorted = favorites.sortedBy { map[it.contactId.toString()] }
|
|
|
|
return ArrayList(sorted)
|
|
}
|
|
|
|
private fun saveCustomOrderToPrefs(items: List<Contact>) {
|
|
activity?.apply {
|
|
val orderIds = items.map { it.contactId }
|
|
val orderGsonString = Gson().toJson(orderIds)
|
|
config.favoritesContactsOrder = orderGsonString
|
|
}
|
|
}
|
|
|
|
private fun setupLetterFastScroller(contacts: List<Contact>) {
|
|
binding.letterFastscroller.setupWithRecyclerView(binding.fragmentList, { position ->
|
|
try {
|
|
val name = contacts[position].getNameToDisplay()
|
|
val character = if (name.isNotEmpty()) name.substring(0, 1) else ""
|
|
FastScrollItemIndicator.Text(character.uppercase(Locale.getDefault()).normalizeString())
|
|
} catch (e: Exception) {
|
|
FastScrollItemIndicator.Text("")
|
|
}
|
|
})
|
|
}
|
|
|
|
override fun onSearchClosed() {
|
|
binding.fragmentPlaceholder.beVisibleIf(allContacts.isEmpty())
|
|
(binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(allContacts)
|
|
setupLetterFastScroller(allContacts)
|
|
}
|
|
|
|
override fun onSearchQueryChanged(text: String) {
|
|
val contacts = allContacts.filter {
|
|
it.name.contains(text, true) || it.doesContainPhoneNumber(text)
|
|
}.sortedByDescending {
|
|
it.name.startsWith(text, true)
|
|
}.toMutableList() as ArrayList<Contact>
|
|
|
|
binding.fragmentPlaceholder.beVisibleIf(contacts.isEmpty())
|
|
(binding.fragmentList.adapter as? ContactsAdapter)?.updateItems(contacts, text)
|
|
setupLetterFastScroller(contacts)
|
|
}
|
|
|
|
private fun setViewType(viewType: Int) {
|
|
val spanCount = context.config.contactsGridColumnCount
|
|
|
|
val layoutManager = if (viewType == VIEW_TYPE_GRID) {
|
|
binding.letterFastscroller.beGone()
|
|
MyGridLayoutManager(context, spanCount)
|
|
} else {
|
|
binding.letterFastscroller.beVisible()
|
|
MyLinearLayoutManager(context)
|
|
}
|
|
binding.fragmentList.layoutManager = layoutManager
|
|
}
|
|
}
|