diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt index 39baf6e6..7ad1d146 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt @@ -14,25 +14,27 @@ import kotlinx.android.synthetic.main.item_filter_contact_source.view.* class FilterContactSourcesAdapter( val activity: SimpleActivity, - private val contactSources: List, + private val data: List, private val displayContactSources: ArrayList -) : - RecyclerView.Adapter() { +) : RecyclerView.Adapter() { + private val selectedKeys = HashSet() + data class ContactSourceModel(val contactSource: ContactSource, val count: Int) + init { - contactSources.forEachIndexed { index, contactSource -> - if (displayContactSources.contains(contactSource.name)) { - selectedKeys.add(contactSource.hashCode()) + data.forEachIndexed { index, model -> + if (displayContactSources.contains(model.contactSource.name)) { + selectedKeys.add(model.hashCode()) } - if (contactSource.type == SMT_PRIVATE && displayContactSources.contains(SMT_PRIVATE)) { - selectedKeys.add(contactSource.hashCode()) + if (model.contactSource.type == SMT_PRIVATE && displayContactSources.contains(SMT_PRIVATE)) { + selectedKeys.add(model.hashCode()) } } } - private fun toggleItemSelection(select: Boolean, contactSource: ContactSource, position: Int) { + private fun toggleItemSelection(select: Boolean, contactSource: ContactSourceModel, position: Int) { if (select) { selectedKeys.add(contactSource.hashCode()) } else { @@ -42,7 +44,7 @@ class FilterContactSourcesAdapter( notifyItemChanged(position) } - fun getSelectedContactSources() = contactSources.filter { selectedKeys.contains(it.hashCode()) } + fun getSelectedContactSources() = data.filter { selectedKeys.contains(it.hashCode()) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = activity.layoutInflater.inflate(R.layout.item_filter_contact_source, parent, false) @@ -50,26 +52,27 @@ class FilterContactSourcesAdapter( } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val contactSource = contactSources[position] - holder.bindView(contactSource) + val model = data[position] + holder.bindView(model) } - override fun getItemCount() = contactSources.size + override fun getItemCount() = data.size inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { - fun bindView(contactSource: ContactSource): View { - val isSelected = selectedKeys.contains(contactSource.hashCode()) + fun bindView(model: ContactSourceModel): View { + val isSelected = selectedKeys.contains(model.hashCode()) itemView.apply { filter_contact_source_checkbox.isChecked = isSelected filter_contact_source_checkbox.setColors(activity.getProperTextColor(), activity.getProperPrimaryColor(), activity.getProperBackgroundColor()) - filter_contact_source_checkbox.text = contactSource.publicName - filter_contact_source_holder.setOnClickListener { viewClicked(!isSelected, contactSource) } + val displayName = "${model.contactSource.publicName} (${model.count})" + filter_contact_source_checkbox.text = displayName + filter_contact_source_holder.setOnClickListener { viewClicked(!isSelected, model) } } return itemView } - private fun viewClicked(select: Boolean, contactSource: ContactSource) { + private fun viewClicked(select: Boolean, contactSource: ContactSourceModel) { toggleItemSelection(select, contactSource, adapterPosition) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt index f0457a18..604853e1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt @@ -1,5 +1,6 @@ package com.simplemobiletools.contacts.pro.dialogs +import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog @@ -11,16 +12,21 @@ import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources import com.simplemobiletools.contacts.pro.helpers.ContactsHelper +import com.simplemobiletools.contacts.pro.models.Contact import com.simplemobiletools.contacts.pro.models.ContactSource import kotlinx.android.synthetic.main.dialog_export_contacts.view.* import java.io.File -import java.util.* -class ExportContactsDialog(val activity: SimpleActivity, val path: String, val hidePath: Boolean, - private val callback: (file: File, ignoredContactSources: HashSet) -> Unit) { - private var contactSources = ArrayList() +class ExportContactsDialog( + val activity: SimpleActivity, val path: String, val hidePath: Boolean, + private val callback: (file: File, ignoredContactSources: HashSet) -> Unit +) { private var ignoreClicks = false private var realPath = if (path.isEmpty()) activity.internalStoragePath else path + private var contactSources = ArrayList() + private var contacts = ArrayList() + private var isContactSourcesReady = false + private var isContactsReady = false init { val view = (activity.layoutInflater.inflate(R.layout.dialog_export_contacts, null) as ViewGroup).apply { @@ -40,47 +46,71 @@ class ExportContactsDialog(val activity: SimpleActivity, val path: String, val h } } - ContactsHelper(activity).getContactSources { - it.mapTo(contactSources) { it.copy() } - activity.runOnUiThread { - export_contacts_list.adapter = FilterContactSourcesAdapter(activity, it, activity.getVisibleContactSources()) - } + ContactsHelper(activity).getContactSources { contactSources -> + contactSources.mapTo(this@ExportContactsDialog.contactSources) { it.copy() } + isContactSourcesReady = true + processDataIfReady(this) + } + + ContactsHelper(activity).getContacts(getAll = true) { contacts -> + contacts.mapTo(this@ExportContactsDialog.contacts) { it.copy() } + isContactsReady = true + processDataIfReady(this) } } AlertDialog.Builder(activity) - .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.cancel, null) - .create().apply { - activity.setupDialogStuff(view, this, R.string.export_contacts) { - getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - if (view.export_contacts_list.adapter == null || ignoreClicks) { - return@setOnClickListener - } + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.cancel, null) + .create().apply { + activity.setupDialogStuff(view, this, R.string.export_contacts) { + getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + if (view.export_contacts_list.adapter == null || ignoreClicks) { + return@setOnClickListener + } - val filename = view.export_contacts_filename.value - when { - filename.isEmpty() -> activity.toast(R.string.empty_name) - filename.isAValidFilename() -> { - val file = File(realPath, "$filename.vcf") - if (!hidePath && file.exists()) { - activity.toast(R.string.name_taken) - return@setOnClickListener - } - - ignoreClicks = true - ensureBackgroundThread { - activity.config.lastExportPath = file.absolutePath.getParentPath() - val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() - val ignoredSources = contactSources.filter { !selectedSources.contains(it) }.map { it.getFullIdentifier() }.toHashSet() - callback(file, ignoredSources) - dismiss() - } + val filename = view.export_contacts_filename.value + when { + filename.isEmpty() -> activity.toast(R.string.empty_name) + filename.isAValidFilename() -> { + val file = File(realPath, "$filename.vcf") + if (!hidePath && file.exists()) { + activity.toast(R.string.name_taken) + return@setOnClickListener + } + + ignoreClicks = true + ensureBackgroundThread { + activity.config.lastExportPath = file.absolutePath.getParentPath() + val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() + val ignoredSources = contactSources + .filter { !selectedSources.map { source -> source.contactSource }.contains(it) } + .map { it.getFullIdentifier() } + .toHashSet() + callback(file, ignoredSources) + dismiss() } - else -> activity.toast(R.string.invalid_name) } + else -> activity.toast(R.string.invalid_name) } } } + } + } + + private fun processDataIfReady(view: View) { + if (!isContactSourcesReady || !isContactsReady) { + return + } + + val adapterData = ArrayList() + for (source in contactSources) { + val count = contacts.filter { it.source == source.name }.count() + adapterData.add(FilterContactSourcesAdapter.ContactSourceModel(source, count)) + } + + activity.runOnUiThread { + view.export_contacts_list.adapter = FilterContactSourcesAdapter(activity, adapterData, activity.getVisibleContactSources()) + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt index 1090c7d3..71465224 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt @@ -5,45 +5,68 @@ import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter +import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter.ContactSourceModel import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources import com.simplemobiletools.contacts.pro.helpers.ContactsHelper import com.simplemobiletools.contacts.pro.helpers.SMT_PRIVATE +import com.simplemobiletools.contacts.pro.models.Contact import com.simplemobiletools.contacts.pro.models.ContactSource import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.* -import java.util.* class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) { private var dialog: AlertDialog? = null private val view = activity.layoutInflater.inflate(R.layout.dialog_filter_contact_sources, null) private var contactSources = ArrayList() + private var contacts = ArrayList() + private var isContactSourcesReady = false + private var isContactsReady = false init { - ContactsHelper(activity).getContactSources { - if (it.isEmpty()) { - return@getContactSources - } + ContactsHelper(activity).getContactSources { contactSources -> + contactSources.mapTo(this.contactSources) { it.copy() } + isContactSourcesReady = true + processDataIfReady() + } - it.mapTo(contactSources) { it.copy() } - val selectedSources = activity.getVisibleContactSources() - activity.runOnUiThread { - view.filter_contact_sources_list.adapter = FilterContactSourcesAdapter(activity, it, selectedSources) + ContactsHelper(activity).getContacts(getAll = true) { contacts -> + contacts.mapTo(this.contacts) { it.copy() } + isContactsReady = true + processDataIfReady() + } + } - dialog = AlertDialog.Builder(activity) - .setPositiveButton(R.string.ok) { dialogInterface, i -> confirmContactSources() } - .setNegativeButton(R.string.cancel, null) - .create().apply { - activity.setupDialogStuff(view, this) - } - } + private fun processDataIfReady() { + if (!isContactSourcesReady || !isContactsReady) { + return + } + + val adapterData = ArrayList() + for (source in contactSources) { + val count = contacts.filter { it.source == source.name }.count() + adapterData.add(ContactSourceModel(source, count)) + } + + val selectedSources = activity.getVisibleContactSources() + activity.runOnUiThread { + view.filter_contact_sources_list.adapter = FilterContactSourcesAdapter(activity, adapterData, selectedSources) + + dialog = AlertDialog.Builder(activity) + .setPositiveButton(R.string.ok) { dialogInterface, i -> confirmContactSources() } + .setNegativeButton(R.string.cancel, null) + .create().apply { + activity.setupDialogStuff(view, this) + } } } private fun confirmContactSources() { val selectedContactSources = (view.filter_contact_sources_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() - val ignoredContactSources = contactSources.filter { !selectedContactSources.contains(it) }.map { - if (it.type == SMT_PRIVATE) SMT_PRIVATE else it.getFullIdentifier() - }.toHashSet() + val ignoredContactSources = contactSources + .filter { !selectedContactSources.map { it.contactSource }.contains(it) } + .map { + if (it.type == SMT_PRIVATE) SMT_PRIVATE else it.getFullIdentifier() + }.toHashSet() if (activity.getVisibleContactSources() != ignoredContactSources) { activity.config.ignoredContactSources = ignoredContactSources