diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bc9514d1..16205e13 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -168,19 +168,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt
index f0bbca97..1f2013ae 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt
@@ -6,8 +6,11 @@ import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.graphics.drawable.ColorDrawable
+import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
+import android.provider.ContactsContract.CommonDataKinds.Email
+import android.provider.ContactsContract.CommonDataKinds.Phone
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.widget.SearchView
@@ -35,6 +38,8 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener {
private var isSearchOpen = false
private var searchMenuItem: MenuItem? = null
+ private var isSelectContactIntent = false
+ private var specialMimeType: String? = null
private val contactsFavoritesList = arrayListOf(
TAB_CONTACTS,
@@ -44,6 +49,18 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_insert_edit_contact)
+ isSelectContactIntent = intent.action == Intent.ACTION_PICK
+
+ if (isSelectContactIntent) {
+ specialMimeType = when (intent.data) {
+ Email.CONTENT_URI -> Email.CONTENT_ITEM_TYPE
+ Phone.CONTENT_URI -> Phone.CONTENT_ITEM_TYPE
+ else -> null
+ }
+ }
+
+ new_contact_holder.beGoneIf(isSelectContactIntent)
+ select_contact_label.beGoneIf(isSelectContactIntent)
if (checkAppSideloading()) {
return
@@ -89,6 +106,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener {
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (resultCode == Activity.RESULT_OK) {
+ hideKeyboard()
finish()
}
}
@@ -213,39 +231,77 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener {
viewpager.adapter = ViewPagerAdapter(this, contactsFavoritesList, getTabsMask())
}
- ContactsHelper(this).getContacts { contacts ->
+ ContactsHelper(this).getContacts {
if (isDestroyed || isFinishing) {
return@getContacts
}
+ val contacts = it.filter {
+ if (specialMimeType != null) {
+ val hasRequiredValues = when (specialMimeType) {
+ Email.CONTENT_ITEM_TYPE -> it.emails.isNotEmpty()
+ Phone.CONTENT_ITEM_TYPE -> it.phoneNumbers.isNotEmpty()
+ else -> true
+ }
+ !it.isPrivate() && hasRequiredValues
+ } else {
+ true
+ }
+ } as ArrayList
+
+ val placeholderText = when (specialMimeType) {
+ Email.CONTENT_ITEM_TYPE -> getString(R.string.no_contacts_with_emails)
+ Phone.CONTENT_ITEM_TYPE -> getString(R.string.no_contacts_with_phone_numbers)
+ else -> null
+ }
+
if (refreshTabsMask and TAB_CONTACTS != 0) {
- contacts_fragment?.refreshContacts(contacts)
+ contacts_fragment?.refreshContacts(contacts, placeholderText)
}
if (refreshTabsMask and TAB_FAVORITES != 0) {
- favorites_fragment?.refreshContacts(contacts)
+ favorites_fragment?.refreshContacts(contacts, placeholderText)
}
}
}
override fun contactClicked(contact: Contact) {
- val phoneNumber = getPhoneNumberFromIntent(intent) ?: ""
- val email = getEmailFromIntent(intent) ?: ""
-
- Intent(applicationContext, EditContactActivity::class.java).apply {
- data = getContactPublicUri(contact)
- action = ADD_NEW_CONTACT_NUMBER
-
- if (phoneNumber.isNotEmpty()) {
- putExtra(KEY_PHONE, phoneNumber)
+ hideKeyboard()
+ if (isSelectContactIntent) {
+ Intent().apply {
+ data = getResultUri(contact)
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ setResult(RESULT_OK, this)
}
+ finish()
+ } else {
+ val phoneNumber = getPhoneNumberFromIntent(intent) ?: ""
+ val email = getEmailFromIntent(intent) ?: ""
+ Intent(applicationContext, EditContactActivity::class.java).apply {
+ data = getContactPublicUri(contact)
+ action = ADD_NEW_CONTACT_NUMBER
- if (email.isNotEmpty()) {
- putExtra(KEY_EMAIL, email)
+ if (phoneNumber.isNotEmpty()) {
+ putExtra(KEY_PHONE, phoneNumber)
+ }
+
+ if (email.isNotEmpty()) {
+ putExtra(KEY_EMAIL, email)
+ }
+
+ putExtra(IS_PRIVATE, contact.isPrivate())
+ startActivityForResult(this, START_EDIT_ACTIVITY)
}
+ }
+ }
- putExtra(IS_PRIVATE, contact.isPrivate())
- startActivityForResult(this, START_EDIT_ACTIVITY)
+ private fun getResultUri(contact: Contact): Uri {
+ return when {
+ specialMimeType != null -> {
+ val contactId = ContactsHelper(this).getContactMimeTypeId(contact.id.toString(), specialMimeType!!)
+ Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, contactId)
+ }
+ else -> getContactPublicUri(contact)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt
deleted file mode 100644
index 2771f70d..00000000
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt
+++ /dev/null
@@ -1,275 +0,0 @@
-package com.simplemobiletools.contacts.pro.activities
-
-import android.app.SearchManager
-import android.content.Context
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.provider.ContactsContract
-import android.provider.ContactsContract.CommonDataKinds.Email
-import android.provider.ContactsContract.CommonDataKinds.Phone
-import android.view.Menu
-import android.view.MenuItem
-import androidx.appcompat.widget.SearchView
-import androidx.core.view.MenuItemCompat
-import com.reddit.indicatorfastscroll.FastScrollItemIndicator
-import com.simplemobiletools.commons.extensions.*
-import com.simplemobiletools.commons.helpers.*
-import com.simplemobiletools.contacts.pro.R
-import com.simplemobiletools.contacts.pro.adapters.SelectContactsAdapter
-import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog
-import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog
-import com.simplemobiletools.contacts.pro.extensions.config
-import com.simplemobiletools.contacts.pro.extensions.getContactPublicUri
-import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources
-import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
-import com.simplemobiletools.contacts.pro.helpers.getProperText
-import com.simplemobiletools.contacts.pro.models.Contact
-import kotlinx.android.synthetic.main.activity_select_contact.*
-import kotlinx.android.synthetic.main.fragment_letters_layout.*
-import java.util.*
-import kotlin.collections.ArrayList
-
-class SelectContactActivity : SimpleActivity() {
- private var specialMimeType: String? = null
- private var isSearchOpen = false
- private var searchMenuItem: MenuItem? = null
- private var contactsIgnoringSearch = ArrayList()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_select_contact)
- fragment_fab.beGone()
-
- if (checkAppSideloading()) {
- return
- }
-
- setupViews()
-
- handlePermission(PERMISSION_READ_CONTACTS) {
- if (it) {
- handlePermission(PERMISSION_WRITE_CONTACTS) {
- if (it) {
- specialMimeType = when (intent.data) {
- Email.CONTENT_URI -> Email.CONTENT_ITEM_TYPE
- Phone.CONTENT_URI -> Phone.CONTENT_ITEM_TYPE
- else -> null
- }
- initContacts()
- } else {
- toast(R.string.no_contacts_permission)
- finish()
- }
- }
- } else {
- toast(R.string.no_contacts_permission)
- finish()
- }
- }
- }
-
- override fun onStop() {
- super.onStop()
- searchMenuItem?.collapseActionView()
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.menu_select_activity, menu)
- setupSearch(menu)
- updateMenuItemColors(menu)
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.sort -> showSortingDialog()
- R.id.filter -> showFilterDialog()
- else -> return super.onOptionsItemSelected(item)
- }
- return true
- }
-
- private fun setupSearch(menu: Menu) {
- val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
- searchMenuItem = menu.findItem(R.id.search)
- (searchMenuItem!!.actionView as SearchView).apply {
- setSearchableInfo(searchManager.getSearchableInfo(componentName))
- isSubmitButtonEnabled = false
- queryHint = getString(R.string.search_contacts)
- setOnQueryTextListener(object : SearchView.OnQueryTextListener {
- override fun onQueryTextSubmit(query: String) = false
-
- override fun onQueryTextChange(newText: String): Boolean {
- if (isSearchOpen) {
- onSearchQueryChanged(newText)
- }
- return true
- }
- })
- }
-
- MenuItemCompat.setOnActionExpandListener(searchMenuItem, object : MenuItemCompat.OnActionExpandListener {
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
- onSearchOpened()
- isSearchOpen = true
- return true
- }
-
- override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
- onSearchClosed()
- isSearchOpen = false
- return true
- }
- })
- }
-
- private fun onSearchQueryChanged(text: String) {
- val adapter = fragment_list.adapter
- if (adapter != null && adapter is SelectContactsAdapter) {
- val shouldNormalize = text.normalizeString() == text
- val filtered = contactsIgnoringSearch.filter {
- getProperText(it.getNameToDisplay(), shouldNormalize).contains(text, true) ||
- getProperText(it.nickname, shouldNormalize).contains(text, true) ||
- it.doesContainPhoneNumber(text, false) ||
- it.emails.any { it.value.contains(text, true) } ||
- it.addresses.any { getProperText(it.value, shouldNormalize).contains(text, true) } ||
- it.IMs.any { it.value.contains(text, true) } ||
- getProperText(it.notes, shouldNormalize).contains(text, true) ||
- getProperText(it.organization.company, shouldNormalize).contains(text, true) ||
- getProperText(it.organization.jobPosition, shouldNormalize).contains(text, true) ||
- it.websites.any { it.contains(text, true) }
- } as ArrayList
-
- filtered.sortBy {
- val nameToDisplay = it.getNameToDisplay()
- !getProperText(nameToDisplay, shouldNormalize).startsWith(text, true) && !nameToDisplay.contains(text, true)
- }
-
- if (filtered.isEmpty()) {
- fragment_placeholder.text = getString(R.string.no_items_found)
- }
-
- fragment_placeholder.beVisibleIf(filtered.isEmpty())
- adapter.updateItems(filtered, text.normalizeString())
- }
- }
-
- private fun onSearchOpened() {
- contactsIgnoringSearch = (fragment_list.adapter as? SelectContactsAdapter)?.contacts ?: ArrayList()
- }
-
- private fun onSearchClosed() {
- (fragment_list.adapter as? SelectContactsAdapter)?.updateItems(contactsIgnoringSearch)
- }
-
- private fun showSortingDialog() {
- ChangeSortingDialog(this) {
- initContacts()
- }
- }
-
- private fun showFilterDialog() {
- FilterContactSourcesDialog(this) {
- initContacts()
- }
- }
-
- private fun initContacts() {
- ContactsHelper(this).getContacts {
- if (isDestroyed || isFinishing) {
- return@getContacts
- }
-
- var contacts = it.filter {
- if (specialMimeType != null) {
- val hasRequiredValues = when (specialMimeType) {
- Email.CONTENT_ITEM_TYPE -> it.emails.isNotEmpty()
- Phone.CONTENT_ITEM_TYPE -> it.phoneNumbers.isNotEmpty()
- else -> true
- }
- !it.isPrivate() && hasRequiredValues
- } else {
- true
- }
- } as ArrayList
-
- val contactSources = getVisibleContactSources()
- contacts = contacts.filter { contactSources.contains(it.source) } as ArrayList
-
- runOnUiThread {
- updatePlaceholderVisibility(contacts)
- SelectContactsAdapter(this, contacts, ArrayList(), false, fragment_list) {
- confirmSelection(it)
- }.apply {
- fragment_list.adapter = this
- }
-
- if (areSystemAnimationsEnabled) {
- fragment_list.scheduleLayoutAnimation()
- }
-
- letter_fastscroller.setupWithRecyclerView(fragment_list, { position ->
- try {
- val name = contacts[position].getNameToDisplay()
- val character = if (name.isNotEmpty()) name.substring(0, 1) else ""
- FastScrollItemIndicator.Text(character.normalizeString().toUpperCase(Locale.getDefault()))
- } catch (e: Exception) {
- FastScrollItemIndicator.Text("")
- }
- })
- }
- }
- }
-
- private fun confirmSelection(contact: Contact) {
- Intent().apply {
- data = getResultUri(contact)
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- setResult(RESULT_OK, this)
- }
- finish()
- }
-
- private fun getResultUri(contact: Contact): Uri {
- return when {
- specialMimeType != null -> {
- val contactId = ContactsHelper(this).getContactMimeTypeId(contact.id.toString(), specialMimeType!!)
- Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, contactId)
- }
- else -> getContactPublicUri(contact)
- }
- }
-
- private fun setupViews() {
- val adjustedPrimaryColor = getAdjustedPrimaryColor()
- fragment_placeholder.setTextColor(config.textColor)
- fragment_placeholder_2.setTextColor(adjustedPrimaryColor)
- fragment_placeholder_2.underlineText()
- fragment_placeholder_2.setOnClickListener {
- FilterContactSourcesDialog(this) {
- initContacts()
- }
- }
-
- letter_fastscroller?.textColor = config.textColor.getColorStateList()
- letter_fastscroller?.pressedTextColor = adjustedPrimaryColor
- letter_fastscroller_thumb?.fontSize = getTextSize()
- letter_fastscroller_thumb?.textColor = adjustedPrimaryColor.getContrastColor()
- letter_fastscroller_thumb?.thumbColor = adjustedPrimaryColor.getColorStateList()
- letter_fastscroller_thumb.setupWithFastScroller(letter_fastscroller)
- }
-
- private fun updatePlaceholderVisibility(contacts: ArrayList) {
- fragment_list.beVisibleIf(contacts.isNotEmpty())
- fragment_placeholder_2.beVisibleIf(contacts.isEmpty())
- fragment_placeholder.beVisibleIf(contacts.isEmpty())
- fragment_placeholder.setText(
- when (specialMimeType) {
- Email.CONTENT_ITEM_TYPE -> R.string.no_contacts_with_emails
- Phone.CONTENT_ITEM_TYPE -> R.string.no_contacts_with_phone_numbers
- else -> R.string.no_contacts_found
- }
- )
- }
-}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt
index 46ecdafe..7e0a9ca3 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt
@@ -103,7 +103,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
}
}
- fun refreshContacts(contacts: ArrayList) {
+ fun refreshContacts(contacts: ArrayList, placeholderText: String? = null) {
if ((config.showTabs and TAB_CONTACTS == 0 && this is ContactsFragment && activity !is InsertOrEditContactActivity) ||
(config.showTabs and TAB_FAVORITES == 0 && this is FavoritesFragment) ||
(config.showTabs and TAB_GROUPS == 0 && this is GroupsFragment)
@@ -137,6 +137,13 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
lastHashCode = currentHash
activity?.runOnUiThread {
setupContacts(filtered)
+
+ if (placeholderText != null) {
+ fragment_placeholder.text = placeholderText
+ fragment_placeholder.tag = AVOID_CHANGING_TEXT_TAG
+ fragment_placeholder_2.beGone()
+ fragment_placeholder_2.tag = AVOID_CHANGING_VISIBILITY_TAG
+ }
}
}
}
@@ -310,7 +317,9 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
}
if (filtered.isEmpty() && this@MyViewPagerFragment is FavoritesFragment) {
- fragment_placeholder.text = activity?.getString(R.string.no_contacts_found)
+ if (fragment_placeholder.tag != AVOID_CHANGING_TEXT_TAG) {
+ fragment_placeholder.text = activity?.getString(R.string.no_contacts_found)
+ }
}
fragment_placeholder.beVisibleIf(filtered.isEmpty())
@@ -345,13 +354,16 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
setupViewVisibility(groupsIgnoringSearch.isNotEmpty())
}
- if (this is FavoritesFragment) {
+ if (this is FavoritesFragment && fragment_placeholder.tag != AVOID_CHANGING_TEXT_TAG) {
fragment_placeholder.text = activity?.getString(R.string.no_favorites)
}
}
private fun setupViewVisibility(hasItemsToShow: Boolean) {
- fragment_placeholder_2?.beVisibleIf(!hasItemsToShow)
+ if (fragment_placeholder_2.tag != AVOID_CHANGING_VISIBILITY_TAG) {
+ fragment_placeholder_2?.beVisibleIf(!hasItemsToShow)
+ }
+
fragment_placeholder?.beVisibleIf(!hasItemsToShow)
fragment_list.beVisibleIf(hasItemsToShow)
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
index 101af93e..5f4edd4c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
@@ -29,6 +29,8 @@ const val ADD_NEW_CONTACT_NUMBER = "add_new_contact_number"
const val FIRST_CONTACT_ID = 1000000
const val FIRST_GROUP_ID = 10000L
const val DEFAULT_FILE_NAME = "contacts.vcf"
+const val AVOID_CHANGING_TEXT_TAG = "avoid_changing_text_tag"
+const val AVOID_CHANGING_VISIBILITY_TAG = "avoid_changing_visibility_tag"
// extras used at third party intents
const val KEY_NAME = "name"
@@ -42,7 +44,8 @@ const val LOCATION_INSERT_OR_EDIT = 3
const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_GROUPS
-val tabsList = arrayListOf(TAB_CONTACTS,
+val tabsList = arrayListOf(
+ TAB_CONTACTS,
TAB_FAVORITES,
TAB_GROUPS
)
@@ -120,6 +123,28 @@ const val SOCIAL_VOICE_CALL = 0
const val SOCIAL_VIDEO_CALL = 1
const val SOCIAL_MESSAGE = 2
-fun getEmptyLocalContact() = LocalContact(0, "", "", "", "", "", "", null, "", ArrayList(), ArrayList(), ArrayList(), 0, ArrayList(), "", ArrayList(), "", "", ArrayList(), ArrayList(), null)
+fun getEmptyLocalContact() = LocalContact(
+ 0,
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ null,
+ "",
+ ArrayList(),
+ ArrayList(),
+ ArrayList(),
+ 0,
+ ArrayList(),
+ "",
+ ArrayList(),
+ "",
+ "",
+ ArrayList(),
+ ArrayList(),
+ null
+)
fun getProperText(text: String, shouldNormalize: Boolean) = if (shouldNormalize) text.normalizeString() else text
diff --git a/app/src/main/res/layout/activity_insert_edit_contact.xml b/app/src/main/res/layout/activity_insert_edit_contact.xml
index ba4a9e87..adff2242 100644
--- a/app/src/main/res/layout/activity_insert_edit_contact.xml
+++ b/app/src/main/res/layout/activity_insert_edit_contact.xml
@@ -23,7 +23,8 @@
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/activity_margin"
- android:paddingBottom="@dimen/medium_margin">
+ android:paddingBottom="@dimen/medium_margin"
+ android:visibility="gone">
+ android:textSize="@dimen/smaller_text_size"
+ android:visibility="gone" />
-
-
-
-
-
diff --git a/app/src/main/res/menu/menu_select_activity.xml b/app/src/main/res/menu/menu_select_activity.xml
deleted file mode 100644
index 78fa6907..00000000
--- a/app/src/main/res/menu/menu_select_activity.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-