diff --git a/CHANGELOG.md b/CHANGELOG.md index 76f705a5..eda7e504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ Changelog ========== +Version 6.4.0 *(2019-09-15)* +---------------------------- + + * Removed the setting for merging duplicate contacts, merge them always + * Show all contact sources of the contact at the View screen + * Fixed a glitch with some missing fields at exporting contacts in .ics files + Version 6.3.5 *(2019-08-27)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 0fa1c71d..b8a85159 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId "com.simplemobiletools.contacts.pro" minSdkVersion 21 targetSdkVersion 28 - versionCode 46 - versionName "6.3.5" + versionCode 47 + versionName "6.4.0" setProperty("archivesBaseName", "contacts") } @@ -51,7 +51,7 @@ android { } dependencies { - implementation 'com.simplemobiletools:commons:5.16.17' + implementation 'com.simplemobiletools:commons:5.17.17' implementation 'joda-time:joda-time:2.10.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ContactActivity.kt index 84e2c247..cdb316b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ContactActivity.kt @@ -51,7 +51,7 @@ abstract class ContactActivity : SimpleActivity() { .diskCacheStrategy(DiskCacheStrategy.RESOURCE) .centerCrop() - if (isDestroyed) { + if (isDestroyed || isFinishing) { return } @@ -77,14 +77,15 @@ abstract class ContactActivity : SimpleActivity() { fun deleteContact() { ConfirmationDialog(this) { if (contact != null) { - ContactsHelper(this).deleteContact(contact!!) - finish() + ContactsHelper(this).deleteContact(contact!!, false) { + finish() + } } } } - fun shareContact() { - shareContacts(arrayListOf(contact!!)) + fun shareContact(contact: Contact) { + shareContacts(arrayListOf(contact)) } fun trySendSMS() { @@ -179,8 +180,8 @@ abstract class ContactActivity : SimpleActivity() { } fun getEventTextId(type: Int) = when (type) { - ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> R.string.birthday ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> R.string.anniversary + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> R.string.birthday else -> R.string.other } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt index 821ffbe9..eb4c2531 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/EditContactActivity.kt @@ -108,7 +108,7 @@ class EditContactActivity : ContactActivity() { when (item.itemId) { R.id.save -> saveContact() - R.id.share -> shareContact() + R.id.share -> shareContact(contact!!) R.id.open_with -> openWith() R.id.delete -> deleteContact() else -> return super.onOptionsItemSelected(item) @@ -821,8 +821,8 @@ class EditContactActivity : ContactActivity() { private fun showEventTypePicker(eventTypeField: TextView) { val items = arrayListOf( - RadioItem(CommonDataKinds.Event.TYPE_BIRTHDAY, getString(R.string.birthday)), RadioItem(CommonDataKinds.Event.TYPE_ANNIVERSARY, getString(R.string.anniversary)), + RadioItem(CommonDataKinds.Event.TYPE_BIRTHDAY, getString(R.string.birthday)), RadioItem(CommonDataKinds.Event.TYPE_OTHER, getString(R.string.other)) ) @@ -992,10 +992,14 @@ class EditContactActivity : ContactActivity() { if (ContactsHelper(this@EditContactActivity).insertContact(contact!!)) { if (deleteCurrentContact) { contact!!.source = originalContactSource - ContactsHelper(this).deleteContact(contact!!) + ContactsHelper(this).deleteContact(contact!!, false) { + setResult(Activity.RESULT_OK) + finish() + } + } else { + setResult(Activity.RESULT_OK) + finish() } - setResult(Activity.RESULT_OK) - finish() } else { toast(R.string.unknown_error_occurred) } @@ -1217,8 +1221,8 @@ class EditContactActivity : ContactActivity() { } private fun getEventTypeId(value: String) = when (value) { - getString(R.string.birthday) -> CommonDataKinds.Event.TYPE_BIRTHDAY getString(R.string.anniversary) -> CommonDataKinds.Event.TYPE_ANNIVERSARY + getString(R.string.birthday) -> CommonDataKinds.Event.TYPE_BIRTHDAY else -> CommonDataKinds.Event.TYPE_OTHER } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt index 37edb2b6..49abd800 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt @@ -58,7 +58,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private var storedShowContactThumbnails = false private var storedShowPhoneNumbers = false private var storedStartNameWithSurname = false - private var storedFilterDuplicates = true private var storedShowTabs = 0 override fun onCreate(savedInstanceState: Bundle?) { @@ -137,10 +136,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } - if (storedFilterDuplicates != config.filterDuplicates) { - refreshContacts(ALL_TABS_MASK) - } - if (werePermissionsHandled && !isFirstResume) { if (viewpager.adapter == null) { initFragments() @@ -213,7 +208,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { storedShowContactThumbnails = showContactThumbnails storedShowPhoneNumbers = showPhoneNumbers storedStartNameWithSurname = startNameWithSurname - storedFilterDuplicates = filterDuplicates storedShowTabs = showTabs } } @@ -527,7 +521,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } override fun refreshContacts(refreshTabsMask: Int) { - if (isDestroyed || isGettingContacts) { + if (isDestroyed || isFinishing || isGettingContacts) { return } @@ -540,7 +534,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { ContactsHelper(this).getContacts { contacts -> isGettingContacts = false - if (isDestroyed) { + if (isDestroyed || isFinishing) { return@getContacts } @@ -575,6 +569,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { add(Release(34, R.string.release_34)) add(Release(39, R.string.release_39)) add(Release(40, R.string.release_40)) + add(Release(47, R.string.release_47)) checkWhatsNew(this, BuildConfig.VERSION_CODE) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt index 670e8486..5199c704 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SelectContactActivity.kt @@ -84,7 +84,7 @@ class SelectContactActivity : SimpleActivity() { private fun initContacts() { ContactsHelper(this).getContacts { - if (isDestroyed) { + if (isDestroyed || isFinishing) { return@getContacts } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SettingsActivity.kt index 6642034f..43e87563 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/SettingsActivity.kt @@ -39,7 +39,6 @@ class SettingsActivity : SimpleActivity() { setupShowPhoneNumbers() setupShowContactsWithNumbers() setupStartNameWithSurname() - setupFilterDuplicates() setupShowCallConfirmation() setupShowDialpadButton() setupShowDialpadLetters() @@ -130,14 +129,6 @@ class SettingsActivity : SimpleActivity() { } } - private fun setupFilterDuplicates() { - settings_filter_duplicates.isChecked = config.filterDuplicates - settings_filter_duplicates_holder.setOnClickListener { - settings_filter_duplicates.toggle() - config.filterDuplicates = settings_filter_duplicates.isChecked - } - } - private fun setupShowDialpadButton() { settings_show_dialpad_button.isChecked = config.showDialpadButton settings_show_dialpad_button_holder.setOnClickListener { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt index 6c92f793..f92de407 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/ViewContactActivity.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.WindowManager import android.widget.RelativeLayout import com.bumptech.glide.Glide +import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS import com.simplemobiletools.commons.helpers.ensureBackgroundThread @@ -16,10 +17,12 @@ import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.CallConfirmationDialog import com.simplemobiletools.contacts.pro.extensions.* import com.simplemobiletools.contacts.pro.helpers.* +import com.simplemobiletools.contacts.pro.models.* import kotlinx.android.synthetic.main.activity_view_contact.* -import kotlinx.android.synthetic.main.item_event.view.* import kotlinx.android.synthetic.main.item_view_address.view.* +import kotlinx.android.synthetic.main.item_view_contact_source.view.* import kotlinx.android.synthetic.main.item_view_email.view.* +import kotlinx.android.synthetic.main.item_view_event.view.* import kotlinx.android.synthetic.main.item_view_group.view.* import kotlinx.android.synthetic.main.item_view_im.view.* import kotlinx.android.synthetic.main.item_view_phone_number.view.* @@ -28,7 +31,12 @@ import kotlinx.android.synthetic.main.item_website.view.* class ViewContactActivity : ContactActivity() { private var isViewIntent = false private var wasEditLaunched = false + private var duplicateContacts = ArrayList() + private var contactSources = ArrayList() private var showFields = 0 + private var fullContact: Contact? = null // contact with all fields filled from duplicates + + private val COMPARABLE_PHONE_NUMBER_LENGTH = 7 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -77,10 +85,10 @@ class ViewContactActivity : ContactActivity() { } when (item.itemId) { - R.id.edit -> editContact() - R.id.share -> shareContact() + R.id.edit -> launchEditContact(contact!!) + R.id.share -> shareContact(fullContact!!) R.id.open_with -> openWith() - R.id.delete -> deleteContact() + R.id.delete -> deleteContactFromAllSources() else -> return super.onOptionsItemSelected(item) } return true @@ -96,6 +104,7 @@ class ViewContactActivity : ContactActivity() { val lookupKey = getLookupKeyFromUri(data) if (lookupKey != null) { contact = ContactsHelper(this).getContactWithLookupKey(lookupKey) + fullContact = contact wasLookupKeyUsed = true } @@ -112,6 +121,8 @@ class ViewContactActivity : ContactActivity() { if (contactId != 0 && !wasLookupKeyUsed) { contact = ContactsHelper(this).getContactWithId(contactId, intent.getBooleanExtra(IS_PRIVATE, false)) + fullContact = contact + if (contact == null) { if (!wasEditLaunched) { toast(R.string.unknown_error_occurred) @@ -191,21 +202,28 @@ class ViewContactActivity : ContactActivity() { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) setupFavorite() setupNames() - setupPhoneNumbers() - setupEmails() - setupAddresses() - setupIMs() - setupEvents() - setupNotes() - setupOrganization() - setupWebsites() - setupGroups() - setupContactSource() + + ContactsHelper(this).getContactSources { + contactSources = it + getDuplicateContacts { + setupPhoneNumbers() + setupEmails() + setupAddresses() + setupIMs() + setupEvents() + setupWebsites() + setupGroups() + setupContactSources() + setupNotes() + setupOrganization() + updateTextColors(contact_scrollview) + } + } } - private fun editContact() { + private fun launchEditContact(contact: Contact) { wasEditLaunched = true - editContact(contact!!) + editContact(contact) } private fun openWith() { @@ -267,8 +285,23 @@ class ViewContactActivity : ContactActivity() { } private fun setupPhoneNumbers() { + var phoneNumbers = contact!!.phoneNumbers.toMutableSet() as LinkedHashSet + duplicateContacts.forEach { + phoneNumbers.addAll(it.phoneNumbers) + } + + phoneNumbers = phoneNumbers.distinctBy { + if (it.normalizedNumber != null && it.normalizedNumber!!.length >= COMPARABLE_PHONE_NUMBER_LENGTH) { + it.normalizedNumber?.substring(it.normalizedNumber!!.length - COMPARABLE_PHONE_NUMBER_LENGTH) + } else { + it.normalizedNumber + } + }.toMutableSet() as LinkedHashSet + + phoneNumbers = phoneNumbers.sortedBy { it.type }.toMutableSet() as LinkedHashSet + fullContact!!.phoneNumbers = phoneNumbers.toMutableList() as ArrayList contact_numbers_holder.removeAllViews() - val phoneNumbers = contact!!.phoneNumbers + if (phoneNumbers.isNotEmpty() && showFields and SHOW_PHONE_NUMBERS_FIELD != 0) { phoneNumbers.forEach { layoutInflater.inflate(R.layout.item_view_phone_number, contact_numbers_holder, false).apply { @@ -297,6 +330,7 @@ class ViewContactActivity : ContactActivity() { } } + // a contact cannot have different emails per contact source. Such contacts are handled as separate ones, not duplicates of each other private fun setupEmails() { contact_emails_holder.removeAllViews() val emails = contact!!.emails @@ -323,8 +357,15 @@ class ViewContactActivity : ContactActivity() { } private fun setupAddresses() { + var addresses = contact!!.addresses.toMutableSet() as LinkedHashSet
+ duplicateContacts.forEach { + addresses.addAll(it.addresses) + } + + addresses = addresses.sortedBy { it.type }.toMutableSet() as LinkedHashSet
+ fullContact!!.addresses = addresses.toMutableList() as ArrayList
contact_addresses_holder.removeAllViews() - val addresses = contact!!.addresses + if (addresses.isNotEmpty() && showFields and SHOW_ADDRESSES_FIELD != 0) { addresses.forEach { layoutInflater.inflate(R.layout.item_view_address, contact_addresses_holder, false).apply { @@ -348,8 +389,15 @@ class ViewContactActivity : ContactActivity() { } private fun setupIMs() { + var IMs = contact!!.IMs.toMutableSet() as LinkedHashSet + duplicateContacts.forEach { + IMs.addAll(it.IMs) + } + + IMs = IMs.sortedBy { it.type }.toMutableSet() as LinkedHashSet + fullContact!!.IMs = IMs.toMutableList() as ArrayList contact_ims_holder.removeAllViews() - val IMs = contact!!.IMs + if (IMs.isNotEmpty() && showFields and SHOW_IMS_FIELD != 0) { IMs.forEach { layoutInflater.inflate(R.layout.item_view_im, contact_ims_holder, false).apply { @@ -369,16 +417,21 @@ class ViewContactActivity : ContactActivity() { } private fun setupEvents() { + var events = contact!!.events.toMutableSet() as LinkedHashSet + duplicateContacts.forEach { + events.addAll(it.events) + } + + events = events.sortedBy { it.type }.toMutableSet() as LinkedHashSet + fullContact!!.events = events.toMutableList() as ArrayList contact_events_holder.removeAllViews() - val events = contact!!.events + if (events.isNotEmpty() && showFields and SHOW_EVENTS_FIELD != 0) { events.forEach { - layoutInflater.inflate(R.layout.item_event, contact_events_holder, false).apply { + layoutInflater.inflate(R.layout.item_view_event, contact_events_holder, false).apply { contact_events_holder.addView(this) - contact_event.alpha = 1f it.value.getDateTimeFromDateString(contact_event) contact_event_type.setText(getEventTextId(it.type)) - contact_event_remove.beGone() copyOnLongClick(it.value) } } @@ -390,6 +443,97 @@ class ViewContactActivity : ContactActivity() { } } + private fun setupWebsites() { + var websites = contact!!.websites.toMutableSet() as LinkedHashSet + duplicateContacts.forEach { + websites.addAll(it.websites) + } + + websites = websites.sorted().toMutableSet() as LinkedHashSet + fullContact!!.websites = websites.toMutableList() as ArrayList + contact_websites_holder.removeAllViews() + + if (websites.isNotEmpty() && showFields and SHOW_WEBSITES_FIELD != 0) { + websites.forEach { + val url = it + layoutInflater.inflate(R.layout.item_website, contact_websites_holder, false).apply { + contact_websites_holder.addView(this) + contact_website.text = url + copyOnLongClick(url) + + setOnClickListener { + openWebsiteIntent(url) + } + } + } + contact_websites_image.beVisible() + contact_websites_holder.beVisible() + } else { + contact_websites_image.beGone() + contact_websites_holder.beGone() + } + } + + private fun setupGroups() { + var groups = contact!!.groups.toMutableSet() as LinkedHashSet + duplicateContacts.forEach { + groups.addAll(it.groups) + } + + groups = groups.sortedBy { it.title }.toMutableSet() as LinkedHashSet + fullContact!!.groups = groups.toMutableList() as ArrayList + contact_groups_holder.removeAllViews() + + if (groups.isNotEmpty() && showFields and SHOW_GROUPS_FIELD != 0) { + groups.forEach { + layoutInflater.inflate(R.layout.item_view_group, contact_groups_holder, false).apply { + val group = it + contact_groups_holder.addView(this) + contact_group.text = group.title + copyOnLongClick(group.title) + } + } + contact_groups_image.beVisible() + contact_groups_holder.beVisible() + } else { + contact_groups_image.beGone() + contact_groups_holder.beGone() + } + } + + private fun setupContactSources() { + contact_sources_holder.removeAllViews() + if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) { + var sources = HashMap() + sources[contact!!] = getPublicContactSourceSync(contact!!.source, contactSources) + duplicateContacts.forEach { + sources[it] = getPublicContactSourceSync(it.source, contactSources) + } + + if (sources.size > 1) { + sources = sources.toList().sortedBy { (key, value) -> value.toLowerCase() }.toMap() as LinkedHashMap + } + + for ((key, value) in sources) { + layoutInflater.inflate(R.layout.item_view_contact_source, contact_sources_holder, false).apply { + contact_source.text = value + contact_source.copyOnLongClick(value) + contact_sources_holder.addView(this) + + contact_source.setOnClickListener { + launchEditContact(key) + } + } + } + + contact_source_image.beVisible() + contact_sources_holder.beVisible() + } else { + contact_source_image.beGone() + contact_sources_holder.beGone() + } + } + private fun setupNotes() { val notes = contact!!.notes if (notes.isNotEmpty() && showFields and SHOW_NOTES_FIELD != 0) { @@ -424,61 +568,38 @@ class ViewContactActivity : ContactActivity() { } } - private fun setupWebsites() { - contact_websites_holder.removeAllViews() - val websites = contact!!.websites - if (websites.isNotEmpty() && showFields and SHOW_WEBSITES_FIELD != 0) { - websites.forEach { - val url = it - layoutInflater.inflate(R.layout.item_website, contact_websites_holder, false).apply { - contact_websites_holder.addView(this) - contact_website.text = url - copyOnLongClick(url) - - setOnClickListener { - openWebsiteIntent(url) + private fun getDuplicateContacts(callback: () -> Unit) { + ContactsHelper(this).getDuplicatesOfContact(contact!!, false) { contacts -> + ensureBackgroundThread { + duplicateContacts.clear() + contacts.forEach { + val duplicate = ContactsHelper(this).getContactWithId(it.id, it.isPrivate()) + if (duplicate != null) { + duplicateContacts.add(duplicate) } } - } - contact_websites_image.beVisible() - contact_websites_holder.beVisible() - } else { - contact_websites_image.beGone() - contact_websites_holder.beGone() - } - } - private fun setupGroups() { - contact_groups_holder.removeAllViews() - val groups = contact!!.groups - if (groups.isNotEmpty() && showFields and SHOW_GROUPS_FIELD != 0) { - groups.forEach { - layoutInflater.inflate(R.layout.item_view_group, contact_groups_holder, false).apply { - val group = it - contact_groups_holder.addView(this) - contact_group.text = group.title - copyOnLongClick(group.title) + runOnUiThread { + callback() } } - contact_groups_image.beVisible() - contact_groups_holder.beVisible() - } else { - contact_groups_image.beGone() - contact_groups_holder.beGone() } } - private fun setupContactSource() { - if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) { - getPublicContactSource(contact!!.source) { - contact_source.text = it - contact_source.copyOnLongClick(it) - } - contact_source_image.beVisible() - contact_source.beVisible() + private fun deleteContactFromAllSources() { + val addition = if (contact_sources_holder.childCount > 1) { + "\n\n${getString(R.string.delete_from_all_sources)}" } else { - contact_source_image.beGone() - contact_source.beGone() + "" + } + + val message = "${getString(R.string.proceed_with_deletion)}$addition" + ConfirmationDialog(this, message) { + if (contact != null) { + ContactsHelper(this).deleteContact(contact!!, true) { + finish() + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index c1e19c88..13cc99dd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -176,16 +176,23 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList + ensureBackgroundThread { + contactsToRemove.forEach { + val contactToRemove = it + val duplicates = allContacts.filter { it.id != contactToRemove.id && it.getHashToCompare() == contactToRemove.getHashToCompare() }.toMutableList() as ArrayList + duplicates.add(contactToRemove) + ContactsHelper(activity).deleteContacts(duplicates) + } - activity.runOnUiThread { - if (contactItems.isEmpty()) { - refreshListener?.refreshContacts(ALL_TABS_MASK) - finishActMode() - } else { - removeSelectedItems(positions) - refreshListener?.refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK) + activity.runOnUiThread { + if (contactItems.isEmpty()) { + refreshListener?.refreshContacts(ALL_TABS_MASK) + finishActMode() + } else { + removeSelectedItems(positions) + refreshListener?.refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK) + } } } } @@ -265,7 +272,7 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList) { val file = getTempFile() if (file == null) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Context.kt index 59868db0..2aafcf93 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Context.kt @@ -15,7 +15,10 @@ import android.provider.ContactsContract import android.telecom.TelecomManager import androidx.core.content.FileProvider import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS +import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS +import com.simplemobiletools.commons.helpers.isMarshmallowPlus +import com.simplemobiletools.commons.helpers.isNougatPlus import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.EditContactActivity @@ -30,7 +33,6 @@ import com.simplemobiletools.contacts.pro.models.ContactSource import com.simplemobiletools.contacts.pro.models.Organization import java.io.File - val Context.config: Config get() = Config.newInstance(applicationContext) val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao() @@ -196,24 +198,39 @@ fun Context.getPublicContactSource(source: String, callback: (String) -> Unit) { when (source) { SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden)) else -> { - ensureBackgroundThread { - ContactsHelper(this).getContactSources { - var newSource = source - for (contactSource in it) { - if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { - newSource += " (${getString(R.string.telegram)})" - break - } - } - Handler(Looper.getMainLooper()).post { - callback(newSource) + ContactsHelper(this).getContactSources { + var newSource = source + for (contactSource in it) { + if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { + newSource += " (${getString(R.string.telegram)})" + break } } + Handler(Looper.getMainLooper()).post { + callback(newSource) + } } } } } +fun Context.getPublicContactSourceSync(source: String, contactSources: ArrayList): String { + return when (source) { + SMT_PRIVATE -> getString(R.string.phone_storage_hidden) + else -> { + var newSource = source + for (contactSource in contactSources) { + if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { + newSource += " (${getString(R.string.telegram)})" + break + } + } + + return newSource + } + } +} + fun Context.sendSMSToContacts(contacts: ArrayList) { val numbers = StringBuilder() contacts.forEach { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt index 1dd4a759..0098fbb3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt @@ -41,10 +41,6 @@ class Config(context: Context) : BaseConfig(context) { SHOW_ADDRESSES_FIELD or SHOW_EVENTS_FIELD or SHOW_NOTES_FIELD or SHOW_GROUPS_FIELD or SHOW_CONTACT_SOURCE_FIELD) set(showContactFields) = prefs.edit().putInt(SHOW_CONTACT_FIELDS, showContactFields).apply() - var filterDuplicates: Boolean - get() = prefs.getBoolean(FILTER_DUPLICATES, true) - set(filterDuplicates) = prefs.edit().putBoolean(FILTER_DUPLICATES, filterDuplicates).apply() - var showTabs: Int get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK) set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt index 0fa64cf7..e9d95de1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt @@ -13,7 +13,6 @@ const val LAST_USED_CONTACT_SOURCE = "last_used_contact_source" const val ON_CONTACT_CLICK = "on_contact_click" const val SHOW_CONTACT_FIELDS = "show_contact_fields" const val SHOW_TABS = "show_tabs" -const val FILTER_DUPLICATES = "filter_duplicates" const val SHOW_CALL_CONFIRMATION = "show_call_confirmation" const val SHOW_DIALPAD_BUTTON = "show_dialpad_button" const val SHOW_DIALPAD_LETTERS = "show_dialpad_letters" diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt index 30d247d9..3bf36901 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt @@ -28,18 +28,18 @@ class ContactsHelper(val context: Context) { private val BATCH_SIZE = 50 private var displayContactSources = ArrayList() - fun getContacts(isExporting: Boolean = false, ignoredContactSources: HashSet = HashSet(), callback: (ArrayList) -> Unit) { + fun getContacts(getAll: Boolean = false, ignoredContactSources: HashSet = HashSet(), callback: (ArrayList) -> Unit) { ensureBackgroundThread { val contacts = SparseArray() displayContactSources = context.getVisibleContactSources() - if (isExporting) { + if (getAll) { displayContactSources = if (ignoredContactSources.isEmpty()) { - context.getAllContactSources().map { it.getFullIdentifier() }.toMutableList() as ArrayList + context.getAllContactSources().map { it.name }.toMutableList() as ArrayList } else { context.getAllContactSources().filter { it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier()) - }.map { it.getFullIdentifier() }.toMutableList() as ArrayList + }.map { it.name }.toMutableList() as ArrayList } } @@ -66,7 +66,7 @@ class ContactsHelper(val context: Context) { contacts.valueAt(it) } - if (ignoredContactSources.isEmpty() && context.config.filterDuplicates && !isExporting) { + if (ignoredContactSources.isEmpty() && !getAll) { tempContacts = tempContacts.distinctBy { it.getHashToCompare() } as ArrayList @@ -848,7 +848,7 @@ class ContactsHelper(val context: Context) { } } - private fun getContactSourcesSync(): ArrayList { + fun getContactSourcesSync(): ArrayList { val sources = getDeviceContactSources() sources.add(context.getPrivateContactSource()) return ArrayList(sources) @@ -1524,21 +1524,29 @@ class ContactsHelper(val context: Context) { LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites) } - fun deleteContact(contact: Contact) { + fun deleteContact(originalContact: Contact, deleteClones: Boolean = false, callback: (success: Boolean) -> Unit) { ensureBackgroundThread { - if (contact.isPrivate()) { - context.contactsDB.deleteContactId(contact.id) + if (deleteClones) { + getDuplicatesOfContact(originalContact, true) { contacts -> + ensureBackgroundThread { + if (deleteContacts(contacts)) { + callback(true) + } + } + } } else { - deleteContacts(arrayListOf(contact)) + if (deleteContacts(arrayListOf(originalContact))) { + callback(true) + } } } } - fun deleteContacts(contacts: ArrayList) { + fun deleteContacts(contacts: ArrayList): Boolean { val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList() LocalContactsHelper(context).deleteContactIds(localContacts) - try { + return try { val operations = ArrayList() val selection = "${ContactsContract.RawContacts._ID} = ?" contacts.filter { !it.isPrivate() }.forEach { @@ -1557,8 +1565,22 @@ class ContactsHelper(val context: Context) { if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) { context.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) } + true } catch (e: Exception) { context.showErrorToast(e) + false + } + } + + fun getDuplicatesOfContact(contact: Contact, addOriginal: Boolean, callback: (ArrayList) -> Unit) { + ensureBackgroundThread { + getContacts(true) { contacts -> + val duplicates = contacts.filter { it.id != contact.id && it.getHashToCompare() == contact.getHashToCompare() }.toMutableList() as ArrayList + if (addOriginal) { + duplicates.add(contact) + } + callback(duplicates) + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt index eb36d4dd..d973db4e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfExporter.kt @@ -70,7 +70,7 @@ class VcfExporter { } contact.events.forEach { - if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY || it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY) { + if (it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY || it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) { val dateTime = it.value.getDateTimeFromDateString() if (it.value.startsWith("--")) { val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfImporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfImporter.kt index 9a959764..a9030e19 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/VcfImporter.kt @@ -88,13 +88,13 @@ class VcfImporter(val activity: SimpleActivity) { } val events = ArrayList() - ezContact.birthdays.forEach { - val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_BIRTHDAY) + ezContact.anniversaries.forEach { + val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_ANNIVERSARY) events.add(event) } - ezContact.anniversaries.forEach { - val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_ANNIVERSARY) + ezContact.birthdays.forEach { + val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_BIRTHDAY) events.add(event) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt index 1662cf78..df352182 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt @@ -112,7 +112,7 @@ data class Contact(var id: Int, var prefix: String, var firstName: String, var m emails.mapTo(newEmails) { Email(it.value, 0, "") } return copy(id = 0, prefix = "", firstName = getNameToDisplay().toLowerCase(), middleName = "", surname = "", suffix = "", nickname = "", photoUri = "", - phoneNumbers = ArrayList(), events = ArrayList(), addresses = ArrayList(), emails = newEmails, starred = 0, contactId = 0, + phoneNumbers = ArrayList(), events = ArrayList(), source = "", addresses = ArrayList(), emails = newEmails, starred = 0, contactId = 0, thumbnailUri = "", notes = "", groups = ArrayList(), websites = ArrayList(), organization = Organization("", ""), IMs = ArrayList()).toString() } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index a6ea7d26..d5772d83 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -244,30 +244,6 @@ - - - - - - - - + android:src="@drawable/ic_phone_vector" + android:visibility="gone" /> - - + android:src="@drawable/ic_email_vector" + android:visibility="gone" /> - - + android:src="@drawable/ic_place_vector" + android:visibility="gone" /> - - + android:src="@drawable/ic_im" + android:visibility="gone" /> - - + android:src="@drawable/ic_cake_vector" + android:visibility="gone" /> + android:src="@drawable/ic_label_vector" + android:visibility="gone" /> + + + + + + + + + + + + + + + + + + + + + + + + - - + android:textSize="@dimen/bigger_text_size" + android:visibility="gone" /> + android:textSize="@dimen/bigger_text_size" + android:visibility="gone" /> - - - - - - - - - - - - + android:visibility="gone" /> diff --git a/app/src/main/res/layout/item_view_contact_source.xml b/app/src/main/res/layout/item_view_contact_source.xml new file mode 100644 index 00000000..cfa4fda6 --- /dev/null +++ b/app/src/main/res/layout/item_view_contact_source.xml @@ -0,0 +1,15 @@ + + diff --git a/app/src/main/res/layout/item_view_event.xml b/app/src/main/res/layout/item_view_event.xml new file mode 100644 index 00000000..002f5cf4 --- /dev/null +++ b/app/src/main/res/layout/item_view_event.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 07c24211..3ea074e5 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 63ddbdaa..aa52c89e 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index 6212f761..de7f3c65 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 4e7e5a01..f891f9fb 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 69f542bd..d8f849d1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e7a49e29..b8d1802b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -146,6 +146,7 @@ Θέλετε σίγουρα να διαγράψετε %s? + Η επαφή θα καταργηθεί από όλες τις πηγές επαφών. diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 3a876325..19911d33 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 622c5425..fe02fd4c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 65551d6f..b76250a9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 1f62984b..4e15f891 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 46f82306..bd713247 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index dcfb6b60..56728db2 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -96,7 +96,7 @@ Cari kontak Cari favorit - Search groups + Cari grup Impor kontak @@ -145,17 +145,18 @@ Nomor yang diblokir - Are you sure you want to delete %s? + Apakah anda yakin ingin menghapus %s? + The contact will be removed from all contact sources. - %d contact - %d contacts + %d kontak + %d kontak - %d group - %d groups + %d grup + %d grup diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index dcfb6b60..56728db2 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -96,7 +96,7 @@ Cari kontak Cari favorit - Search groups + Cari grup Impor kontak @@ -145,17 +145,18 @@ Nomor yang diblokir - Are you sure you want to delete %s? + Apakah anda yakin ingin menghapus %s? + The contact will be removed from all contact sources. - %d contact - %d contacts + %d kontak + %d kontak - %d group - %d groups + %d grup + %d grup diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f330ea8c..ec316575 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 753fdfe5..54cb93c8 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 5088238d..6bb3d023 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 6aa55c79..3accc57f 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5e316618..2d72e6bd 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -146,6 +146,7 @@ %s verwijderen? + De contactpersoon zal worden verwijderd uit alle accounts. diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a33e8e1d..8b7542a0 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 616c1a33..b303ec46 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 82a67c4d..ddb3ac7a 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -14,7 +14,7 @@ Enviar SMS para o grupo Enviar e-mail para o grupo Ligar a %s - Pedir a permissão necessária + Pedir permissão necessária Criar novo contacto Adicionar a contacto existente Tem que tornar esta a aplicação padrão para poder bloquear números. @@ -96,7 +96,7 @@ Pesquisar nos contactos Pesquisar nos favoritos - Search groups + Pesquisar nos grupos Importar contactos @@ -145,17 +145,18 @@ Números bloqueados - Are you sure you want to delete %s? + Tem a certeza de que deseja apagar %s? + The contact will be removed from all contact sources. - %d contact - %d contacts + %d contacto + %d contactos - %d group - %d groups + %d grupo + %d grupos diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b6f4e0be..859df53f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -146,6 +146,7 @@ Вы уверены, что хотите удалить %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 293d5b26..c289ff6b 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -146,6 +146,7 @@ Ste si istý, že chcete vymazať %s? + Kontakt bude vymazaný zo všetkých zdrojov kontaktov. diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 9e85a22b..eea4c810 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d0bdd0e2..1505b03e 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 8cf27893..617256c3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 661e6c3c..0699b165 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources. diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 99febf65..2d97e6f5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -145,17 +145,18 @@ 黑名單 - Are you sure you want to delete %s? + 你確認要刪除 %s 嗎? + The contact will be removed from all contact sources. - %d contact - %d contacts + %d個聯絡人 + %d個聯絡人 - %d group - %d groups + %d個群組 + %d個群組 diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 6bd73043..e93bca01 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -14,6 +14,7 @@ Telegram + Removed the setting for merging duplicate contacts, merge them always Removed the Recents tab due to Googles\' latest security policies being stricter than initiall thought\n Allow showing letters on the dialpad diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8e28dcb8..b4c9f6ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -146,6 +146,7 @@ Are you sure you want to delete %s? + The contact will be removed from all contact sources.