diff --git a/.gitignore b/.gitignore
index b3460d57..32512494 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,6 @@
-# Temp files
-*~
-*.bak
-*.backup
-\#*
-.\#*
-*\#
-*.swp
-*.swap
-*.sav
-*.save
-*.autosav
-*.autosave
-
*.iml
.gradle
/local.properties
-/gradle.properties
/.idea/
.DS_Store
/build
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae86dd8c..e48516de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,24 @@
Changelog
==========
+Version 5.1.0 *(2018-10-28)*
+----------------------------
+
+ * Added an option for toggling 24 hour time format
+ * Added an option to show only contacts with phone numbers
+ * Do not allow creating contacts under WhatsApp contact source
+ * Try fixing the issue with disappearing contacts under some circumstances
+ * Fix some bugs related to selecting contact photo from the device storage
+ * Show the contact email at the list, if name and organization are empty
+ * Properly sort groups containing UTF-8 characters at title
+ * Use a different placeholder image for business contacts
+
+Version 5.0.0 *(2018-10-15)*
+----------------------------
+
+ * Increased the minimal required Android OS version to 5
+ * Try fixing the issue with disappearing fresh contacts
+
Version 4.5.0 *(2018-09-28)*
----------------------------
diff --git a/README.md b/README.md
index 5e9e5da6..b7f75f1a 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ This app is just one piece of a bigger series of apps. You can find the rest of
License
diff --git a/app/build.gradle b/app/build.gradle
index 63ebf515..fcdfe8cf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,10 +8,10 @@ android {
defaultConfig {
applicationId "com.simplemobiletools.contacts"
- minSdkVersion 16
+ minSdkVersion 21
targetSdkVersion 28
- versionCode 32
- versionName "4.5.0"
+ versionCode 34
+ versionName "5.1.0"
setProperty("archivesBaseName", "contacts")
}
@@ -41,11 +41,11 @@ android {
}
dependencies {
- implementation 'com.simplemobiletools:commons:4.8.0'
+ implementation 'com.simplemobiletools:commons:5.2.11'
implementation 'joda-time:joda-time:2.9.9'
implementation 'com.facebook.stetho:stetho:1.5.0'
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
- compile 'com.googlecode.ez-vcard:ez-vcard:0.10.4'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
+ implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.4'
}
Properties props = new Properties()
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 998d518a..91a6c619 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -194,7 +194,7 @@
android:parentActivityName=".activities.MainActivity"/>
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/DialpadActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/DialpadActivity.kt
index 11a45b07..86188994 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/DialpadActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/DialpadActivity.kt
@@ -1,21 +1,16 @@
package com.simplemobiletools.contacts.activities
-import android.annotation.TargetApi
import android.content.Intent
import android.graphics.Color
-import android.os.Build
import android.os.Bundle
-import android.text.InputType
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.simplemobiletools.commons.extensions.*
-import com.simplemobiletools.commons.helpers.isLollipopPlus
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.adapters.ContactsAdapter
import com.simplemobiletools.contacts.dialogs.CallConfirmationDialog
-import com.simplemobiletools.contacts.extensions.afterTextChanged
import com.simplemobiletools.contacts.extensions.callContact
import com.simplemobiletools.contacts.extensions.config
import com.simplemobiletools.contacts.extensions.startCallIntent
@@ -47,7 +42,7 @@ class DialpadActivity : SimpleActivity() {
dialpad_clear_char.setOnClickListener { clearChar(it) }
dialpad_clear_char.setOnLongClickListener { clearInput(); true }
dialpad_call_button.setOnClickListener { initCall() }
- dialpad_input.afterTextChanged { dialpadValueChanged(it) }
+ dialpad_input.onTextChangeListener { dialpadValueChanged(it) }
ContactsHelper(this).getContacts { gotContacts(it) }
disableKeyboardPopping()
@@ -120,13 +115,8 @@ class DialpadActivity : SimpleActivity() {
else -> KeyEvent.KEYCODE_POUND
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun disableKeyboardPopping() {
- if (isLollipopPlus()) {
- dialpad_input.showSoftInputOnFocus = false
- } else {
- dialpad_input.inputType = InputType.TYPE_NULL
- }
+ dialpad_input.showSoftInputOnFocus = false
}
private fun gotContacts(newContacts: ArrayList) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt
index 385f155a..c9fccc55 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt
@@ -5,6 +5,7 @@ import android.app.DatePickerDialog
import android.content.ClipData
import android.content.ContentValues
import android.content.Intent
+import android.graphics.Bitmap
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
@@ -114,7 +115,7 @@ class EditContactActivity : ContactActivity() {
super.onActivityResult(requestCode, resultCode, resultData)
if (resultCode == RESULT_OK) {
when (requestCode) {
- INTENT_TAKE_PHOTO, INTENT_CHOOSE_PHOTO -> startCropPhotoIntent(lastPhotoIntentUri)
+ INTENT_TAKE_PHOTO, INTENT_CHOOSE_PHOTO -> startCropPhotoIntent(lastPhotoIntentUri, resultData?.data)
INTENT_CROP_PHOTO -> updateContactPhoto(lastPhotoIntentUri.toString(), contact_photo)
}
}
@@ -260,15 +261,28 @@ class EditContactActivity : ContactActivity() {
}
}
- private fun startCropPhotoIntent(uri: Uri?) {
- if (uri == null) {
+ private fun startCropPhotoIntent(primaryUri: Uri?, backupUri: Uri?) {
+ if (primaryUri == null) {
toast(R.string.unknown_error_occurred)
return
}
+ var imageUri = primaryUri
+ var bitmap = MediaStore.Images.Media.getBitmap(contentResolver, primaryUri)
+ if (bitmap == null) {
+ imageUri = backupUri
+ bitmap = MediaStore.Images.Media.getBitmap(contentResolver, backupUri) ?: return
+
+ // we might have received an URI which we have no permission to send further, so just copy the received image in a new uri (for example from Google Photos)
+ val newFile = getCachePhoto()
+ val fos = newFile.outputStream()
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
+ imageUri = getCachePhotoUri(newFile)
+ }
+
lastPhotoIntentUri = getCachePhotoUri()
Intent("com.android.camera.action.CROP").apply {
- setDataAndType(uri, "image/*")
+ setDataAndType(imageUri, "image/*")
putExtra(MediaStore.EXTRA_OUTPUT, lastPhotoIntentUri)
putExtra("outputX", 720)
putExtra("outputY", 720)
@@ -277,7 +291,7 @@ class EditContactActivity : ContactActivity() {
putExtra("crop", "true")
putExtra("scale", "true")
putExtra("scaleUpIfNeeded", "true")
- clipData = ClipData("Attachment", arrayOf("text/uri-list"), ClipData.Item(lastPhotoIntentUri))
+ clipData = ClipData("Attachment", arrayOf("text/primaryUri-list"), ClipData.Item(lastPhotoIntentUri))
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
if (resolveActivity(packageManager) != null) {
startActivityForResult(this, INTENT_CROP_PHOTO)
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt
index 0cb2281b..0270aca2 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt
@@ -9,11 +9,11 @@ import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.os.Handler
-import android.support.v4.view.MenuItemCompat
-import android.support.v4.view.ViewPager
-import android.support.v7.widget.SearchView
import android.view.Menu
import android.view.MenuItem
+import androidx.appcompat.widget.SearchView
+import androidx.core.view.MenuItemCompat
+import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
@@ -27,7 +27,6 @@ import com.simplemobiletools.contacts.dialogs.ExportContactsDialog
import com.simplemobiletools.contacts.dialogs.FilterContactSourcesDialog
import com.simplemobiletools.contacts.dialogs.ImportContactsDialog
import com.simplemobiletools.contacts.extensions.config
-import com.simplemobiletools.contacts.extensions.dbHelper
import com.simplemobiletools.contacts.extensions.getTempFile
import com.simplemobiletools.contacts.fragments.MyViewPagerFragment
import com.simplemobiletools.contacts.helpers.*
@@ -63,9 +62,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
appLaunched(BuildConfig.APPLICATION_ID)
setupTabColors()
- // just get a reference to the database to make sure it is created properly
- dbHelper
-
handlePermission(PERMISSION_READ_CALL_LOG) {
if (it) {
handlePermission(PERMISSION_WRITE_CALL_LOG) {
@@ -308,10 +304,10 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
}
}
- private fun getInactiveTabIndexes(activeIndex: Int) = arrayListOf(0, 1, 2, 3).filter { it != activeIndex }
+ private fun getInactiveTabIndexes(activeIndex: Int) = (0 until tabsList.size).filter { it != activeIndex }
private fun initFragments() {
- viewpager.offscreenPageLimit = 3
+ viewpager.offscreenPageLimit = tabsList.size - 1
viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
if (isSearchOpen) {
@@ -320,8 +316,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
}
}
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
- }
+ override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
main_tabs_holder.getTabAt(position)?.select()
@@ -373,7 +368,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
}, 100L)
}
- main_tabs_holder.beVisibleIf(skippedTabs < 3)
+ main_tabs_holder.beVisibleIf(skippedTabs < tabsList.size - 1)
main_dialpad_button.setOnClickListener {
val intent = Intent(applicationContext, DialpadActivity::class.java)
@@ -401,7 +396,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
fun showFilterDialog() {
FilterContactSourcesDialog(this) {
contacts_fragment?.forceListRedraw = true
- refreshContacts(CONTACTS_TAB_MASK)
+ refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK)
}
}
@@ -484,7 +479,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
}
private fun launchAbout() {
- val licenses = LICENSE_MULTISELECT or LICENSE_JODA or LICENSE_GLIDE or LICENSE_GSON or LICENSE_STETHO
+ val licenses = LICENSE_JODA or LICENSE_GLIDE or LICENSE_GSON or LICENSE_STETHO
val faqItems = arrayListOf(
FAQItem(R.string.faq_1_title, R.string.faq_1_text),
@@ -495,9 +490,10 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
}
override fun refreshContacts(refreshTabsMask: Int) {
- if (isActivityDestroyed() || isGettingContacts) {
+ if (isDestroyed || isGettingContacts) {
return
}
+
isGettingContacts = true
if (viewpager.adapter == null) {
@@ -507,7 +503,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
ContactsHelper(this).getContacts {
isGettingContacts = false
- if (isActivityDestroyed()) {
+ if (isDestroyed) {
return@getContacts
}
@@ -551,6 +547,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
add(Release(29, R.string.release_29))
add(Release(31, R.string.release_31))
add(Release(32, R.string.release_32))
+ add(Release(34, R.string.release_34))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt
index 0d592bd1..b71913a6 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt
@@ -6,9 +6,7 @@ import android.os.Bundle
import android.provider.ContactsContract
import android.view.Menu
import android.view.MenuItem
-import com.simplemobiletools.commons.extensions.baseConfig
-import com.simplemobiletools.commons.extensions.isActivityDestroyed
-import com.simplemobiletools.commons.extensions.toast
+import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS
import com.simplemobiletools.contacts.R
@@ -21,14 +19,15 @@ import com.simplemobiletools.contacts.extensions.getVisibleContactSources
import com.simplemobiletools.contacts.helpers.ContactsHelper
import com.simplemobiletools.contacts.helpers.SMT_PRIVATE
import com.simplemobiletools.contacts.models.Contact
-import kotlinx.android.synthetic.main.layout_select_contact.*
+import kotlinx.android.synthetic.main.activity_select_contact.*
class SelectContactActivity : SimpleActivity() {
private var specialMimeType: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.layout_select_contact)
+ setContentView(R.layout.activity_select_contact)
+ setupPlaceholders()
handlePermission(PERMISSION_READ_CONTACTS) {
if (it) {
@@ -80,7 +79,7 @@ class SelectContactActivity : SimpleActivity() {
private fun initContacts() {
ContactsHelper(this).getContacts {
- if (isActivityDestroyed()) {
+ if (isDestroyed) {
return@getContacts
}
@@ -105,8 +104,11 @@ class SelectContactActivity : SimpleActivity() {
contacts.sort()
runOnUiThread {
- select_contact_list.adapter = SelectContactsAdapter(this, contacts, ArrayList(), false) {
+ updatePlaceholderVisibility(contacts)
+ SelectContactsAdapter(this, contacts, ArrayList(), false, select_contact_list) {
confirmSelection(it)
+ }.apply {
+ select_contact_list.adapter = this
}
select_contact_fastscroller.allowBubbleDisplay = baseConfig.showInfoBubble
@@ -132,9 +134,29 @@ class SelectContactActivity : SimpleActivity() {
val contactId = ContactsHelper(this).getContactMimeTypeId(contact.id.toString(), specialMimeType!!)
Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, contactId)
}
- else -> {
- getContactPublicUri(contact)
+ else -> getContactPublicUri(contact)
+ }
+ }
+
+ private fun setupPlaceholders() {
+ select_contact_placeholder.setTextColor(config.textColor)
+ select_contact_placeholder_2.setTextColor(getAdjustedPrimaryColor())
+ select_contact_placeholder_2.underlineText()
+ select_contact_placeholder_2.setOnClickListener {
+ FilterContactSourcesDialog(this) {
+ initContacts()
}
}
}
+
+ private fun updatePlaceholderVisibility(contacts: ArrayList) {
+ select_contact_list.beVisibleIf(contacts.isNotEmpty())
+ select_contact_placeholder_2.beVisibleIf(contacts.isEmpty())
+ select_contact_placeholder.beVisibleIf(contacts.isEmpty())
+ select_contact_placeholder.setText(when (specialMimeType) {
+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE -> R.string.no_contacts_with_emails
+ ContactsContract.CommonDataKinds.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/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SettingsActivity.kt
index 37811085..2df09385 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SettingsActivity.kt
@@ -35,7 +35,9 @@ class SettingsActivity : SimpleActivity() {
setupShowInfoBubble()
setupShowContactThumbnails()
setupShowPhoneNumbers()
+ setupShowContactsWithNumbers()
setupStartNameWithSurname()
+ setupUse24HourTimeFormat()
setupFilterDuplicates()
setupShowCallConfirmation()
setupOnContactClick()
@@ -109,6 +111,14 @@ class SettingsActivity : SimpleActivity() {
}
}
+ private fun setupShowContactsWithNumbers() {
+ settings_show_only_contacts_with_numbers.isChecked = config.showOnlyContactsWithNumbers
+ settings_show_only_contacts_with_numbers_holder.setOnClickListener {
+ settings_show_only_contacts_with_numbers.toggle()
+ config.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked
+ }
+ }
+
private fun setupStartNameWithSurname() {
settings_start_with_surname.isChecked = config.startNameWithSurname
settings_start_with_surname_holder.setOnClickListener {
@@ -117,6 +127,14 @@ class SettingsActivity : SimpleActivity() {
}
}
+ private fun setupUse24HourTimeFormat() {
+ settings_use_24_hour_time_format.isChecked = config.use24HourFormat
+ settings_use_24_hour_time_format_holder.setOnClickListener {
+ settings_use_24_hour_time_format.toggle()
+ config.use24HourFormat = settings_use_24_hour_time_format.isChecked
+ }
+ }
+
private fun setupFilterDuplicates() {
settings_filter_duplicates.isChecked = config.filterDuplicates
settings_filter_duplicates_holder.setOnClickListener {
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt
index a7995535..bbb36948 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt
@@ -354,12 +354,16 @@ class ViewContactActivity : ContactActivity() {
private fun setupOrganization() {
val organization = contact!!.organization
- if (!organization.isEmpty() && showFields and SHOW_ORGANIZATION_FIELD != 0) {
+ if (organization.isNotEmpty() && showFields and SHOW_ORGANIZATION_FIELD != 0) {
contact_organization_company.text = organization.company
contact_organization_job_position.text = organization.jobPosition
contact_organization_image.beGoneIf(organization.isEmpty())
contact_organization_company.beGoneIf(organization.company.isEmpty())
contact_organization_job_position.beGoneIf(organization.jobPosition.isEmpty())
+
+ if (organization.company.isEmpty() && organization.jobPosition.isNotEmpty()) {
+ (contact_organization_image.layoutParams as RelativeLayout.LayoutParams).addRule(RelativeLayout.ALIGN_TOP, contact_organization_job_position.id)
+ }
} else {
contact_organization_image.beGone()
contact_organization_company.beGone()
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt
index 4372437e..d9d2c4ad 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt
@@ -12,7 +12,10 @@ import com.bumptech.glide.signature.ObjectKey
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
-import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.extensions.beVisibleIf
+import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
+import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
+import com.simplemobiletools.commons.extensions.highlightTextPart
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.FastScroller
import com.simplemobiletools.commons.views.MyRecyclerView
@@ -33,6 +36,7 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList
+ holder.bindView(contact, true, allowLongClick) { itemView, layoutPosition ->
setupView(itemView, contact)
}
- bindViewHolder(holder, position, view)
+ bindViewHolder(holder)
}
override fun getItemCount() = contactItems.size
+ private fun getItemWithKey(key: Int): Contact? = contactItems.firstOrNull { it.id == key }
+
fun initDrawables() {
contactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_person, textColor)
+ businessContactDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_business, textColor)
}
fun updateItems(newItems: ArrayList, highlightText: String = "") {
@@ -134,7 +139,8 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList()
- selectedPositions.sortedDescending().forEach {
- val contact = contactItems.getOrNull(it)
- if (contact != null) {
- contactsToRemove.add(contact)
- }
- }
+ val contactsToRemove = getSelectedItems()
+ val positions = getSelectedItemPositions()
contactItems.removeAll(contactsToRemove)
ContactsHelper(activity).deleteContacts(contactsToRemove)
@@ -162,16 +163,15 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList()
- selectedPositions.sortedDescending().forEach {
- contactsToRemove.add(contactItems[it])
- }
+ val contactsToRemove = getSelectedItems()
+ val positions = getSelectedItemPositions()
contactItems.removeAll(contactsToRemove)
if (location == LOCATION_FAVORITES_TAB) {
@@ -180,22 +180,22 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList()
ContactsHelper(activity).getStoredGroups().forEach {
@@ -223,41 +223,30 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList()
- selectedPositions.forEach {
- contactsIDs.add(contactItems[it].id)
- }
-
- val filtered = contactItems.filter { contactsIDs.contains(it.id) } as ArrayList
- activity.shareContacts(filtered)
+ activity.shareContacts(getSelectedItems())
}
private fun sendSMSToContacts() {
- activity.sendSMSToContacts(getSelectedContacts())
+ activity.sendSMSToContacts(getSelectedItems())
}
private fun sendEmailToContacts() {
- activity.sendEmailToContacts(getSelectedContacts())
+ activity.sendEmailToContacts(getSelectedItems())
}
- private fun getSelectedContacts(): ArrayList {
- val contacts = ArrayList()
- selectedPositions.forEach {
- contacts.add(contactItems[it])
- }
- return contacts
- }
+ private fun getSelectedItems() = contactItems.filter { selectedKeys.contains(it.id) } as ArrayList
override fun onViewRecycled(holder: ViewHolder) {
super.onViewRecycled(holder)
- if (!activity.isActivityDestroyed()) {
- Glide.with(activity).clear(holder.itemView?.contact_tmb!!)
+ if (!activity.isDestroyed) {
+ Glide.with(activity).clear(holder.itemView.contact_tmb)
}
}
private fun setupView(view: View, contact: Contact) {
view.apply {
- val fullName = contact.getFullName()
+ contact_frame?.isSelected = selectedKeys.contains(contact.id)
+ val fullName = contact.getNameToDisplay()
contact_name.text = if (textToHighlight.isEmpty()) fullName else fullName.highlightTextPart(textToHighlight, adjustedPrimaryColor)
contact_name.setTextColor(textColor)
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
@@ -278,12 +267,13 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList {
val options = RequestOptions()
.signature(ObjectKey(contact.photoUri))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
- .error(contactDrawable)
+ .error(placeholderImage)
.centerCrop()
Glide.with(activity).load(contact.photoUri).transition(DrawableTransitionOptions.withCrossFade()).apply(options).into(contact_tmb)
@@ -292,12 +282,12 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList contact_tmb.setImageDrawable(contactDrawable)
+ else -> contact_tmb.setImageDrawable(placeholderImage)
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt
index a316d0be..adcb2379 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt
@@ -1,11 +1,9 @@
package com.simplemobiletools.contacts.adapters
-import android.support.v7.widget.RecyclerView
-import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
-import com.simplemobiletools.commons.interfaces.MyAdapterListener
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.activities.SimpleActivity
import com.simplemobiletools.contacts.extensions.config
@@ -16,13 +14,12 @@ import java.util.*
class FilterContactSourcesAdapter(val activity: SimpleActivity, private val contactSources: List, private val displayContactSources: ArrayList) :
RecyclerView.Adapter() {
- private val itemViews = SparseArray()
- private val selectedPositions = HashSet()
+ private val selectedKeys = HashSet()
init {
contactSources.forEachIndexed { index, contactSource ->
if (displayContactSources.contains(contactSource.name)) {
- selectedPositions.add(index)
+ selectedKeys.add(contactSource.hashCode())
}
if (contactSource.name == activity.config.localAccountName && contactSource.type == activity.config.localAccountType) {
@@ -30,61 +27,50 @@ class FilterContactSourcesAdapter(val activity: SimpleActivity, private val cont
}
if (contactSource.type == SMT_PRIVATE && displayContactSources.contains(SMT_PRIVATE)) {
- selectedPositions.add(index)
+ selectedKeys.add(contactSource.hashCode())
}
}
}
- private fun toggleItemSelection(select: Boolean, pos: Int) {
+ private fun toggleItemSelection(select: Boolean, contactSource: ContactSource, position: Int) {
if (select) {
- if (itemViews[pos] != null) {
- selectedPositions.add(pos)
- }
+ selectedKeys.add(contactSource.hashCode())
} else {
- selectedPositions.remove(pos)
+ selectedKeys.remove(contactSource.hashCode())
}
- itemViews[pos]?.filter_contact_source_checkbox?.isChecked = select
+ notifyItemChanged(position)
}
- private val adapterListener = object : MyAdapterListener {
- override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
- toggleItemSelection(select, position)
- }
-
- override fun getSelectedPositions() = selectedPositions
-
- override fun itemLongClicked(position: Int) {}
- }
-
- fun getSelectedItemsSet() = selectedPositions
+ fun getSelectedContactSources() = contactSources.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)
- return ViewHolder(view, adapterListener, activity)
+ return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val contactSource = contactSources[position]
- itemViews.put(position, holder.bindView(contactSource.name))
- toggleItemSelection(selectedPositions.contains(position), position)
+ holder.bindView(contactSource)
}
override fun getItemCount() = contactSources.size
- class ViewHolder(view: View, private val adapterListener: MyAdapterListener, val activity: SimpleActivity) : RecyclerView.ViewHolder(view) {
- fun bindView(contactSource: String): View {
+ inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ fun bindView(contactSource: ContactSource): View {
+ val isSelected = selectedKeys.contains(contactSource.hashCode())
itemView.apply {
+ filter_contact_source_checkbox.isChecked = isSelected
filter_contact_source_checkbox.setColors(activity.config.textColor, activity.getAdjustedPrimaryColor(), activity.config.backgroundColor)
- filter_contact_source_checkbox.text = contactSource
- filter_contact_source_holder.setOnClickListener { viewClicked(!filter_contact_source_checkbox.isChecked) }
+ filter_contact_source_checkbox.text = contactSource.name
+ filter_contact_source_holder.setOnClickListener { viewClicked(!isSelected, contactSource) }
}
return itemView
}
- private fun viewClicked(select: Boolean) {
- adapterListener.toggleItemSelectionAdapter(select, adapterPosition)
+ private fun viewClicked(select: Boolean, contactSource: ContactSource) {
+ toggleItemSelection(select, contactSource, adapterPosition)
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/GroupsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/GroupsAdapter.kt
index ca98b7cd..9b83b358 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/GroupsAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/GroupsAdapter.kt
@@ -41,14 +41,8 @@ class GroupsAdapter(activity: SimpleActivity, var groups: ArrayList, val
}
}
- override fun prepareItemSelection(viewHolder: ViewHolder) {}
-
- override fun markViewHolderSelection(select: Boolean, viewHolder: ViewHolder?) {
- viewHolder?.itemView?.group_frame?.isSelected = select
- }
-
override fun actionItemPressed(id: Int) {
- if (selectedPositions.isEmpty()) {
+ if (selectedKeys.isEmpty()) {
return
}
@@ -63,18 +57,24 @@ class GroupsAdapter(activity: SimpleActivity, var groups: ArrayList, val
override fun getIsItemSelectable(position: Int) = true
+ override fun getItemSelectionKey(position: Int) = groups.getOrNull(position)?.id?.toInt()
+
+ override fun getItemKeyPosition(key: Int) = groups.indexOfFirst { it.id.toInt() == key }
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_group, parent)
override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
val group = groups[position]
- val view = holder.bindView(group, true, true) { itemView, layoutPosition ->
+ holder.bindView(group, true, true) { itemView, layoutPosition ->
setupView(itemView, group)
}
- bindViewHolder(holder, position, view)
+ bindViewHolder(holder)
}
override fun getItemCount() = groups.size
+ private fun getItemWithKey(key: Int): Group? = groups.firstOrNull { it.id.toInt() == key }
+
fun updateItems(newItems: ArrayList) {
groups = newItems
notifyDataSetChanged()
@@ -83,7 +83,8 @@ class GroupsAdapter(activity: SimpleActivity, var groups: ArrayList, val
}
private fun renameGroup() {
- RenameGroupDialog(activity, groups[selectedPositions.first()]) {
+ val group = getItemWithKey(selectedKeys.first()) ?: return
+ RenameGroupDialog(activity, group) {
finishActMode()
refreshListener?.refreshContacts(GROUPS_TAB_MASK)
}
@@ -96,18 +97,17 @@ class GroupsAdapter(activity: SimpleActivity, var groups: ArrayList, val
}
private fun deleteGroups() {
- if (selectedPositions.isEmpty()) {
+ if (selectedKeys.isEmpty()) {
return
}
- val groupsToRemove = ArrayList()
- selectedPositions.sortedDescending().forEach {
- val group = groups[it]
- groupsToRemove.add(group)
- if (group.isPrivateSecretGroup()) {
- activity.dbHelper.deleteGroup(group.id)
+ val groupsToRemove = groups.filter { selectedKeys.contains(it.id.toInt()) } as ArrayList
+ val positions = getSelectedItemPositions()
+ groupsToRemove.forEach {
+ if (it.isPrivateSecretGroup()) {
+ activity.dbHelper.deleteGroup(it.id)
} else {
- ContactsHelper(activity).deleteGroup(group.id)
+ ContactsHelper(activity).deleteGroup(it.id)
}
}
groups.removeAll(groupsToRemove)
@@ -116,12 +116,13 @@ class GroupsAdapter(activity: SimpleActivity, var groups: ArrayList, val
refreshListener?.refreshContacts(GROUPS_TAB_MASK)
finishActMode()
} else {
- removeSelectedItems()
+ removeSelectedItems(positions)
}
}
private fun setupView(view: View, group: Group) {
view.apply {
+ group_frame?.isSelected = selectedKeys.contains(group.id.toInt())
group_name.apply {
setTextColor(textColor)
text = String.format(activity.getString(R.string.groups_placeholder), group.title, group.contactsCount.toString())
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/RecentCallsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/RecentCallsAdapter.kt
index e54d8d2b..44c2c08b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/RecentCallsAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/RecentCallsAdapter.kt
@@ -30,14 +30,8 @@ class RecentCallsAdapter(activity: SimpleActivity, var recentCalls: ArrayList
+ holder.bindView(recentCall, true, true) { itemView, layoutPosition ->
setupView(itemView, recentCall)
}
- bindViewHolder(holder, position, view)
+ bindViewHolder(holder)
}
override fun getItemCount() = recentCalls.size
@@ -77,15 +75,12 @@ class RecentCallsAdapter(activity: SimpleActivity, var recentCalls: ArrayList()
- selectedPositions.sortedDescending().forEach {
- val call = recentCalls[it]
- callsToRemove.add(call)
- }
+ val callsToRemove = getSelectedItems()
+ val positions = getSelectedItemPositions()
ContactsHelper(activity).removeRecentCalls(callsToRemove.map { it.id } as ArrayList)
recentCalls.removeAll(callsToRemove)
@@ -93,12 +88,15 @@ class RecentCallsAdapter(activity: SimpleActivity, var recentCalls: ArrayList
+
private fun setupView(view: View, recentCall: RecentCall) {
view.apply {
+ recent_call_frame?.isSelected = selectedKeys.contains(recentCall.id)
recent_call_name.apply {
text = recentCall.name ?: recentCall.number
setTextColor(textColor)
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/SelectContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/SelectContactsAdapter.kt
index df9d5fe8..4832eccc 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/SelectContactsAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/SelectContactsAdapter.kt
@@ -1,10 +1,11 @@
package com.simplemobiletools.contacts.adapters
import android.graphics.drawable.Drawable
-import android.support.v7.widget.RecyclerView
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
@@ -13,8 +14,7 @@ import com.bumptech.glide.signature.ObjectKey
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
import com.simplemobiletools.commons.extensions.getColoredDrawableWithColor
-import com.simplemobiletools.commons.extensions.isActivityDestroyed
-import com.simplemobiletools.commons.interfaces.MyAdapterListener
+import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.activities.SimpleActivity
import com.simplemobiletools.contacts.extensions.config
@@ -24,7 +24,7 @@ import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.*
import java.util.*
class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List, private val selectedContacts: ArrayList, private val allowPickMultiple: Boolean,
- private val itemClick: ((Contact) -> Unit)? = null) : RecyclerView.Adapter() {
+ private val recyclerView: MyRecyclerView, private val itemClick: ((Contact) -> Unit)? = null) : RecyclerView.Adapter() {
private val itemViews = SparseArray()
private val selectedPositions = HashSet()
private val config = activity.config
@@ -38,10 +38,19 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List
- if (selectedContacts.map { it.id }.contains(contact.id)) {
+ if (selectedContacts.asSequence().map { it.id }.contains(contact.id)) {
selectedPositions.add(index)
}
}
+
+ if (recyclerView.itemDecorationCount > 0) {
+ recyclerView.removeItemDecorationAt(0)
+ }
+
+ DividerItemDecoration(activity, DividerItemDecoration.VERTICAL).apply {
+ setDrawable(activity.resources.getDrawable(R.drawable.divider))
+ recyclerView.addItemDecoration(this)
+ }
}
private fun toggleItemSelection(select: Boolean, pos: Int) {
@@ -56,16 +65,6 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List {
val selectedItemsSet = HashSet(selectedPositions.size)
selectedPositions.forEach { selectedItemsSet.add(contacts[it]) }
@@ -74,7 +73,7 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List Unit)?) : RecyclerView.ViewHolder(view) {
+ inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindView(contact: Contact, contactDrawable: Drawable, config: Config, showContactThumbnails: Boolean,
smallPadding: Int, bigPadding: Int): View {
itemView.apply {
- contact_checkbox.beVisibleIf(showCheckbox)
+ contact_checkbox.beVisibleIf(allowPickMultiple)
contact_checkbox.setColors(config.textColor, context.getAdjustedPrimaryColor(), config.backgroundColor)
val textColor = config.textColor
- contact_name.text = contact.getFullName()
+ contact_name.text = contact.getNameToDisplay()
contact_name.setTextColor(textColor)
contact_name.setPadding(if (showContactThumbnails) smallPadding else bigPadding, smallPadding, smallPadding, 0)
@@ -119,7 +117,7 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List activity.toast(R.string.empty_name)
- filename.isAValidFilename() -> {
- val file = File(path, "$filename.vcf")
- if (file.exists()) {
- activity.toast(R.string.name_taken)
+ activity.setupDialogStuff(view, this, R.string.export_contacts) {
+ getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
+ if (view.export_contacts_list.adapter == null) {
return@setOnClickListener
}
- val selectedIndexes = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedItemsSet()
- val selectedContactSources = HashSet()
- selectedIndexes.forEach {
- selectedContactSources.add(if (contactSources[it].type == SMT_PRIVATE) SMT_PRIVATE else contactSources[it].name)
+ val filename = view.export_contacts_filename.value
+ when {
+ filename.isEmpty() -> activity.toast(R.string.empty_name)
+ filename.isAValidFilename() -> {
+ val file = File(path, "$filename.vcf")
+ if (file.exists()) {
+ activity.toast(R.string.name_taken)
+ return@setOnClickListener
+ }
+
+ val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources()
+ val selectedContactSourceNames = HashSet()
+ selectedSources.forEach {
+ selectedContactSourceNames.add(if (it.type == SMT_PRIVATE) SMT_PRIVATE else it.name)
+ }
+ callback(file, selectedContactSourceNames)
+ dismiss()
+ }
+ else -> activity.toast(R.string.invalid_name)
}
- callback(file, selectedContactSources)
- dismiss()
}
- else -> activity.toast(R.string.invalid_name)
}
}
- }
- }
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/FilterContactSourcesDialog.kt
index 5be53220..e3a91b82 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/FilterContactSourcesDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/FilterContactSourcesDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.activities.SimpleActivity
@@ -24,13 +24,13 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb
return@getContactSources
}
- it.mapTo(contactSources, { it.copy() })
+ it.mapTo(contactSources) { it.copy() }
val selectedSources = activity.getVisibleContactSources()
activity.runOnUiThread {
view.filter_contact_sources_list.adapter = FilterContactSourcesAdapter(activity, it, selectedSources)
dialog = AlertDialog.Builder(activity)
- .setPositiveButton(R.string.ok, { dialogInterface, i -> confirmEventTypes() })
+ .setPositiveButton(R.string.ok) { dialogInterface, i -> confirmEventTypes() }
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this)
@@ -40,21 +40,13 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb
}
private fun confirmEventTypes() {
- val selectedIndexes = (view.filter_contact_sources_list.adapter as FilterContactSourcesAdapter).getSelectedItemsSet()
- val ignoredIndexes = ArrayList()
- for (i in 0 until contactSources.size) {
- if (!selectedIndexes.contains(i)) {
- ignoredIndexes.add(i)
- }
- }
+ val selectedContactSources = (view.filter_contact_sources_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources()
+ val ignoredContactSourceNames = contactSources.filter { !selectedContactSources.contains(it) }.map {
+ if (it.type == SMT_PRIVATE) SMT_PRIVATE else it.name
+ }.toHashSet()
- val ignoredContactSources = HashSet()
- ignoredIndexes.forEach {
- ignoredContactSources.add(if (contactSources[it].type == SMT_PRIVATE) SMT_PRIVATE else contactSources[it].name)
- }
-
- if (activity.getVisibleContactSources() != ignoredContactSources) {
- activity.config.ignoredContactSources = ignoredContactSources
+ if (activity.getVisibleContactSources() != ignoredContactSourceNames) {
+ activity.config.ignoredContactSources = ignoredContactSourceNames
callback()
}
dialog?.dismiss()
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ImportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ImportContactsDialog.kt
index 8f2ed22f..8e85e744 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ImportContactsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ImportContactsDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import android.view.ViewGroup
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleFieldsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleFieldsDialog.kt
index 9b9afcf6..23bdd35c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleFieldsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleFieldsDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleTabsDialog.kt
index 241c62cf..381e8dca 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleTabsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/ManageVisibleTabsDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/RenameGroupDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/RenameGroupDialog.kt
index de1f654c..ca35f293 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/RenameGroupDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/RenameGroupDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.contacts.R
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt
index 76660338..2c2d3b6d 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.baseConfig
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.contacts.R
@@ -33,7 +33,7 @@ class SelectContactsDialog(val activity: SimpleActivity, initialContacts: ArrayL
activity.runOnUiThread {
view.apply {
- select_contact_list.adapter = SelectContactsAdapter(activity, allContacts, initiallySelectedContacts, true)
+ select_contact_list.adapter = SelectContactsAdapter(activity, allContacts, initiallySelectedContacts, true, select_contact_list)
select_contact_fastscroller.allowBubbleDisplay = activity.baseConfig.showInfoBubble
select_contact_fastscroller.setViews(select_contact_list) {
select_contact_fastscroller.updateBubbleText(allContacts[it].getBubbleText())
@@ -42,7 +42,7 @@ class SelectContactsDialog(val activity: SimpleActivity, initialContacts: ArrayL
}
AlertDialog.Builder(activity)
- .setPositiveButton(R.string.ok, { dialog, which -> dialogConfirmed() })
+ .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this)
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt
index f69a34a0..6682d083 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt
@@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.dialogs
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
import android.view.ViewGroup
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt
index a61b26f2..b028ffb9 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt
@@ -36,7 +36,7 @@ fun SimpleActivity.startCallIntent(recipient: String) {
fun SimpleActivity.tryStartCall(contact: Contact) {
if (config.showCallConfirmation) {
- CallConfirmationDialog(this, contact.getFullName()) {
+ CallConfirmationDialog(this, contact.getNameToDisplay()) {
startCall(contact)
}
} else {
@@ -63,8 +63,9 @@ fun SimpleActivity.startCall(contact: Contact) {
fun SimpleActivity.showContactSourcePicker(currentSource: String, callback: (newSource: String) -> Unit) {
ContactsHelper(this).getContactSources {
val ignoredTypes = arrayListOf(
- "org.thoughtcrime.securesms", // Signal
- "org.telegram.messenger" // Telegram
+ SIGNAL_PACKAGE,
+ TELEGRAM_PACKAGE,
+ WHATSAPP_PACKAGE
)
val items = ArrayList()
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt
index dfcafded..45b65c72 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt
@@ -1,19 +1,16 @@
package com.simplemobiletools.contacts.extensions
-import android.annotation.TargetApi
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
-import android.os.Build
import android.provider.ContactsContract
-import android.support.v4.content.FileProvider
+import androidx.core.content.FileProvider
import com.simplemobiletools.commons.extensions.getIntValue
import com.simplemobiletools.commons.extensions.hasPermission
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS
-import com.simplemobiletools.commons.helpers.isLollipopPlus
import com.simplemobiletools.contacts.BuildConfig
import com.simplemobiletools.contacts.R
import com.simplemobiletools.contacts.activities.EditContactActivity
@@ -88,10 +85,9 @@ fun Context.openWebsiteIntent(url: String) {
}
}
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun Context.getLookupUriRawId(dataUri: Uri): Int {
val lookupKey = getLookupKeyFromUri(dataUri)
- if (lookupKey != null && isLollipopPlus()) {
+ if (lookupKey != null) {
val uri = lookupContactUri(lookupKey, this)
if (uri != null) {
return getContactUriRawId(uri)
@@ -100,7 +96,6 @@ fun Context.getLookupUriRawId(dataUri: Uri): Int {
return -1
}
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun Context.getContactUriRawId(uri: Uri): Int {
val projection = arrayOf(ContactsContract.Contacts.NAME_RAW_CONTACT_ID)
var cursor: Cursor? = null
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/EditText.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/EditText.kt
deleted file mode 100644
index 65f826c2..00000000
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/EditText.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.simplemobiletools.contacts.extensions
-
-import android.text.Editable
-import android.text.TextWatcher
-import android.widget.EditText
-
-fun EditText.afterTextChanged(callback: (String) -> Unit) = addTextChangedListener(object : TextWatcher {
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
-
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
-
- override fun afterTextChanged(text: Editable) = callback(text.toString())
-})
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt
index 208c7715..211cc78f 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt
@@ -2,9 +2,9 @@ package com.simplemobiletools.contacts.fragments
import android.content.Context
import android.content.Intent
-import android.support.design.widget.CoordinatorLayout
import android.util.AttributeSet
import android.view.ViewGroup
+import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME
@@ -88,7 +88,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
fun startNameWithSurnameChanged(startNameWithSurname: Boolean) {
if (this !is GroupsFragment && this !is RecentsFragment) {
- (fragment_list.adapter as ContactsAdapter).apply {
+ (fragment_list.adapter as? ContactsAdapter)?.apply {
config.sorting = if (startNameWithSurname) SORT_BY_SURNAME else SORT_BY_FIRST_NAME
this@MyViewPagerFragment.activity!!.refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK)
}
@@ -104,7 +104,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
}
if (config.lastUsedContactSource.isEmpty()) {
- val grouped = contacts.groupBy { it.source }.maxWith(compareBy { it.value.size })
+ val grouped = contacts.asSequence().groupBy { it.source }.maxWith(compareBy { it.value.size })
config.lastUsedContactSource = grouped?.key ?: ""
}
@@ -154,7 +154,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
}
}
- storedGroups = storedGroups.sortedWith(compareBy { it.title }).toMutableList() as ArrayList
+ storedGroups = storedGroups.asSequence().sortedWith(compareBy { it.title.normalizeString() }).toMutableList() as ArrayList
fragment_placeholder_2.beVisibleIf(storedGroups.isEmpty())
fragment_placeholder.beVisibleIf(storedGroups.isEmpty())
@@ -239,7 +239,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
val shouldNormalize = text.normalizeString() == text
(fragment_list.adapter as? ContactsAdapter)?.apply {
val filtered = contactsIgnoringSearch.filter {
- getProperText(it.getFullName(), shouldNormalize).contains(text, true) ||
+ getProperText(it.getNameToDisplay(), shouldNormalize).contains(text, true) ||
getProperText(it.nickname, shouldNormalize).contains(text, true) ||
it.doesContainPhoneNumber(text) ||
it.emails.any { it.value.contains(text, true) } ||
@@ -254,7 +254,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet)
Contact.sorting = config.sorting
Contact.startWithSurname = config.startNameWithSurname
filtered.sort()
- filtered.sortBy { !getProperText(it.getFullName(), shouldNormalize).startsWith(text, true) }
+ filtered.sortBy { !getProperText(it.getNameToDisplay(), shouldNormalize).startsWith(text, true) }
if (filtered.isEmpty() && this@MyViewPagerFragment is FavoritesFragment) {
fragment_placeholder.text = activity.getString(R.string.no_items_found)
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/RecentsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/RecentsFragment.kt
index d4b30ab9..54e09773 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/RecentsFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/RecentsFragment.kt
@@ -5,7 +5,6 @@ import android.content.Intent
import android.util.AttributeSet
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.hasPermission
-import com.simplemobiletools.commons.extensions.isActivityDestroyed
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALL_LOG
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CALL_LOG
import com.simplemobiletools.contacts.activities.EditContactActivity
@@ -33,7 +32,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
}
fun updateRecentCalls(recentCalls: ArrayList) {
- if (activity == null || activity!!.isActivityDestroyed()) {
+ if (activity == null || activity!!.isDestroyed) {
return
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt
index 2370665b..ae605eb7 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt
@@ -20,6 +20,10 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getBoolean(SHOW_PHONE_NUMBERS, false)
set(showPhoneNumbers) = prefs.edit().putBoolean(SHOW_PHONE_NUMBERS, showPhoneNumbers).apply()
+ var showOnlyContactsWithNumbers: Boolean
+ get() = prefs.getBoolean(SHOW_ONLY_CONTACTS_WITH_NUMBERS, false)
+ set(showOnlyContactsWithNumbers) = prefs.edit().putBoolean(SHOW_ONLY_CONTACTS_WITH_NUMBERS, showOnlyContactsWithNumbers).apply()
+
var startNameWithSurname: Boolean
get() = prefs.getBoolean(START_NAME_WITH_SURNAME, false)
set(startNameWithSurname) = prefs.edit().putBoolean(START_NAME_WITH_SURNAME, startNameWithSurname).apply()
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt
index 58309511..ba870934 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt
@@ -5,6 +5,7 @@ import android.provider.ContactsContract.CommonDataKinds
// shared prefs
const val SHOW_CONTACT_THUMBNAILS = "show_contact_thumbnails"
const val SHOW_PHONE_NUMBERS = "show_phone_numbers"
+const val SHOW_ONLY_CONTACTS_WITH_NUMBERS = "show_only_contacts_with_numbers"
const val IGNORED_CONTACT_SOURCES = "ignored_contact_sources"
const val START_NAME_WITH_SURNAME = "start_name_with_surname"
const val LAST_USED_CONTACT_SOURCE = "last_used_contact_source"
@@ -113,3 +114,8 @@ val localAccountTypes = arrayListOf("vnd.sec.contact.phone",
"com.android.huawei.phone",
"Local Phone Account"
)
+
+// apps with special handling
+const val TELEGRAM_PACKAGE = "org.telegram.messenger"
+const val SIGNAL_PACKAGE = "org.thoughtcrime.securesms"
+const val WHATSAPP_PACKAGE = "com.whatsapp"
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt
index 88e3b7d7..cdffaec2 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt
@@ -43,15 +43,26 @@ class ContactsHelper(val activity: Activity) {
}
val contactsSize = contacts.size()
+ val showOnlyContactsWithNumbers = activity.config.showOnlyContactsWithNumbers
var tempContacts = ArrayList(contactsSize)
val resultContacts = ArrayList(contactsSize)
- (0 until contactsSize).mapTo(tempContacts) { contacts.valueAt(it) }
+
+ (0 until contactsSize).filter {
+ if (showOnlyContactsWithNumbers) {
+ contacts.valueAt(it).phoneNumbers.isNotEmpty()
+ } else {
+ true
+ }
+ }.mapTo(tempContacts) {
+ contacts.valueAt(it)
+ }
+
if (activity.config.filterDuplicates) {
tempContacts = tempContacts.distinctBy {
it.getHashToCompare()
} as ArrayList
- tempContacts.groupBy { "${it.getFullName().toLowerCase()}${it.emails}" }.values.forEach {
+ tempContacts.groupBy { "${it.getNameToDisplay().toLowerCase()}${it.emails}" }.values.forEach {
if (it.size == 1) {
resultContacts.add(it.first())
} else {
@@ -819,6 +830,9 @@ class ContactsHelper(val activity: Activity) {
accounts.forEach {
if (ContentResolver.getIsSyncable(it, ContactsContract.AUTHORITY) == 1) {
val contactSource = ContactSource(it.name, it.type)
+ if (it.type == TELEGRAM_PACKAGE) {
+ contactSource.name += " (${activity.getString(R.string.telegram)})"
+ }
sources.add(contactSource)
}
}
@@ -1207,6 +1221,7 @@ class ContactsHelper(val activity: Activity) {
ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).apply {
withValue(ContactsContract.RawContacts.ACCOUNT_NAME, contact.source)
withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, getContactSourceType(contact.source))
+ withValue(ContactsContract.RawContacts.DIRTY, false)
operations.add(build())
}
@@ -1298,7 +1313,7 @@ class ContactsHelper(val activity: Activity) {
}
// organization
- if (!contact.organization.isEmpty()) {
+ if (contact.organization.isNotEmpty()) {
ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply {
withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
@@ -1533,6 +1548,7 @@ class ContactsHelper(val activity: Activity) {
val todayDate = SimpleDateFormat("dd MMM yyyy", Locale.getDefault()).format(currentDate)
val yesterdayDate = SimpleDateFormat("dd MMM yyyy", Locale.getDefault()).format(Date(System.currentTimeMillis() - DAY_SECONDS * 1000))
val yesterday = activity.getString(R.string.yesterday)
+ val timeFormat = if (activity.config.use24HourFormat) "HH:mm" else "h:mm a"
var prevNumber = ""
var cursor: Cursor? = null
@@ -1548,7 +1564,7 @@ class ContactsHelper(val activity: Activity) {
continue
}
- var formattedDate = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale.getDefault()).format(Date(date))
+ var formattedDate = SimpleDateFormat("dd MMM yyyy, $timeFormat", Locale.getDefault()).format(Date(date))
val datePart = formattedDate.substring(0, 11)
when {
datePart == todayDate -> formattedDate = formattedDate.substring(12)
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt
index 3a3dfb92..32c101f3 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfExporter.kt
@@ -122,7 +122,7 @@ class VcfExporter {
card.addNote(contact.notes)
}
- if (!contact.organization.isEmpty()) {
+ if (contact.organization.isNotEmpty()) {
val organization = Organization()
organization.values.add(contact.organization.company)
card.organization = organization
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt
index 9cc27af8..aa824798 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt
@@ -139,7 +139,7 @@ class VcfImporter(val activity: SimpleActivity) {
targetContactSource, starred, contactId, thumbnailUri, photo, notes, groups, organization, websites, cleanPhoneNumbers, IMs)
// if there is no N and ORG fields at the given contact, only FN, treat it as an organization
- if (contact.getFullName().isEmpty() && contact.organization.isEmpty() && ezContact.formattedName.value.isNotEmpty()) {
+ if (contact.getNameToDisplay().isEmpty() && contact.organization.isEmpty() && ezContact.formattedName.value.isNotEmpty()) {
contact.organization.company = ezContact.formattedName.value
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt
index c710d572..2ed8b08a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt
@@ -37,12 +37,22 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
}
}
- if (firstString.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty() && organization.company.isNotEmpty()) {
- firstString = organization.company.normalizeString()
+ if (firstString.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty()) {
+ val fullCompany = getFullCompany()
+ if (fullCompany.isNotEmpty()) {
+ firstString = fullCompany.normalizeString()
+ } else if (emails.isNotEmpty()) {
+ firstString = emails.first().value
+ }
}
- if (secondString.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty() && other.organization.company.isNotEmpty()) {
- secondString = other.organization.company.normalizeString()
+ if (secondString.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty()) {
+ val otherFullCompany = other.getFullCompany()
+ if (otherFullCompany.isNotEmpty()) {
+ secondString = otherFullCompany.normalizeString()
+ } else if (other.emails.isNotEmpty()) {
+ secondString = other.emails.first().value
+ }
}
var result = if (firstString.firstOrNull()?.isLetter() == true && secondString.firstOrNull()?.isLetter() == false) {
@@ -56,7 +66,7 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
-1
} else {
if (firstString.toLowerCase() == secondString.toLowerCase()) {
- getFullName().compareTo(other.getFullName(), true)
+ getNameToDisplay().compareTo(other.getNameToDisplay(), true)
} else {
firstString.compareTo(secondString, true)
}
@@ -76,7 +86,7 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
else -> surname
}
- fun getFullName(): String {
+ fun getNameToDisplay(): String {
var firstPart = if (startWithSurname) surname else firstName
if (middleName.isNotEmpty()) {
firstPart += " $middleName"
@@ -86,9 +96,11 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
val suffixComma = if (suffix.isEmpty()) "" else ", $suffix"
val fullName = "$prefix $firstPart $lastPart$suffixComma".trim()
return if (fullName.isEmpty()) {
- var fullOrganization = if (organization.jobPosition.isEmpty()) "" else "${organization.jobPosition}, "
- fullOrganization += organization.company
- fullOrganization.trim().trimEnd(',')
+ if (organization.isNotEmpty()) {
+ getFullCompany()
+ } else {
+ emails.firstOrNull()?.value?.trim() ?: ""
+ }
} else {
fullName
}
@@ -98,7 +110,7 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
val newEmails = ArrayList()
emails.mapTo(newEmails) { Email(it.value, 0, "") }
- return copy(id = 0, prefix = "", firstName = getFullName().toLowerCase(), middleName = "", surname = "", suffix = "", nickname = "", photoUri = "",
+ return copy(id = 0, prefix = "", firstName = getNameToDisplay().toLowerCase(), middleName = "", surname = "", suffix = "", nickname = "", photoUri = "",
phoneNumbers = ArrayList(), events = ArrayList(), addresses = ArrayList(), emails = newEmails, source = "", starred = 0,
contactId = 0, thumbnailUri = "", notes = "", groups = ArrayList(), websites = ArrayList(), organization = Organization("", ""),
IMs = ArrayList()).toString()
@@ -106,6 +118,14 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m
fun getHashToCompare() = getStringToCompare().hashCode()
+ fun getFullCompany(): String {
+ var fullOrganization = if (organization.company.isEmpty()) "" else "${organization.company}, "
+ fullOrganization += organization.jobPosition
+ return fullOrganization.trim().trimEnd(',')
+ }
+
+ fun isABusinessContact() = prefix.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty() && suffix.isEmpty() && organization.isNotEmpty()
+
// do a more advanced phone number check here, compare numbers and and search query with dashes, spaces and everything but numbers removed
fun doesContainPhoneNumber(text: String): Boolean {
if (text.isNotEmpty()) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Organization.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Organization.kt
index fbb7b69c..6c311db9 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Organization.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Organization.kt
@@ -2,4 +2,6 @@ package com.simplemobiletools.contacts.models
data class Organization(var company: String, var jobPosition: String) {
fun isEmpty() = company.isEmpty() && jobPosition.isEmpty()
+
+ fun isNotEmpty() = !isEmpty()
}
diff --git a/app/src/main/res/layout/activity_dialpad.xml b/app/src/main/res/layout/activity_dialpad.xml
index 6378918f..96aa5f19 100644
--- a/app/src/main/res/layout/activity_dialpad.xml
+++ b/app/src/main/res/layout/activity_dialpad.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/app/src/main/res/layout/activity_edit_contact.xml b/app/src/main/res/layout/activity_edit_contact.xml
index fa6e8eb7..ecf79006 100644
--- a/app/src/main/res/layout/activity_edit_contact.xml
+++ b/app/src/main/res/layout/activity_edit_contact.xml
@@ -10,10 +10,10 @@
android:id="@+id/contact_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="@dimen/medium_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/medium_margin">
@@ -38,16 +38,16 @@
android:id="@+id/contact_actions_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignBottom="@id/contact_photo"
android:layout_alignTop="@+id/contact_photo"
+ android:layout_alignBottom="@id/contact_photo"
android:gravity="center_vertical|right">
diff --git a/app/src/main/res/layout/activity_group_contacts.xml b/app/src/main/res/layout/activity_group_contacts.xml
index 197db89c..ad7edb2a 100644
--- a/app/src/main/res/layout/activity_group_contacts.xml
+++ b/app/src/main/res/layout/activity_group_contacts.xml
@@ -1,5 +1,5 @@
-
@@ -51,8 +51,8 @@
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
- android:paddingLeft="@dimen/normal_margin"
- android:paddingStart="@dimen/normal_margin">
+ android:paddingStart="@dimen/normal_margin"
+ android:paddingLeft="@dimen/normal_margin">
@@ -67,4 +67,4 @@
android:layout_margin="@dimen/activity_margin"
android:src="@drawable/ic_plus"/>
-
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f3b5d8e9..319333c6 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 8f260f80..3e231816 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -18,18 +18,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -40,18 +40,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -62,18 +62,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -84,18 +84,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -106,10 +106,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -130,10 +130,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -154,10 +154,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -178,10 +178,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -202,10 +202,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
+
+
+
+
+
+
+ android:paddingBottom="@dimen/activity_margin">
+
+
+
+
+
+
+ android:paddingBottom="@dimen/activity_margin">
@@ -274,10 +322,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/activity_margin">
@@ -298,18 +346,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
- android:paddingBottom="@dimen/bigger_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/bigger_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/bigger_margin">
+ android:paddingBottom="@dimen/bigger_margin">
diff --git a/app/src/main/res/layout/activity_view_contact.xml b/app/src/main/res/layout/activity_view_contact.xml
index 74ce627d..ec4ec89c 100644
--- a/app/src/main/res/layout/activity_view_contact.xml
+++ b/app/src/main/res/layout/activity_view_contact.xml
@@ -10,10 +10,10 @@
android:id="@+id/contact_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="@dimen/medium_margin"
android:paddingLeft="@dimen/normal_margin"
+ android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/normal_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingBottom="@dimen/medium_margin">
@@ -39,16 +39,16 @@
android:id="@+id/contact_actions_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignBottom="@id/contact_photo"
android:layout_alignTop="@+id/contact_photo"
+ android:layout_alignBottom="@id/contact_photo"
android:gravity="center_vertical|right">
@@ -115,9 +115,9 @@
android:layout_toRightOf="@+id/contact_name_image"
android:lines="1"
android:maxLines="1"
- android:paddingBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
+ android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>
@@ -130,9 +130,9 @@
android:layout_toRightOf="@+id/contact_name_image"
android:lines="1"
android:maxLines="1"
- android:paddingBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
+ android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>
@@ -145,9 +145,9 @@
android:layout_toRightOf="@+id/contact_name_image"
android:lines="1"
android:maxLines="1"
- android:paddingBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
+ android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>
@@ -160,9 +160,9 @@
android:layout_toRightOf="@+id/contact_name_image"
android:lines="1"
android:maxLines="1"
- android:paddingBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
+ android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>
@@ -175,9 +175,9 @@
android:layout_toRightOf="@+id/contact_name_image"
android:lines="1"
android:maxLines="1"
- android:paddingBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
+ android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>
@@ -186,10 +186,10 @@
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_numbers_holder"
- android:paddingBottom="@dimen/small_margin"
+ android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingRight="@dimen/small_margin"
- android:paddingTop="@dimen/medium_margin"
+ android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_phone"/>
diff --git a/app/src/main/res/layout/dialog_call_confirmation.xml b/app/src/main/res/layout/dialog_call_confirmation.xml
index 9d406f6b..44971313 100644
--- a/app/src/main/res/layout/dialog_call_confirmation.xml
+++ b/app/src/main/res/layout/dialog_call_confirmation.xml
@@ -8,10 +8,10 @@
diff --git a/app/src/main/res/layout/dialog_export_contacts.xml b/app/src/main/res/layout/dialog_export_contacts.xml
index e8bfc397..b1708d9a 100644
--- a/app/src/main/res/layout/dialog_export_contacts.xml
+++ b/app/src/main/res/layout/dialog_export_contacts.xml
@@ -12,8 +12,8 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_margin"
- android:paddingRight="@dimen/activity_margin"
- android:paddingTop="@dimen/activity_margin">
+ android:paddingTop="@dimen/activity_margin"
+ android:paddingRight="@dimen/activity_margin">
+ android:paddingBottom="@dimen/small_margin"/>
@@ -65,7 +65,7 @@
android:text="@string/include_contact_sources"
android:textSize="@dimen/smaller_text_size"/>
-
-
@@ -48,8 +48,8 @@
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
- android:paddingLeft="@dimen/normal_margin"
- android:paddingStart="@dimen/normal_margin">
+ android:paddingStart="@dimen/normal_margin"
+ android:paddingLeft="@dimen/normal_margin">
diff --git a/app/src/main/res/layout/item_contact_without_number.xml b/app/src/main/res/layout/item_contact_without_number.xml
index 26b64417..ac84b0a0 100644
--- a/app/src/main/res/layout/item_contact_without_number.xml
+++ b/app/src/main/res/layout/item_contact_without_number.xml
@@ -20,6 +20,7 @@
android:id="@+id/contact_tmb"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
+ android:layout_marginTop="@dimen/tiny_margin"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_person"/>
diff --git a/app/src/main/res/layout/item_recent_call.xml b/app/src/main/res/layout/item_recent_call.xml
index 14c60772..da43a6ea 100644
--- a/app/src/main/res/layout/item_recent_call.xml
+++ b/app/src/main/res/layout/item_recent_call.xml
@@ -11,7 +11,7 @@
android:focusable="true"
android:foreground="@drawable/selector">
-
-
+
diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml
index 30f2f275..6e87be0f 100644
--- a/app/src/main/res/menu/menu.xml
+++ b/app/src/main/res/menu/menu.xml
@@ -5,7 +5,7 @@
android:id="@+id/search"
android:icon="@drawable/ic_search"
android:title="@string/search"
- app:actionViewClass="android.support.v7.widget.SearchView"
+ app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom"/>
- Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
Yeni kontakt
Redaktə et
Kontakt seç
@@ -57,6 +62,7 @@
Sevimlilər
Hazırki zənglər
Zəngə başlamazdan əvvəl zəng təsdiq pəncərəsi göstər
+ Show only contacts with phone numbers
E-poçt
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ec3adbe4..aa9e30e1 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -9,14 +9,19 @@
Unternehmen
Arbeitsstelle
Webseite
- Sende SMS an Kontakte
- Sende E-Mail an Kontakte
- Sende SMS an Gruppe
- Sende E-Mail an Gruppe
+ SMS an Kontakte senden
+ E-Mail an Kontakte senden
+ SMS an Gruppe senden
+ E-Mail an Gruppe senden
%s anrufen
Benötigte Berechtigungen anfordern
- Create new contact
- Add to an existing contact
+ Neuen Kontakt erstellen
+ Zu einem existierenden Kontakt hinzufügen
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
Neuer Kontakt
Kontakt bearbeiten
@@ -34,7 +39,7 @@
Diese Gruppe ist leer
Kontakte hinzufügen
Es sind keine Kontaktgruppen auf diesem Gerät vorhanden
- Erstelle Gruppe
+ Gruppe erstellen
Zu Gruppe hinzufügen
Gruppe in diesem Konto erstellen
@@ -45,18 +50,19 @@
Namen mit Nachnamen beginnen
- Zeige Telefonnummern im Hauptmenü
- Zeige Vorschaubilder der Kontakte
+ Telefonnummern im Hauptmenü zeigen
+ Vorschaubilder der Kontakte zeigen
Beim Klicken auf den Kontakt
Kontakt anrufen
Kontaktdetails anzeigen
- Bearbeite sichtbare Kontaktfelder
- Versuche Kontaktduplikate herauszufiltern
+ Sichtbare Kontaktfelder bearbeiten
+ Versucht Kontaktduplikate herauszufiltern
Anzuzeigende Tabs festlegen
Kontakte
Favoriten
Anrufliste
Bestätigungsdialog zeigen, bevor ein Anruf durchgeführt wird
+ Show only contacts with phone numbers
E-Mail
@@ -78,11 +84,11 @@
Jahrestag
- Sieht so aus, als ob du keine Kontakte zu den Favoriten hinzugefügt hast.
+ Anscheinend haben Sie bisher keine Kontakte zu den Favoriten hinzugefügt.
Favoriten hinzufügen
Zu Favoriten hinzufügen
Aus Favoriten entfernen
- Sie müssen sich im Bearbeitungsmodus befinden, um einen Kontakt zu bearbeiten
+ Sie müssen sich im Bearbeitungsmodus befinden, um einen Kontakt zu bearbeiten.
Kontakte durchsuchen
@@ -98,8 +104,8 @@
Dateiname (ohne .vcf)
- Dialpad
- Add number to contact
+ Wählfeld
+ Nummer zu Kontakt hinzufügen
Sichtbare Felder auswählen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index b548d329..618c88fb 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -15,8 +15,13 @@
Αποστολή email σε ομάδες
Κλήση %s
Ζητούνται τα απαιτούμενα δικαιώματα
- Create new contact
- Add to an existing contact
+ Δημιουργία νέας Επαφής
+ Προσθήκη σε μια υπάρχουσα Επαφή
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
Νέα επαφή
Επεξεργασία επαφής
@@ -57,6 +62,7 @@
Αγαπημένες
Πρόσφατες Κλήσεις
Εμφάνιση διαλόγου επιβεβαίωσης πριν από την έναρξη μιας κλήσης
+ Show only contacts with phone numbers
Email
@@ -98,8 +104,8 @@
Όνομα αρχείου (χωρίς .vcf)
- Dialpad
- Add number to contact
+ Πληκτρολόγιο
+ Προσθήκη αριθμού σε επαφή
Επιλογή εμφάνισης πεδίων
@@ -114,7 +120,7 @@
Ιστοσελίδα
Ομάδες
Προέλευση επαφής
- Instant messaging (IM)
+ Αμεσο μήνυμα (IM)
Θέλω να αλλάξω τα πεδία που θα είναι ορατά στις επαφές. Μπορώ να το κάνω?
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index b3dc4634..d51d9d93 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -15,8 +15,13 @@
Envoyer un e-mail au groupe
Call %s
Demander les autorisations requises
- Create new contact
- Add to an existing contact
+ Créer un nouveau contact
+ Ajouter à un contact existant
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
Nouveau contact
Modifier contact
@@ -57,6 +62,7 @@
Favorites
Appels récents
Afficher une boîte de dialogue de confirmation d\'appel avant de lancer un appel
+ Show only contacts with phone numbers
E-mail
@@ -99,7 +105,7 @@
Dialpad
- Add number to contact
+ Ajouter un numéro au contact
Sélectionner les champs à afficher
@@ -124,12 +130,12 @@
Une appli de contacts pour gérer vos contacts sans pubs.
- Une appli simple pour créer et gérer vos contacts depuis n\'importe quelle source. Les contacts peuvent être stockés sur votre appareil mais aussi synchronisés via Google ou d\'autres comptes. Vous pouvez afficher vos contacts favoris dans une liste séparée.
-
- Vous pouvez l\'utiliser pour gérer les e-mail et événements de vos contacts. Elle permet de trier/filter via de multiples paramètres, et même afficher le surnom en premier.
-
- Aucune publicité ni de permission inutile. Elle est entièrement open source et vous permet de personnaliser les couleurs.
-
+ Une appli simple pour créer et gérer vos contacts depuis n\'importe quelle source. Les contacts peuvent être stockés sur votre appareil mais aussi synchronisés via Google ou d\'autres comptes. Vous pouvez afficher vos contacts favoris dans une liste séparée.
+
+ Vous pouvez l\'utiliser pour gérer les e-mail et événements de vos contacts. Elle permet de trier/filter via de multiples paramètres, et même afficher le surnom en premier.
+
+ Aucune publicité ni de permission inutile. Elle est entièrement open source et vous permet de personnaliser les couleurs.
+
Cette application fait parti d\'un groupe d\'applications. Vous pouvez trouver le reste des applis sur https://www.simplemobiletools.com
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index d5c8544e..19d24c52 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -18,6 +18,11 @@
Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
Novi kontakt
Uredi kontakt
Odaberi kontakt
@@ -57,6 +62,7 @@
Favoriti
Nedavni pozivi
Pokažite dijaloški okvir za potvrdu poziva prije pokretanja poziva
+ Show only contacts with phone numbers
E-pošta
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
new file mode 100644
index 00000000..dd4efaa4
--- /dev/null
+++ b/app/src/main/res/values-it/strings.xml
@@ -0,0 +1,146 @@
+
+ Simple Contacts
+ Contatti
+ Indirizzo
+ Inserimento in corso…
+ Aggiornamento in corso…
+ Memoria del telefono
+ Memoria del telfono (non visibile alle altre applicazioni)
+ Compagnia
+ Posizione lavorativa
+ Sito web
+ Invia un SMS ai contatti
+ Invia un\'email ai contatti
+ Invia un SMS al gruppo
+ Invia un\'email al gruppo
+ Chiama %s
+ Richiedi le permissioni necessarie
+ Crea un nuovo contatto
+ Aggiungi ad un contatto esistente
+
+
+ Nessun contatto trovato
+ Nessun contatto trovato con un\'email
+ Nessun contatto trovato con un numero di telefono
+
+ Nuovo contatto
+ Modifica contatto
+ Seleziona contatto
+ Seleziona contatti
+ Nome
+ Secondo nome
+ Cognome
+ Soprannome
+
+
+ Nessun gruppo
+ Crea un nuovo gruppo
+ Rimuovi dal gruppo
+ Questo gruppo è vuoto
+ Aggiungi contatti
+ Non ci sono gruppi con contatti nel dispositivo
+ Crea gruppo
+ Aggiungi al gruppo
+ Crea un gruppo con un account
+
+
+ Scatta un foto
+ Scegli una foto
+ Rimuovi foto
+
+
+ Prima il nome poi il cognome
+ Mostra i numeri di telefono nella schermata principale
+ Mostra le anteprime dei contatti
+ Al click sul contatto
+ Chiama contatto
+ Visualizza i dettagli del contatto
+ Gestisci i campi mostrati
+ Prova a filetrare i contatti duplicati
+ Gestisci le schede mostrate
+ Contatti
+ Preferiti
+ Chiamate recenti
+ Mostra un dialogo di conferma prima di iniziare una chiamata
+ Mostra solamente i contatti con almeno un numero telefonico
+
+
+ Email
+ Casa
+ Lavoro
+ Altro
+
+
+ Numero
+ Cellulare
+ Principale
+ Fax di lavoro
+ Fax di casa
+ Cercapersone
+ Non è stato trovato alcun numero di telefono
+
+
+ Compleanno
+ Anniversario
+
+
+ Sembra che ancora non si ha nessun contatto preferito.
+ Aggiungi preferito
+ Aggiungi ai preferiti
+ Rimuovi dai preferiti
+ Devi stare nella schermata di modifica per modificare un contatto
+
+
+ Cerca contatti
+ Cerca preferiti
+
+
+ Importa contatti
+ Esporta contatti
+ Importa contatti da un file .vcf
+ Esporta contatti in un file .vcf
+ Individua la provenienza del contatto
+ Includi la provenienza del contatto
+ Nome del file (senza .vcf)
+
+
+ Tastiera
+ Aggiungi numero ai contatti
+
+
+ Seleziona i campi da mostrare
+ Prefisso
+ Suffisso
+ Numeri di telefono
+ Email
+ Indirizzi
+ Eventi (compleanni, anniversari)
+ Note
+ Organizazione
+ Siti web
+ Gruppi
+ Provenienza del contatto
+ Messaggistica istantanea (IM)
+
+
+ Voglio cambiare i campi visibili ai contatti. Come posso fare?
+ Puoi farlo andando in Impostazioni -> Gestisci i campi mostrati. Qui puoi selezionare i campi che saranno visibili. Alcuni sono anche disabilitati in maniera predefinita, quindi potresti trovare qualche nuovo campo.
+
+
+
+ Un\'applicazioni contatti per gestire i propri contatti senza pubblicità.
+
+ Una semplice applicazione per creare o gestire i propri contatti da qualsiasi provenienza. I contatti saranno salvati solamente nel dispositivo, ma possono essere sincronizzati con Google, o con altri servizi. Si possono visualizzare i contatti preferiti in una list separata.
+
+ Si può utilizzare l\'applicazione anche per gestire le email e gli eventi. Può ordinare e filtrare per parametri multipli, ed opzionalmente visualizzare il cognome come nome
+
+ Non contiene pubblicità nè chiede permessi non necessari. È completamente open source ed offre colori personalizzabili.
+
+ Quest\'app fa parte di una serie più grande. Puoi trovare le altre su https://www.simplemobiletools.com
+
+
+
+
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index e87a4211..026ac3bb 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -15,8 +15,13 @@
グループにメールを送信
Call %s
Request the required permissions
- Create new contact
- Add to an existing contact
+ 新しい連絡先を作成
+ 既存の連絡先に追加
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
新しい連絡先
連絡先を編集
@@ -57,6 +62,7 @@
お気に入り
Recent calls
発信する前に確認ダイアログを表示する
+ Show only contacts with phone numbers
メール
@@ -99,7 +105,7 @@
ダイヤルパッド
- Add number to contact
+ 連絡先に番号を追加
表示する項目を選択
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index 4c7bbb68..12228256 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -18,6 +18,11 @@
Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
새로운 연락처
연락처 수정
단건 연락처 선택
@@ -57,6 +62,7 @@
Favorites
Recent calls
Show a call confirmation dialog before initiating a call
+ Show only contacts with phone numbers
이메일
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index e99c1beb..e29dad0f 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -18,6 +18,11 @@
Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
Naujas kontaktas
Redaguoti kontaktą
Pasirinkti kontaktą
@@ -57,6 +62,7 @@
Favorites
Recent calls
Show a call confirmation dialog before initiating a call
+ Show only contacts with phone numbers
Elektroninis paštas
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index de97bde8..8d3ee2c4 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -15,8 +15,13 @@
Enviar e-mail para o grupo
Ligar a %s
Pedir a permissão necessária
- Create new contact
- Add to an existing contact
+ Criar novo contacto
+ Adicionar a contacto existente
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
Novo contacto
Editar contacto
@@ -57,6 +62,7 @@
Favoritos
Chamadas recentes
Mostrar diálogo para confirmar a chamada
+ Show only contacts with phone numbers
E-mail
@@ -98,8 +104,8 @@
Nome do ficheiro (sem .vcf)
- Dialpad
- Add number to contact
+ Teclado
+ Adicionar número a um contacto
Selecione os campos a mostrar
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 98b0eebb..54597139 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -18,6 +18,11 @@
Создать новый контакт
Добавить к существующему контакту
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
Новый контакт
Редактировать контакт
Выбрать контакт
@@ -57,6 +62,7 @@
Избранное
Недавние вызовы
Показывать диалог подтверждения вызова
+ Show only contacts with phone numbers
Эл. почта
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index ac542986..77d6cfe2 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -18,6 +18,11 @@
Vytvoriť nový kontakt
Pridať k existujúcemu kontaktu
+
+ Nenašli sa žiadne kontakty
+ Nenašli sa žiadne kontakty s emailami
+ Nenašli sa žiadne kontakty s telefónnymi číslami
+
Nový kontakt
Upraviť kontakt
Zvoľte kontakt
@@ -57,6 +62,7 @@
Obľúbené
Predošlé hovory
Zobraziť pred spustením hovoru okno na jeho potvrdenie
+ Zobraziť iba kontakty s telefónnymi číslami
Email
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index b2198c6e..53652727 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -15,8 +15,13 @@
Skicka e-post till grupp
Ring %s
Begär de behörigheter som krävs
- Create new contact
- Add to an existing contact
+ Skapa ny kontakt
+ Lägg till i en befintlig kontakt
+
+
+ Inga kontakter hittades
+ Inga kontakter med e-postadresser hittades
+ Inga kontakter med telefonnummer hittades
Ny kontakt
Redigera kontakt
@@ -57,6 +62,7 @@
Favoriter
Senaste samtal
Visa en bekräftelsedialogruta före uppringning
+ Visa bara kontakter med telefonnummer
E-post
@@ -98,8 +104,8 @@
Filnamn (utan .vcf)
- Dialpad
- Add number to contact
+ Knappsats
+ Lägg till nummer i kontakt
Välj vilka fält som ska visas
@@ -114,7 +120,7 @@
Webbplatser
Grupper
Kontaktkälla
- Instant messaging (IM)
+ Snabbmeddelanden (IM)
I want to change what fields are visible at contacts. Can I do it?
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 583219d7..c5d68865 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -18,6 +18,11 @@
Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
Yeni kişi
Kişiyi düzenle
Kişi seç
@@ -57,6 +62,7 @@
Favorites
Recent calls
Show a call confirmation dialog before initiating a call
+ Show only contacts with phone numbers
E-posta
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
deleted file mode 100644
index afdc4448..00000000
--- a/app/src/main/res/values-v21/styles.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 1fe54476..3f730034 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -15,8 +15,13 @@
發送電子郵件給群組
打電話給 %s
請求必要的權限
- Create new contact
- Add to an existing contact
+ 建立新聯絡人
+ 添加至已存在的聯絡人
+
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
新聯絡人
編輯聯絡人
@@ -25,7 +30,7 @@
名字
中間名
姓氏
- Nickname
+ 暱稱
沒有群組
@@ -57,6 +62,7 @@
我的最愛
通話紀錄
開始通話前顯示通話確認框
+ Show only contacts with phone numbers
電子信箱
@@ -98,8 +104,8 @@
檔案名稱 (不含.vcf)
- Dialpad
- Add number to contact
+ 撥號畫面
+ 添加號碼至通訊錄
選擇要顯示的欄位
@@ -114,7 +120,7 @@
網站
群組
聯絡人來源
- Instant messaging (IM)
+ 即時通訊 (IM)
我想要更改在通訊錄會看到哪些欄位。我能這麼做嗎?
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index c3d9f092..7cc00924 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -10,8 +10,10 @@
Hangouts
ICQ
Jabber
+ Telegram
+ Added new options for toggling 24 hour time format and showing only contacts with phone numbers
Added a simple dialpad, dialer will come soon
Added an optional IM field\n
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 53be90a2..8bf9c12c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -18,6 +18,11 @@
Create new contact
Add to an existing contact
+
+ No contacts found
+ No contacts with emails have been found
+ No contacts with phone numbers have been found
+
New contact
Edit contact
Select contact
@@ -57,6 +62,7 @@
Favorites
Recent calls
Show a call confirmation dialog before initiating a call
+ Show only contacts with phone numbers
Email
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index b7e0377a..1c76d77b 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -2,15 +2,12 @@
-
-
-
diff --git a/build.gradle b/build.gradle
index 76ac6173..eca330da 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.0'
+ classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/app.png
index f82264f1..8a75c203 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/app.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.png
index 1626bc5e..0d18499f 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_2.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.png
index 895ff603..0c8b157a 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_3.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/app_4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_4.png
new file mode 100644
index 00000000..f0ab9089
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/app_4.png differ
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 00000000..dbb7bf70
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,2 @@
+android.enableJetifier=true
+android.useAndroidX=true