From 51d76ce99aa4f3562e4428292839bd5ad77ce07c Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Fri, 17 Feb 2023 02:26:29 +0100 Subject: [PATCH 1/6] feat: moved sharable contacts code to commons --- .../pro/activities/ContactActivity.kt | 10 +- .../pro/activities/EditContactActivity.kt | 45 +- .../pro/activities/GroupContactsActivity.kt | 5 +- .../activities/InsertOrEditContactActivity.kt | 10 +- .../contacts/pro/activities/MainActivity.kt | 59 +- .../pro/activities/SettingsActivity.kt | 57 +- .../pro/activities/ViewContactActivity.kt | 10 +- .../contacts/pro/adapters/ContactsAdapter.kt | 8 +- .../adapters/FilterContactSourcesAdapter.kt | 2 +- .../contacts/pro/adapters/GroupsAdapter.kt | 12 +- .../pro/adapters/SelectContactsAdapter.kt | 14 +- .../MyContactsContentProvider.kt | 6 +- .../pro/databases/ContactsDatabase.kt | 180 +- .../pro/dialogs/ChangeSortingDialog.kt | 4 +- .../pro/dialogs/ChooseSocialDialog.kt | 2 +- .../pro/dialogs/CreateNewGroupDialog.kt | 7 +- .../pro/dialogs/ExportContactsDialog.kt | 14 +- .../pro/dialogs/FilterContactSourcesDialog.kt | 11 +- .../pro/dialogs/ImportContactsDialog.kt | 10 +- .../pro/dialogs/ManageVisibleFieldsDialog.kt | 10 +- .../pro/dialogs/ManageVisibleTabsDialog.kt | 8 +- .../pro/dialogs/MyDatePickerDialog.kt | 4 +- .../contacts/pro/dialogs/RenameGroupDialog.kt | 5 +- .../pro/dialogs/SelectContactsDialog.kt | 3 +- .../pro/dialogs/SelectGroupsDialog.kt | 4 +- .../contacts/pro/extensions/Activity.kt | 13 +- .../contacts/pro/extensions/Context.kt | 653 ++-- .../pro/fragments/FavoritesFragment.kt | 2 +- .../pro/fragments/MyViewPagerFragment.kt | 23 +- .../contacts/pro/helpers/Config.kt | 154 +- .../contacts/pro/helpers/Constants.kt | 161 +- .../contacts/pro/helpers/ContactsHelper.kt | 3094 ++++++++--------- .../contacts/pro/helpers/Converters.kt | 152 +- .../pro/helpers/LocalContactsHelper.kt | 346 +- .../contacts/pro/helpers/VcfExporter.kt | 59 +- .../contacts/pro/helpers/VcfImporter.kt | 12 +- .../contacts/pro/interfaces/ContactsDao.kt | 74 +- .../contacts/pro/interfaces/GroupsDao.kt | 38 +- .../pro/interfaces/RefreshContactsListener.kt | 2 +- .../pro/interfaces/RemoveFromGroupListener.kt | 2 +- .../contacts/pro/models/Address.kt | 6 +- .../contacts/pro/models/Contact.kt | 360 +- .../contacts/pro/models/ContactSource.kt | 26 +- .../contacts/pro/models/Email.kt | 6 +- .../contacts/pro/models/Event.kt | 6 +- .../contacts/pro/models/Group.kt | 42 +- .../contacts/pro/models/IM.kt | 6 +- .../contacts/pro/models/LocalContact.kt | 72 +- .../contacts/pro/models/Organization.kt | 14 +- .../pro/models/PhoneNumberConverter.kt | 8 +- .../contacts/pro/models/SocialAction.kt | 6 +- 51 files changed, 2918 insertions(+), 2919 deletions(-) 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 27f08382..be978240 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 @@ -10,7 +10,9 @@ import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.media.RingtoneManager import android.net.Uri +import android.provider.ContactsContract import android.provider.ContactsContract.CommonDataKinds.* +import android.provider.ContactsContract.CommonDataKinds.Email import android.widget.ImageView import android.widget.TextView import com.bumptech.glide.Glide @@ -24,12 +26,12 @@ import com.bumptech.glide.request.target.Target import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.letterBackgroundColors import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.extensions.shareContacts -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* abstract class ContactActivity : SimpleActivity() { protected val PICK_RINGTONE_INTENT_ID = 1500 @@ -207,8 +209,8 @@ abstract class ContactActivity : SimpleActivity() { } fun getEventTextId(type: Int) = when (type) { - Event.TYPE_ANNIVERSARY -> R.string.anniversary - 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 e65c1c2a..ad53706b 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 @@ -29,6 +29,10 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.PhoneNumber import com.simplemobiletools.commons.models.RadioItem +import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.commons.models.contacts.Email +import com.simplemobiletools.commons.models.contacts.Event +import com.simplemobiletools.commons.models.contacts.Organization import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.CustomLabelDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog @@ -36,10 +40,6 @@ import com.simplemobiletools.contacts.pro.dialogs.MyDatePickerDialog import com.simplemobiletools.contacts.pro.dialogs.SelectGroupsDialog import com.simplemobiletools.contacts.pro.extensions.* import com.simplemobiletools.contacts.pro.helpers.* -import com.simplemobiletools.contacts.pro.models.* -import com.simplemobiletools.contacts.pro.models.Email -import com.simplemobiletools.contacts.pro.models.Event -import com.simplemobiletools.contacts.pro.models.Organization import kotlinx.android.synthetic.main.activity_edit_contact.* import kotlinx.android.synthetic.main.item_edit_address.view.* import kotlinx.android.synthetic.main.item_edit_email.view.* @@ -219,15 +219,25 @@ class EditContactActivity : ContactActivity() { val properPrimaryColor = getProperPrimaryColor() arrayOf( - contact_numbers_add_new, contact_emails_add_new, contact_addresses_add_new, contact_ims_add_new, contact_events_add_new, - contact_websites_add_new, contact_groups_add_new + contact_numbers_add_new, + contact_emails_add_new, + contact_addresses_add_new, + contact_ims_add_new, + contact_events_add_new, + contact_websites_add_new, + contact_groups_add_new ).forEach { it.applyColorFilter(properPrimaryColor) } arrayOf( - contact_numbers_add_new.background, contact_emails_add_new.background, contact_addresses_add_new.background, contact_ims_add_new.background, - contact_events_add_new.background, contact_websites_add_new.background, contact_groups_add_new.background + contact_numbers_add_new.background, + contact_emails_add_new.background, + contact_addresses_add_new.background, + contact_ims_add_new.background, + contact_events_add_new.background, + contact_websites_add_new.background, + contact_groups_add_new.background ).forEach { it.applyColorFilter(textColor) } @@ -378,7 +388,7 @@ class EditContactActivity : ContactActivity() { } private fun setupFieldVisibility() { - val showFields = config.showContactFields + val showFields = contactsConfig.showContactFields if (showFields and (SHOW_PREFIX_FIELD or SHOW_FIRST_NAME_FIELD or SHOW_MIDDLE_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_SUFFIX_FIELD) == 0) { contact_name_image.beInvisible() } @@ -599,11 +609,18 @@ class EditContactActivity : ContactActivity() { startActivityForResult(ringtonePickerIntent, INTENT_SELECT_RINGTONE) } catch (e: Exception) { val currentRingtone = contact!!.ringtone ?: getDefaultAlarmSound(RingtoneManager.TYPE_RINGTONE).uri - SelectAlarmSoundDialog(this, currentRingtone, AudioManager.STREAM_RING, PICK_RINGTONE_INTENT_ID, RingtoneManager.TYPE_RINGTONE, true, + SelectAlarmSoundDialog( + this, + currentRingtone, + AudioManager.STREAM_RING, + PICK_RINGTONE_INTENT_ID, + RingtoneManager.TYPE_RINGTONE, + true, onAlarmPicked = { contact!!.ringtone = it?.uri contact_ringtone.text = it?.title - }, onAlarmSoundDeleted = {} + }, + onAlarmSoundDeleted = {} ) } } @@ -727,7 +744,7 @@ class EditContactActivity : ContactActivity() { } private fun setupNewContact() { - originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE + originalContactSource = if (hasContactPermissions()) contactsConfig.lastUsedContactSource else SMT_PRIVATE contact = getEmptyContact() getPublicContactSource(contact!!.source) { contact_source.text = if (it == "") getString(R.string.phone_storage) else it @@ -1032,7 +1049,7 @@ class EditContactActivity : ContactActivity() { contact = contactValues ensureBackgroundThread { - config.lastUsedContactSource = contact!!.source + contactsConfig.lastUsedContactSource = contact!!.source when { contact!!.id == 0 -> insertNewContact(false) originalContactSource != contact!!.source -> insertNewContact(true) @@ -1067,7 +1084,7 @@ class EditContactActivity : ContactActivity() { events = filledEvents, starred = if (isContactStarred()) 1 else 0, notes = contact_notes.value, - websites = filledWebsites, + websites = filledWebsites ) val company = contact_organization_company.value diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/GroupContactsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/GroupContactsActivity.kt index 1e8e2120..55618e44 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/GroupContactsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/GroupContactsActivity.kt @@ -7,19 +7,18 @@ import android.net.Uri import android.os.Bundle import androidx.coordinatorlayout.widget.CoordinatorLayout import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter import com.simplemobiletools.contacts.pro.dialogs.SelectContactsDialog import com.simplemobiletools.contacts.pro.extensions.* -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper import com.simplemobiletools.contacts.pro.helpers.GROUP import com.simplemobiletools.contacts.pro.helpers.LOCATION_GROUP_CONTACTS import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.Group +import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.activity_group_contacts.* class GroupContactsActivity : SimpleActivity(), RemoveFromGroupListener, RefreshContactsListener { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt index 7d3c0e6d..90b1f1c9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt @@ -17,15 +17,13 @@ import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getContactPublicUri +import com.simplemobiletools.commons.extensions.contactsConfig import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.pro.helpers.ADD_NEW_CONTACT_NUMBER -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper import com.simplemobiletools.contacts.pro.helpers.KEY_EMAIL import com.simplemobiletools.contacts.pro.helpers.KEY_NAME import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.activity_insert_edit_contact.* import kotlinx.android.synthetic.main.fragment_contacts.* import kotlinx.android.synthetic.main.fragment_favorites.* @@ -161,7 +159,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { insert_edit_tabs_holder.removeAllTabs() contactsFavoritesList.forEachIndexed { index, value -> - if (config.showTabs and value != 0) { + if (contactsConfig.showTabs and value != 0) { insert_edit_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -351,7 +349,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun getTabsMask(): Int { var mask = TAB_CONTACTS - if (config.showTabs and TAB_FAVORITES != 0) { + if (contactsConfig.showTabs and TAB_FAVORITES != 0) { mask += TAB_FAVORITES } return mask 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 406d0940..18f1024f 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 @@ -14,31 +14,28 @@ import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.viewpager.widget.ViewPager +import com.simplemobiletools.commons.databases.ContactsDatabase import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.extensions.contactsConfig import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.Release +import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter -import com.simplemobiletools.contacts.pro.databases.ContactsDatabase import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.ExportContactsDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getTempFile import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment -import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper import com.simplemobiletools.contacts.pro.helpers.VcfExporter import com.simplemobiletools.contacts.pro.helpers.tabsList import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener -import com.simplemobiletools.contacts.pro.models.Contact import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_contacts.* import kotlinx.android.synthetic.main.fragment_favorites.* @@ -93,19 +90,19 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { override fun onResume() { super.onResume() - if (storedShowPhoneNumbers != config.showPhoneNumbers) { + if (storedShowPhoneNumbers != contactsConfig.showPhoneNumbers) { System.exit(0) return } - if (storedShowTabs != config.showTabs) { - config.lastUsedViewPagerPage = 0 + if (storedShowTabs != contactsConfig.showTabs) { + contactsConfig.lastUsedViewPagerPage = 0 finish() startActivity(intent) return } - val configShowContactThumbnails = config.showContactThumbnails + val configShowContactThumbnails = contactsConfig.showContactThumbnails if (storedShowContactThumbnails != configShowContactThumbnails) { getAllFragments().forEach { it?.showContactThumbnailsChanged(configShowContactThumbnails) @@ -122,13 +119,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { updateMenuColors() setupTabColors() - val configStartNameWithSurname = config.startNameWithSurname + val configStartNameWithSurname = contactsConfig.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } - val configFontSize = config.fontSize + val configFontSize = contactsConfig.fontSize if (storedFontSize != configFontSize) { getAllFragments().forEach { it?.fontSizeChanged() @@ -147,23 +144,23 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_dialpad_button.apply { setImageDrawable(dialpadIcon) background.applyColorFilter(properPrimaryColor) - beVisibleIf(config.showDialpadButton) + beVisibleIf(contactsConfig.showDialpadButton) } isFirstResume = false checkShortcuts() - if (!config.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { + if (!contactsConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { val dialogText = getString(R.string.upgraded_to_pro_contacts, getString(R.string.phone_storage_hidden)) ConfirmationDialog(this, dialogText, 0, R.string.ok, 0, false) {} - config.wasUpgradedFromFreeShown = true + contactsConfig.wasUpgradedFromFreeShown = true } } override fun onPause() { super.onPause() storeStateVariables() - config.lastUsedViewPagerPage = view_pager.currentItem + contactsConfig.lastUsedViewPagerPage = view_pager.currentItem } override fun onDestroy() { @@ -200,7 +197,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_menu.getToolbar().menu.apply { findItem(R.id.sort).isVisible = currentFragment != groups_fragment findItem(R.id.filter).isVisible = currentFragment != groups_fragment - findItem(R.id.dialpad).isVisible = !config.showDialpadButton + findItem(R.id.dialpad).isVisible = !contactsConfig.showDialpadButton findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) } } @@ -242,7 +239,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun storeStateVariables() { - config.apply { + contactsConfig.apply { storedShowContactThumbnails = showContactThumbnails storedShowPhoneNumbers = showPhoneNumbers storedStartNameWithSurname = startNameWithSurname @@ -253,13 +250,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { @SuppressLint("NewApi") private fun checkShortcuts() { - val appIconColor = config.appIconColor - if (isNougatMR1Plus() && config.lastHandledShortcutColor != appIconColor) { + val appIconColor = contactsConfig.appIconColor + if (isNougatMR1Plus() && contactsConfig.lastHandledShortcutColor != appIconColor) { val createNewContact = getCreateNewContactShortcut(appIconColor) try { shortcutManager.dynamicShortcuts = Arrays.asList(createNewContact) - config.lastHandledShortcutColor = appIconColor + contactsConfig.lastHandledShortcutColor = appIconColor } catch (ignored: Exception) { } } @@ -283,7 +280,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getCurrentFragment(): MyViewPagerFragment? { - val showTabs = config.showTabs + val showTabs = contactsConfig.showTabs val fragments = arrayListOf() if (showTabs and TAB_CONTACTS != 0) { fragments.add(contacts_fragment) @@ -317,7 +314,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): ArrayList { - val showTabs = config.showTabs + val showTabs = contactsConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -336,7 +333,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getDeselectedTabDrawableIds(): ArrayList { - val showTabs = config.showTabs + val showTabs = contactsConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -388,7 +385,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { main_tabs_holder.removeAllTabs() tabsList.forEachIndexed { index, value -> - if (config.showTabs and value != 0) { + if (contactsConfig.showTabs and value != 0) { main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -502,7 +499,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun tryExportContacts() { if (isQPlus()) { - ExportContactsDialog(this, config.lastExportPath, true) { file, ignoredContactSources -> + ExportContactsDialog(this, contactsConfig.lastExportPath, true) { file, ignoredContactSources -> ignoredExportContactSources = ignoredContactSources Intent(Intent.ACTION_CREATE_DOCUMENT).apply { @@ -522,7 +519,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } else { handlePermission(PERMISSION_WRITE_STORAGE) { if (it) { - ExportContactsDialog(this, config.lastExportPath, false) { file, ignoredContactSources -> + ExportContactsDialog(this, contactsConfig.lastExportPath, false) { file, ignoredContactSources -> getFileOutputStream(file.toFileDirItem(this), true) { exportContactsTo(ignoredContactSources, it) } @@ -580,7 +577,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { isGettingContacts = true if (view_pager.adapter == null) { - view_pager.adapter = ViewPagerAdapter(this, tabsList, config.showTabs) + view_pager.adapter = ViewPagerAdapter(this, tabsList, contactsConfig.showTabs) view_pager.currentItem = getDefaultTab() } @@ -620,9 +617,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getAllFragments() = arrayListOf(contacts_fragment, favorites_fragment, groups_fragment) private fun getDefaultTab(): Int { - val showTabsMask = config.showTabs - return when (config.defaultTab) { - TAB_LAST_USED -> config.lastUsedViewPagerPage + val showTabsMask = contactsConfig.showTabs + return when (contactsConfig.defaultTab) { + TAB_LAST_USED -> contactsConfig.lastUsedViewPagerPage TAB_CONTACTS -> 0 TAB_FAVORITES -> if (showTabsMask and TAB_CONTACTS > 0) 1 else 0 else -> { 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 33297cde..29109732 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 @@ -8,10 +8,7 @@ import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_CALL_CONTACT -import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_EDIT_CONTACT -import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_VIEW_CONTACT +import com.simplemobiletools.commons.extensions.contactsConfig import kotlinx.android.synthetic.main.activity_settings.* import java.util.* @@ -80,8 +77,8 @@ class SettingsActivity : SimpleActivity() { RadioItem(TAB_LAST_USED, getString(R.string.last_used_tab)) ) - RadioGroupDialog(this@SettingsActivity, items, config.defaultTab) { - config.defaultTab = it as Int + RadioGroupDialog(this@SettingsActivity, items, contactsConfig.defaultTab) { + contactsConfig.defaultTab = it as Int settings_default_tab.text = getDefaultTabText() } } @@ -106,19 +103,19 @@ class SettingsActivity : SimpleActivity() { RadioItem(FONT_SIZE_EXTRA_LARGE, getString(R.string.extra_large)) ) - RadioGroupDialog(this@SettingsActivity, items, config.fontSize) { - config.fontSize = it as Int + RadioGroupDialog(this@SettingsActivity, items, contactsConfig.fontSize) { + contactsConfig.fontSize = it as Int settings_font_size.text = getFontSizeText() } } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = config.useEnglish + settings_use_english_holder.beVisibleIf((contactsConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settings_use_english.isChecked = contactsConfig.useEnglish settings_use_english_holder.setOnClickListener { settings_use_english.toggle() - config.useEnglish = settings_use_english.isChecked + contactsConfig.useEnglish = settings_use_english.isChecked System.exit(0) } } @@ -132,50 +129,50 @@ class SettingsActivity : SimpleActivity() { } private fun setupShowContactThumbnails() { - settings_show_contact_thumbnails.isChecked = config.showContactThumbnails + settings_show_contact_thumbnails.isChecked = contactsConfig.showContactThumbnails settings_show_contact_thumbnails_holder.setOnClickListener { settings_show_contact_thumbnails.toggle() - config.showContactThumbnails = settings_show_contact_thumbnails.isChecked + contactsConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked } } private fun setupShowPhoneNumbers() { - settings_show_phone_numbers.isChecked = config.showPhoneNumbers + settings_show_phone_numbers.isChecked = contactsConfig.showPhoneNumbers settings_show_phone_numbers_holder.setOnClickListener { settings_show_phone_numbers.toggle() - config.showPhoneNumbers = settings_show_phone_numbers.isChecked + contactsConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked } } private fun setupShowContactsWithNumbers() { - settings_show_only_contacts_with_numbers.isChecked = config.showOnlyContactsWithNumbers + settings_show_only_contacts_with_numbers.isChecked = contactsConfig.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 + contactsConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked } } private fun setupStartNameWithSurname() { - settings_start_name_with_surname.isChecked = config.startNameWithSurname + settings_start_name_with_surname.isChecked = contactsConfig.startNameWithSurname settings_start_name_with_surname_holder.setOnClickListener { settings_start_name_with_surname.toggle() - config.startNameWithSurname = settings_start_name_with_surname.isChecked + contactsConfig.startNameWithSurname = settings_start_name_with_surname.isChecked } } private fun setupShowDialpadButton() { - settings_show_dialpad_button.isChecked = config.showDialpadButton + settings_show_dialpad_button.isChecked = contactsConfig.showDialpadButton settings_show_dialpad_button_holder.setOnClickListener { settings_show_dialpad_button.toggle() - config.showDialpadButton = settings_show_dialpad_button.isChecked + contactsConfig.showDialpadButton = settings_show_dialpad_button.isChecked } } private fun setupShowPrivateContacts() { - settings_show_private_contacts.isChecked = config.showPrivateContacts + settings_show_private_contacts.isChecked = contactsConfig.showPrivateContacts settings_show_private_contacts_holder.setOnClickListener { settings_show_private_contacts.toggle() - config.showPrivateContacts = settings_show_private_contacts.isChecked + contactsConfig.showPrivateContacts = settings_show_private_contacts.isChecked } } @@ -188,15 +185,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(ON_CLICK_EDIT_CONTACT, getString(R.string.edit_contact)) ) - RadioGroupDialog(this@SettingsActivity, items, config.onContactClick) { - config.onContactClick = it as Int + RadioGroupDialog(this@SettingsActivity, items, contactsConfig.onContactClick) { + contactsConfig.onContactClick = it as Int settings_on_contact_click.text = getOnContactClickText() } } } private fun getOnContactClickText() = getString( - when (config.onContactClick) { + when (contactsConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> R.string.call_contact ON_CLICK_VIEW_CONTACT -> R.string.view_contact else -> R.string.edit_contact @@ -204,18 +201,18 @@ class SettingsActivity : SimpleActivity() { ) private fun setupShowCallConfirmation() { - settings_show_call_confirmation.isChecked = config.showCallConfirmation + settings_show_call_confirmation.isChecked = contactsConfig.showCallConfirmation settings_show_call_confirmation_holder.setOnClickListener { settings_show_call_confirmation.toggle() - config.showCallConfirmation = settings_show_call_confirmation.isChecked + contactsConfig.showCallConfirmation = settings_show_call_confirmation.isChecked } } private fun setupMergeDuplicateContacts() { - settings_merge_duplicate_contacts.isChecked = config.mergeDuplicateContacts + settings_merge_duplicate_contacts.isChecked = contactsConfig.mergeDuplicateContacts settings_merge_duplicate_contacts_holder.setOnClickListener { settings_merge_duplicate_contacts.toggle() - config.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked + contactsConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked } } } 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 44c9fbed..dc133bee 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 @@ -22,12 +22,12 @@ import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.PhoneNumber +import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.ChooseSocialDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog 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_view_address.view.* import kotlinx.android.synthetic.main.item_view_contact_source.view.* @@ -46,7 +46,7 @@ class ViewContactActivity : ContactActivity() { private var showFields = 0 private var fullContact: Contact? = null // contact with all fields filled from duplicates private var duplicateInitialized = false - private val mergeDuplicate: Boolean get() = config.mergeDuplicateContacts + private val mergeDuplicate: Boolean get() = contactsConfig.mergeDuplicateContacts private val COMPARABLE_PHONE_NUMBER_LENGTH = 9 @@ -59,7 +59,7 @@ class ViewContactActivity : ContactActivity() { return } - showFields = config.showContactFields + showFields = contactsConfig.showContactFields contact_wrapper.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN setupMenu() } @@ -122,7 +122,7 @@ class ViewContactActivity : ContactActivity() { findItem(R.id.manage_visible_fields).setOnMenuItemClickListener { ManageVisibleFieldsDialog(this@ViewContactActivity) { - showFields = config.showContactFields + showFields = contactsConfig.showContactFields ensureBackgroundThread { initContact() } @@ -388,7 +388,7 @@ class ViewContactActivity : ContactActivity() { copyOnLongClick(phoneNumber.value) setOnClickListener { - if (config.showCallConfirmation) { + if (contactsConfig.showCallConfirmation) { CallConfirmationDialog(this@ViewContactActivity, phoneNumber.value) { startCallIntent(phoneNumber.value) } 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 1fa90c5d..cb539c6c 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 @@ -28,10 +28,12 @@ import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.interfaces.ItemMoveCallback import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract import com.simplemobiletools.commons.interfaces.StartReorderDragListener import com.simplemobiletools.commons.models.RadioItem +import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity @@ -41,7 +43,7 @@ import com.simplemobiletools.contacts.pro.extensions.* import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* import java.util.* class ContactsAdapter( @@ -58,7 +60,7 @@ class ContactsAdapter( private val NEW_GROUP_ID = -1 - private var config = activity.config + private var config = activity.contactsConfig private var textToHighlight = highlightText var startNameWithSurname = config.startNameWithSurname @@ -450,7 +452,7 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" override fun onRowMoved(fromPosition: Int, toPosition: Int) { - activity.config.isCustomOrderSelected = true + activity.contactsConfig.isCustomOrderSelected = true if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt index d924829b..ceb5f091 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt @@ -7,9 +7,9 @@ import com.simplemobiletools.commons.extensions.getProperBackgroundColor import com.simplemobiletools.commons.extensions.getProperPrimaryColor import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.helpers.SMT_PRIVATE +import com.simplemobiletools.commons.models.contacts.ContactSource import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity -import com.simplemobiletools.contacts.pro.models.ContactSource import kotlinx.android.synthetic.main.item_filter_contact_source.view.* class FilterContactSourcesAdapter( diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt index 75dba883..e9540145 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt @@ -7,9 +7,7 @@ import android.view.ViewGroup import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.dialogs.ConfirmationDialog -import com.simplemobiletools.commons.extensions.beVisibleIf -import com.simplemobiletools.commons.extensions.getTextSize -import com.simplemobiletools.commons.extensions.highlightTextPart +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.helpers.TAB_GROUPS import com.simplemobiletools.commons.helpers.ensureBackgroundThread @@ -17,11 +15,9 @@ import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.dialogs.RenameGroupDialog -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.groupsDB -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.models.contacts.Group import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener -import com.simplemobiletools.contacts.pro.models.Group import kotlinx.android.synthetic.main.item_group.view.* import java.util.* @@ -31,7 +27,7 @@ class GroupsAdapter( ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { private var textToHighlight = "" - var showContactThumbnails = activity.config.showContactThumbnails + var showContactThumbnails = activity.contactsConfig.showContactThumbnails var fontSize = activity.getTextSize() init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt index 50ac9a8b..4e1c552d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt @@ -11,22 +11,26 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.extensions.contactsConfig import com.simplemobiletools.commons.helpers.SimpleContactsHelper +import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.models.Contact import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.* class SelectContactsAdapter( - val activity: SimpleActivity, var contacts: ArrayList, private val selectedContacts: ArrayList, private val allowPickMultiple: Boolean, - recyclerView: MyRecyclerView, private val itemClick: ((Contact) -> Unit)? = null + val activity: SimpleActivity, + var contacts: ArrayList, + private val selectedContacts: ArrayList, + private val allowPickMultiple: Boolean, + recyclerView: MyRecyclerView, + private val itemClick: ((Contact) -> Unit)? = null ) : RecyclerView.Adapter() { private val itemViews = SparseArray() private val selectedPositions = HashSet() - private val config = activity.config + private val config = activity.contactsConfig private val adjustedPrimaryColor = activity.getProperPrimaryColor() private val fontSize = activity.getTextSize() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt index 193a94c5..900cb881 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt @@ -7,14 +7,14 @@ import android.database.MatrixCursor import android.net.Uri import com.google.gson.Gson import com.simplemobiletools.commons.helpers.MyContactsContentProvider -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.helpers.LocalContactsHelper +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.helpers.LocalContactsHelper class MyContactsContentProvider : ContentProvider() { override fun insert(uri: Uri, contentValues: ContentValues?) = null override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? { - if (context == null || !context!!.config.showPrivateContacts) { + if (context == null || !context!!.contactsConfig.showPrivateContacts) { return null } else { val matrixCursor = MatrixCursor( diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt index b078c7e5..23630594 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt @@ -1,90 +1,90 @@ -package com.simplemobiletools.contacts.pro.databases - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import androidx.room.TypeConverters -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase -import com.simplemobiletools.contacts.pro.helpers.Converters -import com.simplemobiletools.contacts.pro.helpers.FIRST_CONTACT_ID -import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID -import com.simplemobiletools.contacts.pro.helpers.getEmptyLocalContact -import com.simplemobiletools.contacts.pro.interfaces.ContactsDao -import com.simplemobiletools.contacts.pro.interfaces.GroupsDao -import com.simplemobiletools.contacts.pro.models.Group -import com.simplemobiletools.contacts.pro.models.LocalContact -import java.util.concurrent.Executors - -@Database(entities = [LocalContact::class, Group::class], version = 3) -@TypeConverters(Converters::class) -abstract class ContactsDatabase : RoomDatabase() { - - abstract fun ContactsDao(): ContactsDao - - abstract fun GroupsDao(): GroupsDao - - companion object { - private var db: ContactsDatabase? = null - - fun getInstance(context: Context): ContactsDatabase { - if (db == null) { - synchronized(ContactsDatabase::class) { - if (db == null) { - db = Room.databaseBuilder(context.applicationContext, ContactsDatabase::class.java, "local_contacts.db") - .addCallback(object : Callback() { - override fun onCreate(db: SupportSQLiteDatabase) { - super.onCreate(db) - increaseAutoIncrementIds() - } - }) - .addMigrations(MIGRATION_1_2) - .addMigrations(MIGRATION_2_3) - .build() - } - } - } - return db!! - } - - fun destroyInstance() { - db = null - } - - // start autoincrement ID from FIRST_CONTACT_ID/FIRST_GROUP_ID to avoid conflicts - // Room doesn't seem to have a built in way for it, so just create a contact/group and delete it - private fun increaseAutoIncrementIds() { - Executors.newSingleThreadExecutor().execute { - val emptyContact = getEmptyLocalContact() - emptyContact.id = FIRST_CONTACT_ID - db!!.ContactsDao().apply { - insertOrUpdate(emptyContact) - deleteContactId(FIRST_CONTACT_ID) - } - - val emptyGroup = Group(FIRST_GROUP_ID, "") - db!!.GroupsDao().apply { - insertOrUpdate(emptyGroup) - deleteGroupId(FIRST_GROUP_ID) - } - } - } - - private val MIGRATION_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.apply { - execSQL("ALTER TABLE contacts ADD COLUMN photo_uri TEXT NOT NULL DEFAULT ''") - } - } - } - - private val MIGRATION_2_3 = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { - database.apply { - execSQL("ALTER TABLE contacts ADD COLUMN ringtone TEXT DEFAULT ''") - } - } - } - } -} +//package com.simplemobiletools.contacts.pro.databases +// +//import android.content.Context +//import androidx.room.Database +//import androidx.room.Room +//import androidx.room.RoomDatabase +//import androidx.room.TypeConverters +//import androidx.room.migration.Migration +//import androidx.sqlite.db.SupportSQLiteDatabase +//import com.simplemobiletools.contacts.pro.helpers.Converters +//import com.simplemobiletools.contacts.pro.helpers.FIRST_CONTACT_ID +//import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID +//import com.simplemobiletools.contacts.pro.helpers.getEmptyLocalContact +//import com.simplemobiletools.contacts.pro.interfaces.ContactsDao +//import com.simplemobiletools.contacts.pro.interfaces.GroupsDao +//import com.simplemobiletools.contacts.pro.models.Group +//import com.simplemobiletools.contacts.pro.models.LocalContact +//import java.util.concurrent.Executors +// +//@Database(entities = [LocalContact::class, Group::class], version = 3) +//@TypeConverters(Converters::class) +//abstract class ContactsDatabase : RoomDatabase() { +// +// abstract fun ContactsDao(): ContactsDao +// +// abstract fun GroupsDao(): GroupsDao +// +// companion object { +// private var db: ContactsDatabase? = null +// +// fun getInstance(context: Context): ContactsDatabase { +// if (db == null) { +// synchronized(ContactsDatabase::class) { +// if (db == null) { +// db = Room.databaseBuilder(context.applicationContext, ContactsDatabase::class.java, "local_contacts.db") +// .addCallback(object : Callback() { +// override fun onCreate(db: SupportSQLiteDatabase) { +// super.onCreate(db) +// increaseAutoIncrementIds() +// } +// }) +// .addMigrations(MIGRATION_1_2) +// .addMigrations(MIGRATION_2_3) +// .build() +// } +// } +// } +// return db!! +// } +// +// fun destroyInstance() { +// db = null +// } +// +// // start autoincrement ID from FIRST_CONTACT_ID/FIRST_GROUP_ID to avoid conflicts +// // Room doesn't seem to have a built in way for it, so just create a contact/group and delete it +// private fun increaseAutoIncrementIds() { +// Executors.newSingleThreadExecutor().execute { +// val emptyContact = getEmptyLocalContact() +// emptyContact.id = FIRST_CONTACT_ID +// db!!.ContactsDao().apply { +// insertOrUpdate(emptyContact) +// deleteContactId(FIRST_CONTACT_ID) +// } +// +// val emptyGroup = Group(FIRST_GROUP_ID, "") +// db!!.GroupsDao().apply { +// insertOrUpdate(emptyGroup) +// deleteGroupId(FIRST_GROUP_ID) +// } +// } +// } +// +// private val MIGRATION_1_2 = object : Migration(1, 2) { +// override fun migrate(database: SupportSQLiteDatabase) { +// database.apply { +// execSQL("ALTER TABLE contacts ADD COLUMN photo_uri TEXT NOT NULL DEFAULT ''") +// } +// } +// } +// +// private val MIGRATION_2_3 = object : Migration(2, 3) { +// override fun migrate(database: SupportSQLiteDatabase) { +// database.apply { +// execSQL("ALTER TABLE contacts ADD COLUMN ringtone TEXT DEFAULT ''") +// } +// } +// } +// } +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 2f05b66c..44c18836 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -2,16 +2,16 @@ package com.simplemobiletools.contacts.pro.dialogs import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGoneIf +import com.simplemobiletools.commons.extensions.contactsConfig import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_change_sorting.view.* class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCustomSorting: Boolean = false, private val callback: () -> Unit) { private var currSorting = 0 - private var config = activity.config + private var config = activity.contactsConfig private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null) init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChooseSocialDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChooseSocialDialog.kt index 364b1e01..7b7b56a1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChooseSocialDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChooseSocialDialog.kt @@ -8,9 +8,9 @@ import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.extensions.beGone import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.models.contacts.SocialAction import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.extensions.getPackageDrawable -import com.simplemobiletools.contacts.pro.models.SocialAction import kotlinx.android.synthetic.main.dialog_choose_social.view.* import kotlinx.android.synthetic.main.item_choose_social.view.* diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/CreateNewGroupDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/CreateNewGroupDialog.kt index 71f90c2e..df44401d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/CreateNewGroupDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/CreateNewGroupDialog.kt @@ -5,13 +5,12 @@ import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.models.RadioItem +import com.simplemobiletools.commons.models.contacts.ContactSource +import com.simplemobiletools.commons.models.contacts.Group import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.getPrivateContactSource -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.ContactSource -import com.simplemobiletools.contacts.pro.models.Group import kotlinx.android.synthetic.main.dialog_create_new_group.view.* class CreateNewGroupDialog(val activity: BaseSimpleActivity, val callback: (newGroup: Group) -> Unit) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt index 3ead5655..0a4dc314 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt @@ -5,20 +5,20 @@ import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.ContactSource import kotlinx.android.synthetic.main.dialog_export_contacts.view.* import java.io.File class ExportContactsDialog( - val activity: SimpleActivity, val path: String, val hidePath: Boolean, + val activity: SimpleActivity, + val path: String, + val hidePath: Boolean, private val callback: (file: File, ignoredContactSources: HashSet) -> Unit ) { private var ignoreClicks = false @@ -80,7 +80,7 @@ class ExportContactsDialog( ignoreClicks = true ensureBackgroundThread { - activity.config.lastExportPath = file.absolutePath.getParentPath() + activity.contactsConfig.lastExportPath = file.absolutePath.getParentPath() val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() val ignoredSources = contactSources .filter { !selectedSources.contains(it) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt index a496c3da..97a607d8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt @@ -7,11 +7,10 @@ import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.ContactSource +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.getVisibleContactSources +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.* class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) { @@ -78,7 +77,7 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb }.toHashSet() if (activity.getVisibleContactSources() != ignoredContactSources) { - activity.config.ignoredContactSources = ignoredContactSources + activity.contactsConfig.ignoredContactSources = ignoredContactSources callback() } dialog?.dismiss() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt index ad052d59..149e287d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt @@ -2,17 +2,13 @@ package com.simplemobiletools.contacts.pro.dialogs import android.view.ViewGroup import androidx.appcompat.app.AlertDialog -import com.simplemobiletools.commons.extensions.getAlertDialogBuilder -import com.simplemobiletools.commons.extensions.setupDialogStuff -import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getPublicContactSource import com.simplemobiletools.contacts.pro.extensions.showContactSourcePicker -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper import com.simplemobiletools.contacts.pro.helpers.VcfImporter import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_FAIL import kotlinx.android.synthetic.main.dialog_import_contacts.view.* @@ -23,7 +19,7 @@ class ImportContactsDialog(val activity: SimpleActivity, val path: String, priva init { val view = (activity.layoutInflater.inflate(R.layout.dialog_import_contacts, null) as ViewGroup).apply { - targetContactSource = activity.config.lastUsedContactSource + targetContactSource = activity.contactsConfig.lastUsedContactSource activity.getPublicContactSource(targetContactSource) { import_contacts_title.setText(it) if (it.isEmpty()) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt index 375a64f9..d70d6cef 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt @@ -5,8 +5,8 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.helpers.* +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.helpers.* class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: (hasSomethingChanged: Boolean) -> Unit) { private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_fields, null) @@ -33,7 +33,7 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: put(SHOW_RINGTONE_FIELD, R.id.manage_ringtone) } - val showContactFields = activity.config.showContactFields + val showContactFields = activity.contactsConfig.showContactFields for ((key, value) in fields) { view.findViewById(value).isChecked = showContactFields and key != 0 } @@ -54,8 +54,8 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: } } - val hasSomethingChanged = activity.config.showContactFields != result - activity.config.showContactFields = result + val hasSomethingChanged = activity.contactsConfig.showContactFields != result + activity.contactsConfig.showContactFields = result if (hasSomethingChanged) { callback(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt index 5806242d..68e95f18 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt @@ -8,8 +8,8 @@ import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.helpers.TAB_GROUPS import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.helpers.ALL_TABS_MASK class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null) @@ -22,7 +22,7 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { put(TAB_GROUPS, R.id.manage_visible_tabs_groups) } - val showTabs = activity.config.showTabs + val showTabs = activity.contactsConfig.showTabs for ((key, value) in tabs) { view.findViewById(value).isChecked = showTabs and key != 0 } @@ -47,6 +47,6 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { result = ALL_TABS_MASK } - activity.config.showTabs = result + activity.contactsConfig.showTabs = result } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt index 2eb37a9f..90b94058 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt @@ -5,7 +5,7 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.isSPlus import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.config +import com.simplemobiletools.commons.extensions.contactsConfig import kotlinx.android.synthetic.main.dialog_date_picker.view.* import org.joda.time.DateTime import java.util.* @@ -38,7 +38,7 @@ class MyDatePickerDialog(val activity: BaseSimpleActivity, val defaultDate: Stri } } - if (activity.config.isUsingSystemTheme && isSPlus()) { + if (activity.contactsConfig.isUsingSystemTheme && isSPlus()) { val dialogBackgroundColor = activity.getColor(R.color.you_dialog_background_color) view.dialog_holder.setBackgroundColor(dialogBackgroundColor) view.date_picker.setBackgroundColor(dialogBackgroundColor) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/RenameGroupDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/RenameGroupDialog.kt index 44bc8dad..ab7c411b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/RenameGroupDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/RenameGroupDialog.kt @@ -3,11 +3,10 @@ package com.simplemobiletools.contacts.pro.dialogs import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.models.contacts.Group import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.groupsDB -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.Group import kotlinx.android.synthetic.main.dialog_rename_group.view.* class RenameGroupDialog(val activity: BaseSimpleActivity, val group: Group, val callback: () -> Unit) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactsDialog.kt index 57fb9351..14287a76 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactsDialog.kt @@ -7,8 +7,7 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.SelectContactsAdapter -import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.dialog_select_contact.view.* import java.util.* diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectGroupsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectGroupsDialog.kt index 91f9ea22..29afcbb7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectGroupsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectGroupsDialog.kt @@ -3,11 +3,11 @@ package com.simplemobiletools.contacts.pro.dialogs import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.models.contacts.Group import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper -import com.simplemobiletools.contacts.pro.models.Group import kotlinx.android.synthetic.main.dialog_select_groups.view.* import kotlinx.android.synthetic.main.item_checkbox.view.* import kotlinx.android.synthetic.main.item_textview.view.* diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt index 20349305..11f8cc58 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt @@ -7,10 +7,7 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.CallConfirmationDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.CONTACT_ID -import com.simplemobiletools.commons.helpers.IS_PRIVATE -import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE -import com.simplemobiletools.commons.helpers.SMT_PRIVATE +import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R @@ -18,7 +15,9 @@ import com.simplemobiletools.contacts.pro.activities.EditContactActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.activities.ViewContactActivity import com.simplemobiletools.contacts.pro.helpers.* -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.contacts.pro.helpers.DEFAULT_FILE_NAME +import com.simplemobiletools.contacts.pro.helpers.VcfExporter fun SimpleActivity.startCallIntent(recipient: String) { handlePermission(PERMISSION_CALL_PHONE) { @@ -31,7 +30,7 @@ fun SimpleActivity.startCallIntent(recipient: String) { } fun SimpleActivity.tryStartCall(contact: Contact) { - if (config.showCallConfirmation) { + if (contactsConfig.showCallConfirmation) { CallConfirmationDialog(this, contact.getNameToDisplay()) { startCall(contact) } @@ -108,7 +107,7 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { } fun SimpleActivity.handleGenericContactClick(contact: Contact) { - when (config.onContactClick) { + when (contactsConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> callContact(contact) ON_CLICK_VIEW_CONTACT -> viewContact(contact) ON_CLICK_EDIT_CONTACT -> editContact(contact) 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 d2052e8a..a558b343 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 @@ -2,338 +2,340 @@ package com.simplemobiletools.contacts.pro.extensions import android.annotation.SuppressLint import android.content.Context -import android.content.Intent -import android.database.Cursor import android.graphics.drawable.Drawable -import android.net.Uri -import android.os.Handler -import android.os.Looper -import android.provider.ContactsContract import androidx.core.content.FileProvider -import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS -import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS -import com.simplemobiletools.commons.helpers.SMT_PRIVATE -import com.simplemobiletools.commons.helpers.SimpleContactsHelper +import com.simplemobiletools.commons.extensions.getCachePhoto +import com.simplemobiletools.commons.helpers.SIGNAL_PACKAGE +import com.simplemobiletools.commons.helpers.TELEGRAM_PACKAGE +import com.simplemobiletools.commons.helpers.VIBER_PACKAGE +import com.simplemobiletools.commons.helpers.WHATSAPP_PACKAGE import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.databases.ContactsDatabase -import com.simplemobiletools.contacts.pro.helpers.* -import com.simplemobiletools.contacts.pro.interfaces.ContactsDao -import com.simplemobiletools.contacts.pro.interfaces.GroupsDao -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.ContactSource -import com.simplemobiletools.contacts.pro.models.Organization -import com.simplemobiletools.contacts.pro.models.SocialAction import java.io.File -val Context.config: Config get() = Config.newInstance(applicationContext) - -val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao() - -val Context.groupsDB: GroupsDao get() = ContactsDatabase.getInstance(applicationContext).GroupsDao() - -fun Context.getEmptyContact(): Contact { - val originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE - val organization = Organization("", "") - return Contact( - 0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", - null, "", ArrayList(), organization, ArrayList(), ArrayList(), DEFAULT_MIMETYPE, null - ) -} - -fun Context.sendAddressIntent(address: String) { - val location = Uri.encode(address) - val uri = Uri.parse("geo:0,0?q=$location") - - Intent(Intent.ACTION_VIEW, uri).apply { - launchActivityIntent(this) - } -} - -fun Context.openWebsiteIntent(url: String) { - val website = if (url.startsWith("http")) { - url - } else { - "https://$url" - } - - Intent(Intent.ACTION_VIEW).apply { - data = Uri.parse(website) - launchActivityIntent(this) - } -} - -fun Context.getLookupUriRawId(dataUri: Uri): Int { - val lookupKey = getLookupKeyFromUri(dataUri) - if (lookupKey != null) { - val uri = lookupContactUri(lookupKey, this) - if (uri != null) { - return getContactUriRawId(uri) - } - } - return -1 -} - -fun Context.getContactUriRawId(uri: Uri): Int { - val projection = arrayOf(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) - var cursor: Cursor? = null - try { - cursor = contentResolver.query(uri, projection, null, null, null) - if (cursor!!.moveToFirst()) { - return cursor.getIntValue(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) - } - } catch (ignored: Exception) { - } finally { - cursor?.close() - } - return -1 -} - -// from https://android.googlesource.com/platform/packages/apps/Dialer/+/68038172793ee0e2ab3e2e56ddfbeb82879d1f58/java/com/android/contacts/common/util/UriUtils.java -fun getLookupKeyFromUri(lookupUri: Uri): String? { - return if (!isEncodedContactUri(lookupUri)) { - val segments = lookupUri.pathSegments - if (segments.size < 3) null else Uri.encode(segments[2]) - } else { - null - } -} - -fun isEncodedContactUri(uri: Uri?): Boolean { - if (uri == null) { - return false - } - val lastPathSegment = uri.lastPathSegment ?: return false - return lastPathSegment == "encoded" -} - -fun lookupContactUri(lookup: String, context: Context): Uri? { - val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup) - return try { - ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri) - } catch (e: Exception) { - null - } -} - -fun Context.getCachePhoto(): File { - val imagesFolder = File(cacheDir, "my_cache") - if (!imagesFolder.exists()) { - imagesFolder.mkdirs() - } - - val file = File(imagesFolder, "Photo_${System.currentTimeMillis()}.jpg") - file.createNewFile() - return file -} - +// import android.annotation.SuppressLint +// import android.content.Context +// import android.content.Intent +// import android.database.Cursor +// import android.graphics.drawable.Drawable +// import android.net.Uri +// import android.os.Handler +// import android.os.Looper +// import android.provider.ContactsContract +// import androidx.core.content.FileProvider +// import com.simplemobiletools.commons.extensions.* +// import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS +// import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS +// import com.simplemobiletools.commons.helpers.SMT_PRIVATE +// import com.simplemobiletools.commons.helpers.SimpleContactsHelper +// import com.simplemobiletools.contacts.pro.BuildConfig +// import com.simplemobiletools.contacts.pro.R +// import com.simplemobiletools.contacts.pro.databases.ContactsDatabase +// import com.simplemobiletools.contacts.pro.helpers.* +// import com.simplemobiletools.contacts.pro.interfaces.ContactsDao +// import com.simplemobiletools.contacts.pro.interfaces.GroupsDao +// import com.simplemobiletools.commons.models.contacts.* +// import com.simplemobiletools.contacts.pro.models.ContactSource +// import com.simplemobiletools.contacts.pro.models.Organization +// import com.simplemobiletools.contacts.pro.models.SocialAction +// import java.io.File +// +// val Context.config: Config get() = Config.newInstance(applicationContext) +// +// val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao() +// +// val Context.groupsDB: GroupsDao get() = ContactsDatabase.getInstance(applicationContext).GroupsDao() +// +// fun Context.getEmptyContact(): Contact { +// val originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE +// val organization = Organization("", "") +// return Contact( +// 0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", +// null, "", ArrayList(), organization, ArrayList(), ArrayList(), DEFAULT_MIMETYPE, null +// ) +// } +// +// fun Context.sendAddressIntent(address: String) { +// val location = Uri.encode(address) +// val uri = Uri.parse("geo:0,0?q=$location") +// +// Intent(Intent.ACTION_VIEW, uri).apply { +// launchActivityIntent(this) +// } +// } +// +// fun Context.openWebsiteIntent(url: String) { +// val website = if (url.startsWith("http")) { +// url +// } else { +// "https://$url" +// } +// +// Intent(Intent.ACTION_VIEW).apply { +// data = Uri.parse(website) +// launchActivityIntent(this) +// } +// } +// +// fun Context.getLookupUriRawId(dataUri: Uri): Int { +// val lookupKey = getLookupKeyFromUri(dataUri) +// if (lookupKey != null) { +// val uri = lookupContactUri(lookupKey, this) +// if (uri != null) { +// return getContactUriRawId(uri) +// } +// } +// return -1 +// } +// +// fun Context.getContactUriRawId(uri: Uri): Int { +// val projection = arrayOf(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) +// var cursor: Cursor? = null +// try { +// cursor = contentResolver.query(uri, projection, null, null, null) +// if (cursor!!.moveToFirst()) { +// return cursor.getIntValue(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) +// } +// } catch (ignored: Exception) { +// } finally { +// cursor?.close() +// } +// return -1 +// } +// +// // from https://android.googlesource.com/platform/packages/apps/Dialer/+/68038172793ee0e2ab3e2e56ddfbeb82879d1f58/java/com/android/contacts/common/util/UriUtils.java +// fun getLookupKeyFromUri(lookupUri: Uri): String? { +// return if (!isEncodedContactUri(lookupUri)) { +// val segments = lookupUri.pathSegments +// if (segments.size < 3) null else Uri.encode(segments[2]) +// } else { +// null +// } +// } +// +// fun isEncodedContactUri(uri: Uri?): Boolean { +// if (uri == null) { +// return false +// } +// val lastPathSegment = uri.lastPathSegment ?: return false +// return lastPathSegment == "encoded" +// } +// +// fun lookupContactUri(lookup: String, context: Context): Uri? { +// val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup) +// return try { +// ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri) +// } catch (e: Exception) { +// null +// } +// } +// fun Context.getCachePhotoUri(file: File = getCachePhoto()) = FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.provider", file) -fun Context.getPhotoThumbnailSize(): Int { - val uri = ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI - val projection = arrayOf(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) - var cursor: Cursor? = null - try { - cursor = contentResolver.query(uri, projection, null, null, null) - if (cursor?.moveToFirst() == true) { - return cursor.getIntValue(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) - } - } catch (ignored: Exception) { - } finally { - cursor?.close() - } - return 0 -} - -fun Context.hasContactPermissions() = hasPermission(PERMISSION_READ_CONTACTS) && hasPermission(PERMISSION_WRITE_CONTACTS) - -fun Context.getPublicContactSource(source: String, callback: (String) -> Unit) { - when (source) { - SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden)) - else -> { - ContactsHelper(this).getContactSources { - var newSource = source - for (contactSource in it) { - if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { - newSource = getString(R.string.telegram) - break - } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { - newSource = getString(R.string.viber) - 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 - } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { - newSource = getString(R.string.viber) - break - } - } - - return newSource - } - } -} - -fun Context.sendSMSToContacts(contacts: ArrayList) { - val numbers = StringBuilder() - contacts.forEach { - val number = it.phoneNumbers.firstOrNull { it.type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE } - ?: it.phoneNumbers.firstOrNull() - if (number != null) { - numbers.append("${Uri.encode(number.value)};") - } - } - - val uriString = "smsto:${numbers.toString().trimEnd(';')}" - Intent(Intent.ACTION_SENDTO, Uri.parse(uriString)).apply { - launchActivityIntent(this) - } -} - -fun Context.sendEmailToContacts(contacts: ArrayList) { - val emails = ArrayList() - contacts.forEach { - it.emails.forEach { - if (it.value.isNotEmpty()) { - emails.add(it.value) - } - } - } - - Intent(Intent.ACTION_SEND_MULTIPLE).apply { - type = "message/rfc822" - putExtra(Intent.EXTRA_EMAIL, emails.toTypedArray()) - launchActivityIntent(this) - } -} - -fun Context.getTempFile(filename: String = DEFAULT_FILE_NAME): File? { - val folder = File(cacheDir, "contacts") - if (!folder.exists()) { - if (!folder.mkdir()) { - toast(R.string.unknown_error_occurred) - return null - } - } - - return File(folder, filename) -} - -fun Context.addContactsToGroup(contacts: ArrayList, groupId: Long) { - val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList - val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList - if (publicContacts.isNotEmpty()) { - ContactsHelper(this).addContactsToGroup(publicContacts, groupId) - } - - if (privateContacts.isNotEmpty()) { - LocalContactsHelper(this).addContactsToGroup(privateContacts, groupId) - } -} - -fun Context.removeContactsFromGroup(contacts: ArrayList, groupId: Long) { - val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList - val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList - if (publicContacts.isNotEmpty() && hasContactPermissions()) { - ContactsHelper(this).removeContactsFromGroup(publicContacts, groupId) - } - - if (privateContacts.isNotEmpty()) { - LocalContactsHelper(this).removeContactsFromGroup(privateContacts, groupId) - } -} - -fun Context.getContactPublicUri(contact: Contact): Uri { - val lookupKey = if (contact.isPrivate()) { - "local_${contact.id}" - } else { - SimpleContactsHelper(this).getContactLookupKey(contact.id.toString()) - } - return Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey) -} - -fun Context.getVisibleContactSources(): ArrayList { - val sources = getAllContactSources() - val ignoredContactSources = config.ignoredContactSources - return ArrayList(sources).filter { !ignoredContactSources.contains(it.getFullIdentifier()) } - .map { it.name }.toMutableList() as ArrayList -} - -fun Context.getAllContactSources(): ArrayList { - val sources = ContactsHelper(this).getDeviceContactSources() - sources.add(getPrivateContactSource()) - return sources.toMutableList() as ArrayList -} - -fun Context.getPrivateContactSource() = ContactSource(SMT_PRIVATE, SMT_PRIVATE, getString(R.string.phone_storage_hidden)) - -fun Context.getSocialActions(id: Int): ArrayList { - val uri = ContactsContract.Data.CONTENT_URI - val projection = arrayOf( - ContactsContract.Data._ID, - ContactsContract.Data.DATA3, - ContactsContract.Data.MIMETYPE, - ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET - ) - - val socialActions = ArrayList() - var curActionId = 0 - val selection = "${ContactsContract.Data.RAW_CONTACT_ID} = ?" - val selectionArgs = arrayOf(id.toString()) - queryCursor(uri, projection, selection, selectionArgs, null, true) { cursor -> - val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE) - val type = when (mimetype) { - // WhatsApp - "vnd.android.cursor.item/vnd.com.whatsapp.profile" -> SOCIAL_MESSAGE - "vnd.android.cursor.item/vnd.com.whatsapp.voip.call" -> SOCIAL_VOICE_CALL - "vnd.android.cursor.item/vnd.com.whatsapp.video.call" -> SOCIAL_VIDEO_CALL - - // Viber - "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_call" -> SOCIAL_VOICE_CALL - "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_viber" -> SOCIAL_VOICE_CALL - "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_none_viber" -> SOCIAL_VOICE_CALL - "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_message" -> SOCIAL_MESSAGE - - // Signal - "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" -> SOCIAL_MESSAGE - "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call" -> SOCIAL_VOICE_CALL - - // Telegram - "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call" -> SOCIAL_VOICE_CALL - "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video" -> SOCIAL_VIDEO_CALL - "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile" -> SOCIAL_MESSAGE - - // Threema - "vnd.android.cursor.item/vnd.ch.threema.app.profile" -> SOCIAL_MESSAGE - "vnd.android.cursor.item/vnd.ch.threema.app.call" -> SOCIAL_VOICE_CALL - else -> return@queryCursor - } - - val label = cursor.getStringValue(ContactsContract.Data.DATA3) - val realID = cursor.getLongValue(ContactsContract.Data._ID) - val packageName = cursor.getStringValue(ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET) - val socialAction = SocialAction(curActionId++, type, label, mimetype, realID, packageName) - socialActions.add(socialAction) - } - return socialActions -} +// fun Context.getPhotoThumbnailSize(): Int { +// val uri = ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI +// val projection = arrayOf(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) +// var cursor: Cursor? = null +// try { +// cursor = contentResolver.query(uri, projection, null, null, null) +// if (cursor?.moveToFirst() == true) { +// return cursor.getIntValue(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) +// } +// } catch (ignored: Exception) { +// } finally { +// cursor?.close() +// } +// return 0 +// } +// +// fun Context.hasContactPermissions() = hasPermission(PERMISSION_READ_CONTACTS) && hasPermission(PERMISSION_WRITE_CONTACTS) +// +// fun Context.getPublicContactSource(source: String, callback: (String) -> Unit) { +// when (source) { +// SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden)) +// else -> { +// ContactsHelper(this).getContactSources { +// var newSource = source +// for (contactSource in it) { +// if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { +// newSource = getString(R.string.telegram) +// break +// } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { +// newSource = getString(R.string.viber) +// 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 +// } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { +// newSource = getString(R.string.viber) +// break +// } +// } +// +// return newSource +// } +// } +// } +// +// fun Context.sendSMSToContacts(contacts: ArrayList) { +// val numbers = StringBuilder() +// contacts.forEach { +// val number = it.phoneNumbers.firstOrNull { it.type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE } +// ?: it.phoneNumbers.firstOrNull() +// if (number != null) { +// numbers.append("${Uri.encode(number.value)};") +// } +// } +// +// val uriString = "smsto:${numbers.toString().trimEnd(';')}" +// Intent(Intent.ACTION_SENDTO, Uri.parse(uriString)).apply { +// launchActivityIntent(this) +// } +// } +// +// fun Context.sendEmailToContacts(contacts: ArrayList) { +// val emails = ArrayList() +// contacts.forEach { +// it.emails.forEach { +// if (it.value.isNotEmpty()) { +// emails.add(it.value) +// } +// } +// } +// +// Intent(Intent.ACTION_SEND_MULTIPLE).apply { +// type = "message/rfc822" +// putExtra(Intent.EXTRA_EMAIL, emails.toTypedArray()) +// launchActivityIntent(this) +// } +// } +// +// fun Context.getTempFile(filename: String = DEFAULT_FILE_NAME): File? { +// val folder = File(cacheDir, "contacts") +// if (!folder.exists()) { +// if (!folder.mkdir()) { +// toast(R.string.unknown_error_occurred) +// return null +// } +// } +// +// return File(folder, filename) +// } +// +// fun Context.addContactsToGroup(contacts: ArrayList, groupId: Long) { +// val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList +// val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList +// if (publicContacts.isNotEmpty()) { +// ContactsHelper(this).addContactsToGroup(publicContacts, groupId) +// } +// +// if (privateContacts.isNotEmpty()) { +// LocalContactsHelper(this).addContactsToGroup(privateContacts, groupId) +// } +// } +// +// fun Context.removeContactsFromGroup(contacts: ArrayList, groupId: Long) { +// val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList +// val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList +// if (publicContacts.isNotEmpty() && hasContactPermissions()) { +// ContactsHelper(this).removeContactsFromGroup(publicContacts, groupId) +// } +// +// if (privateContacts.isNotEmpty()) { +// LocalContactsHelper(this).removeContactsFromGroup(privateContacts, groupId) +// } +// } +// +// fun Context.getContactPublicUri(contact: Contact): Uri { +// val lookupKey = if (contact.isPrivate()) { +// "local_${contact.id}" +// } else { +// SimpleContactsHelper(this).getContactLookupKey(contact.id.toString()) +// } +// return Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey) +// } +// +// fun Context.getVisibleContactSources(): ArrayList { +// val sources = getAllContactSources() +// val ignoredContactSources = config.ignoredContactSources +// return ArrayList(sources).filter { !ignoredContactSources.contains(it.getFullIdentifier()) } +// .map { it.name }.toMutableList() as ArrayList +// } +// +// fun Context.getAllContactSources(): ArrayList { +// val sources = ContactsHelper(this).getDeviceContactSources() +// sources.add(getPrivateContactSource()) +// return sources.toMutableList() as ArrayList +// } +// +// fun Context.getPrivateContactSource() = ContactSource(SMT_PRIVATE, SMT_PRIVATE, getString(R.string.phone_storage_hidden)) +// +// fun Context.getSocialActions(id: Int): ArrayList { +// val uri = ContactsContract.Data.CONTENT_URI +// val projection = arrayOf( +// ContactsContract.Data._ID, +// ContactsContract.Data.DATA3, +// ContactsContract.Data.MIMETYPE, +// ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET +// ) +// +// val socialActions = ArrayList() +// var curActionId = 0 +// val selection = "${ContactsContract.Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = arrayOf(id.toString()) +// queryCursor(uri, projection, selection, selectionArgs, null, true) { cursor -> +// val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE) +// val type = when (mimetype) { +// // WhatsApp +// "vnd.android.cursor.item/vnd.com.whatsapp.profile" -> SOCIAL_MESSAGE +// "vnd.android.cursor.item/vnd.com.whatsapp.voip.call" -> SOCIAL_VOICE_CALL +// "vnd.android.cursor.item/vnd.com.whatsapp.video.call" -> SOCIAL_VIDEO_CALL +// +// // Viber +// "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_call" -> SOCIAL_VOICE_CALL +// "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_viber" -> SOCIAL_VOICE_CALL +// "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_none_viber" -> SOCIAL_VOICE_CALL +// "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_message" -> SOCIAL_MESSAGE +// +// // Signal +// "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" -> SOCIAL_MESSAGE +// "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call" -> SOCIAL_VOICE_CALL +// +// // Telegram +// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call" -> SOCIAL_VOICE_CALL +// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video" -> SOCIAL_VIDEO_CALL +// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile" -> SOCIAL_MESSAGE +// +// // Threema +// "vnd.android.cursor.item/vnd.ch.threema.app.profile" -> SOCIAL_MESSAGE +// "vnd.android.cursor.item/vnd.ch.threema.app.call" -> SOCIAL_VOICE_CALL +// else -> return@queryCursor +// } +// +// val label = cursor.getStringValue(ContactsContract.Data.DATA3) +// val realID = cursor.getLongValue(ContactsContract.Data._ID) +// val packageName = cursor.getStringValue(ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET) +// val socialAction = SocialAction(curActionId++, type, label, mimetype, realID, packageName) +// socialActions.add(socialAction) +// } +// return socialActions +// } @SuppressLint("UseCompatLoadingForDrawables") fun Context.getPackageDrawable(packageName: String): Drawable { @@ -344,6 +346,7 @@ fun Context.getPackageDrawable(packageName: String): Drawable { WHATSAPP_PACKAGE -> R.drawable.ic_whatsapp_rect_vector VIBER_PACKAGE -> R.drawable.ic_viber_rect_vector else -> R.drawable.ic_threema_rect_vector - }, theme + }, + theme ) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/FavoritesFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/FavoritesFragment.kt index f8460f1f..c3afa1be 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/FavoritesFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/FavoritesFragment.kt @@ -2,11 +2,11 @@ package com.simplemobiletools.contacts.pro.fragments import android.content.Context import android.util.AttributeSet +import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.contacts.pro.activities.MainActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.dialogs.SelectContactsDialog -import com.simplemobiletools.contacts.pro.helpers.ContactsHelper class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) { override fun fabClicked() { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index 0fcd0019..429b60a2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -17,12 +17,11 @@ import com.simplemobiletools.contacts.pro.activities.MainActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter import com.simplemobiletools.contacts.pro.adapters.GroupsAdapter -import com.simplemobiletools.contacts.pro.extensions.config -import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources +import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.helpers.Converters import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.Group +import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.fragment_layout.view.* import kotlinx.android.synthetic.main.fragment_layout.view.fragment_fab import kotlinx.android.synthetic.main.fragment_layout.view.fragment_list @@ -39,13 +38,13 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) private var lastHashCode = 0 private var contactsIgnoringSearch = ArrayList() private var groupsIgnoringSearch = ArrayList() - private lateinit var config: Config + private lateinit var config: ContactsConfig var skipHashComparing = false var forceListRedraw = false fun setupFragment(activity: SimpleActivity) { - config = activity.config + config = activity.contactsConfig if (this.activity == null) { this.activity = activity fragment_fab?.beGoneIf(activity is InsertOrEditContactActivity) @@ -125,7 +124,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) this is FavoritesFragment -> { val favorites = contacts.filter { it.starred == 1 } as ArrayList - if (activity!!.config.isCustomOrderSelected) { + if (activity!!.contactsConfig.isCustomOrderSelected) { sortByCustomOrder(favorites) } else { favorites @@ -159,7 +158,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun sortByCustomOrder(starred: List): ArrayList { - val favoritesOrder = activity!!.config.favoritesContactsOrder + val favoritesOrder = activity!!.contactsConfig.favoritesContactsOrder if (favoritesOrder.isEmpty()) { return ArrayList(starred) @@ -219,7 +218,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } else { (currAdapter as GroupsAdapter).apply { - showContactThumbnails = activity.config.showContactThumbnails + showContactThumbnails = activity.contactsConfig.showContactThumbnails updateItems(storedGroups) } } @@ -281,7 +280,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) activity?.apply { val orderIds = items.map { it.id } val orderGsonString = Gson().toJson(orderIds) - config.favoritesContactsOrder = orderGsonString + contactsConfig.favoritesContactsOrder = orderGsonString } } @@ -300,7 +299,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun setupLetterFastscroller(contacts: ArrayList) { - val sorting = context.config.sorting + val sorting = context.contactsConfig.sorting letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> try { val contact = contacts[position] @@ -309,7 +308,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) sorting and SORT_BY_SURNAME != 0 && contact.surname.isNotEmpty() -> contact.surname sorting and SORT_BY_MIDDLE_NAME != 0 && contact.middleName.isNotEmpty() -> contact.middleName sorting and SORT_BY_FIRST_NAME != 0 && contact.firstName.isNotEmpty() -> contact.firstName - context.config.startNameWithSurname -> contact.surname + context.contactsConfig.startNameWithSurname -> contact.surname else -> contact.firstName } 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 4c584f9c..8da79dd1 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 @@ -1,77 +1,77 @@ -package com.simplemobiletools.contacts.pro.helpers - -import android.content.Context -import com.simplemobiletools.commons.helpers.BaseConfig - -class Config(context: Context) : BaseConfig(context) { - companion object { - fun newInstance(context: Context) = Config(context) - } - - var ignoredContactSources: HashSet - get() = prefs.getStringSet(IGNORED_CONTACT_SOURCES, hashSetOf(".")) as HashSet - set(ignoreContactSources) = prefs.edit().remove(IGNORED_CONTACT_SOURCES).putStringSet(IGNORED_CONTACT_SOURCES, ignoreContactSources).apply() - - var showContactThumbnails: Boolean - get() = prefs.getBoolean(SHOW_CONTACT_THUMBNAILS, true) - set(showContactThumbnails) = prefs.edit().putBoolean(SHOW_CONTACT_THUMBNAILS, showContactThumbnails).apply() - - var showPhoneNumbers: Boolean - 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 lastUsedContactSource: String - get() = prefs.getString(LAST_USED_CONTACT_SOURCE, "")!! - set(lastUsedContactSource) = prefs.edit().putString(LAST_USED_CONTACT_SOURCE, lastUsedContactSource).apply() - - var onContactClick: Int - get() = prefs.getInt(ON_CONTACT_CLICK, ON_CLICK_VIEW_CONTACT) - set(onContactClick) = prefs.edit().putInt(ON_CONTACT_CLICK, onContactClick).apply() - - var showContactFields: Int - get() = prefs.getInt( - SHOW_CONTACT_FIELDS, SHOW_FIRST_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_PHONE_NUMBERS_FIELD or SHOW_EMAILS_FIELD or - 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 showTabs: Int - get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK) - set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply() - - var showDialpadButton: Boolean - get() = prefs.getBoolean(SHOW_DIALPAD_BUTTON, true) - set(showDialpadButton) = prefs.edit().putBoolean(SHOW_DIALPAD_BUTTON, showDialpadButton).apply() - - var wasLocalAccountInitialized: Boolean - get() = prefs.getBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, false) - set(wasLocalAccountInitialized) = prefs.edit().putBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, wasLocalAccountInitialized).apply() - - var lastExportPath: String - get() = prefs.getString(LAST_EXPORT_PATH, "")!! - set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() - - var speedDial: String - get() = prefs.getString(SPEED_DIAL, "")!! - set(speedDial) = prefs.edit().putString(SPEED_DIAL, speedDial).apply() - - var showPrivateContacts: Boolean - get() = prefs.getBoolean(SHOW_PRIVATE_CONTACTS, true) - set(showPrivateContacts) = prefs.edit().putBoolean(SHOW_PRIVATE_CONTACTS, showPrivateContacts).apply() - - var mergeDuplicateContacts: Boolean - get() = prefs.getBoolean(MERGE_DUPLICATE_CONTACTS, true) - set(mergeDuplicateContacts) = prefs.edit().putBoolean(MERGE_DUPLICATE_CONTACTS, mergeDuplicateContacts).apply() - - var favoritesContactsOrder: String - get() = prefs.getString(FAVORITES_CONTACTS_ORDER, "")!! - set(order) = prefs.edit().putString(FAVORITES_CONTACTS_ORDER, order).apply() - - var isCustomOrderSelected: Boolean - get() = prefs.getBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, false) - set(selected) = prefs.edit().putBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, selected).apply() -} +//package com.simplemobiletools.contacts.pro.helpers +// +//import android.content.Context +//import com.simplemobiletools.commons.helpers.BaseConfig +// +//class Config(context: Context) : BaseConfig(context) { +// companion object { +// fun newInstance(context: Context) = Config(context) +// } +// +// var ignoredContactSources: HashSet +// get() = prefs.getStringSet(IGNORED_CONTACT_SOURCES, hashSetOf(".")) as HashSet +// set(ignoreContactSources) = prefs.edit().remove(IGNORED_CONTACT_SOURCES).putStringSet(IGNORED_CONTACT_SOURCES, ignoreContactSources).apply() +// +// var showContactThumbnails: Boolean +// get() = prefs.getBoolean(SHOW_CONTACT_THUMBNAILS, true) +// set(showContactThumbnails) = prefs.edit().putBoolean(SHOW_CONTACT_THUMBNAILS, showContactThumbnails).apply() +// +// var showPhoneNumbers: Boolean +// 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 lastUsedContactSource: String +// get() = prefs.getString(LAST_USED_CONTACT_SOURCE, "")!! +// set(lastUsedContactSource) = prefs.edit().putString(LAST_USED_CONTACT_SOURCE, lastUsedContactSource).apply() +// +// var onContactClick: Int +// get() = prefs.getInt(ON_CONTACT_CLICK, ON_CLICK_VIEW_CONTACT) +// set(onContactClick) = prefs.edit().putInt(ON_CONTACT_CLICK, onContactClick).apply() +// +// var showContactFields: Int +// get() = prefs.getInt( +// SHOW_CONTACT_FIELDS, SHOW_FIRST_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_PHONE_NUMBERS_FIELD or SHOW_EMAILS_FIELD or +// 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 showTabs: Int +// get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK) +// set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply() +// +// var showDialpadButton: Boolean +// get() = prefs.getBoolean(SHOW_DIALPAD_BUTTON, true) +// set(showDialpadButton) = prefs.edit().putBoolean(SHOW_DIALPAD_BUTTON, showDialpadButton).apply() +// +// var wasLocalAccountInitialized: Boolean +// get() = prefs.getBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, false) +// set(wasLocalAccountInitialized) = prefs.edit().putBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, wasLocalAccountInitialized).apply() +// +// var lastExportPath: String +// get() = prefs.getString(LAST_EXPORT_PATH, "")!! +// set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() +// +// var speedDial: String +// get() = prefs.getString(SPEED_DIAL, "")!! +// set(speedDial) = prefs.edit().putString(SPEED_DIAL, speedDial).apply() +// +// var showPrivateContacts: Boolean +// get() = prefs.getBoolean(SHOW_PRIVATE_CONTACTS, true) +// set(showPrivateContacts) = prefs.edit().putBoolean(SHOW_PRIVATE_CONTACTS, showPrivateContacts).apply() +// +// var mergeDuplicateContacts: Boolean +// get() = prefs.getBoolean(MERGE_DUPLICATE_CONTACTS, true) +// set(mergeDuplicateContacts) = prefs.edit().putBoolean(MERGE_DUPLICATE_CONTACTS, mergeDuplicateContacts).apply() +// +// var favoritesContactsOrder: String +// get() = prefs.getString(FAVORITES_CONTACTS_ORDER, "")!! +// set(order) = prefs.edit().putString(FAVORITES_CONTACTS_ORDER, order).apply() +// +// var isCustomOrderSelected: Boolean +// get() = prefs.getBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, false) +// set(selected) = prefs.edit().putBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, selected).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 9d00ac3f..c7df58b0 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 @@ -1,29 +1,26 @@ package com.simplemobiletools.contacts.pro.helpers -import android.provider.ContactsContract.CommonDataKinds -import com.simplemobiletools.commons.extensions.normalizeString import com.simplemobiletools.commons.helpers.TAB_CONTACTS import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.helpers.TAB_GROUPS -import com.simplemobiletools.contacts.pro.models.LocalContact // 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_2" -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 SHOW_DIALPAD_BUTTON = "show_dialpad_button" -const val SPEED_DIAL = "speed_dial" -const val LAST_EXPORT_PATH = "last_export_path" -const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized" -const val SHOW_PRIVATE_CONTACTS = "show_private_contacts" -const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts" -const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order" -const val FAVORITES_CUSTOM_ORDER_SELECTED = "favorites_custom_order_selected" +// 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_2" +// 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 SHOW_DIALPAD_BUTTON = "show_dialpad_button" +// const val SPEED_DIAL = "speed_dial" +// const val LAST_EXPORT_PATH = "last_export_path" +// const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized" +// const val SHOW_PRIVATE_CONTACTS = "show_private_contacts" +// const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts" +// const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order" +// const val FAVORITES_CUSTOM_ORDER_SELECTED = "favorites_custom_order_selected" const val GROUP = "group" const val IS_FROM_SIMPLE_CONTACTS = "is_from_simple_contacts" @@ -44,7 +41,7 @@ const val LOCATION_FAVORITES_TAB = 1 const val LOCATION_GROUP_CONTACTS = 2 const val LOCATION_INSERT_OR_EDIT = 3 -const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_GROUPS +// const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_GROUPS val tabsList = arrayListOf( TAB_CONTACTS, @@ -53,10 +50,10 @@ val tabsList = arrayListOf( ) // contact photo changes -const val PHOTO_ADDED = 1 -const val PHOTO_REMOVED = 2 -const val PHOTO_CHANGED = 3 -const val PHOTO_UNCHANGED = 4 +// const val PHOTO_ADDED = 1 +// const val PHOTO_REMOVED = 2 +// const val PHOTO_CHANGED = 3 +// const val PHOTO_UNCHANGED = 4 // phone number/email types const val CELL = "CELL" @@ -76,44 +73,44 @@ const val HANGOUTS = "Hangouts" const val QQ = "QQ" const val JABBER = "Jabber" -const val ON_CLICK_CALL_CONTACT = 1 -const val ON_CLICK_VIEW_CONTACT = 2 -const val ON_CLICK_EDIT_CONTACT = 3 +// const val ON_CLICK_CALL_CONTACT = 1 +// const val ON_CLICK_VIEW_CONTACT = 2 +// const val ON_CLICK_EDIT_CONTACT = 3 // visible fields filtering -const val SHOW_PREFIX_FIELD = 1 -const val SHOW_FIRST_NAME_FIELD = 2 -const val SHOW_MIDDLE_NAME_FIELD = 4 -const val SHOW_SURNAME_FIELD = 8 -const val SHOW_SUFFIX_FIELD = 16 -const val SHOW_PHONE_NUMBERS_FIELD = 32 -const val SHOW_EMAILS_FIELD = 64 -const val SHOW_ADDRESSES_FIELD = 128 -const val SHOW_EVENTS_FIELD = 256 -const val SHOW_NOTES_FIELD = 512 -const val SHOW_ORGANIZATION_FIELD = 1024 -const val SHOW_GROUPS_FIELD = 2048 -const val SHOW_CONTACT_SOURCE_FIELD = 4096 -const val SHOW_WEBSITES_FIELD = 8192 -const val SHOW_NICKNAME_FIELD = 16384 -const val SHOW_IMS_FIELD = 32768 -const val SHOW_RINGTONE_FIELD = 65536 +// const val SHOW_PREFIX_FIELD = 1 +// const val SHOW_FIRST_NAME_FIELD = 2 +// const val SHOW_MIDDLE_NAME_FIELD = 4 +// const val SHOW_SURNAME_FIELD = 8 +// const val SHOW_SUFFIX_FIELD = 16 +// const val SHOW_PHONE_NUMBERS_FIELD = 32 +// const val SHOW_EMAILS_FIELD = 64 +// const val SHOW_ADDRESSES_FIELD = 128 +// const val SHOW_EVENTS_FIELD = 256 +// const val SHOW_NOTES_FIELD = 512 +// const val SHOW_ORGANIZATION_FIELD = 1024 +// const val SHOW_GROUPS_FIELD = 2048 +// const val SHOW_CONTACT_SOURCE_FIELD = 4096 +// const val SHOW_WEBSITES_FIELD = 8192 +// const val SHOW_NICKNAME_FIELD = 16384 +// const val SHOW_IMS_FIELD = 32768 +// const val SHOW_RINGTONE_FIELD = 65536 -const val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME -const val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE -const val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME -const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY -const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK -const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE -const val DEFAULT_IM_TYPE = CommonDataKinds.Im.PROTOCOL_SKYPE -const val DEFAULT_MIMETYPE = CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE +// const val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME +// const val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE +// const val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME +// const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY +// const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK +// const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE +// const val DEFAULT_IM_TYPE = CommonDataKinds.Im.PROTOCOL_SKYPE +// const val DEFAULT_MIMETYPE = CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE // apps with special handling -const val TELEGRAM_PACKAGE = "org.telegram.messenger" -const val SIGNAL_PACKAGE = "org.thoughtcrime.securesms" -const val WHATSAPP_PACKAGE = "com.whatsapp" -const val VIBER_PACKAGE = "com.viber.voip" -const val THREEMA_PACKAGE = "ch.threema.app" +// const val TELEGRAM_PACKAGE = "org.telegram.messenger" +// const val SIGNAL_PACKAGE = "org.thoughtcrime.securesms" +// const val WHATSAPP_PACKAGE = "com.whatsapp" +// const val VIBER_PACKAGE = "com.viber.voip" +// const val THREEMA_PACKAGE = "ch.threema.app" const val WHATSAPP = "whatsapp" const val SIGNAL = "signal" @@ -125,28 +122,28 @@ const val SOCIAL_VOICE_CALL = 0 const val SOCIAL_VIDEO_CALL = 1 const val SOCIAL_MESSAGE = 2 -fun getEmptyLocalContact() = LocalContact( - 0, - "", - "", - "", - "", - "", - "", - null, - "", - ArrayList(), - ArrayList(), - ArrayList(), - 0, - ArrayList(), - "", - ArrayList(), - "", - "", - ArrayList(), - ArrayList(), - null -) - -fun getProperText(text: String, shouldNormalize: Boolean) = if (shouldNormalize) text.normalizeString() else text +// fun getEmptyLocalContact() = LocalContact( +// 0, +// "", +// "", +// "", +// "", +// "", +// "", +// null, +// "", +// ArrayList(), +// ArrayList(), +// ArrayList(), +// 0, +// ArrayList(), +// "", +// ArrayList(), +// "", +// "", +// ArrayList(), +// ArrayList(), +// null +// ) +// +// fun getProperText(text: String, shouldNormalize: Boolean) = if (shouldNormalize) text.normalizeString() else text diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt index c619bd97..191942f8 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 @@ -1,1547 +1,1547 @@ -package com.simplemobiletools.contacts.pro.helpers - -import android.accounts.Account -import android.accounts.AccountManager -import android.content.* -import android.graphics.Bitmap -import android.net.Uri -import android.os.Handler -import android.os.Looper -import android.provider.ContactsContract.* -import android.provider.ContactsContract.CommonDataKinds.* -import android.provider.MediaStore -import android.text.TextUtils -import android.util.SparseArray -import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.* -import com.simplemobiletools.commons.models.PhoneNumber -import com.simplemobiletools.commons.overloads.times -import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.contacts.pro.extensions.* -import com.simplemobiletools.contacts.pro.models.* -import com.simplemobiletools.contacts.pro.models.Email -import com.simplemobiletools.contacts.pro.models.Event -import com.simplemobiletools.contacts.pro.models.Organization -import java.util.* - -class ContactsHelper(val context: Context) { - private val BATCH_SIZE = 50 - private var displayContactSources = ArrayList() - - fun getContacts( - getAll: Boolean = false, - gettingDuplicates: Boolean = false, - ignoredContactSources: HashSet = HashSet(), - callback: (ArrayList) -> Unit - ) { - ensureBackgroundThread { - val contacts = SparseArray() - displayContactSources = context.getVisibleContactSources() - - if (getAll) { - displayContactSources = if (ignoredContactSources.isEmpty()) { - context.getAllContactSources().map { it.name }.toMutableList() as ArrayList - } else { - context.getAllContactSources().filter { - it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier()) - }.map { it.name }.toMutableList() as ArrayList - } - } - - getDeviceContacts(contacts, ignoredContactSources, gettingDuplicates) - - if (displayContactSources.contains(SMT_PRIVATE)) { - LocalContactsHelper(context).getAllContacts().forEach { - contacts.put(it.id, it) - } - } - - val contactsSize = contacts.size() - val showOnlyContactsWithNumbers = context.config.showOnlyContactsWithNumbers - val tempContacts = ArrayList(contactsSize) - val resultContacts = ArrayList(contactsSize) - - (0 until contactsSize).filter { - if (ignoredContactSources.isEmpty() && showOnlyContactsWithNumbers) { - contacts.valueAt(it).phoneNumbers.isNotEmpty() - } else { - true - } - }.mapTo(tempContacts) { - contacts.valueAt(it) - } - - if (context.config.mergeDuplicateContacts && ignoredContactSources.isEmpty() && !getAll) { - tempContacts.filter { displayContactSources.contains(it.source) }.groupBy { it.getNameToDisplay().toLowerCase() }.values.forEach { it -> - if (it.size == 1) { - resultContacts.add(it.first()) - } else { - val sorted = it.sortedByDescending { it.getStringToCompare().length } - resultContacts.add(sorted.first()) - } - } - } else { - resultContacts.addAll(tempContacts) - } - - // groups are obtained with contactID, not rawID, so assign them to proper contacts like this - val groups = getContactGroups(getStoredGroupsSync()) - val size = groups.size() - for (i in 0 until size) { - val key = groups.keyAt(i) - resultContacts.firstOrNull { it.contactId == key }?.groups = groups.valueAt(i) - } - - Contact.sorting = context.config.sorting - Contact.startWithSurname = context.config.startNameWithSurname - resultContacts.sort() - - Handler(Looper.getMainLooper()).post { - callback(resultContacts) - } - } - } - - private fun getContentResolverAccounts(): HashSet { - val sources = HashSet() - arrayOf(Groups.CONTENT_URI, Settings.CONTENT_URI, RawContacts.CONTENT_URI).forEach { - fillSourcesFromUri(it, sources) - } - - return sources - } - - private fun fillSourcesFromUri(uri: Uri, sources: HashSet) { - val projection = arrayOf( - RawContacts.ACCOUNT_NAME, - RawContacts.ACCOUNT_TYPE - ) - - context.queryCursor(uri, projection) { cursor -> - val name = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" - val type = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" - var publicName = name - if (type == TELEGRAM_PACKAGE) { - publicName = context.getString(R.string.telegram) - } - - val source = ContactSource(name, type, publicName) - sources.add(source) - } - } - - private fun getDeviceContacts(contacts: SparseArray, ignoredContactSources: HashSet?, gettingDuplicates: Boolean) { - if (!context.hasContactPermissions()) { - return - } - - val ignoredSources = ignoredContactSources ?: context.config.ignoredContactSources - val uri = Data.CONTENT_URI - val projection = getContactProjection() - - arrayOf(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, StructuredName.CONTENT_ITEM_TYPE).forEach { mimetype -> - val selection = "${Data.MIMETYPE} = ?" - val selectionArgs = arrayOf(mimetype) - val sortOrder = getSortString() - - context.queryCursor(uri, projection, selection, selectionArgs, sortOrder, true) { cursor -> - val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" - val accountType = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" - - if (ignoredSources.contains("$accountName:$accountType")) { - return@queryCursor - } - - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - var prefix = "" - var firstName = "" - var middleName = "" - var surname = "" - var suffix = "" - - // ignore names at Organization type contacts - if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { - prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" - firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" - middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" - surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" - suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" - } - - var photoUri = "" - var starred = 0 - var contactId = 0 - var thumbnailUri = "" - var ringtone: String? = null - - if (!gettingDuplicates) { - photoUri = cursor.getStringValue(StructuredName.PHOTO_URI) ?: "" - starred = cursor.getIntValue(StructuredName.STARRED) - contactId = cursor.getIntValue(Data.CONTACT_ID) - thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" - ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) - } - - val nickname = "" - val numbers = ArrayList() // proper value is obtained below - val emails = ArrayList() - val addresses = ArrayList
() - val events = ArrayList() - val notes = "" - val groups = ArrayList() - val organization = Organization("", "") - val websites = ArrayList() - val ims = ArrayList() - val contact = Contact( - id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, numbers, emails, addresses, - events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone - ) - - contacts.put(id, contact) - } - } - - val emails = getEmails() - var size = emails.size() - for (i in 0 until size) { - val key = emails.keyAt(i) - contacts[key]?.emails = emails.valueAt(i) - } - - val organizations = getOrganizations() - size = organizations.size() - for (i in 0 until size) { - val key = organizations.keyAt(i) - contacts[key]?.organization = organizations.valueAt(i) - } - - // no need to fetch some fields if we are only getting duplicates of the current contact - if (gettingDuplicates) { - return - } - - val phoneNumbers = getPhoneNumbers(null) - size = phoneNumbers.size() - for (i in 0 until size) { - val key = phoneNumbers.keyAt(i) - if (contacts[key] != null) { - val numbers = phoneNumbers.valueAt(i) - contacts[key].phoneNumbers = numbers - } - } - - val addresses = getAddresses() - size = addresses.size() - for (i in 0 until size) { - val key = addresses.keyAt(i) - contacts[key]?.addresses = addresses.valueAt(i) - } - - val IMs = getIMs() - size = IMs.size() - for (i in 0 until size) { - val key = IMs.keyAt(i) - contacts[key]?.IMs = IMs.valueAt(i) - } - - val events = getEvents() - size = events.size() - for (i in 0 until size) { - val key = events.keyAt(i) - contacts[key]?.events = events.valueAt(i) - } - - val notes = getNotes() - size = notes.size() - for (i in 0 until size) { - val key = notes.keyAt(i) - contacts[key]?.notes = notes.valueAt(i) - } - - val nicknames = getNicknames() - size = nicknames.size() - for (i in 0 until size) { - val key = nicknames.keyAt(i) - contacts[key]?.nickname = nicknames.valueAt(i) - } - - val websites = getWebsites() - size = websites.size() - for (i in 0 until size) { - val key = websites.keyAt(i) - contacts[key]?.websites = websites.valueAt(i) - } - } - - private fun getPhoneNumbers(contactId: Int? = null): SparseArray> { - val phoneNumbers = SparseArray>() - val uri = Phone.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - Phone.NUMBER, - Phone.NORMALIZED_NUMBER, - Phone.TYPE, - Phone.LABEL, - Phone.IS_PRIMARY - ) - - val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val number = cursor.getStringValue(Phone.NUMBER) ?: return@queryCursor - val normalizedNumber = cursor.getStringValue(Phone.NORMALIZED_NUMBER) ?: number.normalizePhoneNumber() - val type = cursor.getIntValue(Phone.TYPE) - val label = cursor.getStringValue(Phone.LABEL) ?: "" - val isPrimary = cursor.getIntValue(Phone.IS_PRIMARY) != 0 - - if (phoneNumbers[id] == null) { - phoneNumbers.put(id, ArrayList()) - } - - val phoneNumber = PhoneNumber(number, type, label, normalizedNumber, isPrimary) - phoneNumbers[id].add(phoneNumber) - } - - return phoneNumbers - } - - private fun getNicknames(contactId: Int? = null): SparseArray { - val nicknames = SparseArray() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - Nickname.NAME - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(Nickname.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val nickname = cursor.getStringValue(Nickname.NAME) ?: return@queryCursor - nicknames.put(id, nickname) - } - - return nicknames - } - - private fun getEmails(contactId: Int? = null): SparseArray> { - val emails = SparseArray>() - val uri = CommonDataKinds.Email.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - CommonDataKinds.Email.DATA, - CommonDataKinds.Email.TYPE, - CommonDataKinds.Email.LABEL - ) - - val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val email = cursor.getStringValue(CommonDataKinds.Email.DATA) ?: return@queryCursor - val type = cursor.getIntValue(CommonDataKinds.Email.TYPE) - val label = cursor.getStringValue(CommonDataKinds.Email.LABEL) ?: "" - - if (emails[id] == null) { - emails.put(id, ArrayList()) - } - - emails[id]!!.add(Email(email, type, label)) - } - - return emails - } - - private fun getAddresses(contactId: Int? = null): SparseArray> { - val addresses = SparseArray>() - val uri = StructuredPostal.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - StructuredPostal.FORMATTED_ADDRESS, - StructuredPostal.TYPE, - StructuredPostal.LABEL - ) - - val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val address = cursor.getStringValue(StructuredPostal.FORMATTED_ADDRESS) ?: return@queryCursor - val type = cursor.getIntValue(StructuredPostal.TYPE) - val label = cursor.getStringValue(StructuredPostal.LABEL) ?: "" - - if (addresses[id] == null) { - addresses.put(id, ArrayList()) - } - - addresses[id]!!.add(Address(address, type, label)) - } - - return addresses - } - - private fun getIMs(contactId: Int? = null): SparseArray> { - val IMs = SparseArray>() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - Im.DATA, - Im.PROTOCOL, - Im.CUSTOM_PROTOCOL - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(Im.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val IM = cursor.getStringValue(Im.DATA) ?: return@queryCursor - val type = cursor.getIntValue(Im.PROTOCOL) - val label = cursor.getStringValue(Im.CUSTOM_PROTOCOL) ?: "" - - if (IMs[id] == null) { - IMs.put(id, ArrayList()) - } - - IMs[id]!!.add(IM(IM, type, label)) - } - - return IMs - } - - private fun getEvents(contactId: Int? = null): SparseArray> { - val events = SparseArray>() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - CommonDataKinds.Event.START_DATE, - CommonDataKinds.Event.TYPE - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Event.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val startDate = cursor.getStringValue(CommonDataKinds.Event.START_DATE) ?: return@queryCursor - val type = cursor.getIntValue(CommonDataKinds.Event.TYPE) - - if (events[id] == null) { - events.put(id, ArrayList()) - } - - events[id]!!.add(Event(startDate, type)) - } - - return events - } - - private fun getNotes(contactId: Int? = null): SparseArray { - val notes = SparseArray() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - Note.NOTE - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(Note.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val note = cursor.getStringValue(Note.NOTE) ?: return@queryCursor - notes.put(id, note) - } - - return notes - } - - private fun getOrganizations(contactId: Int? = null): SparseArray { - val organizations = SparseArray() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - CommonDataKinds.Organization.COMPANY, - CommonDataKinds.Organization.TITLE - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: "" - val title = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: "" - if (company.isEmpty() && title.isEmpty()) { - return@queryCursor - } - - val organization = Organization(company, title) - organizations.put(id, organization) - } - - return organizations - } - - private fun getWebsites(contactId: Int? = null): SparseArray> { - val websites = SparseArray>() - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.RAW_CONTACT_ID, - Website.URL - ) - - val selection = getSourcesSelection(true, contactId != null) - val selectionArgs = getSourcesSelectionArgs(Website.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - val url = cursor.getStringValue(Website.URL) ?: return@queryCursor - - if (websites[id] == null) { - websites.put(id, ArrayList()) - } - - websites[id]!!.add(url) - } - - return websites - } - - private fun getContactGroups(storedGroups: ArrayList, contactId: Int? = null): SparseArray> { - val groups = SparseArray>() - if (!context.hasContactPermissions()) { - return groups - } - - val uri = Data.CONTENT_URI - val projection = arrayOf( - Data.CONTACT_ID, - Data.DATA1 - ) - - val selection = getSourcesSelection(true, contactId != null, false) - val selectionArgs = getSourcesSelectionArgs(GroupMembership.CONTENT_ITEM_TYPE, contactId) - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getIntValue(Data.CONTACT_ID) - val newRowId = cursor.getLongValue(Data.DATA1) - - val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: return@queryCursor - val group = Group(newRowId, groupTitle) - if (groups[id] == null) { - groups.put(id, ArrayList()) - } - groups[id]!!.add(group) - } - - return groups - } - - private fun getQuestionMarks() = ("?," * displayContactSources.filter { it.isNotEmpty() }.size).trimEnd(',') - - private fun getSourcesSelection(addMimeType: Boolean = false, addContactId: Boolean = false, useRawContactId: Boolean = true): String { - val strings = ArrayList() - if (addMimeType) { - strings.add("${Data.MIMETYPE} = ?") - } - - if (addContactId) { - strings.add("${if (useRawContactId) Data.RAW_CONTACT_ID else Data.CONTACT_ID} = ?") - } else { - // sometimes local device storage has null account_name, handle it properly - val accountnameString = StringBuilder() - if (displayContactSources.contains("")) { - accountnameString.append("(") - } - accountnameString.append("${RawContacts.ACCOUNT_NAME} IN (${getQuestionMarks()})") - if (displayContactSources.contains("")) { - accountnameString.append(" OR ${RawContacts.ACCOUNT_NAME} IS NULL)") - } - strings.add(accountnameString.toString()) - } - - return TextUtils.join(" AND ", strings) - } - - private fun getSourcesSelectionArgs(mimetype: String? = null, contactId: Int? = null): Array { - val args = ArrayList() - - if (mimetype != null) { - args.add(mimetype) - } - - if (contactId != null) { - args.add(contactId.toString()) - } else { - args.addAll(displayContactSources.filter { it.isNotEmpty() }) - } - - return args.toTypedArray() - } - - fun getStoredGroups(callback: (ArrayList) -> Unit) { - ensureBackgroundThread { - val groups = getStoredGroupsSync() - Handler(Looper.getMainLooper()).post { - callback(groups) - } - } - } - - fun getStoredGroupsSync(): ArrayList { - val groups = getDeviceStoredGroups() - groups.addAll(context.groupsDB.getGroups()) - return groups - } - - private fun getDeviceStoredGroups(): ArrayList { - val groups = ArrayList() - if (!context.hasContactPermissions()) { - return groups - } - - val uri = Groups.CONTENT_URI - val projection = arrayOf( - Groups._ID, - Groups.TITLE, - Groups.SYSTEM_ID - ) - - val selection = "${Groups.AUTO_ADD} = ? AND ${Groups.FAVORITES} = ?" - val selectionArgs = arrayOf("0", "0") - - context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> - val id = cursor.getLongValue(Groups._ID) - val title = cursor.getStringValue(Groups.TITLE) ?: return@queryCursor - - val systemId = cursor.getStringValue(Groups.SYSTEM_ID) - if (groups.map { it.title }.contains(title) && systemId != null) { - return@queryCursor - } - - groups.add(Group(id, title)) - } - return groups - } - - fun createNewGroup(title: String, accountName: String, accountType: String): Group? { - if (accountType == SMT_PRIVATE) { - val newGroup = Group(null, title) - val id = context.groupsDB.insertOrUpdate(newGroup) - newGroup.id = id - return newGroup - } - - val operations = ArrayList() - ContentProviderOperation.newInsert(Groups.CONTENT_URI).apply { - withValue(Groups.TITLE, title) - withValue(Groups.GROUP_VISIBLE, 1) - withValue(Groups.ACCOUNT_NAME, accountName) - withValue(Groups.ACCOUNT_TYPE, accountType) - operations.add(build()) - } - - try { - val results = context.contentResolver.applyBatch(AUTHORITY, operations) - val rawId = ContentUris.parseId(results[0].uri!!) - return Group(rawId, title) - } catch (e: Exception) { - context.showErrorToast(e) - } - return null - } - - fun renameGroup(group: Group) { - val operations = ArrayList() - ContentProviderOperation.newUpdate(Groups.CONTENT_URI).apply { - val selection = "${Groups._ID} = ?" - val selectionArgs = arrayOf(group.id.toString()) - withSelection(selection, selectionArgs) - withValue(Groups.TITLE, group.title) - operations.add(build()) - } - - try { - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - fun deleteGroup(id: Long) { - val operations = ArrayList() - val uri = ContentUris.withAppendedId(Groups.CONTENT_URI, id).buildUpon() - .appendQueryParameter(CALLER_IS_SYNCADAPTER, "true") - .build() - - operations.add(ContentProviderOperation.newDelete(uri).build()) - - try { - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { - if (id == 0) { - return null - } else if (isLocalPrivate) { - return LocalContactsHelper(context).getContactWithId(id) - } - - val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) - return parseContactCursor(selection, selectionArgs) - } - - fun getContactWithLookupKey(key: String): Contact? { - val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.LOOKUP_KEY} = ?" - val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, key) - return parseContactCursor(selection, selectionArgs) - } - - private fun parseContactCursor(selection: String, selectionArgs: Array): Contact? { - val storedGroups = getStoredGroupsSync() - val uri = Data.CONTENT_URI - val projection = getContactProjection() - - val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) - cursor?.use { - if (cursor.moveToFirst()) { - val id = cursor.getIntValue(Data.RAW_CONTACT_ID) - - var prefix = "" - var firstName = "" - var middleName = "" - var surname = "" - var suffix = "" - var mimetype = cursor.getStringValue(Data.MIMETYPE) - - // if first line is an Organization type contact, go to next line - if (mimetype != StructuredName.CONTENT_ITEM_TYPE) { - if (cursor.moveToNext()) { - mimetype = cursor.getStringValue(Data.MIMETYPE) - } - } - // ignore names at Organization type contacts - if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { - prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" - firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" - middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" - surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" - suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" - } - - val nickname = getNicknames(id)[id] ?: "" - val photoUri = cursor.getStringValueOrNull(Phone.PHOTO_URI) ?: "" - val number = getPhoneNumbers(id)[id] ?: ArrayList() - val emails = getEmails(id)[id] ?: ArrayList() - val addresses = getAddresses(id)[id] ?: ArrayList() - val events = getEvents(id)[id] ?: ArrayList() - val notes = getNotes(id)[id] ?: "" - val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" - val starred = cursor.getIntValue(StructuredName.STARRED) - val ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) - val contactId = cursor.getIntValue(Data.CONTACT_ID) - val groups = getContactGroups(storedGroups, contactId)[contactId] ?: ArrayList() - val thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" - val organization = getOrganizations(id)[id] ?: Organization("", "") - val websites = getWebsites(id)[id] ?: ArrayList() - val ims = getIMs(id)[id] ?: ArrayList() - return Contact( - id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events, - accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone - ) - } - } - - return null - } - - fun getContactSources(callback: (ArrayList) -> Unit) { - ensureBackgroundThread { - callback(getContactSourcesSync()) - } - } - - private fun getContactSourcesSync(): ArrayList { - val sources = getDeviceContactSources() - sources.add(context.getPrivateContactSource()) - return ArrayList(sources) - } - - fun getSaveableContactSources(callback: (ArrayList) -> Unit) { - ensureBackgroundThread { - val ignoredTypes = arrayListOf( - SIGNAL_PACKAGE, - TELEGRAM_PACKAGE, - WHATSAPP_PACKAGE, - THREEMA_PACKAGE - ) - - val contactSources = getContactSourcesSync() - val filteredSources = contactSources.filter { !ignoredTypes.contains(it.type) }.toMutableList() as ArrayList - callback(filteredSources) - } - } - - fun getDeviceContactSources(): LinkedHashSet { - val sources = LinkedHashSet() - if (!context.hasContactPermissions()) { - return sources - } - - if (!context.config.wasLocalAccountInitialized) { - initializeLocalPhoneAccount() - context.config.wasLocalAccountInitialized = true - } - - val accounts = AccountManager.get(context).accounts - accounts.forEach { - if (ContentResolver.getIsSyncable(it, AUTHORITY) == 1) { - var publicName = it.name - if (it.type == TELEGRAM_PACKAGE) { - publicName = context.getString(R.string.telegram) - } else if (it.type == VIBER_PACKAGE) { - publicName = context.getString(R.string.viber) - } - val contactSource = ContactSource(it.name, it.type, publicName) - sources.add(contactSource) - } - } - - var hadEmptyAccount = false - val allAccounts = getContentResolverAccounts() - val contentResolverAccounts = allAccounts.filter { - if (it.name.isEmpty() && it.type.isEmpty() && allAccounts.none { it.name.lowercase(Locale.getDefault()) == "phone" }) { - hadEmptyAccount = true - } - - it.name.isNotEmpty() && it.type.isNotEmpty() && !accounts.contains(Account(it.name, it.type)) - } - sources.addAll(contentResolverAccounts) - - if (hadEmptyAccount) { - sources.add(ContactSource("", "", context.getString(R.string.phone_storage))) - } - - return sources - } - - // make sure the local Phone contact source is initialized and available - // https://stackoverflow.com/a/6096508/1967672 - private fun initializeLocalPhoneAccount() { - try { - val operations = ArrayList() - ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { - withValue(RawContacts.ACCOUNT_NAME, null) - withValue(RawContacts.ACCOUNT_TYPE, null) - operations.add(build()) - } - - val results = context.contentResolver.applyBatch(AUTHORITY, operations) - val rawContactUri = results.firstOrNull()?.uri ?: return - context.contentResolver.delete(rawContactUri, null, null) - } catch (ignored: Exception) { - } - } - - private fun getContactSourceType(accountName: String) = getDeviceContactSources().firstOrNull { it.name == accountName }?.type ?: "" - - private fun getContactProjection() = arrayOf( - Data.MIMETYPE, - Data.CONTACT_ID, - Data.RAW_CONTACT_ID, - StructuredName.PREFIX, - StructuredName.GIVEN_NAME, - StructuredName.MIDDLE_NAME, - StructuredName.FAMILY_NAME, - StructuredName.SUFFIX, - StructuredName.PHOTO_URI, - StructuredName.PHOTO_THUMBNAIL_URI, - StructuredName.STARRED, - StructuredName.CUSTOM_RINGTONE, - RawContacts.ACCOUNT_NAME, - RawContacts.ACCOUNT_TYPE - ) - - private fun getSortString(): String { - val sorting = context.config.sorting - return when { - sorting and SORT_BY_FIRST_NAME != 0 -> "${StructuredName.GIVEN_NAME} COLLATE NOCASE" - sorting and SORT_BY_MIDDLE_NAME != 0 -> "${StructuredName.MIDDLE_NAME} COLLATE NOCASE" - sorting and SORT_BY_SURNAME != 0 -> "${StructuredName.FAMILY_NAME} COLLATE NOCASE" - sorting and SORT_BY_FULL_NAME != 0 -> StructuredName.DISPLAY_NAME - else -> Data.RAW_CONTACT_ID - } - } - - private fun getRealContactId(id: Long): Int { - val uri = Data.CONTENT_URI - val projection = getContactProjection() - val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) - - val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) - cursor?.use { - if (cursor.moveToFirst()) { - return cursor.getIntValue(Data.CONTACT_ID) - } - } - - return 0 - } - - fun updateContact(contact: Contact, photoUpdateStatus: Int): Boolean { - context.toast(R.string.updating) - if (contact.isPrivate()) { - return LocalContactsHelper(context).insertOrUpdateContact(contact) - } - - try { - val operations = ArrayList() - ContentProviderOperation.newUpdate(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" - val selectionArgs = arrayOf(contact.id.toString(), contact.mimetype) - withSelection(selection, selectionArgs) - withValue(StructuredName.PREFIX, contact.prefix) - withValue(StructuredName.GIVEN_NAME, contact.firstName) - withValue(StructuredName.MIDDLE_NAME, contact.middleName) - withValue(StructuredName.FAMILY_NAME, contact.surname) - withValue(StructuredName.SUFFIX, contact.suffix) - operations.add(build()) - } - - // delete nickname - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), Nickname.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add nickname - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) - withValue(Nickname.NAME, contact.nickname) - operations.add(build()) - } - - // delete phone numbers - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), Phone.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add phone numbers - contact.phoneNumbers.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) - withValue(Phone.NUMBER, it.value) - withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) - withValue(Phone.TYPE, it.type) - withValue(Phone.LABEL, it.label) - withValue(Phone.IS_PRIMARY, it.isPrimary) - operations.add(build()) - } - } - - // delete emails - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Email.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add emails - contact.emails.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Email.DATA, it.value) - withValue(CommonDataKinds.Email.TYPE, it.type) - withValue(CommonDataKinds.Email.LABEL, it.label) - operations.add(build()) - } - } - - // delete addresses - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), StructuredPostal.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add addresses - contact.addresses.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) - withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) - withValue(StructuredPostal.TYPE, it.type) - withValue(StructuredPostal.LABEL, it.label) - operations.add(build()) - } - } - - // delete IMs - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), Im.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add IMs - contact.IMs.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) - withValue(Im.DATA, it.value) - withValue(Im.PROTOCOL, it.type) - withValue(Im.CUSTOM_PROTOCOL, it.label) - operations.add(build()) - } - } - - // delete events - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Event.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add events - contact.events.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Event.START_DATE, it.value) - withValue(CommonDataKinds.Event.TYPE, it.type) - operations.add(build()) - } - } - - // delete notes - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), Note.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add notes - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) - withValue(Note.NOTE, contact.notes) - operations.add(build()) - } - - // delete organization - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Organization.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add organization - if (contact.organization.isNotEmpty()) { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - operations.add(build()) - } - } - - // delete websites - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " - val selectionArgs = arrayOf(contact.id.toString(), Website.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - // add websites - contact.websites.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) - withValue(Website.URL, it) - withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) - operations.add(build()) - } - } - - // delete groups - val relevantGroupIDs = getStoredGroupsSync().map { it.id } - if (relevantGroupIDs.isNotEmpty()) { - val IDsString = TextUtils.join(",", relevantGroupIDs) - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} IN ($IDsString)" - val selectionArgs = arrayOf(contact.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - } - - // add groups - contact.groups.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) - withValue(GroupMembership.GROUP_ROW_ID, it.id) - operations.add(build()) - } - } - - // favorite, ringtone - try { - val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contact.contactId.toString()) - val contentValues = ContentValues(2) - contentValues.put(Contacts.STARRED, contact.starred) - contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) - context.contentResolver.update(uri, contentValues, null, null) - } catch (e: Exception) { - context.showErrorToast(e) - } - - // photo - when (photoUpdateStatus) { - PHOTO_ADDED, PHOTO_CHANGED -> addPhoto(contact, operations) - PHOTO_REMOVED -> removePhoto(contact, operations) - } - - context.contentResolver.applyBatch(AUTHORITY, operations) - return true - } catch (e: Exception) { - context.showErrorToast(e) - return false - } - } - - private fun addPhoto(contact: Contact, operations: ArrayList): ArrayList { - if (contact.photoUri.isNotEmpty()) { - val photoUri = Uri.parse(contact.photoUri) - val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) - - val thumbnailSize = context.getPhotoThumbnailSize() - val scaledPhoto = Bitmap.createScaledBitmap(bitmap, thumbnailSize, thumbnailSize, false) - val scaledSizePhotoData = scaledPhoto.getByteArray() - scaledPhoto.recycle() - - val fullSizePhotoData = bitmap.getByteArray() - bitmap.recycle() - - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, contact.id) - withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE) - withValue(Photo.PHOTO, scaledSizePhotoData) - operations.add(build()) - } - - addFullSizePhoto(contact.id.toLong(), fullSizePhotoData) - } - return operations - } - - private fun removePhoto(contact: Contact, operations: ArrayList): ArrayList { - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" - val selectionArgs = arrayOf(contact.id.toString(), Photo.CONTENT_ITEM_TYPE) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - return operations - } - - fun addContactsToGroup(contacts: ArrayList, groupId: Long) { - try { - val operations = ArrayList() - contacts.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValue(Data.RAW_CONTACT_ID, it.id) - withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) - withValue(GroupMembership.GROUP_ROW_ID, groupId) - operations.add(build()) - } - - if (operations.size % BATCH_SIZE == 0) { - context.contentResolver.applyBatch(AUTHORITY, operations) - operations.clear() - } - } - - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { - try { - val operations = ArrayList() - contacts.forEach { - ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { - val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} = ?" - val selectionArgs = arrayOf(it.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE, groupId.toString()) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - if (operations.size % BATCH_SIZE == 0) { - context.contentResolver.applyBatch(AUTHORITY, operations) - operations.clear() - } - } - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - fun insertContact(contact: Contact): Boolean { - if (contact.isPrivate()) { - return LocalContactsHelper(context).insertOrUpdateContact(contact) - } - - try { - val operations = ArrayList() - ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { - withValue(RawContacts.ACCOUNT_NAME, contact.source) - withValue(RawContacts.ACCOUNT_TYPE, getContactSourceType(contact.source)) - operations.add(build()) - } - - // names - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) - withValue(StructuredName.PREFIX, contact.prefix) - withValue(StructuredName.GIVEN_NAME, contact.firstName) - withValue(StructuredName.MIDDLE_NAME, contact.middleName) - withValue(StructuredName.FAMILY_NAME, contact.surname) - withValue(StructuredName.SUFFIX, contact.suffix) - operations.add(build()) - } - - // nickname - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) - withValue(Nickname.NAME, contact.nickname) - operations.add(build()) - } - - // phone numbers - contact.phoneNumbers.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) - withValue(Phone.NUMBER, it.value) - withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) - withValue(Phone.TYPE, it.type) - withValue(Phone.LABEL, it.label) - withValue(Phone.IS_PRIMARY, it.isPrimary) - operations.add(build()) - } - } - - // emails - contact.emails.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Email.DATA, it.value) - withValue(CommonDataKinds.Email.TYPE, it.type) - withValue(CommonDataKinds.Email.LABEL, it.label) - operations.add(build()) - } - } - - // addresses - contact.addresses.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) - withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) - withValue(StructuredPostal.TYPE, it.type) - withValue(StructuredPostal.LABEL, it.label) - operations.add(build()) - } - } - - // IMs - contact.IMs.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) - withValue(Im.DATA, it.value) - withValue(Im.PROTOCOL, it.type) - withValue(Im.CUSTOM_PROTOCOL, it.label) - operations.add(build()) - } - } - - // events - contact.events.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Event.START_DATE, it.value) - withValue(CommonDataKinds.Event.TYPE, it.type) - operations.add(build()) - } - } - - // notes - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) - withValue(Note.NOTE, contact.notes) - operations.add(build()) - } - - // organization - if (contact.organization.isNotEmpty()) { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - operations.add(build()) - } - } - - // websites - contact.websites.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) - withValue(Website.URL, it) - withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) - operations.add(build()) - } - } - - // groups - contact.groups.forEach { - ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { - withValueBackReference(Data.RAW_CONTACT_ID, 0) - withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) - withValue(GroupMembership.GROUP_ROW_ID, it.id) - operations.add(build()) - } - } - - // photo (inspired by https://gist.github.com/slightfoot/5985900) - var fullSizePhotoData: ByteArray? = null - if (contact.photoUri.isNotEmpty()) { - val photoUri = Uri.parse(contact.photoUri) - fullSizePhotoData = context.contentResolver.openInputStream(photoUri)?.readBytes() - } - - val results = context.contentResolver.applyBatch(AUTHORITY, operations) - - // storing contacts on some devices seems to be messed up and they move on Phone instead, or disappear completely - // try storing a lighter contact version with this oldschool version too just so it wont disappear, future edits work well - if (getContactSourceType(contact.source).contains(".sim")) { - val simUri = Uri.parse("content://icc/adn") - ContentValues().apply { - put("number", contact.phoneNumbers.firstOrNull()?.value ?: "") - put("tag", contact.getNameToDisplay()) - context.contentResolver.insert(simUri, this) - } - } - - // fullsize photo - val rawId = ContentUris.parseId(results[0].uri!!) - if (contact.photoUri.isNotEmpty() && fullSizePhotoData != null) { - addFullSizePhoto(rawId, fullSizePhotoData) - } - - // favorite, ringtone - val userId = getRealContactId(rawId) - if (userId != 0) { - val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, userId.toString()) - val contentValues = ContentValues(2) - contentValues.put(Contacts.STARRED, contact.starred) - contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) - context.contentResolver.update(uri, contentValues, null, null) - } - - return true - } catch (e: Exception) { - context.showErrorToast(e) - return false - } - } - - private fun addFullSizePhoto(contactId: Long, fullSizePhotoData: ByteArray) { - val baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, contactId) - val displayPhotoUri = Uri.withAppendedPath(baseUri, RawContacts.DisplayPhoto.CONTENT_DIRECTORY) - val fileDescriptor = context.contentResolver.openAssetFileDescriptor(displayPhotoUri, "rw") - val photoStream = fileDescriptor!!.createOutputStream() - photoStream.write(fullSizePhotoData) - photoStream.close() - fileDescriptor.close() - } - - fun getContactMimeTypeId(contactId: String, mimeType: String): String { - val uri = Data.CONTENT_URI - val projection = arrayOf(Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE) - val selection = "${Data.MIMETYPE} = ? AND ${Data.RAW_CONTACT_ID} = ?" - val selectionArgs = arrayOf(mimeType, contactId) - - - val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) - cursor?.use { - if (cursor.moveToFirst()) { - return cursor.getStringValue(Data._ID) - } - } - return "" - } - - fun addFavorites(contacts: ArrayList) { - ensureBackgroundThread { - toggleLocalFavorites(contacts, true) - if (context.hasContactPermissions()) { - toggleFavorites(contacts, true) - } - } - } - - fun removeFavorites(contacts: ArrayList) { - ensureBackgroundThread { - toggleLocalFavorites(contacts, false) - if (context.hasContactPermissions()) { - toggleFavorites(contacts, false) - } - } - } - - private fun toggleFavorites(contacts: ArrayList, addToFavorites: Boolean) { - try { - val operations = ArrayList() - contacts.filter { !it.isPrivate() }.map { it.contactId.toString() }.forEach { - val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, it) - ContentProviderOperation.newUpdate(uri).apply { - withValue(Contacts.STARRED, if (addToFavorites) 1 else 0) - operations.add(build()) - } - - if (operations.size % BATCH_SIZE == 0) { - context.contentResolver.applyBatch(AUTHORITY, operations) - operations.clear() - } - } - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - private fun toggleLocalFavorites(contacts: ArrayList, addToFavorites: Boolean) { - val localContacts = contacts.filter { it.isPrivate() }.map { it.id }.toTypedArray() - LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites) - } - - fun updateRingtone(contactId: String, newUri: String) { - try { - val operations = ArrayList() - val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contactId) - ContentProviderOperation.newUpdate(uri).apply { - withValue(Contacts.CUSTOM_RINGTONE, newUri) - operations.add(build()) - } - - context.contentResolver.applyBatch(AUTHORITY, operations) - } catch (e: Exception) { - context.showErrorToast(e) - } - } - - fun deleteContact(originalContact: Contact, deleteClones: Boolean = false, callback: (success: Boolean) -> Unit) { - ensureBackgroundThread { - if (deleteClones) { - getDuplicatesOfContact(originalContact, true) { contacts -> - ensureBackgroundThread { - if (deleteContacts(contacts)) { - callback(true) - } - } - } - } else { - if (deleteContacts(arrayListOf(originalContact))) { - callback(true) - } - } - } - } - - fun deleteContacts(contacts: ArrayList): Boolean { - val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList() - LocalContactsHelper(context).deleteContactIds(localContacts) - - return try { - val operations = ArrayList() - val selection = "${RawContacts._ID} = ?" - contacts.filter { !it.isPrivate() }.forEach { - ContentProviderOperation.newDelete(RawContacts.CONTENT_URI).apply { - val selectionArgs = arrayOf(it.id.toString()) - withSelection(selection, selectionArgs) - operations.add(build()) - } - - if (operations.size % BATCH_SIZE == 0) { - context.contentResolver.applyBatch(AUTHORITY, operations) - operations.clear() - } - } - - if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) { - context.contentResolver.applyBatch(AUTHORITY, operations) - } - true - } catch (e: Exception) { - context.showErrorToast(e) - false - } - } - - fun getDuplicatesOfContact(contact: Contact, addOriginal: Boolean, callback: (ArrayList) -> Unit) { - ensureBackgroundThread { - getContacts(true, true) { contacts -> - val duplicates = - contacts.filter { it.id != contact.id && it.getHashToCompare() == contact.getHashToCompare() }.toMutableList() as ArrayList - if (addOriginal) { - duplicates.add(contact) - } - callback(duplicates) - } - } - } -} +// package com.simplemobiletools.contacts.pro.helpers +// +// import android.accounts.Account +// import android.accounts.AccountManager +// import android.content.* +// import android.graphics.Bitmap +// import android.net.Uri +// import android.os.Handler +// import android.os.Looper +// import android.provider.ContactsContract.* +// import android.provider.ContactsContract.CommonDataKinds.* +// import android.provider.MediaStore +// import android.text.TextUtils +// import android.util.SparseArray +// import com.simplemobiletools.commons.extensions.* +// import com.simplemobiletools.commons.helpers.* +// import com.simplemobiletools.commons.models.PhoneNumber +// import com.simplemobiletools.commons.overloads.times +// import com.simplemobiletools.contacts.pro.R +// import com.simplemobiletools.contacts.pro.extensions.* +// import com.simplemobiletools.contacts.pro.models.* +// import com.simplemobiletools.contacts.pro.models.Email +// import com.simplemobiletools.contacts.pro.models.Event +// import com.simplemobiletools.contacts.pro.models.Organization +// import java.util.* +// +// class ContactsHelper(val context: Context) { +// private val BATCH_SIZE = 50 +// private var displayContactSources = ArrayList() +// +// fun getContacts( +// getAll: Boolean = false, +// gettingDuplicates: Boolean = false, +// ignoredContactSources: HashSet = HashSet(), +// callback: (ArrayList) -> Unit +// ) { +// ensureBackgroundThread { +// val contacts = SparseArray() +// displayContactSources = context.getVisibleContactSources() +// +// if (getAll) { +// displayContactSources = if (ignoredContactSources.isEmpty()) { +// context.getAllContactSources().map { it.name }.toMutableList() as ArrayList +// } else { +// context.getAllContactSources().filter { +// it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier()) +// }.map { it.name }.toMutableList() as ArrayList +// } +// } +// +// getDeviceContacts(contacts, ignoredContactSources, gettingDuplicates) +// +// if (displayContactSources.contains(SMT_PRIVATE)) { +// LocalContactsHelper(context).getAllContacts().forEach { +// contacts.put(it.id, it) +// } +// } +// +// val contactsSize = contacts.size() +// val showOnlyContactsWithNumbers = context.config.showOnlyContactsWithNumbers +// val tempContacts = ArrayList(contactsSize) +// val resultContacts = ArrayList(contactsSize) +// +// (0 until contactsSize).filter { +// if (ignoredContactSources.isEmpty() && showOnlyContactsWithNumbers) { +// contacts.valueAt(it).phoneNumbers.isNotEmpty() +// } else { +// true +// } +// }.mapTo(tempContacts) { +// contacts.valueAt(it) +// } +// +// if (context.config.mergeDuplicateContacts && ignoredContactSources.isEmpty() && !getAll) { +// tempContacts.filter { displayContactSources.contains(it.source) }.groupBy { it.getNameToDisplay().toLowerCase() }.values.forEach { it -> +// if (it.size == 1) { +// resultContacts.add(it.first()) +// } else { +// val sorted = it.sortedByDescending { it.getStringToCompare().length } +// resultContacts.add(sorted.first()) +// } +// } +// } else { +// resultContacts.addAll(tempContacts) +// } +// +// // groups are obtained with contactID, not rawID, so assign them to proper contacts like this +// val groups = getContactGroups(getStoredGroupsSync()) +// val size = groups.size() +// for (i in 0 until size) { +// val key = groups.keyAt(i) +// resultContacts.firstOrNull { it.contactId == key }?.groups = groups.valueAt(i) +// } +// +// Contact.sorting = context.config.sorting +// Contact.startWithSurname = context.config.startNameWithSurname +// resultContacts.sort() +// +// Handler(Looper.getMainLooper()).post { +// callback(resultContacts) +// } +// } +// } +// +// private fun getContentResolverAccounts(): HashSet { +// val sources = HashSet() +// arrayOf(Groups.CONTENT_URI, Settings.CONTENT_URI, RawContacts.CONTENT_URI).forEach { +// fillSourcesFromUri(it, sources) +// } +// +// return sources +// } +// +// private fun fillSourcesFromUri(uri: Uri, sources: HashSet) { +// val projection = arrayOf( +// RawContacts.ACCOUNT_NAME, +// RawContacts.ACCOUNT_TYPE +// ) +// +// context.queryCursor(uri, projection) { cursor -> +// val name = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" +// val type = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" +// var publicName = name +// if (type == TELEGRAM_PACKAGE) { +// publicName = context.getString(R.string.telegram) +// } +// +// val source = ContactSource(name, type, publicName) +// sources.add(source) +// } +// } +// +// private fun getDeviceContacts(contacts: SparseArray, ignoredContactSources: HashSet?, gettingDuplicates: Boolean) { +// if (!context.hasContactPermissions()) { +// return +// } +// +// val ignoredSources = ignoredContactSources ?: context.config.ignoredContactSources +// val uri = Data.CONTENT_URI +// val projection = getContactProjection() +// +// arrayOf(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, StructuredName.CONTENT_ITEM_TYPE).forEach { mimetype -> +// val selection = "${Data.MIMETYPE} = ?" +// val selectionArgs = arrayOf(mimetype) +// val sortOrder = getSortString() +// +// context.queryCursor(uri, projection, selection, selectionArgs, sortOrder, true) { cursor -> +// val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" +// val accountType = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" +// +// if (ignoredSources.contains("$accountName:$accountType")) { +// return@queryCursor +// } +// +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// var prefix = "" +// var firstName = "" +// var middleName = "" +// var surname = "" +// var suffix = "" +// +// // ignore names at Organization type contacts +// if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { +// prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" +// firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" +// middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" +// surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" +// suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" +// } +// +// var photoUri = "" +// var starred = 0 +// var contactId = 0 +// var thumbnailUri = "" +// var ringtone: String? = null +// +// if (!gettingDuplicates) { +// photoUri = cursor.getStringValue(StructuredName.PHOTO_URI) ?: "" +// starred = cursor.getIntValue(StructuredName.STARRED) +// contactId = cursor.getIntValue(Data.CONTACT_ID) +// thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" +// ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) +// } +// +// val nickname = "" +// val numbers = ArrayList() // proper value is obtained below +// val emails = ArrayList() +// val addresses = ArrayList
() +// val events = ArrayList() +// val notes = "" +// val groups = ArrayList() +// val organization = Organization("", "") +// val websites = ArrayList() +// val ims = ArrayList() +// val contact = Contact( +// id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, numbers, emails, addresses, +// events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone +// ) +// +// contacts.put(id, contact) +// } +// } +// +// val emails = getEmails() +// var size = emails.size() +// for (i in 0 until size) { +// val key = emails.keyAt(i) +// contacts[key]?.emails = emails.valueAt(i) +// } +// +// val organizations = getOrganizations() +// size = organizations.size() +// for (i in 0 until size) { +// val key = organizations.keyAt(i) +// contacts[key]?.organization = organizations.valueAt(i) +// } +// +// // no need to fetch some fields if we are only getting duplicates of the current contact +// if (gettingDuplicates) { +// return +// } +// +// val phoneNumbers = getPhoneNumbers(null) +// size = phoneNumbers.size() +// for (i in 0 until size) { +// val key = phoneNumbers.keyAt(i) +// if (contacts[key] != null) { +// val numbers = phoneNumbers.valueAt(i) +// contacts[key].phoneNumbers = numbers +// } +// } +// +// val addresses = getAddresses() +// size = addresses.size() +// for (i in 0 until size) { +// val key = addresses.keyAt(i) +// contacts[key]?.addresses = addresses.valueAt(i) +// } +// +// val IMs = getIMs() +// size = IMs.size() +// for (i in 0 until size) { +// val key = IMs.keyAt(i) +// contacts[key]?.IMs = IMs.valueAt(i) +// } +// +// val events = getEvents() +// size = events.size() +// for (i in 0 until size) { +// val key = events.keyAt(i) +// contacts[key]?.events = events.valueAt(i) +// } +// +// val notes = getNotes() +// size = notes.size() +// for (i in 0 until size) { +// val key = notes.keyAt(i) +// contacts[key]?.notes = notes.valueAt(i) +// } +// +// val nicknames = getNicknames() +// size = nicknames.size() +// for (i in 0 until size) { +// val key = nicknames.keyAt(i) +// contacts[key]?.nickname = nicknames.valueAt(i) +// } +// +// val websites = getWebsites() +// size = websites.size() +// for (i in 0 until size) { +// val key = websites.keyAt(i) +// contacts[key]?.websites = websites.valueAt(i) +// } +// } +// +// private fun getPhoneNumbers(contactId: Int? = null): SparseArray> { +// val phoneNumbers = SparseArray>() +// val uri = Phone.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// Phone.NUMBER, +// Phone.NORMALIZED_NUMBER, +// Phone.TYPE, +// Phone.LABEL, +// Phone.IS_PRIMARY +// ) +// +// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val number = cursor.getStringValue(Phone.NUMBER) ?: return@queryCursor +// val normalizedNumber = cursor.getStringValue(Phone.NORMALIZED_NUMBER) ?: number.normalizePhoneNumber() +// val type = cursor.getIntValue(Phone.TYPE) +// val label = cursor.getStringValue(Phone.LABEL) ?: "" +// val isPrimary = cursor.getIntValue(Phone.IS_PRIMARY) != 0 +// +// if (phoneNumbers[id] == null) { +// phoneNumbers.put(id, ArrayList()) +// } +// +// val phoneNumber = PhoneNumber(number, type, label, normalizedNumber, isPrimary) +// phoneNumbers[id].add(phoneNumber) +// } +// +// return phoneNumbers +// } +// +// private fun getNicknames(contactId: Int? = null): SparseArray { +// val nicknames = SparseArray() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// Nickname.NAME +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(Nickname.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val nickname = cursor.getStringValue(Nickname.NAME) ?: return@queryCursor +// nicknames.put(id, nickname) +// } +// +// return nicknames +// } +// +// private fun getEmails(contactId: Int? = null): SparseArray> { +// val emails = SparseArray>() +// val uri = CommonDataKinds.Email.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// CommonDataKinds.Email.DATA, +// CommonDataKinds.Email.TYPE, +// CommonDataKinds.Email.LABEL +// ) +// +// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val email = cursor.getStringValue(CommonDataKinds.Email.DATA) ?: return@queryCursor +// val type = cursor.getIntValue(CommonDataKinds.Email.TYPE) +// val label = cursor.getStringValue(CommonDataKinds.Email.LABEL) ?: "" +// +// if (emails[id] == null) { +// emails.put(id, ArrayList()) +// } +// +// emails[id]!!.add(Email(email, type, label)) +// } +// +// return emails +// } +// +// private fun getAddresses(contactId: Int? = null): SparseArray> { +// val addresses = SparseArray>() +// val uri = StructuredPostal.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// StructuredPostal.FORMATTED_ADDRESS, +// StructuredPostal.TYPE, +// StructuredPostal.LABEL +// ) +// +// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val address = cursor.getStringValue(StructuredPostal.FORMATTED_ADDRESS) ?: return@queryCursor +// val type = cursor.getIntValue(StructuredPostal.TYPE) +// val label = cursor.getStringValue(StructuredPostal.LABEL) ?: "" +// +// if (addresses[id] == null) { +// addresses.put(id, ArrayList()) +// } +// +// addresses[id]!!.add(Address(address, type, label)) +// } +// +// return addresses +// } +// +// private fun getIMs(contactId: Int? = null): SparseArray> { +// val IMs = SparseArray>() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// Im.DATA, +// Im.PROTOCOL, +// Im.CUSTOM_PROTOCOL +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(Im.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val IM = cursor.getStringValue(Im.DATA) ?: return@queryCursor +// val type = cursor.getIntValue(Im.PROTOCOL) +// val label = cursor.getStringValue(Im.CUSTOM_PROTOCOL) ?: "" +// +// if (IMs[id] == null) { +// IMs.put(id, ArrayList()) +// } +// +// IMs[id]!!.add(IM(IM, type, label)) +// } +// +// return IMs +// } +// +// private fun getEvents(contactId: Int? = null): SparseArray> { +// val events = SparseArray>() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// CommonDataKinds.Event.START_DATE, +// CommonDataKinds.Event.TYPE +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Event.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val startDate = cursor.getStringValue(CommonDataKinds.Event.START_DATE) ?: return@queryCursor +// val type = cursor.getIntValue(CommonDataKinds.Event.TYPE) +// +// if (events[id] == null) { +// events.put(id, ArrayList()) +// } +// +// events[id]!!.add(Event(startDate, type)) +// } +// +// return events +// } +// +// private fun getNotes(contactId: Int? = null): SparseArray { +// val notes = SparseArray() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// Note.NOTE +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(Note.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val note = cursor.getStringValue(Note.NOTE) ?: return@queryCursor +// notes.put(id, note) +// } +// +// return notes +// } +// +// private fun getOrganizations(contactId: Int? = null): SparseArray { +// val organizations = SparseArray() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// CommonDataKinds.Organization.COMPANY, +// CommonDataKinds.Organization.TITLE +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: "" +// val title = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: "" +// if (company.isEmpty() && title.isEmpty()) { +// return@queryCursor +// } +// +// val organization = Organization(company, title) +// organizations.put(id, organization) +// } +// +// return organizations +// } +// +// private fun getWebsites(contactId: Int? = null): SparseArray> { +// val websites = SparseArray>() +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.RAW_CONTACT_ID, +// Website.URL +// ) +// +// val selection = getSourcesSelection(true, contactId != null) +// val selectionArgs = getSourcesSelectionArgs(Website.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// val url = cursor.getStringValue(Website.URL) ?: return@queryCursor +// +// if (websites[id] == null) { +// websites.put(id, ArrayList()) +// } +// +// websites[id]!!.add(url) +// } +// +// return websites +// } +// +// private fun getContactGroups(storedGroups: ArrayList, contactId: Int? = null): SparseArray> { +// val groups = SparseArray>() +// if (!context.hasContactPermissions()) { +// return groups +// } +// +// val uri = Data.CONTENT_URI +// val projection = arrayOf( +// Data.CONTACT_ID, +// Data.DATA1 +// ) +// +// val selection = getSourcesSelection(true, contactId != null, false) +// val selectionArgs = getSourcesSelectionArgs(GroupMembership.CONTENT_ITEM_TYPE, contactId) +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getIntValue(Data.CONTACT_ID) +// val newRowId = cursor.getLongValue(Data.DATA1) +// +// val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: return@queryCursor +// val group = Group(newRowId, groupTitle) +// if (groups[id] == null) { +// groups.put(id, ArrayList()) +// } +// groups[id]!!.add(group) +// } +// +// return groups +// } +// +// private fun getQuestionMarks() = ("?," * displayContactSources.filter { it.isNotEmpty() }.size).trimEnd(',') +// +// private fun getSourcesSelection(addMimeType: Boolean = false, addContactId: Boolean = false, useRawContactId: Boolean = true): String { +// val strings = ArrayList() +// if (addMimeType) { +// strings.add("${Data.MIMETYPE} = ?") +// } +// +// if (addContactId) { +// strings.add("${if (useRawContactId) Data.RAW_CONTACT_ID else Data.CONTACT_ID} = ?") +// } else { +// // sometimes local device storage has null account_name, handle it properly +// val accountnameString = StringBuilder() +// if (displayContactSources.contains("")) { +// accountnameString.append("(") +// } +// accountnameString.append("${RawContacts.ACCOUNT_NAME} IN (${getQuestionMarks()})") +// if (displayContactSources.contains("")) { +// accountnameString.append(" OR ${RawContacts.ACCOUNT_NAME} IS NULL)") +// } +// strings.add(accountnameString.toString()) +// } +// +// return TextUtils.join(" AND ", strings) +// } +// +// private fun getSourcesSelectionArgs(mimetype: String? = null, contactId: Int? = null): Array { +// val args = ArrayList() +// +// if (mimetype != null) { +// args.add(mimetype) +// } +// +// if (contactId != null) { +// args.add(contactId.toString()) +// } else { +// args.addAll(displayContactSources.filter { it.isNotEmpty() }) +// } +// +// return args.toTypedArray() +// } +// +// fun getStoredGroups(callback: (ArrayList) -> Unit) { +// ensureBackgroundThread { +// val groups = getStoredGroupsSync() +// Handler(Looper.getMainLooper()).post { +// callback(groups) +// } +// } +// } +// +// fun getStoredGroupsSync(): ArrayList { +// val groups = getDeviceStoredGroups() +// groups.addAll(context.groupsDB.getGroups()) +// return groups +// } +// +// private fun getDeviceStoredGroups(): ArrayList { +// val groups = ArrayList() +// if (!context.hasContactPermissions()) { +// return groups +// } +// +// val uri = Groups.CONTENT_URI +// val projection = arrayOf( +// Groups._ID, +// Groups.TITLE, +// Groups.SYSTEM_ID +// ) +// +// val selection = "${Groups.AUTO_ADD} = ? AND ${Groups.FAVORITES} = ?" +// val selectionArgs = arrayOf("0", "0") +// +// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> +// val id = cursor.getLongValue(Groups._ID) +// val title = cursor.getStringValue(Groups.TITLE) ?: return@queryCursor +// +// val systemId = cursor.getStringValue(Groups.SYSTEM_ID) +// if (groups.map { it.title }.contains(title) && systemId != null) { +// return@queryCursor +// } +// +// groups.add(Group(id, title)) +// } +// return groups +// } +// +// fun createNewGroup(title: String, accountName: String, accountType: String): Group? { +// if (accountType == SMT_PRIVATE) { +// val newGroup = Group(null, title) +// val id = context.groupsDB.insertOrUpdate(newGroup) +// newGroup.id = id +// return newGroup +// } +// +// val operations = ArrayList() +// ContentProviderOperation.newInsert(Groups.CONTENT_URI).apply { +// withValue(Groups.TITLE, title) +// withValue(Groups.GROUP_VISIBLE, 1) +// withValue(Groups.ACCOUNT_NAME, accountName) +// withValue(Groups.ACCOUNT_TYPE, accountType) +// operations.add(build()) +// } +// +// try { +// val results = context.contentResolver.applyBatch(AUTHORITY, operations) +// val rawId = ContentUris.parseId(results[0].uri!!) +// return Group(rawId, title) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// return null +// } +// +// fun renameGroup(group: Group) { +// val operations = ArrayList() +// ContentProviderOperation.newUpdate(Groups.CONTENT_URI).apply { +// val selection = "${Groups._ID} = ?" +// val selectionArgs = arrayOf(group.id.toString()) +// withSelection(selection, selectionArgs) +// withValue(Groups.TITLE, group.title) +// operations.add(build()) +// } +// +// try { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// fun deleteGroup(id: Long) { +// val operations = ArrayList() +// val uri = ContentUris.withAppendedId(Groups.CONTENT_URI, id).buildUpon() +// .appendQueryParameter(CALLER_IS_SYNCADAPTER, "true") +// .build() +// +// operations.add(ContentProviderOperation.newDelete(uri).build()) +// +// try { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { +// if (id == 0) { +// return null +// } else if (isLocalPrivate) { +// return LocalContactsHelper(context).getContactWithId(id) +// } +// +// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) +// return parseContactCursor(selection, selectionArgs) +// } +// +// fun getContactWithLookupKey(key: String): Contact? { +// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.LOOKUP_KEY} = ?" +// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, key) +// return parseContactCursor(selection, selectionArgs) +// } +// +// private fun parseContactCursor(selection: String, selectionArgs: Array): Contact? { +// val storedGroups = getStoredGroupsSync() +// val uri = Data.CONTENT_URI +// val projection = getContactProjection() +// +// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) +// cursor?.use { +// if (cursor.moveToFirst()) { +// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) +// +// var prefix = "" +// var firstName = "" +// var middleName = "" +// var surname = "" +// var suffix = "" +// var mimetype = cursor.getStringValue(Data.MIMETYPE) +// +// // if first line is an Organization type contact, go to next line +// if (mimetype != StructuredName.CONTENT_ITEM_TYPE) { +// if (cursor.moveToNext()) { +// mimetype = cursor.getStringValue(Data.MIMETYPE) +// } +// } +// // ignore names at Organization type contacts +// if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { +// prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" +// firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" +// middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" +// surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" +// suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" +// } +// +// val nickname = getNicknames(id)[id] ?: "" +// val photoUri = cursor.getStringValueOrNull(Phone.PHOTO_URI) ?: "" +// val number = getPhoneNumbers(id)[id] ?: ArrayList() +// val emails = getEmails(id)[id] ?: ArrayList() +// val addresses = getAddresses(id)[id] ?: ArrayList() +// val events = getEvents(id)[id] ?: ArrayList() +// val notes = getNotes(id)[id] ?: "" +// val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" +// val starred = cursor.getIntValue(StructuredName.STARRED) +// val ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) +// val contactId = cursor.getIntValue(Data.CONTACT_ID) +// val groups = getContactGroups(storedGroups, contactId)[contactId] ?: ArrayList() +// val thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" +// val organization = getOrganizations(id)[id] ?: Organization("", "") +// val websites = getWebsites(id)[id] ?: ArrayList() +// val ims = getIMs(id)[id] ?: ArrayList() +// return Contact( +// id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events, +// accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone +// ) +// } +// } +// +// return null +// } +// +// fun getContactSources(callback: (ArrayList) -> Unit) { +// ensureBackgroundThread { +// callback(getContactSourcesSync()) +// } +// } +// +// private fun getContactSourcesSync(): ArrayList { +// val sources = getDeviceContactSources() +// sources.add(context.getPrivateContactSource()) +// return ArrayList(sources) +// } +// +// fun getSaveableContactSources(callback: (ArrayList) -> Unit) { +// ensureBackgroundThread { +// val ignoredTypes = arrayListOf( +// SIGNAL_PACKAGE, +// TELEGRAM_PACKAGE, +// WHATSAPP_PACKAGE, +// THREEMA_PACKAGE +// ) +// +// val contactSources = getContactSourcesSync() +// val filteredSources = contactSources.filter { !ignoredTypes.contains(it.type) }.toMutableList() as ArrayList +// callback(filteredSources) +// } +// } +// +// fun getDeviceContactSources(): LinkedHashSet { +// val sources = LinkedHashSet() +// if (!context.hasContactPermissions()) { +// return sources +// } +// +// if (!context.config.wasLocalAccountInitialized) { +// initializeLocalPhoneAccount() +// context.config.wasLocalAccountInitialized = true +// } +// +// val accounts = AccountManager.get(context).accounts +// accounts.forEach { +// if (ContentResolver.getIsSyncable(it, AUTHORITY) == 1) { +// var publicName = it.name +// if (it.type == TELEGRAM_PACKAGE) { +// publicName = context.getString(R.string.telegram) +// } else if (it.type == VIBER_PACKAGE) { +// publicName = context.getString(R.string.viber) +// } +// val contactSource = ContactSource(it.name, it.type, publicName) +// sources.add(contactSource) +// } +// } +// +// var hadEmptyAccount = false +// val allAccounts = getContentResolverAccounts() +// val contentResolverAccounts = allAccounts.filter { +// if (it.name.isEmpty() && it.type.isEmpty() && allAccounts.none { it.name.lowercase(Locale.getDefault()) == "phone" }) { +// hadEmptyAccount = true +// } +// +// it.name.isNotEmpty() && it.type.isNotEmpty() && !accounts.contains(Account(it.name, it.type)) +// } +// sources.addAll(contentResolverAccounts) +// +// if (hadEmptyAccount) { +// sources.add(ContactSource("", "", context.getString(R.string.phone_storage))) +// } +// +// return sources +// } +// +// // make sure the local Phone contact source is initialized and available +// // https://stackoverflow.com/a/6096508/1967672 +// private fun initializeLocalPhoneAccount() { +// try { +// val operations = ArrayList() +// ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { +// withValue(RawContacts.ACCOUNT_NAME, null) +// withValue(RawContacts.ACCOUNT_TYPE, null) +// operations.add(build()) +// } +// +// val results = context.contentResolver.applyBatch(AUTHORITY, operations) +// val rawContactUri = results.firstOrNull()?.uri ?: return +// context.contentResolver.delete(rawContactUri, null, null) +// } catch (ignored: Exception) { +// } +// } +// +// private fun getContactSourceType(accountName: String) = getDeviceContactSources().firstOrNull { it.name == accountName }?.type ?: "" +// +// private fun getContactProjection() = arrayOf( +// Data.MIMETYPE, +// Data.CONTACT_ID, +// Data.RAW_CONTACT_ID, +// StructuredName.PREFIX, +// StructuredName.GIVEN_NAME, +// StructuredName.MIDDLE_NAME, +// StructuredName.FAMILY_NAME, +// StructuredName.SUFFIX, +// StructuredName.PHOTO_URI, +// StructuredName.PHOTO_THUMBNAIL_URI, +// StructuredName.STARRED, +// StructuredName.CUSTOM_RINGTONE, +// RawContacts.ACCOUNT_NAME, +// RawContacts.ACCOUNT_TYPE +// ) +// +// private fun getSortString(): String { +// val sorting = context.config.sorting +// return when { +// sorting and SORT_BY_FIRST_NAME != 0 -> "${StructuredName.GIVEN_NAME} COLLATE NOCASE" +// sorting and SORT_BY_MIDDLE_NAME != 0 -> "${StructuredName.MIDDLE_NAME} COLLATE NOCASE" +// sorting and SORT_BY_SURNAME != 0 -> "${StructuredName.FAMILY_NAME} COLLATE NOCASE" +// sorting and SORT_BY_FULL_NAME != 0 -> StructuredName.DISPLAY_NAME +// else -> Data.RAW_CONTACT_ID +// } +// } +// +// private fun getRealContactId(id: Long): Int { +// val uri = Data.CONTENT_URI +// val projection = getContactProjection() +// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) +// +// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) +// cursor?.use { +// if (cursor.moveToFirst()) { +// return cursor.getIntValue(Data.CONTACT_ID) +// } +// } +// +// return 0 +// } +// +// fun updateContact(contact: Contact, photoUpdateStatus: Int): Boolean { +// context.toast(R.string.updating) +// if (contact.isPrivate()) { +// return LocalContactsHelper(context).insertOrUpdateContact(contact) +// } +// +// try { +// val operations = ArrayList() +// ContentProviderOperation.newUpdate(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" +// val selectionArgs = arrayOf(contact.id.toString(), contact.mimetype) +// withSelection(selection, selectionArgs) +// withValue(StructuredName.PREFIX, contact.prefix) +// withValue(StructuredName.GIVEN_NAME, contact.firstName) +// withValue(StructuredName.MIDDLE_NAME, contact.middleName) +// withValue(StructuredName.FAMILY_NAME, contact.surname) +// withValue(StructuredName.SUFFIX, contact.suffix) +// operations.add(build()) +// } +// +// // delete nickname +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), Nickname.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add nickname +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) +// withValue(Nickname.NAME, contact.nickname) +// operations.add(build()) +// } +// +// // delete phone numbers +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), Phone.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add phone numbers +// contact.phoneNumbers.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) +// withValue(Phone.NUMBER, it.value) +// withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) +// withValue(Phone.TYPE, it.type) +// withValue(Phone.LABEL, it.label) +// withValue(Phone.IS_PRIMARY, it.isPrimary) +// operations.add(build()) +// } +// } +// +// // delete emails +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Email.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add emails +// contact.emails.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Email.DATA, it.value) +// withValue(CommonDataKinds.Email.TYPE, it.type) +// withValue(CommonDataKinds.Email.LABEL, it.label) +// operations.add(build()) +// } +// } +// +// // delete addresses +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), StructuredPostal.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add addresses +// contact.addresses.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) +// withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) +// withValue(StructuredPostal.TYPE, it.type) +// withValue(StructuredPostal.LABEL, it.label) +// operations.add(build()) +// } +// } +// +// // delete IMs +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), Im.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add IMs +// contact.IMs.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) +// withValue(Im.DATA, it.value) +// withValue(Im.PROTOCOL, it.type) +// withValue(Im.CUSTOM_PROTOCOL, it.label) +// operations.add(build()) +// } +// } +// +// // delete events +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Event.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add events +// contact.events.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Event.START_DATE, it.value) +// withValue(CommonDataKinds.Event.TYPE, it.type) +// operations.add(build()) +// } +// } +// +// // delete notes +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), Note.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add notes +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) +// withValue(Note.NOTE, contact.notes) +// operations.add(build()) +// } +// +// // delete organization +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Organization.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add organization +// if (contact.organization.isNotEmpty()) { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) +// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) +// withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) +// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) +// operations.add(build()) +// } +// } +// +// // delete websites +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " +// val selectionArgs = arrayOf(contact.id.toString(), Website.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// // add websites +// contact.websites.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) +// withValue(Website.URL, it) +// withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) +// operations.add(build()) +// } +// } +// +// // delete groups +// val relevantGroupIDs = getStoredGroupsSync().map { it.id } +// if (relevantGroupIDs.isNotEmpty()) { +// val IDsString = TextUtils.join(",", relevantGroupIDs) +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} IN ($IDsString)" +// val selectionArgs = arrayOf(contact.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// } +// +// // add groups +// contact.groups.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) +// withValue(GroupMembership.GROUP_ROW_ID, it.id) +// operations.add(build()) +// } +// } +// +// // favorite, ringtone +// try { +// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contact.contactId.toString()) +// val contentValues = ContentValues(2) +// contentValues.put(Contacts.STARRED, contact.starred) +// contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) +// context.contentResolver.update(uri, contentValues, null, null) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// +// // photo +// when (photoUpdateStatus) { +// PHOTO_ADDED, PHOTO_CHANGED -> addPhoto(contact, operations) +// PHOTO_REMOVED -> removePhoto(contact, operations) +// } +// +// context.contentResolver.applyBatch(AUTHORITY, operations) +// return true +// } catch (e: Exception) { +// context.showErrorToast(e) +// return false +// } +// } +// +// private fun addPhoto(contact: Contact, operations: ArrayList): ArrayList { +// if (contact.photoUri.isNotEmpty()) { +// val photoUri = Uri.parse(contact.photoUri) +// val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) +// +// val thumbnailSize = context.getPhotoThumbnailSize() +// val scaledPhoto = Bitmap.createScaledBitmap(bitmap, thumbnailSize, thumbnailSize, false) +// val scaledSizePhotoData = scaledPhoto.getByteArray() +// scaledPhoto.recycle() +// +// val fullSizePhotoData = bitmap.getByteArray() +// bitmap.recycle() +// +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, contact.id) +// withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE) +// withValue(Photo.PHOTO, scaledSizePhotoData) +// operations.add(build()) +// } +// +// addFullSizePhoto(contact.id.toLong(), fullSizePhotoData) +// } +// return operations +// } +// +// private fun removePhoto(contact: Contact, operations: ArrayList): ArrayList { +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" +// val selectionArgs = arrayOf(contact.id.toString(), Photo.CONTENT_ITEM_TYPE) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// return operations +// } +// +// fun addContactsToGroup(contacts: ArrayList, groupId: Long) { +// try { +// val operations = ArrayList() +// contacts.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValue(Data.RAW_CONTACT_ID, it.id) +// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) +// withValue(GroupMembership.GROUP_ROW_ID, groupId) +// operations.add(build()) +// } +// +// if (operations.size % BATCH_SIZE == 0) { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// operations.clear() +// } +// } +// +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { +// try { +// val operations = ArrayList() +// contacts.forEach { +// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { +// val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} = ?" +// val selectionArgs = arrayOf(it.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE, groupId.toString()) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// if (operations.size % BATCH_SIZE == 0) { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// operations.clear() +// } +// } +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// fun insertContact(contact: Contact): Boolean { +// if (contact.isPrivate()) { +// return LocalContactsHelper(context).insertOrUpdateContact(contact) +// } +// +// try { +// val operations = ArrayList() +// ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { +// withValue(RawContacts.ACCOUNT_NAME, contact.source) +// withValue(RawContacts.ACCOUNT_TYPE, getContactSourceType(contact.source)) +// operations.add(build()) +// } +// +// // names +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) +// withValue(StructuredName.PREFIX, contact.prefix) +// withValue(StructuredName.GIVEN_NAME, contact.firstName) +// withValue(StructuredName.MIDDLE_NAME, contact.middleName) +// withValue(StructuredName.FAMILY_NAME, contact.surname) +// withValue(StructuredName.SUFFIX, contact.suffix) +// operations.add(build()) +// } +// +// // nickname +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) +// withValue(Nickname.NAME, contact.nickname) +// operations.add(build()) +// } +// +// // phone numbers +// contact.phoneNumbers.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) +// withValue(Phone.NUMBER, it.value) +// withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) +// withValue(Phone.TYPE, it.type) +// withValue(Phone.LABEL, it.label) +// withValue(Phone.IS_PRIMARY, it.isPrimary) +// operations.add(build()) +// } +// } +// +// // emails +// contact.emails.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Email.DATA, it.value) +// withValue(CommonDataKinds.Email.TYPE, it.type) +// withValue(CommonDataKinds.Email.LABEL, it.label) +// operations.add(build()) +// } +// } +// +// // addresses +// contact.addresses.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) +// withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) +// withValue(StructuredPostal.TYPE, it.type) +// withValue(StructuredPostal.LABEL, it.label) +// operations.add(build()) +// } +// } +// +// // IMs +// contact.IMs.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) +// withValue(Im.DATA, it.value) +// withValue(Im.PROTOCOL, it.type) +// withValue(Im.CUSTOM_PROTOCOL, it.label) +// operations.add(build()) +// } +// } +// +// // events +// contact.events.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Event.START_DATE, it.value) +// withValue(CommonDataKinds.Event.TYPE, it.type) +// operations.add(build()) +// } +// } +// +// // notes +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) +// withValue(Note.NOTE, contact.notes) +// operations.add(build()) +// } +// +// // organization +// if (contact.organization.isNotEmpty()) { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) +// withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) +// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) +// withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) +// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) +// operations.add(build()) +// } +// } +// +// // websites +// contact.websites.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) +// withValue(Website.URL, it) +// withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) +// operations.add(build()) +// } +// } +// +// // groups +// contact.groups.forEach { +// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { +// withValueBackReference(Data.RAW_CONTACT_ID, 0) +// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) +// withValue(GroupMembership.GROUP_ROW_ID, it.id) +// operations.add(build()) +// } +// } +// +// // photo (inspired by https://gist.github.com/slightfoot/5985900) +// var fullSizePhotoData: ByteArray? = null +// if (contact.photoUri.isNotEmpty()) { +// val photoUri = Uri.parse(contact.photoUri) +// fullSizePhotoData = context.contentResolver.openInputStream(photoUri)?.readBytes() +// } +// +// val results = context.contentResolver.applyBatch(AUTHORITY, operations) +// +// // storing contacts on some devices seems to be messed up and they move on Phone instead, or disappear completely +// // try storing a lighter contact version with this oldschool version too just so it wont disappear, future edits work well +// if (getContactSourceType(contact.source).contains(".sim")) { +// val simUri = Uri.parse("content://icc/adn") +// ContentValues().apply { +// put("number", contact.phoneNumbers.firstOrNull()?.value ?: "") +// put("tag", contact.getNameToDisplay()) +// context.contentResolver.insert(simUri, this) +// } +// } +// +// // fullsize photo +// val rawId = ContentUris.parseId(results[0].uri!!) +// if (contact.photoUri.isNotEmpty() && fullSizePhotoData != null) { +// addFullSizePhoto(rawId, fullSizePhotoData) +// } +// +// // favorite, ringtone +// val userId = getRealContactId(rawId) +// if (userId != 0) { +// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, userId.toString()) +// val contentValues = ContentValues(2) +// contentValues.put(Contacts.STARRED, contact.starred) +// contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) +// context.contentResolver.update(uri, contentValues, null, null) +// } +// +// return true +// } catch (e: Exception) { +// context.showErrorToast(e) +// return false +// } +// } +// +// private fun addFullSizePhoto(contactId: Long, fullSizePhotoData: ByteArray) { +// val baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, contactId) +// val displayPhotoUri = Uri.withAppendedPath(baseUri, RawContacts.DisplayPhoto.CONTENT_DIRECTORY) +// val fileDescriptor = context.contentResolver.openAssetFileDescriptor(displayPhotoUri, "rw") +// val photoStream = fileDescriptor!!.createOutputStream() +// photoStream.write(fullSizePhotoData) +// photoStream.close() +// fileDescriptor.close() +// } +// +// fun getContactMimeTypeId(contactId: String, mimeType: String): String { +// val uri = Data.CONTENT_URI +// val projection = arrayOf(Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE) +// val selection = "${Data.MIMETYPE} = ? AND ${Data.RAW_CONTACT_ID} = ?" +// val selectionArgs = arrayOf(mimeType, contactId) +// +// +// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) +// cursor?.use { +// if (cursor.moveToFirst()) { +// return cursor.getStringValue(Data._ID) +// } +// } +// return "" +// } +// +// fun addFavorites(contacts: ArrayList) { +// ensureBackgroundThread { +// toggleLocalFavorites(contacts, true) +// if (context.hasContactPermissions()) { +// toggleFavorites(contacts, true) +// } +// } +// } +// +// fun removeFavorites(contacts: ArrayList) { +// ensureBackgroundThread { +// toggleLocalFavorites(contacts, false) +// if (context.hasContactPermissions()) { +// toggleFavorites(contacts, false) +// } +// } +// } +// +// private fun toggleFavorites(contacts: ArrayList, addToFavorites: Boolean) { +// try { +// val operations = ArrayList() +// contacts.filter { !it.isPrivate() }.map { it.contactId.toString() }.forEach { +// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, it) +// ContentProviderOperation.newUpdate(uri).apply { +// withValue(Contacts.STARRED, if (addToFavorites) 1 else 0) +// operations.add(build()) +// } +// +// if (operations.size % BATCH_SIZE == 0) { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// operations.clear() +// } +// } +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// private fun toggleLocalFavorites(contacts: ArrayList, addToFavorites: Boolean) { +// val localContacts = contacts.filter { it.isPrivate() }.map { it.id }.toTypedArray() +// LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites) +// } +// +// fun updateRingtone(contactId: String, newUri: String) { +// try { +// val operations = ArrayList() +// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contactId) +// ContentProviderOperation.newUpdate(uri).apply { +// withValue(Contacts.CUSTOM_RINGTONE, newUri) +// operations.add(build()) +// } +// +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } catch (e: Exception) { +// context.showErrorToast(e) +// } +// } +// +// fun deleteContact(originalContact: Contact, deleteClones: Boolean = false, callback: (success: Boolean) -> Unit) { +// ensureBackgroundThread { +// if (deleteClones) { +// getDuplicatesOfContact(originalContact, true) { contacts -> +// ensureBackgroundThread { +// if (deleteContacts(contacts)) { +// callback(true) +// } +// } +// } +// } else { +// if (deleteContacts(arrayListOf(originalContact))) { +// callback(true) +// } +// } +// } +// } +// +// fun deleteContacts(contacts: ArrayList): Boolean { +// val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList() +// LocalContactsHelper(context).deleteContactIds(localContacts) +// +// return try { +// val operations = ArrayList() +// val selection = "${RawContacts._ID} = ?" +// contacts.filter { !it.isPrivate() }.forEach { +// ContentProviderOperation.newDelete(RawContacts.CONTENT_URI).apply { +// val selectionArgs = arrayOf(it.id.toString()) +// withSelection(selection, selectionArgs) +// operations.add(build()) +// } +// +// if (operations.size % BATCH_SIZE == 0) { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// operations.clear() +// } +// } +// +// if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) { +// context.contentResolver.applyBatch(AUTHORITY, operations) +// } +// true +// } catch (e: Exception) { +// context.showErrorToast(e) +// false +// } +// } +// +// fun getDuplicatesOfContact(contact: Contact, addOriginal: Boolean, callback: (ArrayList) -> Unit) { +// ensureBackgroundThread { +// getContacts(true, 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/Converters.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt index ee8aa14c..9cc2462c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt @@ -1,76 +1,76 @@ -package com.simplemobiletools.contacts.pro.helpers - -import androidx.room.TypeConverter -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken -import com.simplemobiletools.commons.models.PhoneNumber -import com.simplemobiletools.contacts.pro.models.* - -class Converters { - private val gson = Gson() - private val longType = object : TypeToken>() {}.type - private val stringType = object : TypeToken>() {}.type - private val numberType = object : TypeToken>() {}.type - private val numberConverterType = object : TypeToken>() {}.type - private val emailType = object : TypeToken>() {}.type - private val addressType = object : TypeToken>() {}.type - private val eventType = object : TypeToken>() {}.type - private val imType = object : TypeToken>() {}.type - - @TypeConverter - fun jsonToStringList(value: String) = gson.fromJson>(value, stringType) - - @TypeConverter - fun stringListToJson(list: ArrayList) = gson.toJson(list) - - @TypeConverter - fun jsonToLongList(value: String) = gson.fromJson>(value, longType) - - @TypeConverter - fun longListToJson(list: ArrayList) = gson.toJson(list) - - // some hacky converting is needed since PhoneNumber model has been added to proguard rules, but obfuscated json was stored in database - // convert [{"a":"678910","b":2,"c":"","d":"678910","e":false}] to PhoneNumber(value=678910, type=2, label=, normalizedNumber=678910, isPrimary=false) - @TypeConverter - fun jsonToPhoneNumberList(value: String): ArrayList { - val numbers = gson.fromJson>(value, numberType) - return if (numbers.any { it.value == null }) { - val phoneNumbers = ArrayList() - val numberConverters = gson.fromJson>(value, numberConverterType) - numberConverters.forEach { converter -> - val phoneNumber = PhoneNumber(converter.a, converter.b, converter.c, converter.d, converter.e) - phoneNumbers.add(phoneNumber) - } - phoneNumbers - } else { - numbers - } - } - - @TypeConverter - fun phoneNumberListToJson(list: ArrayList) = gson.toJson(list) - - @TypeConverter - fun jsonToEmailList(value: String) = gson.fromJson>(value, emailType) - - @TypeConverter - fun emailListToJson(list: ArrayList) = gson.toJson(list) - - @TypeConverter - fun jsonToAddressList(value: String) = gson.fromJson>(value, addressType) - - @TypeConverter - fun addressListToJson(list: ArrayList
) = gson.toJson(list) - - @TypeConverter - fun jsonToEventList(value: String) = gson.fromJson>(value, eventType) - - @TypeConverter - fun eventListToJson(list: ArrayList) = gson.toJson(list) - - @TypeConverter - fun jsonToIMsList(value: String) = gson.fromJson>(value, imType) - - @TypeConverter - fun IMsListToJson(list: ArrayList) = gson.toJson(list) -} +//package com.simplemobiletools.contacts.pro.helpers +// +//import androidx.room.TypeConverter +//import com.google.gson.Gson +//import com.google.gson.reflect.TypeToken +//import com.simplemobiletools.commons.models.PhoneNumber +//import com.simplemobiletools.contacts.pro.models.* +// +//class Converters { +// private val gson = Gson() +// private val longType = object : TypeToken>() {}.type +// private val stringType = object : TypeToken>() {}.type +// private val numberType = object : TypeToken>() {}.type +// private val numberConverterType = object : TypeToken>() {}.type +// private val emailType = object : TypeToken>() {}.type +// private val addressType = object : TypeToken>() {}.type +// private val eventType = object : TypeToken>() {}.type +// private val imType = object : TypeToken>() {}.type +// +// @TypeConverter +// fun jsonToStringList(value: String) = gson.fromJson>(value, stringType) +// +// @TypeConverter +// fun stringListToJson(list: ArrayList) = gson.toJson(list) +// +// @TypeConverter +// fun jsonToLongList(value: String) = gson.fromJson>(value, longType) +// +// @TypeConverter +// fun longListToJson(list: ArrayList) = gson.toJson(list) +// +// // some hacky converting is needed since PhoneNumber model has been added to proguard rules, but obfuscated json was stored in database +// // convert [{"a":"678910","b":2,"c":"","d":"678910","e":false}] to PhoneNumber(value=678910, type=2, label=, normalizedNumber=678910, isPrimary=false) +// @TypeConverter +// fun jsonToPhoneNumberList(value: String): ArrayList { +// val numbers = gson.fromJson>(value, numberType) +// return if (numbers.any { it.value == null }) { +// val phoneNumbers = ArrayList() +// val numberConverters = gson.fromJson>(value, numberConverterType) +// numberConverters.forEach { converter -> +// val phoneNumber = PhoneNumber(converter.a, converter.b, converter.c, converter.d, converter.e) +// phoneNumbers.add(phoneNumber) +// } +// phoneNumbers +// } else { +// numbers +// } +// } +// +// @TypeConverter +// fun phoneNumberListToJson(list: ArrayList) = gson.toJson(list) +// +// @TypeConverter +// fun jsonToEmailList(value: String) = gson.fromJson>(value, emailType) +// +// @TypeConverter +// fun emailListToJson(list: ArrayList) = gson.toJson(list) +// +// @TypeConverter +// fun jsonToAddressList(value: String) = gson.fromJson>(value, addressType) +// +// @TypeConverter +// fun addressListToJson(list: ArrayList
) = gson.toJson(list) +// +// @TypeConverter +// fun jsonToEventList(value: String) = gson.fromJson>(value, eventType) +// +// @TypeConverter +// fun eventListToJson(list: ArrayList) = gson.toJson(list) +// +// @TypeConverter +// fun jsonToIMsList(value: String) = gson.fromJson>(value, imType) +// +// @TypeConverter +// fun IMsListToJson(list: ArrayList) = gson.toJson(list) +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt index de3b760e..b56db7ea 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt @@ -1,173 +1,173 @@ -package com.simplemobiletools.contacts.pro.helpers - -import android.content.Context -import android.graphics.BitmapFactory -import android.net.Uri -import android.provider.ContactsContract.CommonDataKinds.Event -import android.provider.MediaStore -import com.simplemobiletools.commons.extensions.getByteArray -import com.simplemobiletools.commons.helpers.SMT_PRIVATE -import com.simplemobiletools.commons.models.SimpleContact -import com.simplemobiletools.contacts.pro.extensions.contactsDB -import com.simplemobiletools.contacts.pro.extensions.getEmptyContact -import com.simplemobiletools.contacts.pro.models.Contact -import com.simplemobiletools.contacts.pro.models.Group -import com.simplemobiletools.contacts.pro.models.LocalContact -import com.simplemobiletools.contacts.pro.models.Organization - -class LocalContactsHelper(val context: Context) { - fun getAllContacts(favoritesOnly: Boolean = false): ArrayList { - val contacts = if (favoritesOnly) context.contactsDB.getFavoriteContacts() else context.contactsDB.getContacts() - val storedGroups = ContactsHelper(context).getStoredGroupsSync() - return contacts.map { convertLocalContactToContact(it, storedGroups) }.toMutableList() as ArrayList - } - - fun getContactWithId(id: Int): Contact? { - val storedGroups = ContactsHelper(context).getStoredGroupsSync() - return convertLocalContactToContact(context.contactsDB.getContactWithId(id), storedGroups) - } - - fun insertOrUpdateContact(contact: Contact): Boolean { - val localContact = convertContactToLocalContact(contact) - return context.contactsDB.insertOrUpdate(localContact) > 0 - } - - fun addContactsToGroup(contacts: ArrayList, groupId: Long) { - contacts.forEach { - val localContact = convertContactToLocalContact(it) - val newGroups = localContact.groups - newGroups.add(groupId) - newGroups.distinct() - localContact.groups = newGroups - context.contactsDB.insertOrUpdate(localContact) - } - } - - fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { - contacts.forEach { - val localContact = convertContactToLocalContact(it) - val newGroups = localContact.groups - newGroups.remove(groupId) - localContact.groups = newGroups - context.contactsDB.insertOrUpdate(localContact) - } - } - - fun deleteContactIds(ids: MutableList) { - ids.chunked(30).forEach { - context.contactsDB.deleteContactIds(it) - } - } - - fun toggleFavorites(ids: Array, addToFavorites: Boolean) { - val isStarred = if (addToFavorites) 1 else 0 - ids.forEach { - context.contactsDB.updateStarred(isStarred, it) - } - } - - fun updateRingtone(id: Int, ringtone: String) { - context.contactsDB.updateRingtone(ringtone, id) - } - - private fun getPhotoByteArray(uri: String): ByteArray { - if (uri.isEmpty()) { - return ByteArray(0) - } - - val photoUri = Uri.parse(uri) - val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) - - val fullSizePhotoData = bitmap.getByteArray() - bitmap.recycle() - - return fullSizePhotoData - } - - private fun convertLocalContactToContact(localContact: LocalContact?, storedGroups: ArrayList): Contact? { - if (localContact == null) { - return null - } - - val contactPhoto = if (localContact.photo == null) { - null - } else { - try { - BitmapFactory.decodeByteArray(localContact.photo, 0, localContact.photo!!.size) - } catch (e: OutOfMemoryError) { - null - } - } - - return context.getEmptyContact().apply { - id = localContact.id!! - prefix = localContact.prefix - firstName = localContact.firstName - middleName = localContact.middleName - surname = localContact.surname - suffix = localContact.suffix - nickname = localContact.nickname - phoneNumbers = localContact.phoneNumbers - emails = localContact.emails - addresses = localContact.addresses - events = localContact.events - source = SMT_PRIVATE - starred = localContact.starred - contactId = localContact.id!! - thumbnailUri = "" - photo = contactPhoto - photoUri = localContact.photoUri - notes = localContact.notes - groups = storedGroups.filter { localContact.groups.contains(it.id) } as ArrayList - organization = Organization(localContact.company, localContact.jobPosition) - websites = localContact.websites - IMs = localContact.IMs - ringtone = localContact.ringtone - } - } - - private fun convertContactToLocalContact(contact: Contact): LocalContact { - val photoByteArray = if (contact.photoUri.isNotEmpty()) { - getPhotoByteArray(contact.photoUri) - } else { - contact.photo?.getByteArray() - } - - return getEmptyLocalContact().apply { - id = if (contact.id <= FIRST_CONTACT_ID) null else contact.id - prefix = contact.prefix - firstName = contact.firstName - middleName = contact.middleName - surname = contact.surname - suffix = contact.suffix - nickname = contact.nickname - photo = photoByteArray - phoneNumbers = contact.phoneNumbers - emails = contact.emails - events = contact.events - starred = contact.starred - addresses = contact.addresses - notes = contact.notes - groups = contact.groups.map { it.id }.toMutableList() as ArrayList - company = contact.organization.company - jobPosition = contact.organization.jobPosition - websites = contact.websites - IMs = contact.IMs - ringtone = contact.ringtone - } - } - - private fun convertContactToSimpleContact(contact: Contact?, withPhoneNumbersOnly: Boolean): SimpleContact? { - return if (contact == null || (withPhoneNumbersOnly && contact.phoneNumbers.isEmpty())) { - null - } else { - val birthdays = contact.events.filter { it.type == Event.TYPE_BIRTHDAY }.map { it.value }.toMutableList() as ArrayList - val anniversaries = contact.events.filter { it.type == Event.TYPE_ANNIVERSARY }.map { it.value }.toMutableList() as ArrayList - SimpleContact(contact.id, contact.id, contact.getNameToDisplay(), contact.photoUri, contact.phoneNumbers, birthdays, anniversaries) - } - } - - fun getPrivateSimpleContactsSync(favoritesOnly: Boolean, withPhoneNumbersOnly: Boolean) = getAllContacts(favoritesOnly).mapNotNull { - convertContactToSimpleContact(it, withPhoneNumbersOnly) - } -} +//package com.simplemobiletools.contacts.pro.helpers +// +//import android.content.Context +//import android.graphics.BitmapFactory +//import android.net.Uri +//import android.provider.ContactsContract.CommonDataKinds.Event +//import android.provider.MediaStore +//import com.simplemobiletools.commons.extensions.getByteArray +//import com.simplemobiletools.commons.helpers.SMT_PRIVATE +//import com.simplemobiletools.commons.models.SimpleContact +//import com.simplemobiletools.contacts.pro.extensions.contactsDB +//import com.simplemobiletools.contacts.pro.extensions.getEmptyContact +//import com.simplemobiletools.commons.models.contacts.* +//import com.simplemobiletools.contacts.pro.models.Group +//import com.simplemobiletools.contacts.pro.models.LocalContact +//import com.simplemobiletools.contacts.pro.models.Organization +// +//class LocalContactsHelper(val context: Context) { +// fun getAllContacts(favoritesOnly: Boolean = false): ArrayList { +// val contacts = if (favoritesOnly) context.contactsDB.getFavoriteContacts() else context.contactsDB.getContacts() +// val storedGroups = ContactsHelper(context).getStoredGroupsSync() +// return contacts.map { convertLocalContactToContact(it, storedGroups) }.toMutableList() as ArrayList +// } +// +// fun getContactWithId(id: Int): Contact? { +// val storedGroups = ContactsHelper(context).getStoredGroupsSync() +// return convertLocalContactToContact(context.contactsDB.getContactWithId(id), storedGroups) +// } +// +// fun insertOrUpdateContact(contact: Contact): Boolean { +// val localContact = convertContactToLocalContact(contact) +// return context.contactsDB.insertOrUpdate(localContact) > 0 +// } +// +// fun addContactsToGroup(contacts: ArrayList, groupId: Long) { +// contacts.forEach { +// val localContact = convertContactToLocalContact(it) +// val newGroups = localContact.groups +// newGroups.add(groupId) +// newGroups.distinct() +// localContact.groups = newGroups +// context.contactsDB.insertOrUpdate(localContact) +// } +// } +// +// fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { +// contacts.forEach { +// val localContact = convertContactToLocalContact(it) +// val newGroups = localContact.groups +// newGroups.remove(groupId) +// localContact.groups = newGroups +// context.contactsDB.insertOrUpdate(localContact) +// } +// } +// +// fun deleteContactIds(ids: MutableList) { +// ids.chunked(30).forEach { +// context.contactsDB.deleteContactIds(it) +// } +// } +// +// fun toggleFavorites(ids: Array, addToFavorites: Boolean) { +// val isStarred = if (addToFavorites) 1 else 0 +// ids.forEach { +// context.contactsDB.updateStarred(isStarred, it) +// } +// } +// +// fun updateRingtone(id: Int, ringtone: String) { +// context.contactsDB.updateRingtone(ringtone, id) +// } +// +// private fun getPhotoByteArray(uri: String): ByteArray { +// if (uri.isEmpty()) { +// return ByteArray(0) +// } +// +// val photoUri = Uri.parse(uri) +// val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) +// +// val fullSizePhotoData = bitmap.getByteArray() +// bitmap.recycle() +// +// return fullSizePhotoData +// } +// +// private fun convertLocalContactToContact(localContact: LocalContact?, storedGroups: ArrayList): Contact? { +// if (localContact == null) { +// return null +// } +// +// val contactPhoto = if (localContact.photo == null) { +// null +// } else { +// try { +// BitmapFactory.decodeByteArray(localContact.photo, 0, localContact.photo!!.size) +// } catch (e: OutOfMemoryError) { +// null +// } +// } +// +// return context.getEmptyContact().apply { +// id = localContact.id!! +// prefix = localContact.prefix +// firstName = localContact.firstName +// middleName = localContact.middleName +// surname = localContact.surname +// suffix = localContact.suffix +// nickname = localContact.nickname +// phoneNumbers = localContact.phoneNumbers +// emails = localContact.emails +// addresses = localContact.addresses +// events = localContact.events +// source = SMT_PRIVATE +// starred = localContact.starred +// contactId = localContact.id!! +// thumbnailUri = "" +// photo = contactPhoto +// photoUri = localContact.photoUri +// notes = localContact.notes +// groups = storedGroups.filter { localContact.groups.contains(it.id) } as ArrayList +// organization = Organization(localContact.company, localContact.jobPosition) +// websites = localContact.websites +// IMs = localContact.IMs +// ringtone = localContact.ringtone +// } +// } +// +// private fun convertContactToLocalContact(contact: Contact): LocalContact { +// val photoByteArray = if (contact.photoUri.isNotEmpty()) { +// getPhotoByteArray(contact.photoUri) +// } else { +// contact.photo?.getByteArray() +// } +// +// return getEmptyLocalContact().apply { +// id = if (contact.id <= FIRST_CONTACT_ID) null else contact.id +// prefix = contact.prefix +// firstName = contact.firstName +// middleName = contact.middleName +// surname = contact.surname +// suffix = contact.suffix +// nickname = contact.nickname +// photo = photoByteArray +// phoneNumbers = contact.phoneNumbers +// emails = contact.emails +// events = contact.events +// starred = contact.starred +// addresses = contact.addresses +// notes = contact.notes +// groups = contact.groups.map { it.id }.toMutableList() as ArrayList +// company = contact.organization.company +// jobPosition = contact.organization.jobPosition +// websites = contact.websites +// IMs = contact.IMs +// ringtone = contact.ringtone +// } +// } +// +// private fun convertContactToSimpleContact(contact: Contact?, withPhoneNumbersOnly: Boolean): SimpleContact? { +// return if (contact == null || (withPhoneNumbersOnly && contact.phoneNumbers.isEmpty())) { +// null +// } else { +// val birthdays = contact.events.filter { it.type == Event.TYPE_BIRTHDAY }.map { it.value }.toMutableList() as ArrayList +// val anniversaries = contact.events.filter { it.type == Event.TYPE_ANNIVERSARY }.map { it.value }.toMutableList() as ArrayList +// SimpleContact(contact.id, contact.id, contact.getNameToDisplay(), contact.photoUri, contact.phoneNumbers, birthdays, anniversaries) +// } +// } +// +// fun getPrivateSimpleContactsSync(favoritesOnly: Boolean, withPhoneNumbersOnly: Boolean) = getAllContacts(favoritesOnly).mapNotNull { +// convertContactToSimpleContact(it, withPhoneNumbersOnly) +// } +//} 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 6b8415c7..e02462cc 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 @@ -1,20 +1,16 @@ package com.simplemobiletools.contacts.pro.helpers import android.net.Uri -import android.provider.ContactsContract.CommonDataKinds.Email -import android.provider.ContactsContract.CommonDataKinds.Event -import android.provider.ContactsContract.CommonDataKinds.Im -import android.provider.ContactsContract.CommonDataKinds.Phone -import android.provider.ContactsContract.CommonDataKinds.StructuredPostal +import android.provider.ContactsContract import android.provider.MediaStore import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getByteArray import com.simplemobiletools.commons.extensions.getDateTimeFromDateString import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.helpers.VcfExporter.ExportResult.EXPORT_FAIL -import com.simplemobiletools.contacts.pro.models.Contact import ezvcard.Ezvcard import ezvcard.VCard import ezvcard.VCardVersion @@ -83,7 +79,7 @@ class VcfExporter { } contact.events.forEach { event -> - if (event.type == Event.TYPE_ANNIVERSARY || event.type == Event.TYPE_BIRTHDAY) { + if (event.type == ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY || event.type == ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) { val dateTime = event.value.getDateTimeFromDateString(false) Calendar.getInstance().apply { clear() @@ -91,11 +87,10 @@ class VcfExporter { set(Calendar.YEAR, 1900) } else { set(Calendar.YEAR, dateTime.year) - } set(Calendar.MONTH, dateTime.monthOfYear - 1) set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth) - if (event.type == Event.TYPE_BIRTHDAY) { + if (event.type == ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) { card.birthdays.add(Birthday(time)) } else { card.anniversaries.add(Anniversary(time)) @@ -113,14 +108,14 @@ class VcfExporter { contact.IMs.forEach { val impp = when (it.type) { - Im.PROTOCOL_AIM -> Impp.aim(it.value) - Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) - Im.PROTOCOL_MSN -> Impp.msn(it.value) - Im.PROTOCOL_ICQ -> Impp.icq(it.value) - Im.PROTOCOL_SKYPE -> Impp.skype(it.value) - Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) - Im.PROTOCOL_QQ -> Impp(QQ, it.value) - Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_AIM -> Impp.aim(it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_MSN -> Impp.msn(it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_ICQ -> Impp.icq(it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_SKYPE -> Impp.skype(it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ -> Impp(QQ, it.value) + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) else -> Impp(it.label, it.value) } @@ -176,29 +171,29 @@ class VcfExporter { } private fun getPhoneNumberTypeLabel(type: Int, label: String) = when (type) { - Phone.TYPE_MOBILE -> CELL - Phone.TYPE_HOME -> HOME - Phone.TYPE_WORK -> WORK - Phone.TYPE_MAIN -> PREF - Phone.TYPE_FAX_WORK -> WORK_FAX - Phone.TYPE_FAX_HOME -> HOME_FAX - Phone.TYPE_PAGER -> PAGER - Phone.TYPE_OTHER -> OTHER + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE -> CELL + ContactsContract.CommonDataKinds.Phone.TYPE_HOME -> HOME + ContactsContract.CommonDataKinds.Phone.TYPE_WORK -> WORK + ContactsContract.CommonDataKinds.Phone.TYPE_MAIN -> PREF + ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK -> WORK_FAX + ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME -> HOME_FAX + ContactsContract.CommonDataKinds.Phone.TYPE_PAGER -> PAGER + ContactsContract.CommonDataKinds.Phone.TYPE_OTHER -> OTHER else -> label } private fun getEmailTypeLabel(type: Int, label: String) = when (type) { - Email.TYPE_HOME -> HOME - Email.TYPE_WORK -> WORK - Email.TYPE_MOBILE -> MOBILE - Email.TYPE_OTHER -> OTHER + ContactsContract.CommonDataKinds.Email.TYPE_HOME -> HOME + ContactsContract.CommonDataKinds.Email.TYPE_WORK -> WORK + ContactsContract.CommonDataKinds.Email.TYPE_MOBILE -> MOBILE + ContactsContract.CommonDataKinds.Email.TYPE_OTHER -> OTHER else -> label } private fun getAddressTypeLabel(type: Int, label: String) = when (type) { - StructuredPostal.TYPE_HOME -> HOME - StructuredPostal.TYPE_WORK -> WORK - StructuredPostal.TYPE_OTHER -> OTHER + ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME -> HOME + ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK -> WORK + ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER -> OTHER else -> label } } 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 c23c1738..a48f1f86 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 @@ -7,17 +7,19 @@ import android.provider.ContactsContract.CommonDataKinds.Im import android.provider.ContactsContract.CommonDataKinds.Phone import android.provider.ContactsContract.CommonDataKinds.StructuredPostal import android.widget.Toast +import com.simplemobiletools.commons.extensions.groupsDB import com.simplemobiletools.commons.extensions.normalizePhoneNumber import com.simplemobiletools.commons.extensions.showErrorToast -import com.simplemobiletools.commons.models.PhoneNumber -import com.simplemobiletools.contacts.pro.activities.SimpleActivity -import com.simplemobiletools.contacts.pro.extensions.getCachePhoto +import com.simplemobiletools.commons.extensions.getCachePhoto import com.simplemobiletools.contacts.pro.extensions.getCachePhotoUri -import com.simplemobiletools.contacts.pro.extensions.groupsDB +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.helpers.DEFAULT_MIMETYPE +import com.simplemobiletools.commons.models.PhoneNumber +import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_FAIL import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_OK import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_PARTIAL -import com.simplemobiletools.contacts.pro.models.* import ezvcard.Ezvcard import ezvcard.VCard import ezvcard.util.PartialDate diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt index b4a7bda9..dbee2fd6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt @@ -1,37 +1,37 @@ -package com.simplemobiletools.contacts.pro.interfaces - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.simplemobiletools.contacts.pro.models.LocalContact - -@Dao -interface ContactsDao { - @Query("SELECT * FROM contacts") - fun getContacts(): List - - @Query("SELECT * FROM contacts WHERE starred = 1") - fun getFavoriteContacts(): List - - @Query("SELECT * FROM contacts WHERE id = :id") - fun getContactWithId(id: Int): LocalContact? - - @Query("SELECT * FROM contacts WHERE phone_numbers LIKE :number") - fun getContactWithNumber(number: String): LocalContact? - - @Query("UPDATE contacts SET starred = :isStarred WHERE id = :id") - fun updateStarred(isStarred: Int, id: Int) - - @Query("UPDATE contacts SET ringtone = :ringtone WHERE id = :id") - fun updateRingtone(ringtone: String, id: Int) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertOrUpdate(contact: LocalContact): Long - - @Query("DELETE FROM contacts WHERE id = :id") - fun deleteContactId(id: Int) - - @Query("DELETE FROM contacts WHERE id IN (:ids)") - fun deleteContactIds(ids: List) -} +//package com.simplemobiletools.contacts.pro.interfaces +// +//import androidx.room.Dao +//import androidx.room.Insert +//import androidx.room.OnConflictStrategy +//import androidx.room.Query +//import com.simplemobiletools.contacts.pro.models.LocalContact +// +//@Dao +//interface ContactsDao { +// @Query("SELECT * FROM contacts") +// fun getContacts(): List +// +// @Query("SELECT * FROM contacts WHERE starred = 1") +// fun getFavoriteContacts(): List +// +// @Query("SELECT * FROM contacts WHERE id = :id") +// fun getContactWithId(id: Int): LocalContact? +// +// @Query("SELECT * FROM contacts WHERE phone_numbers LIKE :number") +// fun getContactWithNumber(number: String): LocalContact? +// +// @Query("UPDATE contacts SET starred = :isStarred WHERE id = :id") +// fun updateStarred(isStarred: Int, id: Int) +// +// @Query("UPDATE contacts SET ringtone = :ringtone WHERE id = :id") +// fun updateRingtone(ringtone: String, id: Int) +// +// @Insert(onConflict = OnConflictStrategy.REPLACE) +// fun insertOrUpdate(contact: LocalContact): Long +// +// @Query("DELETE FROM contacts WHERE id = :id") +// fun deleteContactId(id: Int) +// +// @Query("DELETE FROM contacts WHERE id IN (:ids)") +// fun deleteContactIds(ids: List) +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt index 8991a6f0..61c488af 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt @@ -1,19 +1,19 @@ -package com.simplemobiletools.contacts.pro.interfaces - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.simplemobiletools.contacts.pro.models.Group - -@Dao -interface GroupsDao { - @Query("SELECT * FROM groups") - fun getGroups(): List - - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertOrUpdate(group: Group): Long - - @Query("DELETE FROM groups WHERE id = :id") - fun deleteGroupId(id: Long) -} +//package com.simplemobiletools.contacts.pro.interfaces +// +//import androidx.room.Dao +//import androidx.room.Insert +//import androidx.room.OnConflictStrategy +//import androidx.room.Query +//import com.simplemobiletools.contacts.pro.models.Group +// +//@Dao +//interface GroupsDao { +// @Query("SELECT * FROM groups") +// fun getGroups(): List +// +// @Insert(onConflict = OnConflictStrategy.REPLACE) +// fun insertOrUpdate(group: Group): Long +// +// @Query("DELETE FROM groups WHERE id = :id") +// fun deleteGroupId(id: Long) +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RefreshContactsListener.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RefreshContactsListener.kt index 1a917f56..ec68aa5c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RefreshContactsListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RefreshContactsListener.kt @@ -1,6 +1,6 @@ package com.simplemobiletools.contacts.pro.interfaces -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* interface RefreshContactsListener { fun refreshContacts(refreshTabsMask: Int) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RemoveFromGroupListener.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RemoveFromGroupListener.kt index 753f0013..76b6f485 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RemoveFromGroupListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/RemoveFromGroupListener.kt @@ -1,6 +1,6 @@ package com.simplemobiletools.contacts.pro.interfaces -import com.simplemobiletools.contacts.pro.models.Contact +import com.simplemobiletools.commons.models.contacts.* interface RemoveFromGroupListener { fun removeFromGroup(contacts: ArrayList) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt index 3dc9ae35..859fe9c4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt @@ -1,3 +1,3 @@ -package com.simplemobiletools.contacts.pro.models - -data class Address(var value: String, var type: Int, var label: String) +//package com.simplemobiletools.contacts.pro.models +// +//data class Address(var value: String, var type: Int, var label: String) 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 1873f642..bf02cb7f 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 @@ -1,180 +1,180 @@ -package com.simplemobiletools.contacts.pro.models - -import android.graphics.Bitmap -import com.simplemobiletools.commons.extensions.normalizeString -import com.simplemobiletools.commons.helpers.* -import com.simplemobiletools.commons.models.PhoneNumber - -data class Contact( - var id: Int, var prefix: String, var firstName: String, var middleName: String, var surname: String, var suffix: String, var nickname: String, - var photoUri: String, var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, - var events: ArrayList, var source: String, var starred: Int, var contactId: Int, var thumbnailUri: String, var photo: Bitmap?, var notes: String, - var groups: ArrayList, var organization: Organization, var websites: ArrayList, var IMs: ArrayList, var mimetype: String, - var ringtone: String? -) : - Comparable { - companion object { - var sorting = 0 - var startWithSurname = false - } - - override fun compareTo(other: Contact): Int { - var result = when { - sorting and SORT_BY_FIRST_NAME != 0 -> { - val firstString = firstName.normalizeString() - val secondString = other.firstName.normalizeString() - compareUsingStrings(firstString, secondString, other) - } - sorting and SORT_BY_MIDDLE_NAME != 0 -> { - val firstString = middleName.normalizeString() - val secondString = other.middleName.normalizeString() - compareUsingStrings(firstString, secondString, other) - } - sorting and SORT_BY_SURNAME != 0 -> { - val firstString = surname.normalizeString() - val secondString = other.surname.normalizeString() - compareUsingStrings(firstString, secondString, other) - } - sorting and SORT_BY_FULL_NAME != 0 -> { - val firstString = getNameToDisplay().normalizeString() - val secondString = other.getNameToDisplay().normalizeString() - compareUsingStrings(firstString, secondString, other) - } - else -> compareUsingIds(other) - } - - if (sorting and SORT_DESCENDING != 0) { - result *= -1 - } - - return result - } - - private fun compareUsingStrings(firstString: String, secondString: String, other: Contact): Int { - var firstValue = firstString - var secondValue = secondString - - if (firstValue.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty()) { - val fullCompany = getFullCompany() - if (fullCompany.isNotEmpty()) { - firstValue = fullCompany.normalizeString() - } else if (emails.isNotEmpty()) { - firstValue = emails.first().value - } - } - - if (secondValue.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty()) { - val otherFullCompany = other.getFullCompany() - if (otherFullCompany.isNotEmpty()) { - secondValue = otherFullCompany.normalizeString() - } else if (other.emails.isNotEmpty()) { - secondValue = other.emails.first().value - } - } - - return if (firstValue.firstOrNull()?.isLetter() == true && secondValue.firstOrNull()?.isLetter() == false) { - -1 - } else if (firstValue.firstOrNull()?.isLetter() == false && secondValue.firstOrNull()?.isLetter() == true) { - 1 - } else { - if (firstValue.isEmpty() && secondValue.isNotEmpty()) { - 1 - } else if (firstValue.isNotEmpty() && secondValue.isEmpty()) { - -1 - } else { - if (firstValue.equals(secondValue, ignoreCase = true)) { - getNameToDisplay().compareTo(other.getNameToDisplay(), true) - } else { - firstValue.compareTo(secondValue, true) - } - } - } - } - - private fun compareUsingIds(other: Contact): Int { - val firstId = id - val secondId = other.id - return firstId.compareTo(secondId) - } - - fun getBubbleText() = when { - sorting and SORT_BY_FIRST_NAME != 0 -> firstName - sorting and SORT_BY_MIDDLE_NAME != 0 -> middleName - else -> surname - } - - fun getNameToDisplay(): String { - val firstMiddle = "$firstName $middleName".trim() - val firstPart = if (startWithSurname) { - if (surname.isNotEmpty() && firstMiddle.isNotEmpty()) { - "$surname," - } else { - surname - } - } else { - firstMiddle - } - val lastPart = if (startWithSurname) firstMiddle else surname - val suffixComma = if (suffix.isEmpty()) "" else ", $suffix" - val fullName = "$prefix $firstPart $lastPart$suffixComma".trim() - return if (fullName.isEmpty()) { - if (organization.isNotEmpty()) { - getFullCompany() - } else { - emails.firstOrNull()?.value?.trim() ?: "" - } - } else { - fullName - } - } - - // photos stored locally always have different hashcodes. Avoid constantly refreshing the contact lists as the app thinks something changed. - fun getHashWithoutPrivatePhoto(): Int { - val photoToUse = if (isPrivate()) null else photo - return copy(photo = photoToUse).hashCode() - } - - fun getStringToCompare(): String { - val photoToUse = if (isPrivate()) null else photo - return copy( - id = 0, - prefix = "", - firstName = getNameToDisplay().toLowerCase(), - middleName = "", - surname = "", - suffix = "", - nickname = "", - photoUri = "", - phoneNumbers = ArrayList(), - emails = ArrayList(), - events = ArrayList(), - source = "", - addresses = ArrayList(), - starred = 0, - contactId = 0, - thumbnailUri = "", - photo = photoToUse, - notes = "", - groups = ArrayList(), - websites = ArrayList(), - organization = Organization("", ""), - IMs = ArrayList(), - ringtone = "" - ).toString() - } - - 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() - - fun isPrivate() = source == SMT_PRIVATE - - fun getSignatureKey() = if (photoUri.isNotEmpty()) photoUri else hashCode() -} +//package com.simplemobiletools.contacts.pro.models +// +//import android.graphics.Bitmap +//import com.simplemobiletools.commons.extensions.normalizeString +//import com.simplemobiletools.commons.helpers.* +//import com.simplemobiletools.commons.models.PhoneNumber +// +//data class Contact( +// var id: Int, var prefix: String, var firstName: String, var middleName: String, var surname: String, var suffix: String, var nickname: String, +// var photoUri: String, var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, +// var events: ArrayList, var source: String, var starred: Int, var contactId: Int, var thumbnailUri: String, var photo: Bitmap?, var notes: String, +// var groups: ArrayList, var organization: Organization, var websites: ArrayList, var IMs: ArrayList, var mimetype: String, +// var ringtone: String? +//) : +// Comparable { +// companion object { +// var sorting = 0 +// var startWithSurname = false +// } +// +// override fun compareTo(other: Contact): Int { +// var result = when { +// sorting and SORT_BY_FIRST_NAME != 0 -> { +// val firstString = firstName.normalizeString() +// val secondString = other.firstName.normalizeString() +// compareUsingStrings(firstString, secondString, other) +// } +// sorting and SORT_BY_MIDDLE_NAME != 0 -> { +// val firstString = middleName.normalizeString() +// val secondString = other.middleName.normalizeString() +// compareUsingStrings(firstString, secondString, other) +// } +// sorting and SORT_BY_SURNAME != 0 -> { +// val firstString = surname.normalizeString() +// val secondString = other.surname.normalizeString() +// compareUsingStrings(firstString, secondString, other) +// } +// sorting and SORT_BY_FULL_NAME != 0 -> { +// val firstString = getNameToDisplay().normalizeString() +// val secondString = other.getNameToDisplay().normalizeString() +// compareUsingStrings(firstString, secondString, other) +// } +// else -> compareUsingIds(other) +// } +// +// if (sorting and SORT_DESCENDING != 0) { +// result *= -1 +// } +// +// return result +// } +// +// private fun compareUsingStrings(firstString: String, secondString: String, other: Contact): Int { +// var firstValue = firstString +// var secondValue = secondString +// +// if (firstValue.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty()) { +// val fullCompany = getFullCompany() +// if (fullCompany.isNotEmpty()) { +// firstValue = fullCompany.normalizeString() +// } else if (emails.isNotEmpty()) { +// firstValue = emails.first().value +// } +// } +// +// if (secondValue.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty()) { +// val otherFullCompany = other.getFullCompany() +// if (otherFullCompany.isNotEmpty()) { +// secondValue = otherFullCompany.normalizeString() +// } else if (other.emails.isNotEmpty()) { +// secondValue = other.emails.first().value +// } +// } +// +// return if (firstValue.firstOrNull()?.isLetter() == true && secondValue.firstOrNull()?.isLetter() == false) { +// -1 +// } else if (firstValue.firstOrNull()?.isLetter() == false && secondValue.firstOrNull()?.isLetter() == true) { +// 1 +// } else { +// if (firstValue.isEmpty() && secondValue.isNotEmpty()) { +// 1 +// } else if (firstValue.isNotEmpty() && secondValue.isEmpty()) { +// -1 +// } else { +// if (firstValue.equals(secondValue, ignoreCase = true)) { +// getNameToDisplay().compareTo(other.getNameToDisplay(), true) +// } else { +// firstValue.compareTo(secondValue, true) +// } +// } +// } +// } +// +// private fun compareUsingIds(other: Contact): Int { +// val firstId = id +// val secondId = other.id +// return firstId.compareTo(secondId) +// } +// +// fun getBubbleText() = when { +// sorting and SORT_BY_FIRST_NAME != 0 -> firstName +// sorting and SORT_BY_MIDDLE_NAME != 0 -> middleName +// else -> surname +// } +// +// fun getNameToDisplay(): String { +// val firstMiddle = "$firstName $middleName".trim() +// val firstPart = if (startWithSurname) { +// if (surname.isNotEmpty() && firstMiddle.isNotEmpty()) { +// "$surname," +// } else { +// surname +// } +// } else { +// firstMiddle +// } +// val lastPart = if (startWithSurname) firstMiddle else surname +// val suffixComma = if (suffix.isEmpty()) "" else ", $suffix" +// val fullName = "$prefix $firstPart $lastPart$suffixComma".trim() +// return if (fullName.isEmpty()) { +// if (organization.isNotEmpty()) { +// getFullCompany() +// } else { +// emails.firstOrNull()?.value?.trim() ?: "" +// } +// } else { +// fullName +// } +// } +// +// // photos stored locally always have different hashcodes. Avoid constantly refreshing the contact lists as the app thinks something changed. +// fun getHashWithoutPrivatePhoto(): Int { +// val photoToUse = if (isPrivate()) null else photo +// return copy(photo = photoToUse).hashCode() +// } +// +// fun getStringToCompare(): String { +// val photoToUse = if (isPrivate()) null else photo +// return copy( +// id = 0, +// prefix = "", +// firstName = getNameToDisplay().toLowerCase(), +// middleName = "", +// surname = "", +// suffix = "", +// nickname = "", +// photoUri = "", +// phoneNumbers = ArrayList(), +// emails = ArrayList(), +// events = ArrayList(), +// source = "", +// addresses = ArrayList(), +// starred = 0, +// contactId = 0, +// thumbnailUri = "", +// photo = photoToUse, +// notes = "", +// groups = ArrayList(), +// websites = ArrayList(), +// organization = Organization("", ""), +// IMs = ArrayList(), +// ringtone = "" +// ).toString() +// } +// +// 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() +// +// fun isPrivate() = source == SMT_PRIVATE +// +// fun getSignatureKey() = if (photoUri.isNotEmpty()) photoUri else hashCode() +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt index d159464d..2e82de86 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt @@ -1,13 +1,13 @@ -package com.simplemobiletools.contacts.pro.models - -import com.simplemobiletools.commons.helpers.SMT_PRIVATE - -data class ContactSource(var name: String, var type: String, var publicName: String, var count: Int = 0) { - fun getFullIdentifier(): String { - return if (type == SMT_PRIVATE) { - type - } else { - "$name:$type" - } - } -} +//package com.simplemobiletools.contacts.pro.models +// +//import com.simplemobiletools.commons.helpers.SMT_PRIVATE +// +//data class ContactSource(var name: String, var type: String, var publicName: String, var count: Int = 0) { +// fun getFullIdentifier(): String { +// return if (type == SMT_PRIVATE) { +// type +// } else { +// "$name:$type" +// } +// } +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt index 39bdaad3..af09ee89 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt @@ -1,3 +1,3 @@ -package com.simplemobiletools.contacts.pro.models - -data class Email(var value: String, var type: Int, var label: String) +//package com.simplemobiletools.contacts.pro.models +// +//data class Email(var value: String, var type: Int, var label: String) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt index fc3fd7f7..d934e57f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt @@ -1,3 +1,3 @@ -package com.simplemobiletools.contacts.pro.models - -data class Event(var value: String, var type: Int) +//package com.simplemobiletools.contacts.pro.models +// +//data class Event(var value: String, var type: Int) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt index 9628e664..9e77ee62 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt @@ -1,21 +1,21 @@ -package com.simplemobiletools.contacts.pro.models - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.Index -import androidx.room.PrimaryKey -import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID -import java.io.Serializable - -@Entity(tableName = "groups", indices = [(Index(value = ["id"], unique = true))]) -data class Group( - @PrimaryKey(autoGenerate = true) var id: Long?, - @ColumnInfo(name = "title") var title: String, - @ColumnInfo(name = "contacts_count") var contactsCount: Int = 0) : Serializable { - - fun addContact() = contactsCount++ - - fun getBubbleText() = title - - fun isPrivateSecretGroup() = id ?: 0 >= FIRST_GROUP_ID -} +//package com.simplemobiletools.contacts.pro.models +// +//import androidx.room.ColumnInfo +//import androidx.room.Entity +//import androidx.room.Index +//import androidx.room.PrimaryKey +//import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID +//import java.io.Serializable +// +//@Entity(tableName = "groups", indices = [(Index(value = ["id"], unique = true))]) +//data class Group( +// @PrimaryKey(autoGenerate = true) var id: Long?, +// @ColumnInfo(name = "title") var title: String, +// @ColumnInfo(name = "contacts_count") var contactsCount: Int = 0) : Serializable { +// +// fun addContact() = contactsCount++ +// +// fun getBubbleText() = title +// +// fun isPrivateSecretGroup() = id ?: 0 >= FIRST_GROUP_ID +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt index e3f7e0ab..e1c505b3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt @@ -1,3 +1,3 @@ -package com.simplemobiletools.contacts.pro.models - -data class IM(var value: String, var type: Int, var label: String) +//package com.simplemobiletools.contacts.pro.models +// +//data class IM(var value: String, var type: Int, var label: String) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt index 1f01cd82..7bce1c32 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt @@ -1,36 +1,36 @@ -package com.simplemobiletools.contacts.pro.models - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.Index -import androidx.room.PrimaryKey -import com.simplemobiletools.commons.models.PhoneNumber - -@Entity(tableName = "contacts", indices = [(Index(value = ["id"], unique = true))]) -data class LocalContact( - @PrimaryKey(autoGenerate = true) var id: Int?, - @ColumnInfo(name = "prefix") var prefix: String, - @ColumnInfo(name = "first_name") var firstName: String, - @ColumnInfo(name = "middle_name") var middleName: String, - @ColumnInfo(name = "surname") var surname: String, - @ColumnInfo(name = "suffix") var suffix: String, - @ColumnInfo(name = "nickname") var nickname: String, - @ColumnInfo(name = "photo", typeAffinity = ColumnInfo.BLOB) var photo: ByteArray?, - @ColumnInfo(name = "photo_uri") var photoUri: String, - @ColumnInfo(name = "phone_numbers") var phoneNumbers: ArrayList, - @ColumnInfo(name = "emails") var emails: ArrayList, - @ColumnInfo(name = "events") var events: ArrayList, - @ColumnInfo(name = "starred") var starred: Int, - @ColumnInfo(name = "addresses") var addresses: ArrayList
, - @ColumnInfo(name = "notes") var notes: String, - @ColumnInfo(name = "groups") var groups: ArrayList, - @ColumnInfo(name = "company") var company: String, - @ColumnInfo(name = "job_position") var jobPosition: String, - @ColumnInfo(name = "websites") var websites: ArrayList, - @ColumnInfo(name = "ims") var IMs: ArrayList, - @ColumnInfo(name = "ringtone") var ringtone: String? -) { - override fun equals(other: Any?) = id == (other as? LocalContact?)?.id - - override fun hashCode() = id ?: 0 -} +//package com.simplemobiletools.contacts.pro.models +// +//import androidx.room.ColumnInfo +//import androidx.room.Entity +//import androidx.room.Index +//import androidx.room.PrimaryKey +//import com.simplemobiletools.commons.models.PhoneNumber +// +//@Entity(tableName = "contacts", indices = [(Index(value = ["id"], unique = true))]) +//data class LocalContact( +// @PrimaryKey(autoGenerate = true) var id: Int?, +// @ColumnInfo(name = "prefix") var prefix: String, +// @ColumnInfo(name = "first_name") var firstName: String, +// @ColumnInfo(name = "middle_name") var middleName: String, +// @ColumnInfo(name = "surname") var surname: String, +// @ColumnInfo(name = "suffix") var suffix: String, +// @ColumnInfo(name = "nickname") var nickname: String, +// @ColumnInfo(name = "photo", typeAffinity = ColumnInfo.BLOB) var photo: ByteArray?, +// @ColumnInfo(name = "photo_uri") var photoUri: String, +// @ColumnInfo(name = "phone_numbers") var phoneNumbers: ArrayList, +// @ColumnInfo(name = "emails") var emails: ArrayList, +// @ColumnInfo(name = "events") var events: ArrayList, +// @ColumnInfo(name = "starred") var starred: Int, +// @ColumnInfo(name = "addresses") var addresses: ArrayList
, +// @ColumnInfo(name = "notes") var notes: String, +// @ColumnInfo(name = "groups") var groups: ArrayList, +// @ColumnInfo(name = "company") var company: String, +// @ColumnInfo(name = "job_position") var jobPosition: String, +// @ColumnInfo(name = "websites") var websites: ArrayList, +// @ColumnInfo(name = "ims") var IMs: ArrayList, +// @ColumnInfo(name = "ringtone") var ringtone: String? +//) { +// override fun equals(other: Any?) = id == (other as? LocalContact?)?.id +// +// override fun hashCode() = id ?: 0 +//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt index 91697c25..c48a17f9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt @@ -1,7 +1,7 @@ -package com.simplemobiletools.contacts.pro.models - -data class Organization(var company: String, var jobPosition: String) { - fun isEmpty() = company.isEmpty() && jobPosition.isEmpty() - - fun isNotEmpty() = !isEmpty() -} +//package com.simplemobiletools.contacts.pro.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/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt index d2072389..7c5e3e70 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt @@ -1,4 +1,4 @@ -package com.simplemobiletools.contacts.pro.models - -// need for hacky parsing of no longer minified PhoneNumber model in Converters.kt -data class PhoneNumberConverter(var a: String, var b: Int, var c: String, var d: String, var e: Boolean = false) +//package com.simplemobiletools.contacts.pro.models +// +//// need for hacky parsing of no longer minified PhoneNumber model in Converters.kt +//data class PhoneNumberConverter(var a: String, var b: Int, var c: String, var d: String, var e: Boolean = false) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt index a0064fa4..7f08c5a4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt @@ -1,3 +1,3 @@ -package com.simplemobiletools.contacts.pro.models - -data class SocialAction(var actionId: Int, var type: Int, var label: String, var mimetype: String, val dataId: Long, val packageName: String) +//package com.simplemobiletools.contacts.pro.models +// +//data class SocialAction(var actionId: Int, var type: Int, var label: String, var mimetype: String, val dataId: Long, val packageName: String) From c47604bd6e542c2f01f8f782de40330be0114439 Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Mon, 20 Feb 2023 09:18:26 +0100 Subject: [PATCH 2/6] feat: removed dead code --- .../pro/databases/ContactsDatabase.kt | 90 - .../contacts/pro/extensions/Context.kt | 322 ---- .../contacts/pro/helpers/Config.kt | 77 - .../contacts/pro/helpers/Constants.kt | 95 - .../contacts/pro/helpers/ContactsHelper.kt | 1547 ----------------- .../contacts/pro/helpers/Converters.kt | 76 - .../pro/helpers/LocalContactsHelper.kt | 173 -- .../contacts/pro/interfaces/ContactsDao.kt | 37 - .../contacts/pro/interfaces/GroupsDao.kt | 19 - .../contacts/pro/models/Address.kt | 3 - .../contacts/pro/models/Contact.kt | 180 -- .../contacts/pro/models/ContactSource.kt | 13 - .../contacts/pro/models/Email.kt | 3 - .../contacts/pro/models/Event.kt | 3 - .../contacts/pro/models/Group.kt | 21 - .../contacts/pro/models/IM.kt | 3 - .../contacts/pro/models/LocalContact.kt | 36 - .../contacts/pro/models/Organization.kt | 7 - .../pro/models/PhoneNumberConverter.kt | 4 - .../contacts/pro/models/SocialAction.kt | 3 - 20 files changed, 2712 deletions(-) delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt delete mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt deleted file mode 100644 index 23630594..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/databases/ContactsDatabase.kt +++ /dev/null @@ -1,90 +0,0 @@ -//package com.simplemobiletools.contacts.pro.databases -// -//import android.content.Context -//import androidx.room.Database -//import androidx.room.Room -//import androidx.room.RoomDatabase -//import androidx.room.TypeConverters -//import androidx.room.migration.Migration -//import androidx.sqlite.db.SupportSQLiteDatabase -//import com.simplemobiletools.contacts.pro.helpers.Converters -//import com.simplemobiletools.contacts.pro.helpers.FIRST_CONTACT_ID -//import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID -//import com.simplemobiletools.contacts.pro.helpers.getEmptyLocalContact -//import com.simplemobiletools.contacts.pro.interfaces.ContactsDao -//import com.simplemobiletools.contacts.pro.interfaces.GroupsDao -//import com.simplemobiletools.contacts.pro.models.Group -//import com.simplemobiletools.contacts.pro.models.LocalContact -//import java.util.concurrent.Executors -// -//@Database(entities = [LocalContact::class, Group::class], version = 3) -//@TypeConverters(Converters::class) -//abstract class ContactsDatabase : RoomDatabase() { -// -// abstract fun ContactsDao(): ContactsDao -// -// abstract fun GroupsDao(): GroupsDao -// -// companion object { -// private var db: ContactsDatabase? = null -// -// fun getInstance(context: Context): ContactsDatabase { -// if (db == null) { -// synchronized(ContactsDatabase::class) { -// if (db == null) { -// db = Room.databaseBuilder(context.applicationContext, ContactsDatabase::class.java, "local_contacts.db") -// .addCallback(object : Callback() { -// override fun onCreate(db: SupportSQLiteDatabase) { -// super.onCreate(db) -// increaseAutoIncrementIds() -// } -// }) -// .addMigrations(MIGRATION_1_2) -// .addMigrations(MIGRATION_2_3) -// .build() -// } -// } -// } -// return db!! -// } -// -// fun destroyInstance() { -// db = null -// } -// -// // start autoincrement ID from FIRST_CONTACT_ID/FIRST_GROUP_ID to avoid conflicts -// // Room doesn't seem to have a built in way for it, so just create a contact/group and delete it -// private fun increaseAutoIncrementIds() { -// Executors.newSingleThreadExecutor().execute { -// val emptyContact = getEmptyLocalContact() -// emptyContact.id = FIRST_CONTACT_ID -// db!!.ContactsDao().apply { -// insertOrUpdate(emptyContact) -// deleteContactId(FIRST_CONTACT_ID) -// } -// -// val emptyGroup = Group(FIRST_GROUP_ID, "") -// db!!.GroupsDao().apply { -// insertOrUpdate(emptyGroup) -// deleteGroupId(FIRST_GROUP_ID) -// } -// } -// } -// -// private val MIGRATION_1_2 = object : Migration(1, 2) { -// override fun migrate(database: SupportSQLiteDatabase) { -// database.apply { -// execSQL("ALTER TABLE contacts ADD COLUMN photo_uri TEXT NOT NULL DEFAULT ''") -// } -// } -// } -// -// private val MIGRATION_2_3 = object : Migration(2, 3) { -// override fun migrate(database: SupportSQLiteDatabase) { -// database.apply { -// execSQL("ALTER TABLE contacts ADD COLUMN ringtone TEXT DEFAULT ''") -// } -// } -// } -// } -//} 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 a558b343..e3434309 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 @@ -13,330 +13,8 @@ import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R import java.io.File -// import android.annotation.SuppressLint -// import android.content.Context -// import android.content.Intent -// import android.database.Cursor -// import android.graphics.drawable.Drawable -// import android.net.Uri -// import android.os.Handler -// import android.os.Looper -// import android.provider.ContactsContract -// import androidx.core.content.FileProvider -// import com.simplemobiletools.commons.extensions.* -// import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS -// import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS -// import com.simplemobiletools.commons.helpers.SMT_PRIVATE -// import com.simplemobiletools.commons.helpers.SimpleContactsHelper -// import com.simplemobiletools.contacts.pro.BuildConfig -// import com.simplemobiletools.contacts.pro.R -// import com.simplemobiletools.contacts.pro.databases.ContactsDatabase -// import com.simplemobiletools.contacts.pro.helpers.* -// import com.simplemobiletools.contacts.pro.interfaces.ContactsDao -// import com.simplemobiletools.contacts.pro.interfaces.GroupsDao -// import com.simplemobiletools.commons.models.contacts.* -// import com.simplemobiletools.contacts.pro.models.ContactSource -// import com.simplemobiletools.contacts.pro.models.Organization -// import com.simplemobiletools.contacts.pro.models.SocialAction -// import java.io.File -// -// val Context.config: Config get() = Config.newInstance(applicationContext) -// -// val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao() -// -// val Context.groupsDB: GroupsDao get() = ContactsDatabase.getInstance(applicationContext).GroupsDao() -// -// fun Context.getEmptyContact(): Contact { -// val originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE -// val organization = Organization("", "") -// return Contact( -// 0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "", -// null, "", ArrayList(), organization, ArrayList(), ArrayList(), DEFAULT_MIMETYPE, null -// ) -// } -// -// fun Context.sendAddressIntent(address: String) { -// val location = Uri.encode(address) -// val uri = Uri.parse("geo:0,0?q=$location") -// -// Intent(Intent.ACTION_VIEW, uri).apply { -// launchActivityIntent(this) -// } -// } -// -// fun Context.openWebsiteIntent(url: String) { -// val website = if (url.startsWith("http")) { -// url -// } else { -// "https://$url" -// } -// -// Intent(Intent.ACTION_VIEW).apply { -// data = Uri.parse(website) -// launchActivityIntent(this) -// } -// } -// -// fun Context.getLookupUriRawId(dataUri: Uri): Int { -// val lookupKey = getLookupKeyFromUri(dataUri) -// if (lookupKey != null) { -// val uri = lookupContactUri(lookupKey, this) -// if (uri != null) { -// return getContactUriRawId(uri) -// } -// } -// return -1 -// } -// -// fun Context.getContactUriRawId(uri: Uri): Int { -// val projection = arrayOf(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) -// var cursor: Cursor? = null -// try { -// cursor = contentResolver.query(uri, projection, null, null, null) -// if (cursor!!.moveToFirst()) { -// return cursor.getIntValue(ContactsContract.Contacts.NAME_RAW_CONTACT_ID) -// } -// } catch (ignored: Exception) { -// } finally { -// cursor?.close() -// } -// return -1 -// } -// -// // from https://android.googlesource.com/platform/packages/apps/Dialer/+/68038172793ee0e2ab3e2e56ddfbeb82879d1f58/java/com/android/contacts/common/util/UriUtils.java -// fun getLookupKeyFromUri(lookupUri: Uri): String? { -// return if (!isEncodedContactUri(lookupUri)) { -// val segments = lookupUri.pathSegments -// if (segments.size < 3) null else Uri.encode(segments[2]) -// } else { -// null -// } -// } -// -// fun isEncodedContactUri(uri: Uri?): Boolean { -// if (uri == null) { -// return false -// } -// val lastPathSegment = uri.lastPathSegment ?: return false -// return lastPathSegment == "encoded" -// } -// -// fun lookupContactUri(lookup: String, context: Context): Uri? { -// val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup) -// return try { -// ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri) -// } catch (e: Exception) { -// null -// } -// } -// fun Context.getCachePhotoUri(file: File = getCachePhoto()) = FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.provider", file) -// fun Context.getPhotoThumbnailSize(): Int { -// val uri = ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI -// val projection = arrayOf(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) -// var cursor: Cursor? = null -// try { -// cursor = contentResolver.query(uri, projection, null, null, null) -// if (cursor?.moveToFirst() == true) { -// return cursor.getIntValue(ContactsContract.DisplayPhoto.THUMBNAIL_MAX_DIM) -// } -// } catch (ignored: Exception) { -// } finally { -// cursor?.close() -// } -// return 0 -// } -// -// fun Context.hasContactPermissions() = hasPermission(PERMISSION_READ_CONTACTS) && hasPermission(PERMISSION_WRITE_CONTACTS) -// -// fun Context.getPublicContactSource(source: String, callback: (String) -> Unit) { -// when (source) { -// SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden)) -// else -> { -// ContactsHelper(this).getContactSources { -// var newSource = source -// for (contactSource in it) { -// if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { -// newSource = getString(R.string.telegram) -// break -// } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { -// newSource = getString(R.string.viber) -// 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 -// } else if (contactSource.name == source && contactSource.type == VIBER_PACKAGE) { -// newSource = getString(R.string.viber) -// break -// } -// } -// -// return newSource -// } -// } -// } -// -// fun Context.sendSMSToContacts(contacts: ArrayList) { -// val numbers = StringBuilder() -// contacts.forEach { -// val number = it.phoneNumbers.firstOrNull { it.type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE } -// ?: it.phoneNumbers.firstOrNull() -// if (number != null) { -// numbers.append("${Uri.encode(number.value)};") -// } -// } -// -// val uriString = "smsto:${numbers.toString().trimEnd(';')}" -// Intent(Intent.ACTION_SENDTO, Uri.parse(uriString)).apply { -// launchActivityIntent(this) -// } -// } -// -// fun Context.sendEmailToContacts(contacts: ArrayList) { -// val emails = ArrayList() -// contacts.forEach { -// it.emails.forEach { -// if (it.value.isNotEmpty()) { -// emails.add(it.value) -// } -// } -// } -// -// Intent(Intent.ACTION_SEND_MULTIPLE).apply { -// type = "message/rfc822" -// putExtra(Intent.EXTRA_EMAIL, emails.toTypedArray()) -// launchActivityIntent(this) -// } -// } -// -// fun Context.getTempFile(filename: String = DEFAULT_FILE_NAME): File? { -// val folder = File(cacheDir, "contacts") -// if (!folder.exists()) { -// if (!folder.mkdir()) { -// toast(R.string.unknown_error_occurred) -// return null -// } -// } -// -// return File(folder, filename) -// } -// -// fun Context.addContactsToGroup(contacts: ArrayList, groupId: Long) { -// val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList -// val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList -// if (publicContacts.isNotEmpty()) { -// ContactsHelper(this).addContactsToGroup(publicContacts, groupId) -// } -// -// if (privateContacts.isNotEmpty()) { -// LocalContactsHelper(this).addContactsToGroup(privateContacts, groupId) -// } -// } -// -// fun Context.removeContactsFromGroup(contacts: ArrayList, groupId: Long) { -// val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList -// val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList -// if (publicContacts.isNotEmpty() && hasContactPermissions()) { -// ContactsHelper(this).removeContactsFromGroup(publicContacts, groupId) -// } -// -// if (privateContacts.isNotEmpty()) { -// LocalContactsHelper(this).removeContactsFromGroup(privateContacts, groupId) -// } -// } -// -// fun Context.getContactPublicUri(contact: Contact): Uri { -// val lookupKey = if (contact.isPrivate()) { -// "local_${contact.id}" -// } else { -// SimpleContactsHelper(this).getContactLookupKey(contact.id.toString()) -// } -// return Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey) -// } -// -// fun Context.getVisibleContactSources(): ArrayList { -// val sources = getAllContactSources() -// val ignoredContactSources = config.ignoredContactSources -// return ArrayList(sources).filter { !ignoredContactSources.contains(it.getFullIdentifier()) } -// .map { it.name }.toMutableList() as ArrayList -// } -// -// fun Context.getAllContactSources(): ArrayList { -// val sources = ContactsHelper(this).getDeviceContactSources() -// sources.add(getPrivateContactSource()) -// return sources.toMutableList() as ArrayList -// } -// -// fun Context.getPrivateContactSource() = ContactSource(SMT_PRIVATE, SMT_PRIVATE, getString(R.string.phone_storage_hidden)) -// -// fun Context.getSocialActions(id: Int): ArrayList { -// val uri = ContactsContract.Data.CONTENT_URI -// val projection = arrayOf( -// ContactsContract.Data._ID, -// ContactsContract.Data.DATA3, -// ContactsContract.Data.MIMETYPE, -// ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET -// ) -// -// val socialActions = ArrayList() -// var curActionId = 0 -// val selection = "${ContactsContract.Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = arrayOf(id.toString()) -// queryCursor(uri, projection, selection, selectionArgs, null, true) { cursor -> -// val mimetype = cursor.getStringValue(ContactsContract.Data.MIMETYPE) -// val type = when (mimetype) { -// // WhatsApp -// "vnd.android.cursor.item/vnd.com.whatsapp.profile" -> SOCIAL_MESSAGE -// "vnd.android.cursor.item/vnd.com.whatsapp.voip.call" -> SOCIAL_VOICE_CALL -// "vnd.android.cursor.item/vnd.com.whatsapp.video.call" -> SOCIAL_VIDEO_CALL -// -// // Viber -// "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_call" -> SOCIAL_VOICE_CALL -// "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_viber" -> SOCIAL_VOICE_CALL -// "vnd.android.cursor.item/vnd.com.viber.voip.viber_out_call_none_viber" -> SOCIAL_VOICE_CALL -// "vnd.android.cursor.item/vnd.com.viber.voip.viber_number_message" -> SOCIAL_MESSAGE -// -// // Signal -// "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.contact" -> SOCIAL_MESSAGE -// "vnd.android.cursor.item/vnd.org.thoughtcrime.securesms.call" -> SOCIAL_VOICE_CALL -// -// // Telegram -// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call" -> SOCIAL_VOICE_CALL -// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.call.video" -> SOCIAL_VIDEO_CALL -// "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile" -> SOCIAL_MESSAGE -// -// // Threema -// "vnd.android.cursor.item/vnd.ch.threema.app.profile" -> SOCIAL_MESSAGE -// "vnd.android.cursor.item/vnd.ch.threema.app.call" -> SOCIAL_VOICE_CALL -// else -> return@queryCursor -// } -// -// val label = cursor.getStringValue(ContactsContract.Data.DATA3) -// val realID = cursor.getLongValue(ContactsContract.Data._ID) -// val packageName = cursor.getStringValue(ContactsContract.Data.ACCOUNT_TYPE_AND_DATA_SET) -// val socialAction = SocialAction(curActionId++, type, label, mimetype, realID, packageName) -// socialActions.add(socialAction) -// } -// return socialActions -// } - @SuppressLint("UseCompatLoadingForDrawables") fun Context.getPackageDrawable(packageName: String): Drawable { return resources.getDrawable( 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 deleted file mode 100644 index 8da79dd1..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt +++ /dev/null @@ -1,77 +0,0 @@ -//package com.simplemobiletools.contacts.pro.helpers -// -//import android.content.Context -//import com.simplemobiletools.commons.helpers.BaseConfig -// -//class Config(context: Context) : BaseConfig(context) { -// companion object { -// fun newInstance(context: Context) = Config(context) -// } -// -// var ignoredContactSources: HashSet -// get() = prefs.getStringSet(IGNORED_CONTACT_SOURCES, hashSetOf(".")) as HashSet -// set(ignoreContactSources) = prefs.edit().remove(IGNORED_CONTACT_SOURCES).putStringSet(IGNORED_CONTACT_SOURCES, ignoreContactSources).apply() -// -// var showContactThumbnails: Boolean -// get() = prefs.getBoolean(SHOW_CONTACT_THUMBNAILS, true) -// set(showContactThumbnails) = prefs.edit().putBoolean(SHOW_CONTACT_THUMBNAILS, showContactThumbnails).apply() -// -// var showPhoneNumbers: Boolean -// 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 lastUsedContactSource: String -// get() = prefs.getString(LAST_USED_CONTACT_SOURCE, "")!! -// set(lastUsedContactSource) = prefs.edit().putString(LAST_USED_CONTACT_SOURCE, lastUsedContactSource).apply() -// -// var onContactClick: Int -// get() = prefs.getInt(ON_CONTACT_CLICK, ON_CLICK_VIEW_CONTACT) -// set(onContactClick) = prefs.edit().putInt(ON_CONTACT_CLICK, onContactClick).apply() -// -// var showContactFields: Int -// get() = prefs.getInt( -// SHOW_CONTACT_FIELDS, SHOW_FIRST_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_PHONE_NUMBERS_FIELD or SHOW_EMAILS_FIELD or -// 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 showTabs: Int -// get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK) -// set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply() -// -// var showDialpadButton: Boolean -// get() = prefs.getBoolean(SHOW_DIALPAD_BUTTON, true) -// set(showDialpadButton) = prefs.edit().putBoolean(SHOW_DIALPAD_BUTTON, showDialpadButton).apply() -// -// var wasLocalAccountInitialized: Boolean -// get() = prefs.getBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, false) -// set(wasLocalAccountInitialized) = prefs.edit().putBoolean(WAS_LOCAL_ACCOUNT_INITIALIZED, wasLocalAccountInitialized).apply() -// -// var lastExportPath: String -// get() = prefs.getString(LAST_EXPORT_PATH, "")!! -// set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() -// -// var speedDial: String -// get() = prefs.getString(SPEED_DIAL, "")!! -// set(speedDial) = prefs.edit().putString(SPEED_DIAL, speedDial).apply() -// -// var showPrivateContacts: Boolean -// get() = prefs.getBoolean(SHOW_PRIVATE_CONTACTS, true) -// set(showPrivateContacts) = prefs.edit().putBoolean(SHOW_PRIVATE_CONTACTS, showPrivateContacts).apply() -// -// var mergeDuplicateContacts: Boolean -// get() = prefs.getBoolean(MERGE_DUPLICATE_CONTACTS, true) -// set(mergeDuplicateContacts) = prefs.edit().putBoolean(MERGE_DUPLICATE_CONTACTS, mergeDuplicateContacts).apply() -// -// var favoritesContactsOrder: String -// get() = prefs.getString(FAVORITES_CONTACTS_ORDER, "")!! -// set(order) = prefs.edit().putString(FAVORITES_CONTACTS_ORDER, order).apply() -// -// var isCustomOrderSelected: Boolean -// get() = prefs.getBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, false) -// set(selected) = prefs.edit().putBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, selected).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 c7df58b0..958524b9 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 @@ -4,24 +4,6 @@ import com.simplemobiletools.commons.helpers.TAB_CONTACTS import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.helpers.TAB_GROUPS -// 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_2" -// 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 SHOW_DIALPAD_BUTTON = "show_dialpad_button" -// const val SPEED_DIAL = "speed_dial" -// const val LAST_EXPORT_PATH = "last_export_path" -// const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized" -// const val SHOW_PRIVATE_CONTACTS = "show_private_contacts" -// const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts" -// const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order" -// const val FAVORITES_CUSTOM_ORDER_SELECTED = "favorites_custom_order_selected" - const val GROUP = "group" const val IS_FROM_SIMPLE_CONTACTS = "is_from_simple_contacts" const val ADD_NEW_CONTACT_NUMBER = "add_new_contact_number" @@ -41,20 +23,12 @@ const val LOCATION_FAVORITES_TAB = 1 const val LOCATION_GROUP_CONTACTS = 2 const val LOCATION_INSERT_OR_EDIT = 3 -// const val ALL_TABS_MASK = TAB_CONTACTS or TAB_FAVORITES or TAB_GROUPS - val tabsList = arrayListOf( TAB_CONTACTS, TAB_FAVORITES, TAB_GROUPS ) -// contact photo changes -// const val PHOTO_ADDED = 1 -// const val PHOTO_REMOVED = 2 -// const val PHOTO_CHANGED = 3 -// const val PHOTO_UNCHANGED = 4 - // phone number/email types const val CELL = "CELL" const val WORK = "WORK" @@ -73,77 +47,8 @@ const val HANGOUTS = "Hangouts" const val QQ = "QQ" const val JABBER = "Jabber" -// const val ON_CLICK_CALL_CONTACT = 1 -// const val ON_CLICK_VIEW_CONTACT = 2 -// const val ON_CLICK_EDIT_CONTACT = 3 - -// visible fields filtering -// const val SHOW_PREFIX_FIELD = 1 -// const val SHOW_FIRST_NAME_FIELD = 2 -// const val SHOW_MIDDLE_NAME_FIELD = 4 -// const val SHOW_SURNAME_FIELD = 8 -// const val SHOW_SUFFIX_FIELD = 16 -// const val SHOW_PHONE_NUMBERS_FIELD = 32 -// const val SHOW_EMAILS_FIELD = 64 -// const val SHOW_ADDRESSES_FIELD = 128 -// const val SHOW_EVENTS_FIELD = 256 -// const val SHOW_NOTES_FIELD = 512 -// const val SHOW_ORGANIZATION_FIELD = 1024 -// const val SHOW_GROUPS_FIELD = 2048 -// const val SHOW_CONTACT_SOURCE_FIELD = 4096 -// const val SHOW_WEBSITES_FIELD = 8192 -// const val SHOW_NICKNAME_FIELD = 16384 -// const val SHOW_IMS_FIELD = 32768 -// const val SHOW_RINGTONE_FIELD = 65536 - -// const val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME -// const val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE -// const val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME -// const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY -// const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK -// const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE -// const val DEFAULT_IM_TYPE = CommonDataKinds.Im.PROTOCOL_SKYPE -// const val DEFAULT_MIMETYPE = CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE - -// apps with special handling -// const val TELEGRAM_PACKAGE = "org.telegram.messenger" -// const val SIGNAL_PACKAGE = "org.thoughtcrime.securesms" -// const val WHATSAPP_PACKAGE = "com.whatsapp" -// const val VIBER_PACKAGE = "com.viber.voip" -// const val THREEMA_PACKAGE = "ch.threema.app" - const val WHATSAPP = "whatsapp" const val SIGNAL = "signal" const val VIBER = "viber" const val TELEGRAM = "telegram" const val THREEMA = "threema" - -const val SOCIAL_VOICE_CALL = 0 -const val SOCIAL_VIDEO_CALL = 1 -const val SOCIAL_MESSAGE = 2 - -// fun getEmptyLocalContact() = LocalContact( -// 0, -// "", -// "", -// "", -// "", -// "", -// "", -// null, -// "", -// ArrayList(), -// ArrayList(), -// ArrayList(), -// 0, -// ArrayList(), -// "", -// ArrayList(), -// "", -// "", -// ArrayList(), -// ArrayList(), -// null -// ) -// -// fun getProperText(text: String, shouldNormalize: Boolean) = if (shouldNormalize) text.normalizeString() else text 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 deleted file mode 100644 index 191942f8..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/ContactsHelper.kt +++ /dev/null @@ -1,1547 +0,0 @@ -// package com.simplemobiletools.contacts.pro.helpers -// -// import android.accounts.Account -// import android.accounts.AccountManager -// import android.content.* -// import android.graphics.Bitmap -// import android.net.Uri -// import android.os.Handler -// import android.os.Looper -// import android.provider.ContactsContract.* -// import android.provider.ContactsContract.CommonDataKinds.* -// import android.provider.MediaStore -// import android.text.TextUtils -// import android.util.SparseArray -// import com.simplemobiletools.commons.extensions.* -// import com.simplemobiletools.commons.helpers.* -// import com.simplemobiletools.commons.models.PhoneNumber -// import com.simplemobiletools.commons.overloads.times -// import com.simplemobiletools.contacts.pro.R -// import com.simplemobiletools.contacts.pro.extensions.* -// import com.simplemobiletools.contacts.pro.models.* -// import com.simplemobiletools.contacts.pro.models.Email -// import com.simplemobiletools.contacts.pro.models.Event -// import com.simplemobiletools.contacts.pro.models.Organization -// import java.util.* -// -// class ContactsHelper(val context: Context) { -// private val BATCH_SIZE = 50 -// private var displayContactSources = ArrayList() -// -// fun getContacts( -// getAll: Boolean = false, -// gettingDuplicates: Boolean = false, -// ignoredContactSources: HashSet = HashSet(), -// callback: (ArrayList) -> Unit -// ) { -// ensureBackgroundThread { -// val contacts = SparseArray() -// displayContactSources = context.getVisibleContactSources() -// -// if (getAll) { -// displayContactSources = if (ignoredContactSources.isEmpty()) { -// context.getAllContactSources().map { it.name }.toMutableList() as ArrayList -// } else { -// context.getAllContactSources().filter { -// it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier()) -// }.map { it.name }.toMutableList() as ArrayList -// } -// } -// -// getDeviceContacts(contacts, ignoredContactSources, gettingDuplicates) -// -// if (displayContactSources.contains(SMT_PRIVATE)) { -// LocalContactsHelper(context).getAllContacts().forEach { -// contacts.put(it.id, it) -// } -// } -// -// val contactsSize = contacts.size() -// val showOnlyContactsWithNumbers = context.config.showOnlyContactsWithNumbers -// val tempContacts = ArrayList(contactsSize) -// val resultContacts = ArrayList(contactsSize) -// -// (0 until contactsSize).filter { -// if (ignoredContactSources.isEmpty() && showOnlyContactsWithNumbers) { -// contacts.valueAt(it).phoneNumbers.isNotEmpty() -// } else { -// true -// } -// }.mapTo(tempContacts) { -// contacts.valueAt(it) -// } -// -// if (context.config.mergeDuplicateContacts && ignoredContactSources.isEmpty() && !getAll) { -// tempContacts.filter { displayContactSources.contains(it.source) }.groupBy { it.getNameToDisplay().toLowerCase() }.values.forEach { it -> -// if (it.size == 1) { -// resultContacts.add(it.first()) -// } else { -// val sorted = it.sortedByDescending { it.getStringToCompare().length } -// resultContacts.add(sorted.first()) -// } -// } -// } else { -// resultContacts.addAll(tempContacts) -// } -// -// // groups are obtained with contactID, not rawID, so assign them to proper contacts like this -// val groups = getContactGroups(getStoredGroupsSync()) -// val size = groups.size() -// for (i in 0 until size) { -// val key = groups.keyAt(i) -// resultContacts.firstOrNull { it.contactId == key }?.groups = groups.valueAt(i) -// } -// -// Contact.sorting = context.config.sorting -// Contact.startWithSurname = context.config.startNameWithSurname -// resultContacts.sort() -// -// Handler(Looper.getMainLooper()).post { -// callback(resultContacts) -// } -// } -// } -// -// private fun getContentResolverAccounts(): HashSet { -// val sources = HashSet() -// arrayOf(Groups.CONTENT_URI, Settings.CONTENT_URI, RawContacts.CONTENT_URI).forEach { -// fillSourcesFromUri(it, sources) -// } -// -// return sources -// } -// -// private fun fillSourcesFromUri(uri: Uri, sources: HashSet) { -// val projection = arrayOf( -// RawContacts.ACCOUNT_NAME, -// RawContacts.ACCOUNT_TYPE -// ) -// -// context.queryCursor(uri, projection) { cursor -> -// val name = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" -// val type = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" -// var publicName = name -// if (type == TELEGRAM_PACKAGE) { -// publicName = context.getString(R.string.telegram) -// } -// -// val source = ContactSource(name, type, publicName) -// sources.add(source) -// } -// } -// -// private fun getDeviceContacts(contacts: SparseArray, ignoredContactSources: HashSet?, gettingDuplicates: Boolean) { -// if (!context.hasContactPermissions()) { -// return -// } -// -// val ignoredSources = ignoredContactSources ?: context.config.ignoredContactSources -// val uri = Data.CONTENT_URI -// val projection = getContactProjection() -// -// arrayOf(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, StructuredName.CONTENT_ITEM_TYPE).forEach { mimetype -> -// val selection = "${Data.MIMETYPE} = ?" -// val selectionArgs = arrayOf(mimetype) -// val sortOrder = getSortString() -// -// context.queryCursor(uri, projection, selection, selectionArgs, sortOrder, true) { cursor -> -// val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" -// val accountType = cursor.getStringValue(RawContacts.ACCOUNT_TYPE) ?: "" -// -// if (ignoredSources.contains("$accountName:$accountType")) { -// return@queryCursor -// } -// -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// var prefix = "" -// var firstName = "" -// var middleName = "" -// var surname = "" -// var suffix = "" -// -// // ignore names at Organization type contacts -// if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { -// prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" -// firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" -// middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" -// surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" -// suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" -// } -// -// var photoUri = "" -// var starred = 0 -// var contactId = 0 -// var thumbnailUri = "" -// var ringtone: String? = null -// -// if (!gettingDuplicates) { -// photoUri = cursor.getStringValue(StructuredName.PHOTO_URI) ?: "" -// starred = cursor.getIntValue(StructuredName.STARRED) -// contactId = cursor.getIntValue(Data.CONTACT_ID) -// thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" -// ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) -// } -// -// val nickname = "" -// val numbers = ArrayList() // proper value is obtained below -// val emails = ArrayList() -// val addresses = ArrayList
() -// val events = ArrayList() -// val notes = "" -// val groups = ArrayList() -// val organization = Organization("", "") -// val websites = ArrayList() -// val ims = ArrayList() -// val contact = Contact( -// id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, numbers, emails, addresses, -// events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone -// ) -// -// contacts.put(id, contact) -// } -// } -// -// val emails = getEmails() -// var size = emails.size() -// for (i in 0 until size) { -// val key = emails.keyAt(i) -// contacts[key]?.emails = emails.valueAt(i) -// } -// -// val organizations = getOrganizations() -// size = organizations.size() -// for (i in 0 until size) { -// val key = organizations.keyAt(i) -// contacts[key]?.organization = organizations.valueAt(i) -// } -// -// // no need to fetch some fields if we are only getting duplicates of the current contact -// if (gettingDuplicates) { -// return -// } -// -// val phoneNumbers = getPhoneNumbers(null) -// size = phoneNumbers.size() -// for (i in 0 until size) { -// val key = phoneNumbers.keyAt(i) -// if (contacts[key] != null) { -// val numbers = phoneNumbers.valueAt(i) -// contacts[key].phoneNumbers = numbers -// } -// } -// -// val addresses = getAddresses() -// size = addresses.size() -// for (i in 0 until size) { -// val key = addresses.keyAt(i) -// contacts[key]?.addresses = addresses.valueAt(i) -// } -// -// val IMs = getIMs() -// size = IMs.size() -// for (i in 0 until size) { -// val key = IMs.keyAt(i) -// contacts[key]?.IMs = IMs.valueAt(i) -// } -// -// val events = getEvents() -// size = events.size() -// for (i in 0 until size) { -// val key = events.keyAt(i) -// contacts[key]?.events = events.valueAt(i) -// } -// -// val notes = getNotes() -// size = notes.size() -// for (i in 0 until size) { -// val key = notes.keyAt(i) -// contacts[key]?.notes = notes.valueAt(i) -// } -// -// val nicknames = getNicknames() -// size = nicknames.size() -// for (i in 0 until size) { -// val key = nicknames.keyAt(i) -// contacts[key]?.nickname = nicknames.valueAt(i) -// } -// -// val websites = getWebsites() -// size = websites.size() -// for (i in 0 until size) { -// val key = websites.keyAt(i) -// contacts[key]?.websites = websites.valueAt(i) -// } -// } -// -// private fun getPhoneNumbers(contactId: Int? = null): SparseArray> { -// val phoneNumbers = SparseArray>() -// val uri = Phone.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// Phone.NUMBER, -// Phone.NORMALIZED_NUMBER, -// Phone.TYPE, -// Phone.LABEL, -// Phone.IS_PRIMARY -// ) -// -// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val number = cursor.getStringValue(Phone.NUMBER) ?: return@queryCursor -// val normalizedNumber = cursor.getStringValue(Phone.NORMALIZED_NUMBER) ?: number.normalizePhoneNumber() -// val type = cursor.getIntValue(Phone.TYPE) -// val label = cursor.getStringValue(Phone.LABEL) ?: "" -// val isPrimary = cursor.getIntValue(Phone.IS_PRIMARY) != 0 -// -// if (phoneNumbers[id] == null) { -// phoneNumbers.put(id, ArrayList()) -// } -// -// val phoneNumber = PhoneNumber(number, type, label, normalizedNumber, isPrimary) -// phoneNumbers[id].add(phoneNumber) -// } -// -// return phoneNumbers -// } -// -// private fun getNicknames(contactId: Int? = null): SparseArray { -// val nicknames = SparseArray() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// Nickname.NAME -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(Nickname.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val nickname = cursor.getStringValue(Nickname.NAME) ?: return@queryCursor -// nicknames.put(id, nickname) -// } -// -// return nicknames -// } -// -// private fun getEmails(contactId: Int? = null): SparseArray> { -// val emails = SparseArray>() -// val uri = CommonDataKinds.Email.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// CommonDataKinds.Email.DATA, -// CommonDataKinds.Email.TYPE, -// CommonDataKinds.Email.LABEL -// ) -// -// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val email = cursor.getStringValue(CommonDataKinds.Email.DATA) ?: return@queryCursor -// val type = cursor.getIntValue(CommonDataKinds.Email.TYPE) -// val label = cursor.getStringValue(CommonDataKinds.Email.LABEL) ?: "" -// -// if (emails[id] == null) { -// emails.put(id, ArrayList()) -// } -// -// emails[id]!!.add(Email(email, type, label)) -// } -// -// return emails -// } -// -// private fun getAddresses(contactId: Int? = null): SparseArray> { -// val addresses = SparseArray>() -// val uri = StructuredPostal.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// StructuredPostal.FORMATTED_ADDRESS, -// StructuredPostal.TYPE, -// StructuredPostal.LABEL -// ) -// -// val selection = if (contactId == null) getSourcesSelection() else "${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = if (contactId == null) getSourcesSelectionArgs() else arrayOf(contactId.toString()) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val address = cursor.getStringValue(StructuredPostal.FORMATTED_ADDRESS) ?: return@queryCursor -// val type = cursor.getIntValue(StructuredPostal.TYPE) -// val label = cursor.getStringValue(StructuredPostal.LABEL) ?: "" -// -// if (addresses[id] == null) { -// addresses.put(id, ArrayList()) -// } -// -// addresses[id]!!.add(Address(address, type, label)) -// } -// -// return addresses -// } -// -// private fun getIMs(contactId: Int? = null): SparseArray> { -// val IMs = SparseArray>() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// Im.DATA, -// Im.PROTOCOL, -// Im.CUSTOM_PROTOCOL -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(Im.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val IM = cursor.getStringValue(Im.DATA) ?: return@queryCursor -// val type = cursor.getIntValue(Im.PROTOCOL) -// val label = cursor.getStringValue(Im.CUSTOM_PROTOCOL) ?: "" -// -// if (IMs[id] == null) { -// IMs.put(id, ArrayList()) -// } -// -// IMs[id]!!.add(IM(IM, type, label)) -// } -// -// return IMs -// } -// -// private fun getEvents(contactId: Int? = null): SparseArray> { -// val events = SparseArray>() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// CommonDataKinds.Event.START_DATE, -// CommonDataKinds.Event.TYPE -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Event.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val startDate = cursor.getStringValue(CommonDataKinds.Event.START_DATE) ?: return@queryCursor -// val type = cursor.getIntValue(CommonDataKinds.Event.TYPE) -// -// if (events[id] == null) { -// events.put(id, ArrayList()) -// } -// -// events[id]!!.add(Event(startDate, type)) -// } -// -// return events -// } -// -// private fun getNotes(contactId: Int? = null): SparseArray { -// val notes = SparseArray() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// Note.NOTE -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(Note.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val note = cursor.getStringValue(Note.NOTE) ?: return@queryCursor -// notes.put(id, note) -// } -// -// return notes -// } -// -// private fun getOrganizations(contactId: Int? = null): SparseArray { -// val organizations = SparseArray() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// CommonDataKinds.Organization.COMPANY, -// CommonDataKinds.Organization.TITLE -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(CommonDataKinds.Organization.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val company = cursor.getStringValue(CommonDataKinds.Organization.COMPANY) ?: "" -// val title = cursor.getStringValue(CommonDataKinds.Organization.TITLE) ?: "" -// if (company.isEmpty() && title.isEmpty()) { -// return@queryCursor -// } -// -// val organization = Organization(company, title) -// organizations.put(id, organization) -// } -// -// return organizations -// } -// -// private fun getWebsites(contactId: Int? = null): SparseArray> { -// val websites = SparseArray>() -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.RAW_CONTACT_ID, -// Website.URL -// ) -// -// val selection = getSourcesSelection(true, contactId != null) -// val selectionArgs = getSourcesSelectionArgs(Website.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// val url = cursor.getStringValue(Website.URL) ?: return@queryCursor -// -// if (websites[id] == null) { -// websites.put(id, ArrayList()) -// } -// -// websites[id]!!.add(url) -// } -// -// return websites -// } -// -// private fun getContactGroups(storedGroups: ArrayList, contactId: Int? = null): SparseArray> { -// val groups = SparseArray>() -// if (!context.hasContactPermissions()) { -// return groups -// } -// -// val uri = Data.CONTENT_URI -// val projection = arrayOf( -// Data.CONTACT_ID, -// Data.DATA1 -// ) -// -// val selection = getSourcesSelection(true, contactId != null, false) -// val selectionArgs = getSourcesSelectionArgs(GroupMembership.CONTENT_ITEM_TYPE, contactId) -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getIntValue(Data.CONTACT_ID) -// val newRowId = cursor.getLongValue(Data.DATA1) -// -// val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: return@queryCursor -// val group = Group(newRowId, groupTitle) -// if (groups[id] == null) { -// groups.put(id, ArrayList()) -// } -// groups[id]!!.add(group) -// } -// -// return groups -// } -// -// private fun getQuestionMarks() = ("?," * displayContactSources.filter { it.isNotEmpty() }.size).trimEnd(',') -// -// private fun getSourcesSelection(addMimeType: Boolean = false, addContactId: Boolean = false, useRawContactId: Boolean = true): String { -// val strings = ArrayList() -// if (addMimeType) { -// strings.add("${Data.MIMETYPE} = ?") -// } -// -// if (addContactId) { -// strings.add("${if (useRawContactId) Data.RAW_CONTACT_ID else Data.CONTACT_ID} = ?") -// } else { -// // sometimes local device storage has null account_name, handle it properly -// val accountnameString = StringBuilder() -// if (displayContactSources.contains("")) { -// accountnameString.append("(") -// } -// accountnameString.append("${RawContacts.ACCOUNT_NAME} IN (${getQuestionMarks()})") -// if (displayContactSources.contains("")) { -// accountnameString.append(" OR ${RawContacts.ACCOUNT_NAME} IS NULL)") -// } -// strings.add(accountnameString.toString()) -// } -// -// return TextUtils.join(" AND ", strings) -// } -// -// private fun getSourcesSelectionArgs(mimetype: String? = null, contactId: Int? = null): Array { -// val args = ArrayList() -// -// if (mimetype != null) { -// args.add(mimetype) -// } -// -// if (contactId != null) { -// args.add(contactId.toString()) -// } else { -// args.addAll(displayContactSources.filter { it.isNotEmpty() }) -// } -// -// return args.toTypedArray() -// } -// -// fun getStoredGroups(callback: (ArrayList) -> Unit) { -// ensureBackgroundThread { -// val groups = getStoredGroupsSync() -// Handler(Looper.getMainLooper()).post { -// callback(groups) -// } -// } -// } -// -// fun getStoredGroupsSync(): ArrayList { -// val groups = getDeviceStoredGroups() -// groups.addAll(context.groupsDB.getGroups()) -// return groups -// } -// -// private fun getDeviceStoredGroups(): ArrayList { -// val groups = ArrayList() -// if (!context.hasContactPermissions()) { -// return groups -// } -// -// val uri = Groups.CONTENT_URI -// val projection = arrayOf( -// Groups._ID, -// Groups.TITLE, -// Groups.SYSTEM_ID -// ) -// -// val selection = "${Groups.AUTO_ADD} = ? AND ${Groups.FAVORITES} = ?" -// val selectionArgs = arrayOf("0", "0") -// -// context.queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor -> -// val id = cursor.getLongValue(Groups._ID) -// val title = cursor.getStringValue(Groups.TITLE) ?: return@queryCursor -// -// val systemId = cursor.getStringValue(Groups.SYSTEM_ID) -// if (groups.map { it.title }.contains(title) && systemId != null) { -// return@queryCursor -// } -// -// groups.add(Group(id, title)) -// } -// return groups -// } -// -// fun createNewGroup(title: String, accountName: String, accountType: String): Group? { -// if (accountType == SMT_PRIVATE) { -// val newGroup = Group(null, title) -// val id = context.groupsDB.insertOrUpdate(newGroup) -// newGroup.id = id -// return newGroup -// } -// -// val operations = ArrayList() -// ContentProviderOperation.newInsert(Groups.CONTENT_URI).apply { -// withValue(Groups.TITLE, title) -// withValue(Groups.GROUP_VISIBLE, 1) -// withValue(Groups.ACCOUNT_NAME, accountName) -// withValue(Groups.ACCOUNT_TYPE, accountType) -// operations.add(build()) -// } -// -// try { -// val results = context.contentResolver.applyBatch(AUTHORITY, operations) -// val rawId = ContentUris.parseId(results[0].uri!!) -// return Group(rawId, title) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// return null -// } -// -// fun renameGroup(group: Group) { -// val operations = ArrayList() -// ContentProviderOperation.newUpdate(Groups.CONTENT_URI).apply { -// val selection = "${Groups._ID} = ?" -// val selectionArgs = arrayOf(group.id.toString()) -// withSelection(selection, selectionArgs) -// withValue(Groups.TITLE, group.title) -// operations.add(build()) -// } -// -// try { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// fun deleteGroup(id: Long) { -// val operations = ArrayList() -// val uri = ContentUris.withAppendedId(Groups.CONTENT_URI, id).buildUpon() -// .appendQueryParameter(CALLER_IS_SYNCADAPTER, "true") -// .build() -// -// operations.add(ContentProviderOperation.newDelete(uri).build()) -// -// try { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { -// if (id == 0) { -// return null -// } else if (isLocalPrivate) { -// return LocalContactsHelper(context).getContactWithId(id) -// } -// -// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) -// return parseContactCursor(selection, selectionArgs) -// } -// -// fun getContactWithLookupKey(key: String): Contact? { -// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.LOOKUP_KEY} = ?" -// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, key) -// return parseContactCursor(selection, selectionArgs) -// } -// -// private fun parseContactCursor(selection: String, selectionArgs: Array): Contact? { -// val storedGroups = getStoredGroupsSync() -// val uri = Data.CONTENT_URI -// val projection = getContactProjection() -// -// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) -// cursor?.use { -// if (cursor.moveToFirst()) { -// val id = cursor.getIntValue(Data.RAW_CONTACT_ID) -// -// var prefix = "" -// var firstName = "" -// var middleName = "" -// var surname = "" -// var suffix = "" -// var mimetype = cursor.getStringValue(Data.MIMETYPE) -// -// // if first line is an Organization type contact, go to next line -// if (mimetype != StructuredName.CONTENT_ITEM_TYPE) { -// if (cursor.moveToNext()) { -// mimetype = cursor.getStringValue(Data.MIMETYPE) -// } -// } -// // ignore names at Organization type contacts -// if (mimetype == StructuredName.CONTENT_ITEM_TYPE) { -// prefix = cursor.getStringValue(StructuredName.PREFIX) ?: "" -// firstName = cursor.getStringValue(StructuredName.GIVEN_NAME) ?: "" -// middleName = cursor.getStringValue(StructuredName.MIDDLE_NAME) ?: "" -// surname = cursor.getStringValue(StructuredName.FAMILY_NAME) ?: "" -// suffix = cursor.getStringValue(StructuredName.SUFFIX) ?: "" -// } -// -// val nickname = getNicknames(id)[id] ?: "" -// val photoUri = cursor.getStringValueOrNull(Phone.PHOTO_URI) ?: "" -// val number = getPhoneNumbers(id)[id] ?: ArrayList() -// val emails = getEmails(id)[id] ?: ArrayList() -// val addresses = getAddresses(id)[id] ?: ArrayList() -// val events = getEvents(id)[id] ?: ArrayList() -// val notes = getNotes(id)[id] ?: "" -// val accountName = cursor.getStringValue(RawContacts.ACCOUNT_NAME) ?: "" -// val starred = cursor.getIntValue(StructuredName.STARRED) -// val ringtone = cursor.getStringValue(StructuredName.CUSTOM_RINGTONE) -// val contactId = cursor.getIntValue(Data.CONTACT_ID) -// val groups = getContactGroups(storedGroups, contactId)[contactId] ?: ArrayList() -// val thumbnailUri = cursor.getStringValue(StructuredName.PHOTO_THUMBNAIL_URI) ?: "" -// val organization = getOrganizations(id)[id] ?: Organization("", "") -// val websites = getWebsites(id)[id] ?: ArrayList() -// val ims = getIMs(id)[id] ?: ArrayList() -// return Contact( -// id, prefix, firstName, middleName, surname, suffix, nickname, photoUri, number, emails, addresses, events, -// accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites, ims, mimetype, ringtone -// ) -// } -// } -// -// return null -// } -// -// fun getContactSources(callback: (ArrayList) -> Unit) { -// ensureBackgroundThread { -// callback(getContactSourcesSync()) -// } -// } -// -// private fun getContactSourcesSync(): ArrayList { -// val sources = getDeviceContactSources() -// sources.add(context.getPrivateContactSource()) -// return ArrayList(sources) -// } -// -// fun getSaveableContactSources(callback: (ArrayList) -> Unit) { -// ensureBackgroundThread { -// val ignoredTypes = arrayListOf( -// SIGNAL_PACKAGE, -// TELEGRAM_PACKAGE, -// WHATSAPP_PACKAGE, -// THREEMA_PACKAGE -// ) -// -// val contactSources = getContactSourcesSync() -// val filteredSources = contactSources.filter { !ignoredTypes.contains(it.type) }.toMutableList() as ArrayList -// callback(filteredSources) -// } -// } -// -// fun getDeviceContactSources(): LinkedHashSet { -// val sources = LinkedHashSet() -// if (!context.hasContactPermissions()) { -// return sources -// } -// -// if (!context.config.wasLocalAccountInitialized) { -// initializeLocalPhoneAccount() -// context.config.wasLocalAccountInitialized = true -// } -// -// val accounts = AccountManager.get(context).accounts -// accounts.forEach { -// if (ContentResolver.getIsSyncable(it, AUTHORITY) == 1) { -// var publicName = it.name -// if (it.type == TELEGRAM_PACKAGE) { -// publicName = context.getString(R.string.telegram) -// } else if (it.type == VIBER_PACKAGE) { -// publicName = context.getString(R.string.viber) -// } -// val contactSource = ContactSource(it.name, it.type, publicName) -// sources.add(contactSource) -// } -// } -// -// var hadEmptyAccount = false -// val allAccounts = getContentResolverAccounts() -// val contentResolverAccounts = allAccounts.filter { -// if (it.name.isEmpty() && it.type.isEmpty() && allAccounts.none { it.name.lowercase(Locale.getDefault()) == "phone" }) { -// hadEmptyAccount = true -// } -// -// it.name.isNotEmpty() && it.type.isNotEmpty() && !accounts.contains(Account(it.name, it.type)) -// } -// sources.addAll(contentResolverAccounts) -// -// if (hadEmptyAccount) { -// sources.add(ContactSource("", "", context.getString(R.string.phone_storage))) -// } -// -// return sources -// } -// -// // make sure the local Phone contact source is initialized and available -// // https://stackoverflow.com/a/6096508/1967672 -// private fun initializeLocalPhoneAccount() { -// try { -// val operations = ArrayList() -// ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { -// withValue(RawContacts.ACCOUNT_NAME, null) -// withValue(RawContacts.ACCOUNT_TYPE, null) -// operations.add(build()) -// } -// -// val results = context.contentResolver.applyBatch(AUTHORITY, operations) -// val rawContactUri = results.firstOrNull()?.uri ?: return -// context.contentResolver.delete(rawContactUri, null, null) -// } catch (ignored: Exception) { -// } -// } -// -// private fun getContactSourceType(accountName: String) = getDeviceContactSources().firstOrNull { it.name == accountName }?.type ?: "" -// -// private fun getContactProjection() = arrayOf( -// Data.MIMETYPE, -// Data.CONTACT_ID, -// Data.RAW_CONTACT_ID, -// StructuredName.PREFIX, -// StructuredName.GIVEN_NAME, -// StructuredName.MIDDLE_NAME, -// StructuredName.FAMILY_NAME, -// StructuredName.SUFFIX, -// StructuredName.PHOTO_URI, -// StructuredName.PHOTO_THUMBNAIL_URI, -// StructuredName.STARRED, -// StructuredName.CUSTOM_RINGTONE, -// RawContacts.ACCOUNT_NAME, -// RawContacts.ACCOUNT_TYPE -// ) -// -// private fun getSortString(): String { -// val sorting = context.config.sorting -// return when { -// sorting and SORT_BY_FIRST_NAME != 0 -> "${StructuredName.GIVEN_NAME} COLLATE NOCASE" -// sorting and SORT_BY_MIDDLE_NAME != 0 -> "${StructuredName.MIDDLE_NAME} COLLATE NOCASE" -// sorting and SORT_BY_SURNAME != 0 -> "${StructuredName.FAMILY_NAME} COLLATE NOCASE" -// sorting and SORT_BY_FULL_NAME != 0 -> StructuredName.DISPLAY_NAME -// else -> Data.RAW_CONTACT_ID -// } -// } -// -// private fun getRealContactId(id: Long): Int { -// val uri = Data.CONTENT_URI -// val projection = getContactProjection() -// val selection = "(${Data.MIMETYPE} = ? OR ${Data.MIMETYPE} = ?) AND ${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = arrayOf(StructuredName.CONTENT_ITEM_TYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE, id.toString()) -// -// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) -// cursor?.use { -// if (cursor.moveToFirst()) { -// return cursor.getIntValue(Data.CONTACT_ID) -// } -// } -// -// return 0 -// } -// -// fun updateContact(contact: Contact, photoUpdateStatus: Int): Boolean { -// context.toast(R.string.updating) -// if (contact.isPrivate()) { -// return LocalContactsHelper(context).insertOrUpdateContact(contact) -// } -// -// try { -// val operations = ArrayList() -// ContentProviderOperation.newUpdate(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" -// val selectionArgs = arrayOf(contact.id.toString(), contact.mimetype) -// withSelection(selection, selectionArgs) -// withValue(StructuredName.PREFIX, contact.prefix) -// withValue(StructuredName.GIVEN_NAME, contact.firstName) -// withValue(StructuredName.MIDDLE_NAME, contact.middleName) -// withValue(StructuredName.FAMILY_NAME, contact.surname) -// withValue(StructuredName.SUFFIX, contact.suffix) -// operations.add(build()) -// } -// -// // delete nickname -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), Nickname.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add nickname -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) -// withValue(Nickname.NAME, contact.nickname) -// operations.add(build()) -// } -// -// // delete phone numbers -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), Phone.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add phone numbers -// contact.phoneNumbers.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) -// withValue(Phone.NUMBER, it.value) -// withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) -// withValue(Phone.TYPE, it.type) -// withValue(Phone.LABEL, it.label) -// withValue(Phone.IS_PRIMARY, it.isPrimary) -// operations.add(build()) -// } -// } -// -// // delete emails -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Email.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add emails -// contact.emails.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Email.DATA, it.value) -// withValue(CommonDataKinds.Email.TYPE, it.type) -// withValue(CommonDataKinds.Email.LABEL, it.label) -// operations.add(build()) -// } -// } -// -// // delete addresses -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), StructuredPostal.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add addresses -// contact.addresses.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) -// withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) -// withValue(StructuredPostal.TYPE, it.type) -// withValue(StructuredPostal.LABEL, it.label) -// operations.add(build()) -// } -// } -// -// // delete IMs -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), Im.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add IMs -// contact.IMs.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) -// withValue(Im.DATA, it.value) -// withValue(Im.PROTOCOL, it.type) -// withValue(Im.CUSTOM_PROTOCOL, it.label) -// operations.add(build()) -// } -// } -// -// // delete events -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Event.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add events -// contact.events.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Event.START_DATE, it.value) -// withValue(CommonDataKinds.Event.TYPE, it.type) -// operations.add(build()) -// } -// } -// -// // delete notes -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), Note.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add notes -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) -// withValue(Note.NOTE, contact.notes) -// operations.add(build()) -// } -// -// // delete organization -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.Organization.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add organization -// if (contact.organization.isNotEmpty()) { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) -// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) -// withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) -// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) -// operations.add(build()) -// } -// } -// -// // delete websites -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? " -// val selectionArgs = arrayOf(contact.id.toString(), Website.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// // add websites -// contact.websites.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) -// withValue(Website.URL, it) -// withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) -// operations.add(build()) -// } -// } -// -// // delete groups -// val relevantGroupIDs = getStoredGroupsSync().map { it.id } -// if (relevantGroupIDs.isNotEmpty()) { -// val IDsString = TextUtils.join(",", relevantGroupIDs) -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} IN ($IDsString)" -// val selectionArgs = arrayOf(contact.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// } -// -// // add groups -// contact.groups.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) -// withValue(GroupMembership.GROUP_ROW_ID, it.id) -// operations.add(build()) -// } -// } -// -// // favorite, ringtone -// try { -// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contact.contactId.toString()) -// val contentValues = ContentValues(2) -// contentValues.put(Contacts.STARRED, contact.starred) -// contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) -// context.contentResolver.update(uri, contentValues, null, null) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// -// // photo -// when (photoUpdateStatus) { -// PHOTO_ADDED, PHOTO_CHANGED -> addPhoto(contact, operations) -// PHOTO_REMOVED -> removePhoto(contact, operations) -// } -// -// context.contentResolver.applyBatch(AUTHORITY, operations) -// return true -// } catch (e: Exception) { -// context.showErrorToast(e) -// return false -// } -// } -// -// private fun addPhoto(contact: Contact, operations: ArrayList): ArrayList { -// if (contact.photoUri.isNotEmpty()) { -// val photoUri = Uri.parse(contact.photoUri) -// val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) -// -// val thumbnailSize = context.getPhotoThumbnailSize() -// val scaledPhoto = Bitmap.createScaledBitmap(bitmap, thumbnailSize, thumbnailSize, false) -// val scaledSizePhotoData = scaledPhoto.getByteArray() -// scaledPhoto.recycle() -// -// val fullSizePhotoData = bitmap.getByteArray() -// bitmap.recycle() -// -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, contact.id) -// withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE) -// withValue(Photo.PHOTO, scaledSizePhotoData) -// operations.add(build()) -// } -// -// addFullSizePhoto(contact.id.toLong(), fullSizePhotoData) -// } -// return operations -// } -// -// private fun removePhoto(contact: Contact, operations: ArrayList): ArrayList { -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.RAW_CONTACT_ID} = ? AND ${Data.MIMETYPE} = ?" -// val selectionArgs = arrayOf(contact.id.toString(), Photo.CONTENT_ITEM_TYPE) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// return operations -// } -// -// fun addContactsToGroup(contacts: ArrayList, groupId: Long) { -// try { -// val operations = ArrayList() -// contacts.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValue(Data.RAW_CONTACT_ID, it.id) -// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) -// withValue(GroupMembership.GROUP_ROW_ID, groupId) -// operations.add(build()) -// } -// -// if (operations.size % BATCH_SIZE == 0) { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// operations.clear() -// } -// } -// -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { -// try { -// val operations = ArrayList() -// contacts.forEach { -// ContentProviderOperation.newDelete(Data.CONTENT_URI).apply { -// val selection = "${Data.CONTACT_ID} = ? AND ${Data.MIMETYPE} = ? AND ${Data.DATA1} = ?" -// val selectionArgs = arrayOf(it.contactId.toString(), GroupMembership.CONTENT_ITEM_TYPE, groupId.toString()) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// if (operations.size % BATCH_SIZE == 0) { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// operations.clear() -// } -// } -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// fun insertContact(contact: Contact): Boolean { -// if (contact.isPrivate()) { -// return LocalContactsHelper(context).insertOrUpdateContact(contact) -// } -// -// try { -// val operations = ArrayList() -// ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).apply { -// withValue(RawContacts.ACCOUNT_NAME, contact.source) -// withValue(RawContacts.ACCOUNT_TYPE, getContactSourceType(contact.source)) -// operations.add(build()) -// } -// -// // names -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) -// withValue(StructuredName.PREFIX, contact.prefix) -// withValue(StructuredName.GIVEN_NAME, contact.firstName) -// withValue(StructuredName.MIDDLE_NAME, contact.middleName) -// withValue(StructuredName.FAMILY_NAME, contact.surname) -// withValue(StructuredName.SUFFIX, contact.suffix) -// operations.add(build()) -// } -// -// // nickname -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE) -// withValue(Nickname.NAME, contact.nickname) -// operations.add(build()) -// } -// -// // phone numbers -// contact.phoneNumbers.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) -// withValue(Phone.NUMBER, it.value) -// withValue(Phone.NORMALIZED_NUMBER, it.normalizedNumber) -// withValue(Phone.TYPE, it.type) -// withValue(Phone.LABEL, it.label) -// withValue(Phone.IS_PRIMARY, it.isPrimary) -// operations.add(build()) -// } -// } -// -// // emails -// contact.emails.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Email.DATA, it.value) -// withValue(CommonDataKinds.Email.TYPE, it.type) -// withValue(CommonDataKinds.Email.LABEL, it.label) -// operations.add(build()) -// } -// } -// -// // addresses -// contact.addresses.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE) -// withValue(StructuredPostal.FORMATTED_ADDRESS, it.value) -// withValue(StructuredPostal.TYPE, it.type) -// withValue(StructuredPostal.LABEL, it.label) -// operations.add(build()) -// } -// } -// -// // IMs -// contact.IMs.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE) -// withValue(Im.DATA, it.value) -// withValue(Im.PROTOCOL, it.type) -// withValue(Im.CUSTOM_PROTOCOL, it.label) -// operations.add(build()) -// } -// } -// -// // events -// contact.events.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, CommonDataKinds.Event.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Event.START_DATE, it.value) -// withValue(CommonDataKinds.Event.TYPE, it.type) -// operations.add(build()) -// } -// } -// -// // notes -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE) -// withValue(Note.NOTE, contact.notes) -// operations.add(build()) -// } -// -// // organization -// if (contact.organization.isNotEmpty()) { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) -// withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) -// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) -// withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) -// withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) -// operations.add(build()) -// } -// } -// -// // websites -// contact.websites.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE) -// withValue(Website.URL, it) -// withValue(Website.TYPE, DEFAULT_WEBSITE_TYPE) -// operations.add(build()) -// } -// } -// -// // groups -// contact.groups.forEach { -// ContentProviderOperation.newInsert(Data.CONTENT_URI).apply { -// withValueBackReference(Data.RAW_CONTACT_ID, 0) -// withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE) -// withValue(GroupMembership.GROUP_ROW_ID, it.id) -// operations.add(build()) -// } -// } -// -// // photo (inspired by https://gist.github.com/slightfoot/5985900) -// var fullSizePhotoData: ByteArray? = null -// if (contact.photoUri.isNotEmpty()) { -// val photoUri = Uri.parse(contact.photoUri) -// fullSizePhotoData = context.contentResolver.openInputStream(photoUri)?.readBytes() -// } -// -// val results = context.contentResolver.applyBatch(AUTHORITY, operations) -// -// // storing contacts on some devices seems to be messed up and they move on Phone instead, or disappear completely -// // try storing a lighter contact version with this oldschool version too just so it wont disappear, future edits work well -// if (getContactSourceType(contact.source).contains(".sim")) { -// val simUri = Uri.parse("content://icc/adn") -// ContentValues().apply { -// put("number", contact.phoneNumbers.firstOrNull()?.value ?: "") -// put("tag", contact.getNameToDisplay()) -// context.contentResolver.insert(simUri, this) -// } -// } -// -// // fullsize photo -// val rawId = ContentUris.parseId(results[0].uri!!) -// if (contact.photoUri.isNotEmpty() && fullSizePhotoData != null) { -// addFullSizePhoto(rawId, fullSizePhotoData) -// } -// -// // favorite, ringtone -// val userId = getRealContactId(rawId) -// if (userId != 0) { -// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, userId.toString()) -// val contentValues = ContentValues(2) -// contentValues.put(Contacts.STARRED, contact.starred) -// contentValues.put(Contacts.CUSTOM_RINGTONE, contact.ringtone) -// context.contentResolver.update(uri, contentValues, null, null) -// } -// -// return true -// } catch (e: Exception) { -// context.showErrorToast(e) -// return false -// } -// } -// -// private fun addFullSizePhoto(contactId: Long, fullSizePhotoData: ByteArray) { -// val baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, contactId) -// val displayPhotoUri = Uri.withAppendedPath(baseUri, RawContacts.DisplayPhoto.CONTENT_DIRECTORY) -// val fileDescriptor = context.contentResolver.openAssetFileDescriptor(displayPhotoUri, "rw") -// val photoStream = fileDescriptor!!.createOutputStream() -// photoStream.write(fullSizePhotoData) -// photoStream.close() -// fileDescriptor.close() -// } -// -// fun getContactMimeTypeId(contactId: String, mimeType: String): String { -// val uri = Data.CONTENT_URI -// val projection = arrayOf(Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE) -// val selection = "${Data.MIMETYPE} = ? AND ${Data.RAW_CONTACT_ID} = ?" -// val selectionArgs = arrayOf(mimeType, contactId) -// -// -// val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) -// cursor?.use { -// if (cursor.moveToFirst()) { -// return cursor.getStringValue(Data._ID) -// } -// } -// return "" -// } -// -// fun addFavorites(contacts: ArrayList) { -// ensureBackgroundThread { -// toggleLocalFavorites(contacts, true) -// if (context.hasContactPermissions()) { -// toggleFavorites(contacts, true) -// } -// } -// } -// -// fun removeFavorites(contacts: ArrayList) { -// ensureBackgroundThread { -// toggleLocalFavorites(contacts, false) -// if (context.hasContactPermissions()) { -// toggleFavorites(contacts, false) -// } -// } -// } -// -// private fun toggleFavorites(contacts: ArrayList, addToFavorites: Boolean) { -// try { -// val operations = ArrayList() -// contacts.filter { !it.isPrivate() }.map { it.contactId.toString() }.forEach { -// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, it) -// ContentProviderOperation.newUpdate(uri).apply { -// withValue(Contacts.STARRED, if (addToFavorites) 1 else 0) -// operations.add(build()) -// } -// -// if (operations.size % BATCH_SIZE == 0) { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// operations.clear() -// } -// } -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// private fun toggleLocalFavorites(contacts: ArrayList, addToFavorites: Boolean) { -// val localContacts = contacts.filter { it.isPrivate() }.map { it.id }.toTypedArray() -// LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites) -// } -// -// fun updateRingtone(contactId: String, newUri: String) { -// try { -// val operations = ArrayList() -// val uri = Uri.withAppendedPath(Contacts.CONTENT_URI, contactId) -// ContentProviderOperation.newUpdate(uri).apply { -// withValue(Contacts.CUSTOM_RINGTONE, newUri) -// operations.add(build()) -// } -// -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } catch (e: Exception) { -// context.showErrorToast(e) -// } -// } -// -// fun deleteContact(originalContact: Contact, deleteClones: Boolean = false, callback: (success: Boolean) -> Unit) { -// ensureBackgroundThread { -// if (deleteClones) { -// getDuplicatesOfContact(originalContact, true) { contacts -> -// ensureBackgroundThread { -// if (deleteContacts(contacts)) { -// callback(true) -// } -// } -// } -// } else { -// if (deleteContacts(arrayListOf(originalContact))) { -// callback(true) -// } -// } -// } -// } -// -// fun deleteContacts(contacts: ArrayList): Boolean { -// val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList() -// LocalContactsHelper(context).deleteContactIds(localContacts) -// -// return try { -// val operations = ArrayList() -// val selection = "${RawContacts._ID} = ?" -// contacts.filter { !it.isPrivate() }.forEach { -// ContentProviderOperation.newDelete(RawContacts.CONTENT_URI).apply { -// val selectionArgs = arrayOf(it.id.toString()) -// withSelection(selection, selectionArgs) -// operations.add(build()) -// } -// -// if (operations.size % BATCH_SIZE == 0) { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// operations.clear() -// } -// } -// -// if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) { -// context.contentResolver.applyBatch(AUTHORITY, operations) -// } -// true -// } catch (e: Exception) { -// context.showErrorToast(e) -// false -// } -// } -// -// fun getDuplicatesOfContact(contact: Contact, addOriginal: Boolean, callback: (ArrayList) -> Unit) { -// ensureBackgroundThread { -// getContacts(true, 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/Converters.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt deleted file mode 100644 index 9cc2462c..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Converters.kt +++ /dev/null @@ -1,76 +0,0 @@ -//package com.simplemobiletools.contacts.pro.helpers -// -//import androidx.room.TypeConverter -//import com.google.gson.Gson -//import com.google.gson.reflect.TypeToken -//import com.simplemobiletools.commons.models.PhoneNumber -//import com.simplemobiletools.contacts.pro.models.* -// -//class Converters { -// private val gson = Gson() -// private val longType = object : TypeToken>() {}.type -// private val stringType = object : TypeToken>() {}.type -// private val numberType = object : TypeToken>() {}.type -// private val numberConverterType = object : TypeToken>() {}.type -// private val emailType = object : TypeToken>() {}.type -// private val addressType = object : TypeToken>() {}.type -// private val eventType = object : TypeToken>() {}.type -// private val imType = object : TypeToken>() {}.type -// -// @TypeConverter -// fun jsonToStringList(value: String) = gson.fromJson>(value, stringType) -// -// @TypeConverter -// fun stringListToJson(list: ArrayList) = gson.toJson(list) -// -// @TypeConverter -// fun jsonToLongList(value: String) = gson.fromJson>(value, longType) -// -// @TypeConverter -// fun longListToJson(list: ArrayList) = gson.toJson(list) -// -// // some hacky converting is needed since PhoneNumber model has been added to proguard rules, but obfuscated json was stored in database -// // convert [{"a":"678910","b":2,"c":"","d":"678910","e":false}] to PhoneNumber(value=678910, type=2, label=, normalizedNumber=678910, isPrimary=false) -// @TypeConverter -// fun jsonToPhoneNumberList(value: String): ArrayList { -// val numbers = gson.fromJson>(value, numberType) -// return if (numbers.any { it.value == null }) { -// val phoneNumbers = ArrayList() -// val numberConverters = gson.fromJson>(value, numberConverterType) -// numberConverters.forEach { converter -> -// val phoneNumber = PhoneNumber(converter.a, converter.b, converter.c, converter.d, converter.e) -// phoneNumbers.add(phoneNumber) -// } -// phoneNumbers -// } else { -// numbers -// } -// } -// -// @TypeConverter -// fun phoneNumberListToJson(list: ArrayList) = gson.toJson(list) -// -// @TypeConverter -// fun jsonToEmailList(value: String) = gson.fromJson>(value, emailType) -// -// @TypeConverter -// fun emailListToJson(list: ArrayList) = gson.toJson(list) -// -// @TypeConverter -// fun jsonToAddressList(value: String) = gson.fromJson>(value, addressType) -// -// @TypeConverter -// fun addressListToJson(list: ArrayList
) = gson.toJson(list) -// -// @TypeConverter -// fun jsonToEventList(value: String) = gson.fromJson>(value, eventType) -// -// @TypeConverter -// fun eventListToJson(list: ArrayList) = gson.toJson(list) -// -// @TypeConverter -// fun jsonToIMsList(value: String) = gson.fromJson>(value, imType) -// -// @TypeConverter -// fun IMsListToJson(list: ArrayList) = gson.toJson(list) -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt deleted file mode 100644 index b56db7ea..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/LocalContactsHelper.kt +++ /dev/null @@ -1,173 +0,0 @@ -//package com.simplemobiletools.contacts.pro.helpers -// -//import android.content.Context -//import android.graphics.BitmapFactory -//import android.net.Uri -//import android.provider.ContactsContract.CommonDataKinds.Event -//import android.provider.MediaStore -//import com.simplemobiletools.commons.extensions.getByteArray -//import com.simplemobiletools.commons.helpers.SMT_PRIVATE -//import com.simplemobiletools.commons.models.SimpleContact -//import com.simplemobiletools.contacts.pro.extensions.contactsDB -//import com.simplemobiletools.contacts.pro.extensions.getEmptyContact -//import com.simplemobiletools.commons.models.contacts.* -//import com.simplemobiletools.contacts.pro.models.Group -//import com.simplemobiletools.contacts.pro.models.LocalContact -//import com.simplemobiletools.contacts.pro.models.Organization -// -//class LocalContactsHelper(val context: Context) { -// fun getAllContacts(favoritesOnly: Boolean = false): ArrayList { -// val contacts = if (favoritesOnly) context.contactsDB.getFavoriteContacts() else context.contactsDB.getContacts() -// val storedGroups = ContactsHelper(context).getStoredGroupsSync() -// return contacts.map { convertLocalContactToContact(it, storedGroups) }.toMutableList() as ArrayList -// } -// -// fun getContactWithId(id: Int): Contact? { -// val storedGroups = ContactsHelper(context).getStoredGroupsSync() -// return convertLocalContactToContact(context.contactsDB.getContactWithId(id), storedGroups) -// } -// -// fun insertOrUpdateContact(contact: Contact): Boolean { -// val localContact = convertContactToLocalContact(contact) -// return context.contactsDB.insertOrUpdate(localContact) > 0 -// } -// -// fun addContactsToGroup(contacts: ArrayList, groupId: Long) { -// contacts.forEach { -// val localContact = convertContactToLocalContact(it) -// val newGroups = localContact.groups -// newGroups.add(groupId) -// newGroups.distinct() -// localContact.groups = newGroups -// context.contactsDB.insertOrUpdate(localContact) -// } -// } -// -// fun removeContactsFromGroup(contacts: ArrayList, groupId: Long) { -// contacts.forEach { -// val localContact = convertContactToLocalContact(it) -// val newGroups = localContact.groups -// newGroups.remove(groupId) -// localContact.groups = newGroups -// context.contactsDB.insertOrUpdate(localContact) -// } -// } -// -// fun deleteContactIds(ids: MutableList) { -// ids.chunked(30).forEach { -// context.contactsDB.deleteContactIds(it) -// } -// } -// -// fun toggleFavorites(ids: Array, addToFavorites: Boolean) { -// val isStarred = if (addToFavorites) 1 else 0 -// ids.forEach { -// context.contactsDB.updateStarred(isStarred, it) -// } -// } -// -// fun updateRingtone(id: Int, ringtone: String) { -// context.contactsDB.updateRingtone(ringtone, id) -// } -// -// private fun getPhotoByteArray(uri: String): ByteArray { -// if (uri.isEmpty()) { -// return ByteArray(0) -// } -// -// val photoUri = Uri.parse(uri) -// val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoUri) -// -// val fullSizePhotoData = bitmap.getByteArray() -// bitmap.recycle() -// -// return fullSizePhotoData -// } -// -// private fun convertLocalContactToContact(localContact: LocalContact?, storedGroups: ArrayList): Contact? { -// if (localContact == null) { -// return null -// } -// -// val contactPhoto = if (localContact.photo == null) { -// null -// } else { -// try { -// BitmapFactory.decodeByteArray(localContact.photo, 0, localContact.photo!!.size) -// } catch (e: OutOfMemoryError) { -// null -// } -// } -// -// return context.getEmptyContact().apply { -// id = localContact.id!! -// prefix = localContact.prefix -// firstName = localContact.firstName -// middleName = localContact.middleName -// surname = localContact.surname -// suffix = localContact.suffix -// nickname = localContact.nickname -// phoneNumbers = localContact.phoneNumbers -// emails = localContact.emails -// addresses = localContact.addresses -// events = localContact.events -// source = SMT_PRIVATE -// starred = localContact.starred -// contactId = localContact.id!! -// thumbnailUri = "" -// photo = contactPhoto -// photoUri = localContact.photoUri -// notes = localContact.notes -// groups = storedGroups.filter { localContact.groups.contains(it.id) } as ArrayList -// organization = Organization(localContact.company, localContact.jobPosition) -// websites = localContact.websites -// IMs = localContact.IMs -// ringtone = localContact.ringtone -// } -// } -// -// private fun convertContactToLocalContact(contact: Contact): LocalContact { -// val photoByteArray = if (contact.photoUri.isNotEmpty()) { -// getPhotoByteArray(contact.photoUri) -// } else { -// contact.photo?.getByteArray() -// } -// -// return getEmptyLocalContact().apply { -// id = if (contact.id <= FIRST_CONTACT_ID) null else contact.id -// prefix = contact.prefix -// firstName = contact.firstName -// middleName = contact.middleName -// surname = contact.surname -// suffix = contact.suffix -// nickname = contact.nickname -// photo = photoByteArray -// phoneNumbers = contact.phoneNumbers -// emails = contact.emails -// events = contact.events -// starred = contact.starred -// addresses = contact.addresses -// notes = contact.notes -// groups = contact.groups.map { it.id }.toMutableList() as ArrayList -// company = contact.organization.company -// jobPosition = contact.organization.jobPosition -// websites = contact.websites -// IMs = contact.IMs -// ringtone = contact.ringtone -// } -// } -// -// private fun convertContactToSimpleContact(contact: Contact?, withPhoneNumbersOnly: Boolean): SimpleContact? { -// return if (contact == null || (withPhoneNumbersOnly && contact.phoneNumbers.isEmpty())) { -// null -// } else { -// val birthdays = contact.events.filter { it.type == Event.TYPE_BIRTHDAY }.map { it.value }.toMutableList() as ArrayList -// val anniversaries = contact.events.filter { it.type == Event.TYPE_ANNIVERSARY }.map { it.value }.toMutableList() as ArrayList -// SimpleContact(contact.id, contact.id, contact.getNameToDisplay(), contact.photoUri, contact.phoneNumbers, birthdays, anniversaries) -// } -// } -// -// fun getPrivateSimpleContactsSync(favoritesOnly: Boolean, withPhoneNumbersOnly: Boolean) = getAllContacts(favoritesOnly).mapNotNull { -// convertContactToSimpleContact(it, withPhoneNumbersOnly) -// } -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt deleted file mode 100644 index dbee2fd6..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/ContactsDao.kt +++ /dev/null @@ -1,37 +0,0 @@ -//package com.simplemobiletools.contacts.pro.interfaces -// -//import androidx.room.Dao -//import androidx.room.Insert -//import androidx.room.OnConflictStrategy -//import androidx.room.Query -//import com.simplemobiletools.contacts.pro.models.LocalContact -// -//@Dao -//interface ContactsDao { -// @Query("SELECT * FROM contacts") -// fun getContacts(): List -// -// @Query("SELECT * FROM contacts WHERE starred = 1") -// fun getFavoriteContacts(): List -// -// @Query("SELECT * FROM contacts WHERE id = :id") -// fun getContactWithId(id: Int): LocalContact? -// -// @Query("SELECT * FROM contacts WHERE phone_numbers LIKE :number") -// fun getContactWithNumber(number: String): LocalContact? -// -// @Query("UPDATE contacts SET starred = :isStarred WHERE id = :id") -// fun updateStarred(isStarred: Int, id: Int) -// -// @Query("UPDATE contacts SET ringtone = :ringtone WHERE id = :id") -// fun updateRingtone(ringtone: String, id: Int) -// -// @Insert(onConflict = OnConflictStrategy.REPLACE) -// fun insertOrUpdate(contact: LocalContact): Long -// -// @Query("DELETE FROM contacts WHERE id = :id") -// fun deleteContactId(id: Int) -// -// @Query("DELETE FROM contacts WHERE id IN (:ids)") -// fun deleteContactIds(ids: List) -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt deleted file mode 100644 index 61c488af..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/interfaces/GroupsDao.kt +++ /dev/null @@ -1,19 +0,0 @@ -//package com.simplemobiletools.contacts.pro.interfaces -// -//import androidx.room.Dao -//import androidx.room.Insert -//import androidx.room.OnConflictStrategy -//import androidx.room.Query -//import com.simplemobiletools.contacts.pro.models.Group -// -//@Dao -//interface GroupsDao { -// @Query("SELECT * FROM groups") -// fun getGroups(): List -// -// @Insert(onConflict = OnConflictStrategy.REPLACE) -// fun insertOrUpdate(group: Group): Long -// -// @Query("DELETE FROM groups WHERE id = :id") -// fun deleteGroupId(id: Long) -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt deleted file mode 100644 index 859fe9c4..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Address.kt +++ /dev/null @@ -1,3 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//data class Address(var value: String, var type: Int, var label: String) 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 deleted file mode 100644 index bf02cb7f..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Contact.kt +++ /dev/null @@ -1,180 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//import android.graphics.Bitmap -//import com.simplemobiletools.commons.extensions.normalizeString -//import com.simplemobiletools.commons.helpers.* -//import com.simplemobiletools.commons.models.PhoneNumber -// -//data class Contact( -// var id: Int, var prefix: String, var firstName: String, var middleName: String, var surname: String, var suffix: String, var nickname: String, -// var photoUri: String, var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, -// var events: ArrayList, var source: String, var starred: Int, var contactId: Int, var thumbnailUri: String, var photo: Bitmap?, var notes: String, -// var groups: ArrayList, var organization: Organization, var websites: ArrayList, var IMs: ArrayList, var mimetype: String, -// var ringtone: String? -//) : -// Comparable { -// companion object { -// var sorting = 0 -// var startWithSurname = false -// } -// -// override fun compareTo(other: Contact): Int { -// var result = when { -// sorting and SORT_BY_FIRST_NAME != 0 -> { -// val firstString = firstName.normalizeString() -// val secondString = other.firstName.normalizeString() -// compareUsingStrings(firstString, secondString, other) -// } -// sorting and SORT_BY_MIDDLE_NAME != 0 -> { -// val firstString = middleName.normalizeString() -// val secondString = other.middleName.normalizeString() -// compareUsingStrings(firstString, secondString, other) -// } -// sorting and SORT_BY_SURNAME != 0 -> { -// val firstString = surname.normalizeString() -// val secondString = other.surname.normalizeString() -// compareUsingStrings(firstString, secondString, other) -// } -// sorting and SORT_BY_FULL_NAME != 0 -> { -// val firstString = getNameToDisplay().normalizeString() -// val secondString = other.getNameToDisplay().normalizeString() -// compareUsingStrings(firstString, secondString, other) -// } -// else -> compareUsingIds(other) -// } -// -// if (sorting and SORT_DESCENDING != 0) { -// result *= -1 -// } -// -// return result -// } -// -// private fun compareUsingStrings(firstString: String, secondString: String, other: Contact): Int { -// var firstValue = firstString -// var secondValue = secondString -// -// if (firstValue.isEmpty() && firstName.isEmpty() && middleName.isEmpty() && surname.isEmpty()) { -// val fullCompany = getFullCompany() -// if (fullCompany.isNotEmpty()) { -// firstValue = fullCompany.normalizeString() -// } else if (emails.isNotEmpty()) { -// firstValue = emails.first().value -// } -// } -// -// if (secondValue.isEmpty() && other.firstName.isEmpty() && other.middleName.isEmpty() && other.surname.isEmpty()) { -// val otherFullCompany = other.getFullCompany() -// if (otherFullCompany.isNotEmpty()) { -// secondValue = otherFullCompany.normalizeString() -// } else if (other.emails.isNotEmpty()) { -// secondValue = other.emails.first().value -// } -// } -// -// return if (firstValue.firstOrNull()?.isLetter() == true && secondValue.firstOrNull()?.isLetter() == false) { -// -1 -// } else if (firstValue.firstOrNull()?.isLetter() == false && secondValue.firstOrNull()?.isLetter() == true) { -// 1 -// } else { -// if (firstValue.isEmpty() && secondValue.isNotEmpty()) { -// 1 -// } else if (firstValue.isNotEmpty() && secondValue.isEmpty()) { -// -1 -// } else { -// if (firstValue.equals(secondValue, ignoreCase = true)) { -// getNameToDisplay().compareTo(other.getNameToDisplay(), true) -// } else { -// firstValue.compareTo(secondValue, true) -// } -// } -// } -// } -// -// private fun compareUsingIds(other: Contact): Int { -// val firstId = id -// val secondId = other.id -// return firstId.compareTo(secondId) -// } -// -// fun getBubbleText() = when { -// sorting and SORT_BY_FIRST_NAME != 0 -> firstName -// sorting and SORT_BY_MIDDLE_NAME != 0 -> middleName -// else -> surname -// } -// -// fun getNameToDisplay(): String { -// val firstMiddle = "$firstName $middleName".trim() -// val firstPart = if (startWithSurname) { -// if (surname.isNotEmpty() && firstMiddle.isNotEmpty()) { -// "$surname," -// } else { -// surname -// } -// } else { -// firstMiddle -// } -// val lastPart = if (startWithSurname) firstMiddle else surname -// val suffixComma = if (suffix.isEmpty()) "" else ", $suffix" -// val fullName = "$prefix $firstPart $lastPart$suffixComma".trim() -// return if (fullName.isEmpty()) { -// if (organization.isNotEmpty()) { -// getFullCompany() -// } else { -// emails.firstOrNull()?.value?.trim() ?: "" -// } -// } else { -// fullName -// } -// } -// -// // photos stored locally always have different hashcodes. Avoid constantly refreshing the contact lists as the app thinks something changed. -// fun getHashWithoutPrivatePhoto(): Int { -// val photoToUse = if (isPrivate()) null else photo -// return copy(photo = photoToUse).hashCode() -// } -// -// fun getStringToCompare(): String { -// val photoToUse = if (isPrivate()) null else photo -// return copy( -// id = 0, -// prefix = "", -// firstName = getNameToDisplay().toLowerCase(), -// middleName = "", -// surname = "", -// suffix = "", -// nickname = "", -// photoUri = "", -// phoneNumbers = ArrayList(), -// emails = ArrayList(), -// events = ArrayList(), -// source = "", -// addresses = ArrayList(), -// starred = 0, -// contactId = 0, -// thumbnailUri = "", -// photo = photoToUse, -// notes = "", -// groups = ArrayList(), -// websites = ArrayList(), -// organization = Organization("", ""), -// IMs = ArrayList(), -// ringtone = "" -// ).toString() -// } -// -// 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() -// -// fun isPrivate() = source == SMT_PRIVATE -// -// fun getSignatureKey() = if (photoUri.isNotEmpty()) photoUri else hashCode() -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt deleted file mode 100644 index 2e82de86..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/ContactSource.kt +++ /dev/null @@ -1,13 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//import com.simplemobiletools.commons.helpers.SMT_PRIVATE -// -//data class ContactSource(var name: String, var type: String, var publicName: String, var count: Int = 0) { -// fun getFullIdentifier(): String { -// return if (type == SMT_PRIVATE) { -// type -// } else { -// "$name:$type" -// } -// } -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt deleted file mode 100644 index af09ee89..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Email.kt +++ /dev/null @@ -1,3 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//data class Email(var value: String, var type: Int, var label: String) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt deleted file mode 100644 index d934e57f..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Event.kt +++ /dev/null @@ -1,3 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//data class Event(var value: String, var type: Int) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt deleted file mode 100644 index 9e77ee62..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Group.kt +++ /dev/null @@ -1,21 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//import androidx.room.ColumnInfo -//import androidx.room.Entity -//import androidx.room.Index -//import androidx.room.PrimaryKey -//import com.simplemobiletools.contacts.pro.helpers.FIRST_GROUP_ID -//import java.io.Serializable -// -//@Entity(tableName = "groups", indices = [(Index(value = ["id"], unique = true))]) -//data class Group( -// @PrimaryKey(autoGenerate = true) var id: Long?, -// @ColumnInfo(name = "title") var title: String, -// @ColumnInfo(name = "contacts_count") var contactsCount: Int = 0) : Serializable { -// -// fun addContact() = contactsCount++ -// -// fun getBubbleText() = title -// -// fun isPrivateSecretGroup() = id ?: 0 >= FIRST_GROUP_ID -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt deleted file mode 100644 index e1c505b3..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/IM.kt +++ /dev/null @@ -1,3 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//data class IM(var value: String, var type: Int, var label: String) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt deleted file mode 100644 index 7bce1c32..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/LocalContact.kt +++ /dev/null @@ -1,36 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//import androidx.room.ColumnInfo -//import androidx.room.Entity -//import androidx.room.Index -//import androidx.room.PrimaryKey -//import com.simplemobiletools.commons.models.PhoneNumber -// -//@Entity(tableName = "contacts", indices = [(Index(value = ["id"], unique = true))]) -//data class LocalContact( -// @PrimaryKey(autoGenerate = true) var id: Int?, -// @ColumnInfo(name = "prefix") var prefix: String, -// @ColumnInfo(name = "first_name") var firstName: String, -// @ColumnInfo(name = "middle_name") var middleName: String, -// @ColumnInfo(name = "surname") var surname: String, -// @ColumnInfo(name = "suffix") var suffix: String, -// @ColumnInfo(name = "nickname") var nickname: String, -// @ColumnInfo(name = "photo", typeAffinity = ColumnInfo.BLOB) var photo: ByteArray?, -// @ColumnInfo(name = "photo_uri") var photoUri: String, -// @ColumnInfo(name = "phone_numbers") var phoneNumbers: ArrayList, -// @ColumnInfo(name = "emails") var emails: ArrayList, -// @ColumnInfo(name = "events") var events: ArrayList, -// @ColumnInfo(name = "starred") var starred: Int, -// @ColumnInfo(name = "addresses") var addresses: ArrayList
, -// @ColumnInfo(name = "notes") var notes: String, -// @ColumnInfo(name = "groups") var groups: ArrayList, -// @ColumnInfo(name = "company") var company: String, -// @ColumnInfo(name = "job_position") var jobPosition: String, -// @ColumnInfo(name = "websites") var websites: ArrayList, -// @ColumnInfo(name = "ims") var IMs: ArrayList, -// @ColumnInfo(name = "ringtone") var ringtone: String? -//) { -// override fun equals(other: Any?) = id == (other as? LocalContact?)?.id -// -// override fun hashCode() = id ?: 0 -//} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt deleted file mode 100644 index c48a17f9..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/Organization.kt +++ /dev/null @@ -1,7 +0,0 @@ -//package com.simplemobiletools.contacts.pro.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/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt deleted file mode 100644 index 7c5e3e70..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/PhoneNumberConverter.kt +++ /dev/null @@ -1,4 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//// need for hacky parsing of no longer minified PhoneNumber model in Converters.kt -//data class PhoneNumberConverter(var a: String, var b: Int, var c: String, var d: String, var e: Boolean = false) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt deleted file mode 100644 index 7f08c5a4..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/SocialAction.kt +++ /dev/null @@ -1,3 +0,0 @@ -//package com.simplemobiletools.contacts.pro.models -// -//data class SocialAction(var actionId: Int, var type: Int, var label: String, var mimetype: String, val dataId: Long, val packageName: String) From 66ff093a66412f90a5a7eb80ce8fcd792e03f7c7 Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Tue, 21 Feb 2023 13:15:48 +0100 Subject: [PATCH 3/6] fix: use baseConfig instead of ContactsConfig --- .../pro/activities/EditContactActivity.kt | 6 +- .../activities/InsertOrEditContactActivity.kt | 6 +- .../contacts/pro/activities/MainActivity.kt | 52 ++++++++--------- .../pro/activities/SettingsActivity.kt | 56 +++++++++--------- .../pro/activities/ViewContactActivity.kt | 8 +-- .../contacts/pro/adapters/ContactsAdapter.kt | 4 +- .../contacts/pro/adapters/GroupsAdapter.kt | 2 +- .../pro/adapters/SelectContactsAdapter.kt | 4 +- .../MyContactsContentProvider.kt | 4 +- .../pro/dialogs/ChangeSortingDialog.kt | 4 +- .../pro/dialogs/ExportContactsDialog.kt | 4 +- .../pro/dialogs/FilterContactSourcesDialog.kt | 4 +- .../pro/dialogs/ImportContactsDialog.kt | 2 +- .../pro/dialogs/ManageVisibleFieldsDialog.kt | 8 +-- .../pro/dialogs/ManageVisibleTabsDialog.kt | 6 +- .../pro/dialogs/MyDatePickerDialog.kt | 4 +- .../contacts/pro/extensions/Activity.kt | 4 +- .../pro/fragments/MyViewPagerFragment.kt | 18 +++--- .../contacts/pro/helpers/VcfExporter.kt | 57 ++++++++++--------- 19 files changed, 129 insertions(+), 124 deletions(-) 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 ad53706b..d4007a7e 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 @@ -388,7 +388,7 @@ class EditContactActivity : ContactActivity() { } private fun setupFieldVisibility() { - val showFields = contactsConfig.showContactFields + val showFields = this.baseConfig.showContactFields if (showFields and (SHOW_PREFIX_FIELD or SHOW_FIRST_NAME_FIELD or SHOW_MIDDLE_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_SUFFIX_FIELD) == 0) { contact_name_image.beInvisible() } @@ -744,7 +744,7 @@ class EditContactActivity : ContactActivity() { } private fun setupNewContact() { - originalContactSource = if (hasContactPermissions()) contactsConfig.lastUsedContactSource else SMT_PRIVATE + originalContactSource = if (hasContactPermissions()) this.baseConfig.lastUsedContactSource else SMT_PRIVATE contact = getEmptyContact() getPublicContactSource(contact!!.source) { contact_source.text = if (it == "") getString(R.string.phone_storage) else it @@ -1049,7 +1049,7 @@ class EditContactActivity : ContactActivity() { contact = contactValues ensureBackgroundThread { - contactsConfig.lastUsedContactSource = contact!!.source + this.baseConfig.lastUsedContactSource = contact!!.source when { contact!!.id == 0 -> insertNewContact(false) originalContactSource != contact!!.source -> insertNewContact(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt index 90b1f1c9..6a7f51d7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt @@ -17,7 +17,7 @@ import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.pro.helpers.ADD_NEW_CONTACT_NUMBER import com.simplemobiletools.contacts.pro.helpers.KEY_EMAIL @@ -159,7 +159,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { insert_edit_tabs_holder.removeAllTabs() contactsFavoritesList.forEachIndexed { index, value -> - if (contactsConfig.showTabs and value != 0) { + if (this.baseConfig.showTabs and value != 0) { insert_edit_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -349,7 +349,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun getTabsMask(): Int { var mask = TAB_CONTACTS - if (contactsConfig.showTabs and TAB_FAVORITES != 0) { + if (this.baseConfig.showTabs and TAB_FAVORITES != 0) { mask += TAB_FAVORITES } return mask 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 18f1024f..fccc2537 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 @@ -18,7 +18,7 @@ import com.simplemobiletools.commons.databases.ContactsDatabase import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.Release @@ -90,19 +90,19 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { override fun onResume() { super.onResume() - if (storedShowPhoneNumbers != contactsConfig.showPhoneNumbers) { + if (storedShowPhoneNumbers != this.baseConfig.showPhoneNumbers) { System.exit(0) return } - if (storedShowTabs != contactsConfig.showTabs) { - contactsConfig.lastUsedViewPagerPage = 0 + if (storedShowTabs != this.baseConfig.showTabs) { + this.baseConfig.lastUsedViewPagerPage = 0 finish() startActivity(intent) return } - val configShowContactThumbnails = contactsConfig.showContactThumbnails + val configShowContactThumbnails = this.baseConfig.showContactThumbnails if (storedShowContactThumbnails != configShowContactThumbnails) { getAllFragments().forEach { it?.showContactThumbnailsChanged(configShowContactThumbnails) @@ -119,13 +119,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { updateMenuColors() setupTabColors() - val configStartNameWithSurname = contactsConfig.startNameWithSurname + val configStartNameWithSurname = this.baseConfig.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } - val configFontSize = contactsConfig.fontSize + val configFontSize = this.baseConfig.fontSize if (storedFontSize != configFontSize) { getAllFragments().forEach { it?.fontSizeChanged() @@ -144,23 +144,23 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_dialpad_button.apply { setImageDrawable(dialpadIcon) background.applyColorFilter(properPrimaryColor) - beVisibleIf(contactsConfig.showDialpadButton) + beVisibleIf(this@MainActivity.baseConfig.showDialpadButton) } isFirstResume = false checkShortcuts() - if (!contactsConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { + if (!this.baseConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { val dialogText = getString(R.string.upgraded_to_pro_contacts, getString(R.string.phone_storage_hidden)) ConfirmationDialog(this, dialogText, 0, R.string.ok, 0, false) {} - contactsConfig.wasUpgradedFromFreeShown = true + this.baseConfig.wasUpgradedFromFreeShown = true } } override fun onPause() { super.onPause() storeStateVariables() - contactsConfig.lastUsedViewPagerPage = view_pager.currentItem + this.baseConfig.lastUsedViewPagerPage = view_pager.currentItem } override fun onDestroy() { @@ -197,7 +197,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_menu.getToolbar().menu.apply { findItem(R.id.sort).isVisible = currentFragment != groups_fragment findItem(R.id.filter).isVisible = currentFragment != groups_fragment - findItem(R.id.dialpad).isVisible = !contactsConfig.showDialpadButton + findItem(R.id.dialpad).isVisible = !this@MainActivity.baseConfig.showDialpadButton findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) } } @@ -239,7 +239,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun storeStateVariables() { - contactsConfig.apply { + this.baseConfig.apply { storedShowContactThumbnails = showContactThumbnails storedShowPhoneNumbers = showPhoneNumbers storedStartNameWithSurname = startNameWithSurname @@ -250,13 +250,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { @SuppressLint("NewApi") private fun checkShortcuts() { - val appIconColor = contactsConfig.appIconColor - if (isNougatMR1Plus() && contactsConfig.lastHandledShortcutColor != appIconColor) { + val appIconColor = this.baseConfig.appIconColor + if (isNougatMR1Plus() && this.baseConfig.lastHandledShortcutColor != appIconColor) { val createNewContact = getCreateNewContactShortcut(appIconColor) try { shortcutManager.dynamicShortcuts = Arrays.asList(createNewContact) - contactsConfig.lastHandledShortcutColor = appIconColor + this.baseConfig.lastHandledShortcutColor = appIconColor } catch (ignored: Exception) { } } @@ -280,7 +280,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getCurrentFragment(): MyViewPagerFragment? { - val showTabs = contactsConfig.showTabs + val showTabs = this.baseConfig.showTabs val fragments = arrayListOf() if (showTabs and TAB_CONTACTS != 0) { fragments.add(contacts_fragment) @@ -314,7 +314,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): ArrayList { - val showTabs = contactsConfig.showTabs + val showTabs = this.baseConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -333,7 +333,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getDeselectedTabDrawableIds(): ArrayList { - val showTabs = contactsConfig.showTabs + val showTabs = this.baseConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -385,7 +385,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { main_tabs_holder.removeAllTabs() tabsList.forEachIndexed { index, value -> - if (contactsConfig.showTabs and value != 0) { + if (this.baseConfig.showTabs and value != 0) { main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -499,7 +499,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun tryExportContacts() { if (isQPlus()) { - ExportContactsDialog(this, contactsConfig.lastExportPath, true) { file, ignoredContactSources -> + ExportContactsDialog(this, this.baseConfig.lastExportPath, true) { file, ignoredContactSources -> ignoredExportContactSources = ignoredContactSources Intent(Intent.ACTION_CREATE_DOCUMENT).apply { @@ -519,7 +519,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } else { handlePermission(PERMISSION_WRITE_STORAGE) { if (it) { - ExportContactsDialog(this, contactsConfig.lastExportPath, false) { file, ignoredContactSources -> + ExportContactsDialog(this, this.baseConfig.lastExportPath, false) { file, ignoredContactSources -> getFileOutputStream(file.toFileDirItem(this), true) { exportContactsTo(ignoredContactSources, it) } @@ -577,7 +577,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { isGettingContacts = true if (view_pager.adapter == null) { - view_pager.adapter = ViewPagerAdapter(this, tabsList, contactsConfig.showTabs) + view_pager.adapter = ViewPagerAdapter(this, tabsList, this.baseConfig.showTabs) view_pager.currentItem = getDefaultTab() } @@ -617,9 +617,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getAllFragments() = arrayListOf(contacts_fragment, favorites_fragment, groups_fragment) private fun getDefaultTab(): Int { - val showTabsMask = contactsConfig.showTabs - return when (contactsConfig.defaultTab) { - TAB_LAST_USED -> contactsConfig.lastUsedViewPagerPage + val showTabsMask = this.baseConfig.showTabs + return when (this.baseConfig.defaultTab) { + TAB_LAST_USED -> this.baseConfig.lastUsedViewPagerPage TAB_CONTACTS -> 0 TAB_FAVORITES -> if (showTabsMask and TAB_CONTACTS > 0) 1 else 0 else -> { 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 29109732..feb3e2cd 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 @@ -8,7 +8,7 @@ import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import kotlinx.android.synthetic.main.activity_settings.* import java.util.* @@ -77,15 +77,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(TAB_LAST_USED, getString(R.string.last_used_tab)) ) - RadioGroupDialog(this@SettingsActivity, items, contactsConfig.defaultTab) { - contactsConfig.defaultTab = it as Int + RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.defaultTab) { + this.baseConfig.defaultTab = it as Int settings_default_tab.text = getDefaultTabText() } } } private fun getDefaultTabText() = getString( - when (baseConfig.defaultTab) { + when (this.baseConfig.defaultTab) { TAB_CONTACTS -> R.string.contacts_tab TAB_FAVORITES -> R.string.favorites_tab TAB_GROUPS -> R.string.groups_tab @@ -103,19 +103,19 @@ class SettingsActivity : SimpleActivity() { RadioItem(FONT_SIZE_EXTRA_LARGE, getString(R.string.extra_large)) ) - RadioGroupDialog(this@SettingsActivity, items, contactsConfig.fontSize) { - contactsConfig.fontSize = it as Int + RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.fontSize) { + this.baseConfig.fontSize = it as Int settings_font_size.text = getFontSizeText() } } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((contactsConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = contactsConfig.useEnglish + settings_use_english_holder.beVisibleIf((this.baseConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settings_use_english.isChecked = this.baseConfig.useEnglish settings_use_english_holder.setOnClickListener { settings_use_english.toggle() - contactsConfig.useEnglish = settings_use_english.isChecked + this.baseConfig.useEnglish = settings_use_english.isChecked System.exit(0) } } @@ -129,50 +129,50 @@ class SettingsActivity : SimpleActivity() { } private fun setupShowContactThumbnails() { - settings_show_contact_thumbnails.isChecked = contactsConfig.showContactThumbnails + settings_show_contact_thumbnails.isChecked = this.baseConfig.showContactThumbnails settings_show_contact_thumbnails_holder.setOnClickListener { settings_show_contact_thumbnails.toggle() - contactsConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked + this.baseConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked } } private fun setupShowPhoneNumbers() { - settings_show_phone_numbers.isChecked = contactsConfig.showPhoneNumbers + settings_show_phone_numbers.isChecked = this.baseConfig.showPhoneNumbers settings_show_phone_numbers_holder.setOnClickListener { settings_show_phone_numbers.toggle() - contactsConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked + this.baseConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked } } private fun setupShowContactsWithNumbers() { - settings_show_only_contacts_with_numbers.isChecked = contactsConfig.showOnlyContactsWithNumbers + settings_show_only_contacts_with_numbers.isChecked = this.baseConfig.showOnlyContactsWithNumbers settings_show_only_contacts_with_numbers_holder.setOnClickListener { settings_show_only_contacts_with_numbers.toggle() - contactsConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked + this.baseConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked } } private fun setupStartNameWithSurname() { - settings_start_name_with_surname.isChecked = contactsConfig.startNameWithSurname + settings_start_name_with_surname.isChecked = this.baseConfig.startNameWithSurname settings_start_name_with_surname_holder.setOnClickListener { settings_start_name_with_surname.toggle() - contactsConfig.startNameWithSurname = settings_start_name_with_surname.isChecked + this.baseConfig.startNameWithSurname = settings_start_name_with_surname.isChecked } } private fun setupShowDialpadButton() { - settings_show_dialpad_button.isChecked = contactsConfig.showDialpadButton + settings_show_dialpad_button.isChecked = this.baseConfig.showDialpadButton settings_show_dialpad_button_holder.setOnClickListener { settings_show_dialpad_button.toggle() - contactsConfig.showDialpadButton = settings_show_dialpad_button.isChecked + this.baseConfig.showDialpadButton = settings_show_dialpad_button.isChecked } } private fun setupShowPrivateContacts() { - settings_show_private_contacts.isChecked = contactsConfig.showPrivateContacts + settings_show_private_contacts.isChecked = this.baseConfig.showPrivateContacts settings_show_private_contacts_holder.setOnClickListener { settings_show_private_contacts.toggle() - contactsConfig.showPrivateContacts = settings_show_private_contacts.isChecked + this.baseConfig.showPrivateContacts = settings_show_private_contacts.isChecked } } @@ -185,15 +185,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(ON_CLICK_EDIT_CONTACT, getString(R.string.edit_contact)) ) - RadioGroupDialog(this@SettingsActivity, items, contactsConfig.onContactClick) { - contactsConfig.onContactClick = it as Int + RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.onContactClick) { + this.baseConfig.onContactClick = it as Int settings_on_contact_click.text = getOnContactClickText() } } } private fun getOnContactClickText() = getString( - when (contactsConfig.onContactClick) { + when (this.baseConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> R.string.call_contact ON_CLICK_VIEW_CONTACT -> R.string.view_contact else -> R.string.edit_contact @@ -201,18 +201,18 @@ class SettingsActivity : SimpleActivity() { ) private fun setupShowCallConfirmation() { - settings_show_call_confirmation.isChecked = contactsConfig.showCallConfirmation + settings_show_call_confirmation.isChecked = this.baseConfig.showCallConfirmation settings_show_call_confirmation_holder.setOnClickListener { settings_show_call_confirmation.toggle() - contactsConfig.showCallConfirmation = settings_show_call_confirmation.isChecked + this.baseConfig.showCallConfirmation = settings_show_call_confirmation.isChecked } } private fun setupMergeDuplicateContacts() { - settings_merge_duplicate_contacts.isChecked = contactsConfig.mergeDuplicateContacts + settings_merge_duplicate_contacts.isChecked = this.baseConfig.mergeDuplicateContacts settings_merge_duplicate_contacts_holder.setOnClickListener { settings_merge_duplicate_contacts.toggle() - contactsConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked + this.baseConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked } } } 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 dc133bee..d9b9df5c 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 @@ -46,7 +46,7 @@ class ViewContactActivity : ContactActivity() { private var showFields = 0 private var fullContact: Contact? = null // contact with all fields filled from duplicates private var duplicateInitialized = false - private val mergeDuplicate: Boolean get() = contactsConfig.mergeDuplicateContacts + private val mergeDuplicate: Boolean get() = this.baseConfig.mergeDuplicateContacts private val COMPARABLE_PHONE_NUMBER_LENGTH = 9 @@ -59,7 +59,7 @@ class ViewContactActivity : ContactActivity() { return } - showFields = contactsConfig.showContactFields + showFields = this.baseConfig.showContactFields contact_wrapper.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN setupMenu() } @@ -122,7 +122,7 @@ class ViewContactActivity : ContactActivity() { findItem(R.id.manage_visible_fields).setOnMenuItemClickListener { ManageVisibleFieldsDialog(this@ViewContactActivity) { - showFields = contactsConfig.showContactFields + showFields = this@ViewContactActivity.baseConfig.showContactFields ensureBackgroundThread { initContact() } @@ -388,7 +388,7 @@ class ViewContactActivity : ContactActivity() { copyOnLongClick(phoneNumber.value) setOnClickListener { - if (contactsConfig.showCallConfirmation) { + if (this@ViewContactActivity.baseConfig.showCallConfirmation) { CallConfirmationDialog(this@ViewContactActivity, phoneNumber.value) { startCallIntent(phoneNumber.value) } 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 cb539c6c..586c7a74 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 @@ -60,7 +60,7 @@ class ContactsAdapter( private val NEW_GROUP_ID = -1 - private var config = activity.contactsConfig + private var config = activity.baseConfig private var textToHighlight = highlightText var startNameWithSurname = config.startNameWithSurname @@ -452,7 +452,7 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" override fun onRowMoved(fromPosition: Int, toPosition: Int) { - activity.contactsConfig.isCustomOrderSelected = true + activity.baseConfig.isCustomOrderSelected = true if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt index e9540145..a4f74cce 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt @@ -27,7 +27,7 @@ class GroupsAdapter( ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { private var textToHighlight = "" - var showContactThumbnails = activity.contactsConfig.showContactThumbnails + var showContactThumbnails = activity.baseConfig.showContactThumbnails var fontSize = activity.getTextSize() init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt index 4e1c552d..ecbbf492 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt @@ -11,7 +11,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.commons.views.MyRecyclerView @@ -30,7 +30,7 @@ class SelectContactsAdapter( RecyclerView.Adapter() { private val itemViews = SparseArray() private val selectedPositions = HashSet() - private val config = activity.contactsConfig + private val config = activity.baseConfig private val adjustedPrimaryColor = activity.getProperPrimaryColor() private val fontSize = activity.getTextSize() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt index 900cb881..a89cd45f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt @@ -6,15 +6,15 @@ import android.database.Cursor import android.database.MatrixCursor import android.net.Uri import com.google.gson.Gson +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.MyContactsContentProvider -import com.simplemobiletools.commons.extensions.contactsConfig import com.simplemobiletools.commons.helpers.LocalContactsHelper class MyContactsContentProvider : ContentProvider() { override fun insert(uri: Uri, contentValues: ContentValues?) = null override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? { - if (context == null || !context!!.contactsConfig.showPrivateContacts) { + if (context == null || !context!!.baseConfig.showPrivateContacts) { return null } else { val matrixCursor = MatrixCursor( diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 44c18836..5ca84879 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -2,7 +2,7 @@ package com.simplemobiletools.contacts.pro.dialogs import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGoneIf -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.* @@ -11,7 +11,7 @@ import kotlinx.android.synthetic.main.dialog_change_sorting.view.* class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCustomSorting: Boolean = false, private val callback: () -> Unit) { private var currSorting = 0 - private var config = activity.contactsConfig + private var config = activity.baseConfig private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null) init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt index 0a4dc314..3c2d3361 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt @@ -5,7 +5,7 @@ import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.models.contacts.* @@ -80,7 +80,7 @@ class ExportContactsDialog( ignoreClicks = true ensureBackgroundThread { - activity.contactsConfig.lastExportPath = file.absolutePath.getParentPath() + activity.baseConfig.lastExportPath = file.absolutePath.getParentPath() val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() val ignoredSources = contactSources .filter { !selectedSources.contains(it) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt index 97a607d8..e52e8d26 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt @@ -7,7 +7,7 @@ import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.extensions.getVisibleContactSources import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.models.contacts.* @@ -77,7 +77,7 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb }.toHashSet() if (activity.getVisibleContactSources() != ignoredContactSources) { - activity.contactsConfig.ignoredContactSources = ignoredContactSources + activity.baseConfig.ignoredContactSources = ignoredContactSources callback() } dialog?.dismiss() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt index 149e287d..436118b3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt @@ -19,7 +19,7 @@ class ImportContactsDialog(val activity: SimpleActivity, val path: String, priva init { val view = (activity.layoutInflater.inflate(R.layout.dialog_import_contacts, null) as ViewGroup).apply { - targetContactSource = activity.contactsConfig.lastUsedContactSource + targetContactSource = activity.baseConfig.lastUsedContactSource activity.getPublicContactSource(targetContactSource) { import_contacts_title.setText(it) if (it.isEmpty()) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt index d70d6cef..6d9147b2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt @@ -5,7 +5,7 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.* class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: (hasSomethingChanged: Boolean) -> Unit) { @@ -33,7 +33,7 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: put(SHOW_RINGTONE_FIELD, R.id.manage_ringtone) } - val showContactFields = activity.contactsConfig.showContactFields + val showContactFields = activity.baseConfig.showContactFields for ((key, value) in fields) { view.findViewById(value).isChecked = showContactFields and key != 0 } @@ -54,8 +54,8 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: } } - val hasSomethingChanged = activity.contactsConfig.showContactFields != result - activity.contactsConfig.showContactFields = result + val hasSomethingChanged = activity.baseConfig.showContactFields != result + activity.baseConfig.showContactFields = result if (hasSomethingChanged) { callback(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt index 68e95f18..9adf617b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt @@ -8,7 +8,7 @@ import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.helpers.TAB_GROUPS import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.ALL_TABS_MASK class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { @@ -22,7 +22,7 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { put(TAB_GROUPS, R.id.manage_visible_tabs_groups) } - val showTabs = activity.contactsConfig.showTabs + val showTabs = activity.baseConfig.showTabs for ((key, value) in tabs) { view.findViewById(value).isChecked = showTabs and key != 0 } @@ -47,6 +47,6 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { result = ALL_TABS_MASK } - activity.contactsConfig.showTabs = result + activity.baseConfig.showTabs = result } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt index 90b94058..3fcb7b7c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt @@ -5,7 +5,7 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.isSPlus import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import kotlinx.android.synthetic.main.dialog_date_picker.view.* import org.joda.time.DateTime import java.util.* @@ -38,7 +38,7 @@ class MyDatePickerDialog(val activity: BaseSimpleActivity, val defaultDate: Stri } } - if (activity.contactsConfig.isUsingSystemTheme && isSPlus()) { + if (activity.baseConfig.isUsingSystemTheme && isSPlus()) { val dialogBackgroundColor = activity.getColor(R.color.you_dialog_background_color) view.dialog_holder.setBackgroundColor(dialogBackgroundColor) view.date_picker.setBackgroundColor(dialogBackgroundColor) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt index 11f8cc58..db7eac9b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt @@ -30,7 +30,7 @@ fun SimpleActivity.startCallIntent(recipient: String) { } fun SimpleActivity.tryStartCall(contact: Contact) { - if (contactsConfig.showCallConfirmation) { + if (this.baseConfig.showCallConfirmation) { CallConfirmationDialog(this, contact.getNameToDisplay()) { startCall(contact) } @@ -107,7 +107,7 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { } fun SimpleActivity.handleGenericContactClick(contact: Contact) { - when (contactsConfig.onContactClick) { + when (this.baseConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> callContact(contact) ON_CLICK_VIEW_CONTACT -> viewContact(contact) ON_CLICK_EDIT_CONTACT -> editContact(contact) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index 429b60a2..2faa833c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -17,7 +17,7 @@ import com.simplemobiletools.contacts.pro.activities.MainActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter import com.simplemobiletools.contacts.pro.adapters.GroupsAdapter -import com.simplemobiletools.commons.extensions.contactsConfig +import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.Converters import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener @@ -38,13 +38,13 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) private var lastHashCode = 0 private var contactsIgnoringSearch = ArrayList() private var groupsIgnoringSearch = ArrayList() - private lateinit var config: ContactsConfig + private lateinit var config: BaseConfig var skipHashComparing = false var forceListRedraw = false fun setupFragment(activity: SimpleActivity) { - config = activity.contactsConfig + config = activity.baseConfig if (this.activity == null) { this.activity = activity fragment_fab?.beGoneIf(activity is InsertOrEditContactActivity) @@ -124,7 +124,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) this is FavoritesFragment -> { val favorites = contacts.filter { it.starred == 1 } as ArrayList - if (activity!!.contactsConfig.isCustomOrderSelected) { + if (activity!!.baseConfig.isCustomOrderSelected) { sortByCustomOrder(favorites) } else { favorites @@ -158,7 +158,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun sortByCustomOrder(starred: List): ArrayList { - val favoritesOrder = activity!!.contactsConfig.favoritesContactsOrder + val favoritesOrder = activity!!.baseConfig.favoritesContactsOrder if (favoritesOrder.isEmpty()) { return ArrayList(starred) @@ -218,7 +218,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } else { (currAdapter as GroupsAdapter).apply { - showContactThumbnails = activity.contactsConfig.showContactThumbnails + showContactThumbnails = activity.baseConfig.showContactThumbnails updateItems(storedGroups) } } @@ -280,7 +280,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) activity?.apply { val orderIds = items.map { it.id } val orderGsonString = Gson().toJson(orderIds) - contactsConfig.favoritesContactsOrder = orderGsonString + this.baseConfig.favoritesContactsOrder = orderGsonString } } @@ -299,7 +299,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun setupLetterFastscroller(contacts: ArrayList) { - val sorting = context.contactsConfig.sorting + val sorting = context.baseConfig.sorting letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> try { val contact = contacts[position] @@ -308,7 +308,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) sorting and SORT_BY_SURNAME != 0 && contact.surname.isNotEmpty() -> contact.surname sorting and SORT_BY_MIDDLE_NAME != 0 && contact.middleName.isNotEmpty() -> contact.middleName sorting and SORT_BY_FIRST_NAME != 0 && contact.firstName.isNotEmpty() -> contact.firstName - context.contactsConfig.startNameWithSurname -> contact.surname + context.baseConfig.startNameWithSurname -> contact.surname else -> contact.firstName } 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 e02462cc..87a9b3fd 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 @@ -1,7 +1,11 @@ package com.simplemobiletools.contacts.pro.helpers import android.net.Uri -import android.provider.ContactsContract +import android.provider.ContactsContract.CommonDataKinds.Email +import android.provider.ContactsContract.CommonDataKinds.Event +import android.provider.ContactsContract.CommonDataKinds.Im +import android.provider.ContactsContract.CommonDataKinds.Phone +import android.provider.ContactsContract.CommonDataKinds.StructuredPostal import android.provider.MediaStore import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.getByteArray @@ -79,7 +83,7 @@ class VcfExporter { } contact.events.forEach { event -> - if (event.type == ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY || event.type == ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) { + if (event.type == Event.TYPE_ANNIVERSARY || event.type == Event.TYPE_BIRTHDAY) { val dateTime = event.value.getDateTimeFromDateString(false) Calendar.getInstance().apply { clear() @@ -87,10 +91,11 @@ class VcfExporter { set(Calendar.YEAR, 1900) } else { set(Calendar.YEAR, dateTime.year) + } set(Calendar.MONTH, dateTime.monthOfYear - 1) set(Calendar.DAY_OF_MONTH, dateTime.dayOfMonth) - if (event.type == ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) { + if (event.type == Event.TYPE_BIRTHDAY) { card.birthdays.add(Birthday(time)) } else { card.anniversaries.add(Anniversary(time)) @@ -108,14 +113,14 @@ class VcfExporter { contact.IMs.forEach { val impp = when (it.type) { - ContactsContract.CommonDataKinds.Im.PROTOCOL_AIM -> Impp.aim(it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_MSN -> Impp.msn(it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_ICQ -> Impp.icq(it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_SKYPE -> Impp.skype(it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ -> Impp(QQ, it.value) - ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) + Im.PROTOCOL_AIM -> Impp.aim(it.value) + Im.PROTOCOL_YAHOO -> Impp.yahoo(it.value) + Im.PROTOCOL_MSN -> Impp.msn(it.value) + Im.PROTOCOL_ICQ -> Impp.icq(it.value) + Im.PROTOCOL_SKYPE -> Impp.skype(it.value) + Im.PROTOCOL_GOOGLE_TALK -> Impp(HANGOUTS, it.value) + Im.PROTOCOL_QQ -> Impp(QQ, it.value) + Im.PROTOCOL_JABBER -> Impp(JABBER, it.value) else -> Impp(it.label, it.value) } @@ -171,29 +176,29 @@ class VcfExporter { } private fun getPhoneNumberTypeLabel(type: Int, label: String) = when (type) { - ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE -> CELL - ContactsContract.CommonDataKinds.Phone.TYPE_HOME -> HOME - ContactsContract.CommonDataKinds.Phone.TYPE_WORK -> WORK - ContactsContract.CommonDataKinds.Phone.TYPE_MAIN -> PREF - ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK -> WORK_FAX - ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME -> HOME_FAX - ContactsContract.CommonDataKinds.Phone.TYPE_PAGER -> PAGER - ContactsContract.CommonDataKinds.Phone.TYPE_OTHER -> OTHER + Phone.TYPE_MOBILE -> CELL + Phone.TYPE_HOME -> HOME + Phone.TYPE_WORK -> WORK + Phone.TYPE_MAIN -> PREF + Phone.TYPE_FAX_WORK -> WORK_FAX + Phone.TYPE_FAX_HOME -> HOME_FAX + Phone.TYPE_PAGER -> PAGER + Phone.TYPE_OTHER -> OTHER else -> label } private fun getEmailTypeLabel(type: Int, label: String) = when (type) { - ContactsContract.CommonDataKinds.Email.TYPE_HOME -> HOME - ContactsContract.CommonDataKinds.Email.TYPE_WORK -> WORK - ContactsContract.CommonDataKinds.Email.TYPE_MOBILE -> MOBILE - ContactsContract.CommonDataKinds.Email.TYPE_OTHER -> OTHER + Email.TYPE_HOME -> HOME + Email.TYPE_WORK -> WORK + Email.TYPE_MOBILE -> MOBILE + Email.TYPE_OTHER -> OTHER else -> label } private fun getAddressTypeLabel(type: Int, label: String) = when (type) { - ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME -> HOME - ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK -> WORK - ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER -> OTHER + StructuredPostal.TYPE_HOME -> HOME + StructuredPostal.TYPE_WORK -> WORK + StructuredPostal.TYPE_OTHER -> OTHER else -> label } } From 8a84e84a8d66a0457c10c77566b6708b6c173d5b Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Thu, 23 Feb 2023 20:53:09 +0100 Subject: [PATCH 4/6] fix: removed reference to `this` when using baseConfig --- .../pro/activities/EditContactActivity.kt | 6 +-- .../activities/InsertOrEditContactActivity.kt | 4 +- .../contacts/pro/activities/MainActivity.kt | 50 ++++++++--------- .../pro/activities/SettingsActivity.kt | 54 +++++++++---------- .../pro/activities/ViewContactActivity.kt | 8 +-- .../contacts/pro/extensions/Activity.kt | 4 +- .../pro/fragments/MyViewPagerFragment.kt | 2 +- 7 files changed, 64 insertions(+), 64 deletions(-) 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 d4007a7e..4d1d1812 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 @@ -388,7 +388,7 @@ class EditContactActivity : ContactActivity() { } private fun setupFieldVisibility() { - val showFields = this.baseConfig.showContactFields + val showFields = baseConfig.showContactFields if (showFields and (SHOW_PREFIX_FIELD or SHOW_FIRST_NAME_FIELD or SHOW_MIDDLE_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_SUFFIX_FIELD) == 0) { contact_name_image.beInvisible() } @@ -744,7 +744,7 @@ class EditContactActivity : ContactActivity() { } private fun setupNewContact() { - originalContactSource = if (hasContactPermissions()) this.baseConfig.lastUsedContactSource else SMT_PRIVATE + originalContactSource = if (hasContactPermissions()) baseConfig.lastUsedContactSource else SMT_PRIVATE contact = getEmptyContact() getPublicContactSource(contact!!.source) { contact_source.text = if (it == "") getString(R.string.phone_storage) else it @@ -1049,7 +1049,7 @@ class EditContactActivity : ContactActivity() { contact = contactValues ensureBackgroundThread { - this.baseConfig.lastUsedContactSource = contact!!.source + baseConfig.lastUsedContactSource = contact!!.source when { contact!!.id == 0 -> insertNewContact(false) originalContactSource != contact!!.source -> insertNewContact(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt index 6a7f51d7..9de04ac0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt @@ -159,7 +159,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { insert_edit_tabs_holder.removeAllTabs() contactsFavoritesList.forEachIndexed { index, value -> - if (this.baseConfig.showTabs and value != 0) { + if (baseConfig.showTabs and value != 0) { insert_edit_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -349,7 +349,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun getTabsMask(): Int { var mask = TAB_CONTACTS - if (this.baseConfig.showTabs and TAB_FAVORITES != 0) { + if (baseConfig.showTabs and TAB_FAVORITES != 0) { mask += TAB_FAVORITES } return mask 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 fccc2537..14a394e4 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 @@ -90,19 +90,19 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { override fun onResume() { super.onResume() - if (storedShowPhoneNumbers != this.baseConfig.showPhoneNumbers) { + if (storedShowPhoneNumbers != baseConfig.showPhoneNumbers) { System.exit(0) return } - if (storedShowTabs != this.baseConfig.showTabs) { - this.baseConfig.lastUsedViewPagerPage = 0 + if (storedShowTabs != baseConfig.showTabs) { + baseConfig.lastUsedViewPagerPage = 0 finish() startActivity(intent) return } - val configShowContactThumbnails = this.baseConfig.showContactThumbnails + val configShowContactThumbnails = baseConfig.showContactThumbnails if (storedShowContactThumbnails != configShowContactThumbnails) { getAllFragments().forEach { it?.showContactThumbnailsChanged(configShowContactThumbnails) @@ -119,13 +119,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { updateMenuColors() setupTabColors() - val configStartNameWithSurname = this.baseConfig.startNameWithSurname + val configStartNameWithSurname = baseConfig.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } - val configFontSize = this.baseConfig.fontSize + val configFontSize = baseConfig.fontSize if (storedFontSize != configFontSize) { getAllFragments().forEach { it?.fontSizeChanged() @@ -144,23 +144,23 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_dialpad_button.apply { setImageDrawable(dialpadIcon) background.applyColorFilter(properPrimaryColor) - beVisibleIf(this@MainActivity.baseConfig.showDialpadButton) + beVisibleIf(baseConfig.showDialpadButton) } isFirstResume = false checkShortcuts() - if (!this.baseConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { + if (!baseConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { val dialogText = getString(R.string.upgraded_to_pro_contacts, getString(R.string.phone_storage_hidden)) ConfirmationDialog(this, dialogText, 0, R.string.ok, 0, false) {} - this.baseConfig.wasUpgradedFromFreeShown = true + baseConfig.wasUpgradedFromFreeShown = true } } override fun onPause() { super.onPause() storeStateVariables() - this.baseConfig.lastUsedViewPagerPage = view_pager.currentItem + baseConfig.lastUsedViewPagerPage = view_pager.currentItem } override fun onDestroy() { @@ -197,7 +197,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_menu.getToolbar().menu.apply { findItem(R.id.sort).isVisible = currentFragment != groups_fragment findItem(R.id.filter).isVisible = currentFragment != groups_fragment - findItem(R.id.dialpad).isVisible = !this@MainActivity.baseConfig.showDialpadButton + findItem(R.id.dialpad).isVisible = !baseConfig.showDialpadButton findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) } } @@ -239,7 +239,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun storeStateVariables() { - this.baseConfig.apply { + baseConfig.apply { storedShowContactThumbnails = showContactThumbnails storedShowPhoneNumbers = showPhoneNumbers storedStartNameWithSurname = startNameWithSurname @@ -250,13 +250,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { @SuppressLint("NewApi") private fun checkShortcuts() { - val appIconColor = this.baseConfig.appIconColor - if (isNougatMR1Plus() && this.baseConfig.lastHandledShortcutColor != appIconColor) { + val appIconColor = baseConfig.appIconColor + if (isNougatMR1Plus() && baseConfig.lastHandledShortcutColor != appIconColor) { val createNewContact = getCreateNewContactShortcut(appIconColor) try { shortcutManager.dynamicShortcuts = Arrays.asList(createNewContact) - this.baseConfig.lastHandledShortcutColor = appIconColor + baseConfig.lastHandledShortcutColor = appIconColor } catch (ignored: Exception) { } } @@ -280,7 +280,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getCurrentFragment(): MyViewPagerFragment? { - val showTabs = this.baseConfig.showTabs + val showTabs = baseConfig.showTabs val fragments = arrayListOf() if (showTabs and TAB_CONTACTS != 0) { fragments.add(contacts_fragment) @@ -314,7 +314,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): ArrayList { - val showTabs = this.baseConfig.showTabs + val showTabs = baseConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -333,7 +333,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getDeselectedTabDrawableIds(): ArrayList { - val showTabs = this.baseConfig.showTabs + val showTabs = baseConfig.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -385,7 +385,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { main_tabs_holder.removeAllTabs() tabsList.forEachIndexed { index, value -> - if (this.baseConfig.showTabs and value != 0) { + if (baseConfig.showTabs and value != 0) { main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -499,7 +499,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun tryExportContacts() { if (isQPlus()) { - ExportContactsDialog(this, this.baseConfig.lastExportPath, true) { file, ignoredContactSources -> + ExportContactsDialog(this, baseConfig.lastExportPath, true) { file, ignoredContactSources -> ignoredExportContactSources = ignoredContactSources Intent(Intent.ACTION_CREATE_DOCUMENT).apply { @@ -519,7 +519,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } else { handlePermission(PERMISSION_WRITE_STORAGE) { if (it) { - ExportContactsDialog(this, this.baseConfig.lastExportPath, false) { file, ignoredContactSources -> + ExportContactsDialog(this, baseConfig.lastExportPath, false) { file, ignoredContactSources -> getFileOutputStream(file.toFileDirItem(this), true) { exportContactsTo(ignoredContactSources, it) } @@ -577,7 +577,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { isGettingContacts = true if (view_pager.adapter == null) { - view_pager.adapter = ViewPagerAdapter(this, tabsList, this.baseConfig.showTabs) + view_pager.adapter = ViewPagerAdapter(this, tabsList, baseConfig.showTabs) view_pager.currentItem = getDefaultTab() } @@ -617,9 +617,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getAllFragments() = arrayListOf(contacts_fragment, favorites_fragment, groups_fragment) private fun getDefaultTab(): Int { - val showTabsMask = this.baseConfig.showTabs - return when (this.baseConfig.defaultTab) { - TAB_LAST_USED -> this.baseConfig.lastUsedViewPagerPage + val showTabsMask = baseConfig.showTabs + return when (baseConfig.defaultTab) { + TAB_LAST_USED -> baseConfig.lastUsedViewPagerPage TAB_CONTACTS -> 0 TAB_FAVORITES -> if (showTabsMask and TAB_CONTACTS > 0) 1 else 0 else -> { 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 feb3e2cd..57edb7ec 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 @@ -77,15 +77,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(TAB_LAST_USED, getString(R.string.last_used_tab)) ) - RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.defaultTab) { - this.baseConfig.defaultTab = it as Int + RadioGroupDialog(this@SettingsActivity, items, baseConfig.defaultTab) { + baseConfig.defaultTab = it as Int settings_default_tab.text = getDefaultTabText() } } } private fun getDefaultTabText() = getString( - when (this.baseConfig.defaultTab) { + when (baseConfig.defaultTab) { TAB_CONTACTS -> R.string.contacts_tab TAB_FAVORITES -> R.string.favorites_tab TAB_GROUPS -> R.string.groups_tab @@ -103,19 +103,19 @@ class SettingsActivity : SimpleActivity() { RadioItem(FONT_SIZE_EXTRA_LARGE, getString(R.string.extra_large)) ) - RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.fontSize) { - this.baseConfig.fontSize = it as Int + RadioGroupDialog(this@SettingsActivity, items, baseConfig.fontSize) { + baseConfig.fontSize = it as Int settings_font_size.text = getFontSizeText() } } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((this.baseConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = this.baseConfig.useEnglish + settings_use_english_holder.beVisibleIf((baseConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settings_use_english.isChecked = baseConfig.useEnglish settings_use_english_holder.setOnClickListener { settings_use_english.toggle() - this.baseConfig.useEnglish = settings_use_english.isChecked + baseConfig.useEnglish = settings_use_english.isChecked System.exit(0) } } @@ -129,50 +129,50 @@ class SettingsActivity : SimpleActivity() { } private fun setupShowContactThumbnails() { - settings_show_contact_thumbnails.isChecked = this.baseConfig.showContactThumbnails + settings_show_contact_thumbnails.isChecked = baseConfig.showContactThumbnails settings_show_contact_thumbnails_holder.setOnClickListener { settings_show_contact_thumbnails.toggle() - this.baseConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked + baseConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked } } private fun setupShowPhoneNumbers() { - settings_show_phone_numbers.isChecked = this.baseConfig.showPhoneNumbers + settings_show_phone_numbers.isChecked = baseConfig.showPhoneNumbers settings_show_phone_numbers_holder.setOnClickListener { settings_show_phone_numbers.toggle() - this.baseConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked + baseConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked } } private fun setupShowContactsWithNumbers() { - settings_show_only_contacts_with_numbers.isChecked = this.baseConfig.showOnlyContactsWithNumbers + settings_show_only_contacts_with_numbers.isChecked = baseConfig.showOnlyContactsWithNumbers settings_show_only_contacts_with_numbers_holder.setOnClickListener { settings_show_only_contacts_with_numbers.toggle() - this.baseConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked + baseConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked } } private fun setupStartNameWithSurname() { - settings_start_name_with_surname.isChecked = this.baseConfig.startNameWithSurname + settings_start_name_with_surname.isChecked = baseConfig.startNameWithSurname settings_start_name_with_surname_holder.setOnClickListener { settings_start_name_with_surname.toggle() - this.baseConfig.startNameWithSurname = settings_start_name_with_surname.isChecked + baseConfig.startNameWithSurname = settings_start_name_with_surname.isChecked } } private fun setupShowDialpadButton() { - settings_show_dialpad_button.isChecked = this.baseConfig.showDialpadButton + settings_show_dialpad_button.isChecked = baseConfig.showDialpadButton settings_show_dialpad_button_holder.setOnClickListener { settings_show_dialpad_button.toggle() - this.baseConfig.showDialpadButton = settings_show_dialpad_button.isChecked + baseConfig.showDialpadButton = settings_show_dialpad_button.isChecked } } private fun setupShowPrivateContacts() { - settings_show_private_contacts.isChecked = this.baseConfig.showPrivateContacts + settings_show_private_contacts.isChecked = baseConfig.showPrivateContacts settings_show_private_contacts_holder.setOnClickListener { settings_show_private_contacts.toggle() - this.baseConfig.showPrivateContacts = settings_show_private_contacts.isChecked + baseConfig.showPrivateContacts = settings_show_private_contacts.isChecked } } @@ -185,15 +185,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(ON_CLICK_EDIT_CONTACT, getString(R.string.edit_contact)) ) - RadioGroupDialog(this@SettingsActivity, items, this.baseConfig.onContactClick) { - this.baseConfig.onContactClick = it as Int + RadioGroupDialog(this@SettingsActivity, items, baseConfig.onContactClick) { + baseConfig.onContactClick = it as Int settings_on_contact_click.text = getOnContactClickText() } } } private fun getOnContactClickText() = getString( - when (this.baseConfig.onContactClick) { + when (baseConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> R.string.call_contact ON_CLICK_VIEW_CONTACT -> R.string.view_contact else -> R.string.edit_contact @@ -201,18 +201,18 @@ class SettingsActivity : SimpleActivity() { ) private fun setupShowCallConfirmation() { - settings_show_call_confirmation.isChecked = this.baseConfig.showCallConfirmation + settings_show_call_confirmation.isChecked = baseConfig.showCallConfirmation settings_show_call_confirmation_holder.setOnClickListener { settings_show_call_confirmation.toggle() - this.baseConfig.showCallConfirmation = settings_show_call_confirmation.isChecked + baseConfig.showCallConfirmation = settings_show_call_confirmation.isChecked } } private fun setupMergeDuplicateContacts() { - settings_merge_duplicate_contacts.isChecked = this.baseConfig.mergeDuplicateContacts + settings_merge_duplicate_contacts.isChecked = baseConfig.mergeDuplicateContacts settings_merge_duplicate_contacts_holder.setOnClickListener { settings_merge_duplicate_contacts.toggle() - this.baseConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked + baseConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked } } } 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 d9b9df5c..4f414eba 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 @@ -46,7 +46,7 @@ class ViewContactActivity : ContactActivity() { private var showFields = 0 private var fullContact: Contact? = null // contact with all fields filled from duplicates private var duplicateInitialized = false - private val mergeDuplicate: Boolean get() = this.baseConfig.mergeDuplicateContacts + private val mergeDuplicate: Boolean get() = baseConfig.mergeDuplicateContacts private val COMPARABLE_PHONE_NUMBER_LENGTH = 9 @@ -59,7 +59,7 @@ class ViewContactActivity : ContactActivity() { return } - showFields = this.baseConfig.showContactFields + showFields = baseConfig.showContactFields contact_wrapper.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN setupMenu() } @@ -122,7 +122,7 @@ class ViewContactActivity : ContactActivity() { findItem(R.id.manage_visible_fields).setOnMenuItemClickListener { ManageVisibleFieldsDialog(this@ViewContactActivity) { - showFields = this@ViewContactActivity.baseConfig.showContactFields + showFields = baseConfig.showContactFields ensureBackgroundThread { initContact() } @@ -388,7 +388,7 @@ class ViewContactActivity : ContactActivity() { copyOnLongClick(phoneNumber.value) setOnClickListener { - if (this@ViewContactActivity.baseConfig.showCallConfirmation) { + if (baseConfig.showCallConfirmation) { CallConfirmationDialog(this@ViewContactActivity, phoneNumber.value) { startCallIntent(phoneNumber.value) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt index db7eac9b..e6b19c09 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt @@ -30,7 +30,7 @@ fun SimpleActivity.startCallIntent(recipient: String) { } fun SimpleActivity.tryStartCall(contact: Contact) { - if (this.baseConfig.showCallConfirmation) { + if (baseConfig.showCallConfirmation) { CallConfirmationDialog(this, contact.getNameToDisplay()) { startCall(contact) } @@ -107,7 +107,7 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { } fun SimpleActivity.handleGenericContactClick(contact: Contact) { - when (this.baseConfig.onContactClick) { + when (baseConfig.onContactClick) { ON_CLICK_CALL_CONTACT -> callContact(contact) ON_CLICK_VIEW_CONTACT -> viewContact(contact) ON_CLICK_EDIT_CONTACT -> editContact(contact) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index 2faa833c..f3f2d6f7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -280,7 +280,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) activity?.apply { val orderIds = items.map { it.id } val orderGsonString = Gson().toJson(orderIds) - this.baseConfig.favoritesContactsOrder = orderGsonString + baseConfig.favoritesContactsOrder = orderGsonString } } From 25daf4de8f9285911bafb618b93ea372f6cdb8f0 Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Fri, 24 Feb 2023 11:37:21 +0100 Subject: [PATCH 5/6] fix: use reference config instead of baseConfig --- .../pro/activities/ContactActivity.kt | 8 ++- .../pro/activities/EditContactActivity.kt | 6 +-- .../activities/InsertOrEditContactActivity.kt | 8 +-- .../contacts/pro/activities/MainActivity.kt | 52 +++++++++--------- .../pro/activities/SettingsActivity.kt | 54 +++++++++---------- .../pro/activities/ViewContactActivity.kt | 8 +-- .../contacts/pro/adapters/ContactsAdapter.kt | 4 +- .../contacts/pro/adapters/GroupsAdapter.kt | 3 +- .../pro/adapters/SelectContactsAdapter.kt | 4 +- .../MyContactsContentProvider.kt | 4 +- .../pro/dialogs/ChangeSortingDialog.kt | 4 +- .../pro/dialogs/ExportContactsDialog.kt | 4 +- .../pro/dialogs/FilterContactSourcesDialog.kt | 4 +- .../pro/dialogs/ImportContactsDialog.kt | 3 +- .../pro/dialogs/ManageVisibleFieldsDialog.kt | 8 +-- .../pro/dialogs/ManageVisibleTabsDialog.kt | 6 +-- .../pro/dialogs/MyDatePickerDialog.kt | 4 +- .../contacts/pro/extensions/Activity.kt | 7 ++- .../contacts/pro/extensions/Context.kt | 2 + .../pro/fragments/MyViewPagerFragment.kt | 18 +++---- .../contacts/pro/helpers/Config.kt | 10 ++++ 21 files changed, 116 insertions(+), 105 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt 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 be978240..4e8b5fd0 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 @@ -10,9 +10,7 @@ import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.media.RingtoneManager import android.net.Uri -import android.provider.ContactsContract import android.provider.ContactsContract.CommonDataKinds.* -import android.provider.ContactsContract.CommonDataKinds.Email import android.widget.ImageView import android.widget.TextView import com.bumptech.glide.Glide @@ -31,7 +29,7 @@ import com.simplemobiletools.commons.helpers.letterBackgroundColors import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.extensions.shareContacts -import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.commons.models.contacts.Contact abstract class ContactActivity : SimpleActivity() { protected val PICK_RINGTONE_INTENT_ID = 1500 @@ -209,8 +207,8 @@ abstract class ContactActivity : SimpleActivity() { } fun getEventTextId(type: Int) = when (type) { - ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> R.string.anniversary - ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> R.string.birthday + Event.TYPE_ANNIVERSARY -> R.string.anniversary + 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 4d1d1812..34318028 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 @@ -388,7 +388,7 @@ class EditContactActivity : ContactActivity() { } private fun setupFieldVisibility() { - val showFields = baseConfig.showContactFields + val showFields = config.showContactFields if (showFields and (SHOW_PREFIX_FIELD or SHOW_FIRST_NAME_FIELD or SHOW_MIDDLE_NAME_FIELD or SHOW_SURNAME_FIELD or SHOW_SUFFIX_FIELD) == 0) { contact_name_image.beInvisible() } @@ -744,7 +744,7 @@ class EditContactActivity : ContactActivity() { } private fun setupNewContact() { - originalContactSource = if (hasContactPermissions()) baseConfig.lastUsedContactSource else SMT_PRIVATE + originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE contact = getEmptyContact() getPublicContactSource(contact!!.source) { contact_source.text = if (it == "") getString(R.string.phone_storage) else it @@ -1049,7 +1049,7 @@ class EditContactActivity : ContactActivity() { contact = contactValues ensureBackgroundThread { - baseConfig.lastUsedContactSource = contact!!.source + config.lastUsedContactSource = contact!!.source when { contact!!.id == 0 -> insertNewContact(false) originalContactSource != contact!!.source -> insertNewContact(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt index 9de04ac0..71773824 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/InsertOrEditContactActivity.kt @@ -13,17 +13,17 @@ import android.widget.TextView import androidx.viewpager.widget.ViewPager import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog -import com.simplemobiletools.commons.extensions.baseConfig +import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.pro.helpers.ADD_NEW_CONTACT_NUMBER import com.simplemobiletools.contacts.pro.helpers.KEY_EMAIL import com.simplemobiletools.contacts.pro.helpers.KEY_NAME import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener -import com.simplemobiletools.commons.models.contacts.* import kotlinx.android.synthetic.main.activity_insert_edit_contact.* import kotlinx.android.synthetic.main.fragment_contacts.* import kotlinx.android.synthetic.main.fragment_favorites.* @@ -159,7 +159,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { insert_edit_tabs_holder.removeAllTabs() contactsFavoritesList.forEachIndexed { index, value -> - if (baseConfig.showTabs and value != 0) { + if (config.showTabs and value != 0) { insert_edit_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -349,7 +349,7 @@ class InsertOrEditContactActivity : SimpleActivity(), RefreshContactsListener { private fun getTabsMask(): Int { var mask = TAB_CONTACTS - if (baseConfig.showTabs and TAB_FAVORITES != 0) { + if (config.showTabs and TAB_FAVORITES != 0) { mask += TAB_FAVORITES } return mask 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 14a394e4..122fbc6a 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 @@ -18,7 +18,6 @@ import com.simplemobiletools.commons.databases.ContactsDatabase import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.FAQItem import com.simplemobiletools.commons.models.Release @@ -30,6 +29,7 @@ import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.ExportContactsDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog +import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment @@ -90,19 +90,19 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { override fun onResume() { super.onResume() - if (storedShowPhoneNumbers != baseConfig.showPhoneNumbers) { + if (storedShowPhoneNumbers != config.showPhoneNumbers) { System.exit(0) return } - if (storedShowTabs != baseConfig.showTabs) { - baseConfig.lastUsedViewPagerPage = 0 + if (storedShowTabs != config.showTabs) { + config.lastUsedViewPagerPage = 0 finish() startActivity(intent) return } - val configShowContactThumbnails = baseConfig.showContactThumbnails + val configShowContactThumbnails = config.showContactThumbnails if (storedShowContactThumbnails != configShowContactThumbnails) { getAllFragments().forEach { it?.showContactThumbnailsChanged(configShowContactThumbnails) @@ -119,13 +119,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { updateMenuColors() setupTabColors() - val configStartNameWithSurname = baseConfig.startNameWithSurname + val configStartNameWithSurname = config.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } - val configFontSize = baseConfig.fontSize + val configFontSize = config.fontSize if (storedFontSize != configFontSize) { getAllFragments().forEach { it?.fontSizeChanged() @@ -144,23 +144,23 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_dialpad_button.apply { setImageDrawable(dialpadIcon) background.applyColorFilter(properPrimaryColor) - beVisibleIf(baseConfig.showDialpadButton) + beVisibleIf(config.showDialpadButton) } isFirstResume = false checkShortcuts() - if (!baseConfig.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { + if (!config.wasUpgradedFromFreeShown && isPackageInstalled("com.simplemobiletools.contacts")) { val dialogText = getString(R.string.upgraded_to_pro_contacts, getString(R.string.phone_storage_hidden)) ConfirmationDialog(this, dialogText, 0, R.string.ok, 0, false) {} - baseConfig.wasUpgradedFromFreeShown = true + config.wasUpgradedFromFreeShown = true } } override fun onPause() { super.onPause() storeStateVariables() - baseConfig.lastUsedViewPagerPage = view_pager.currentItem + config.lastUsedViewPagerPage = view_pager.currentItem } override fun onDestroy() { @@ -197,7 +197,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { main_menu.getToolbar().menu.apply { findItem(R.id.sort).isVisible = currentFragment != groups_fragment findItem(R.id.filter).isVisible = currentFragment != groups_fragment - findItem(R.id.dialpad).isVisible = !baseConfig.showDialpadButton + findItem(R.id.dialpad).isVisible = !config.showDialpadButton findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) } } @@ -239,7 +239,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun storeStateVariables() { - baseConfig.apply { + config.apply { storedShowContactThumbnails = showContactThumbnails storedShowPhoneNumbers = showPhoneNumbers storedStartNameWithSurname = startNameWithSurname @@ -250,13 +250,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { @SuppressLint("NewApi") private fun checkShortcuts() { - val appIconColor = baseConfig.appIconColor - if (isNougatMR1Plus() && baseConfig.lastHandledShortcutColor != appIconColor) { + val appIconColor = config.appIconColor + if (isNougatMR1Plus() && config.lastHandledShortcutColor != appIconColor) { val createNewContact = getCreateNewContactShortcut(appIconColor) try { shortcutManager.dynamicShortcuts = Arrays.asList(createNewContact) - baseConfig.lastHandledShortcutColor = appIconColor + config.lastHandledShortcutColor = appIconColor } catch (ignored: Exception) { } } @@ -280,7 +280,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getCurrentFragment(): MyViewPagerFragment? { - val showTabs = baseConfig.showTabs + val showTabs = config.showTabs val fragments = arrayListOf() if (showTabs and TAB_CONTACTS != 0) { fragments.add(contacts_fragment) @@ -314,7 +314,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): ArrayList { - val showTabs = baseConfig.showTabs + val showTabs = config.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -333,7 +333,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } private fun getDeselectedTabDrawableIds(): ArrayList { - val showTabs = baseConfig.showTabs + val showTabs = config.showTabs val icons = ArrayList() if (showTabs and TAB_CONTACTS != 0) { @@ -385,7 +385,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun setupTabs() { main_tabs_holder.removeAllTabs() tabsList.forEachIndexed { index, value -> - if (baseConfig.showTabs and value != 0) { + if (config.showTabs and value != 0) { main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) @@ -499,7 +499,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun tryExportContacts() { if (isQPlus()) { - ExportContactsDialog(this, baseConfig.lastExportPath, true) { file, ignoredContactSources -> + ExportContactsDialog(this, config.lastExportPath, true) { file, ignoredContactSources -> ignoredExportContactSources = ignoredContactSources Intent(Intent.ACTION_CREATE_DOCUMENT).apply { @@ -519,7 +519,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } else { handlePermission(PERMISSION_WRITE_STORAGE) { if (it) { - ExportContactsDialog(this, baseConfig.lastExportPath, false) { file, ignoredContactSources -> + ExportContactsDialog(this, config.lastExportPath, false) { file, ignoredContactSources -> getFileOutputStream(file.toFileDirItem(this), true) { exportContactsTo(ignoredContactSources, it) } @@ -577,7 +577,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { isGettingContacts = true if (view_pager.adapter == null) { - view_pager.adapter = ViewPagerAdapter(this, tabsList, baseConfig.showTabs) + view_pager.adapter = ViewPagerAdapter(this, tabsList, config.showTabs) view_pager.currentItem = getDefaultTab() } @@ -617,9 +617,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getAllFragments() = arrayListOf(contacts_fragment, favorites_fragment, groups_fragment) private fun getDefaultTab(): Int { - val showTabsMask = baseConfig.showTabs - return when (baseConfig.defaultTab) { - TAB_LAST_USED -> baseConfig.lastUsedViewPagerPage + val showTabsMask = config.showTabs + return when (config.defaultTab) { + TAB_LAST_USED -> config.lastUsedViewPagerPage TAB_CONTACTS -> 0 TAB_FAVORITES -> if (showTabsMask and TAB_CONTACTS > 0) 1 else 0 else -> { 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 57edb7ec..e45db403 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 @@ -8,7 +8,7 @@ import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog -import com.simplemobiletools.commons.extensions.baseConfig +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.activity_settings.* import java.util.* @@ -77,8 +77,8 @@ class SettingsActivity : SimpleActivity() { RadioItem(TAB_LAST_USED, getString(R.string.last_used_tab)) ) - RadioGroupDialog(this@SettingsActivity, items, baseConfig.defaultTab) { - baseConfig.defaultTab = it as Int + RadioGroupDialog(this@SettingsActivity, items, config.defaultTab) { + config.defaultTab = it as Int settings_default_tab.text = getDefaultTabText() } } @@ -103,19 +103,19 @@ class SettingsActivity : SimpleActivity() { RadioItem(FONT_SIZE_EXTRA_LARGE, getString(R.string.extra_large)) ) - RadioGroupDialog(this@SettingsActivity, items, baseConfig.fontSize) { - baseConfig.fontSize = it as Int + RadioGroupDialog(this@SettingsActivity, items, config.fontSize) { + config.fontSize = it as Int settings_font_size.text = getFontSizeText() } } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((baseConfig.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = baseConfig.useEnglish + settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settings_use_english.isChecked = config.useEnglish settings_use_english_holder.setOnClickListener { settings_use_english.toggle() - baseConfig.useEnglish = settings_use_english.isChecked + config.useEnglish = settings_use_english.isChecked System.exit(0) } } @@ -129,50 +129,50 @@ class SettingsActivity : SimpleActivity() { } private fun setupShowContactThumbnails() { - settings_show_contact_thumbnails.isChecked = baseConfig.showContactThumbnails + settings_show_contact_thumbnails.isChecked = config.showContactThumbnails settings_show_contact_thumbnails_holder.setOnClickListener { settings_show_contact_thumbnails.toggle() - baseConfig.showContactThumbnails = settings_show_contact_thumbnails.isChecked + config.showContactThumbnails = settings_show_contact_thumbnails.isChecked } } private fun setupShowPhoneNumbers() { - settings_show_phone_numbers.isChecked = baseConfig.showPhoneNumbers + settings_show_phone_numbers.isChecked = config.showPhoneNumbers settings_show_phone_numbers_holder.setOnClickListener { settings_show_phone_numbers.toggle() - baseConfig.showPhoneNumbers = settings_show_phone_numbers.isChecked + config.showPhoneNumbers = settings_show_phone_numbers.isChecked } } private fun setupShowContactsWithNumbers() { - settings_show_only_contacts_with_numbers.isChecked = baseConfig.showOnlyContactsWithNumbers + settings_show_only_contacts_with_numbers.isChecked = config.showOnlyContactsWithNumbers settings_show_only_contacts_with_numbers_holder.setOnClickListener { settings_show_only_contacts_with_numbers.toggle() - baseConfig.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked + config.showOnlyContactsWithNumbers = settings_show_only_contacts_with_numbers.isChecked } } private fun setupStartNameWithSurname() { - settings_start_name_with_surname.isChecked = baseConfig.startNameWithSurname + settings_start_name_with_surname.isChecked = config.startNameWithSurname settings_start_name_with_surname_holder.setOnClickListener { settings_start_name_with_surname.toggle() - baseConfig.startNameWithSurname = settings_start_name_with_surname.isChecked + config.startNameWithSurname = settings_start_name_with_surname.isChecked } } private fun setupShowDialpadButton() { - settings_show_dialpad_button.isChecked = baseConfig.showDialpadButton + settings_show_dialpad_button.isChecked = config.showDialpadButton settings_show_dialpad_button_holder.setOnClickListener { settings_show_dialpad_button.toggle() - baseConfig.showDialpadButton = settings_show_dialpad_button.isChecked + config.showDialpadButton = settings_show_dialpad_button.isChecked } } private fun setupShowPrivateContacts() { - settings_show_private_contacts.isChecked = baseConfig.showPrivateContacts + settings_show_private_contacts.isChecked = config.showPrivateContacts settings_show_private_contacts_holder.setOnClickListener { settings_show_private_contacts.toggle() - baseConfig.showPrivateContacts = settings_show_private_contacts.isChecked + config.showPrivateContacts = settings_show_private_contacts.isChecked } } @@ -185,15 +185,15 @@ class SettingsActivity : SimpleActivity() { RadioItem(ON_CLICK_EDIT_CONTACT, getString(R.string.edit_contact)) ) - RadioGroupDialog(this@SettingsActivity, items, baseConfig.onContactClick) { - baseConfig.onContactClick = it as Int + RadioGroupDialog(this@SettingsActivity, items, config.onContactClick) { + config.onContactClick = it as Int settings_on_contact_click.text = getOnContactClickText() } } } private fun getOnContactClickText() = getString( - when (baseConfig.onContactClick) { + when (config.onContactClick) { ON_CLICK_CALL_CONTACT -> R.string.call_contact ON_CLICK_VIEW_CONTACT -> R.string.view_contact else -> R.string.edit_contact @@ -201,18 +201,18 @@ class SettingsActivity : SimpleActivity() { ) private fun setupShowCallConfirmation() { - settings_show_call_confirmation.isChecked = baseConfig.showCallConfirmation + settings_show_call_confirmation.isChecked = config.showCallConfirmation settings_show_call_confirmation_holder.setOnClickListener { settings_show_call_confirmation.toggle() - baseConfig.showCallConfirmation = settings_show_call_confirmation.isChecked + config.showCallConfirmation = settings_show_call_confirmation.isChecked } } private fun setupMergeDuplicateContacts() { - settings_merge_duplicate_contacts.isChecked = baseConfig.mergeDuplicateContacts + settings_merge_duplicate_contacts.isChecked = config.mergeDuplicateContacts settings_merge_duplicate_contacts_holder.setOnClickListener { settings_merge_duplicate_contacts.toggle() - baseConfig.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked + config.mergeDuplicateContacts = settings_merge_duplicate_contacts.isChecked } } } 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 4f414eba..af8907a1 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 @@ -46,7 +46,7 @@ class ViewContactActivity : ContactActivity() { private var showFields = 0 private var fullContact: Contact? = null // contact with all fields filled from duplicates private var duplicateInitialized = false - private val mergeDuplicate: Boolean get() = baseConfig.mergeDuplicateContacts + private val mergeDuplicate: Boolean get() = config.mergeDuplicateContacts private val COMPARABLE_PHONE_NUMBER_LENGTH = 9 @@ -59,7 +59,7 @@ class ViewContactActivity : ContactActivity() { return } - showFields = baseConfig.showContactFields + showFields = config.showContactFields contact_wrapper.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN setupMenu() } @@ -122,7 +122,7 @@ class ViewContactActivity : ContactActivity() { findItem(R.id.manage_visible_fields).setOnMenuItemClickListener { ManageVisibleFieldsDialog(this@ViewContactActivity) { - showFields = baseConfig.showContactFields + showFields = config.showContactFields ensureBackgroundThread { initContact() } @@ -388,7 +388,7 @@ class ViewContactActivity : ContactActivity() { copyOnLongClick(phoneNumber.value) setOnClickListener { - if (baseConfig.showCallConfirmation) { + if (config.showCallConfirmation) { CallConfirmationDialog(this@ViewContactActivity, phoneNumber.value) { startCallIntent(phoneNumber.value) } 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 586c7a74..311dca86 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 @@ -60,7 +60,7 @@ class ContactsAdapter( private val NEW_GROUP_ID = -1 - private var config = activity.baseConfig + private var config = activity.config private var textToHighlight = highlightText var startNameWithSurname = config.startNameWithSurname @@ -452,7 +452,7 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" override fun onRowMoved(fromPosition: Int, toPosition: Int) { - activity.baseConfig.isCustomOrderSelected = true + activity.config.isCustomOrderSelected = true if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt index a4f74cce..91948e64 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/GroupsAdapter.kt @@ -17,6 +17,7 @@ import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.dialogs.RenameGroupDialog import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.models.contacts.Group +import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import kotlinx.android.synthetic.main.item_group.view.* import java.util.* @@ -27,7 +28,7 @@ class GroupsAdapter( ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { private var textToHighlight = "" - var showContactThumbnails = activity.baseConfig.showContactThumbnails + var showContactThumbnails = activity.config.showContactThumbnails var fontSize = activity.getTextSize() init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt index ecbbf492..5d2841ae 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt @@ -11,12 +11,12 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.SimpleContactsHelper import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.* class SelectContactsAdapter( @@ -30,7 +30,7 @@ class SelectContactsAdapter( RecyclerView.Adapter() { private val itemViews = SparseArray() private val selectedPositions = HashSet() - private val config = activity.baseConfig + private val config = activity.config private val adjustedPrimaryColor = activity.getProperPrimaryColor() private val fontSize = activity.getTextSize() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt index a89cd45f..eb54f45d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/contentproviders/MyContactsContentProvider.kt @@ -6,15 +6,15 @@ import android.database.Cursor import android.database.MatrixCursor import android.net.Uri import com.google.gson.Gson -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.MyContactsContentProvider import com.simplemobiletools.commons.helpers.LocalContactsHelper +import com.simplemobiletools.contacts.pro.extensions.config class MyContactsContentProvider : ContentProvider() { override fun insert(uri: Uri, contentValues: ContentValues?) = null override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? { - if (context == null || !context!!.baseConfig.showPrivateContacts) { + if (context == null || !context!!.config.showPrivateContacts) { return null } else { val matrixCursor = MatrixCursor( diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 5ca84879..2f05b66c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -2,16 +2,16 @@ package com.simplemobiletools.contacts.pro.dialogs import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGoneIf -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.contacts.pro.R +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_change_sorting.view.* class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCustomSorting: Boolean = false, private val callback: () -> Unit) { private var currSorting = 0 - private var config = activity.baseConfig + private var config = activity.config private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null) init { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt index 3c2d3361..31370967 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt @@ -5,13 +5,13 @@ import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_export_contacts.view.* import java.io.File @@ -80,7 +80,7 @@ class ExportContactsDialog( ignoreClicks = true ensureBackgroundThread { - activity.baseConfig.lastExportPath = file.absolutePath.getParentPath() + activity.config.lastExportPath = file.absolutePath.getParentPath() val selectedSources = (view.export_contacts_list.adapter as FilterContactSourcesAdapter).getSelectedContactSources() val ignoredSources = contactSources .filter { !selectedSources.contains(it) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt index e52e8d26..014c9947 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/FilterContactSourcesDialog.kt @@ -7,10 +7,10 @@ import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.extensions.getVisibleContactSources import com.simplemobiletools.commons.helpers.ContactsHelper import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.* class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) { @@ -77,7 +77,7 @@ class FilterContactSourcesDialog(val activity: SimpleActivity, private val callb }.toHashSet() if (activity.getVisibleContactSources() != ignoredContactSources) { - activity.baseConfig.ignoredContactSources = ignoredContactSources + activity.config.ignoredContactSources = ignoredContactSources callback() } dialog?.dismiss() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt index 436118b3..cc73aa0d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ImportContactsDialog.kt @@ -8,6 +8,7 @@ import com.simplemobiletools.commons.helpers.SMT_PRIVATE import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.SimpleActivity +import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.showContactSourcePicker import com.simplemobiletools.contacts.pro.helpers.VcfImporter import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_FAIL @@ -19,7 +20,7 @@ class ImportContactsDialog(val activity: SimpleActivity, val path: String, priva init { val view = (activity.layoutInflater.inflate(R.layout.dialog_import_contacts, null) as ViewGroup).apply { - targetContactSource = activity.baseConfig.lastUsedContactSource + targetContactSource = activity.config.lastUsedContactSource activity.getPublicContactSource(targetContactSource) { import_contacts_title.setText(it) if (it.isEmpty()) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt index 6d9147b2..b0b16161 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleFieldsDialog.kt @@ -5,8 +5,8 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.contacts.pro.extensions.config class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: (hasSomethingChanged: Boolean) -> Unit) { private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_fields, null) @@ -33,7 +33,7 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: put(SHOW_RINGTONE_FIELD, R.id.manage_ringtone) } - val showContactFields = activity.baseConfig.showContactFields + val showContactFields = activity.config.showContactFields for ((key, value) in fields) { view.findViewById(value).isChecked = showContactFields and key != 0 } @@ -54,8 +54,8 @@ class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: } } - val hasSomethingChanged = activity.baseConfig.showContactFields != result - activity.baseConfig.showContactFields = result + val hasSomethingChanged = activity.config.showContactFields != result + activity.config.showContactFields = result if (hasSomethingChanged) { callback(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt index 9adf617b..ba40a6f3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageVisibleTabsDialog.kt @@ -8,8 +8,8 @@ import com.simplemobiletools.commons.helpers.TAB_FAVORITES import com.simplemobiletools.commons.helpers.TAB_GROUPS import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.ALL_TABS_MASK +import com.simplemobiletools.contacts.pro.extensions.config class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null) @@ -22,7 +22,7 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { put(TAB_GROUPS, R.id.manage_visible_tabs_groups) } - val showTabs = activity.baseConfig.showTabs + val showTabs = activity.config.showTabs for ((key, value) in tabs) { view.findViewById(value).isChecked = showTabs and key != 0 } @@ -47,6 +47,6 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { result = ALL_TABS_MASK } - activity.baseConfig.showTabs = result + activity.config.showTabs = result } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt index 3fcb7b7c..2eb37a9f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/MyDatePickerDialog.kt @@ -5,7 +5,7 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.isSPlus import com.simplemobiletools.contacts.pro.R -import com.simplemobiletools.commons.extensions.baseConfig +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_date_picker.view.* import org.joda.time.DateTime import java.util.* @@ -38,7 +38,7 @@ class MyDatePickerDialog(val activity: BaseSimpleActivity, val defaultDate: Stri } } - if (activity.baseConfig.isUsingSystemTheme && isSPlus()) { + if (activity.config.isUsingSystemTheme && isSPlus()) { val dialogBackgroundColor = activity.getColor(R.color.you_dialog_background_color) view.dialog_holder.setBackgroundColor(dialogBackgroundColor) view.date_picker.setBackgroundColor(dialogBackgroundColor) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt index e6b19c09..53faecd8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Activity.kt @@ -9,13 +9,12 @@ import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.RadioItem +import com.simplemobiletools.commons.models.contacts.Contact import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.activities.EditContactActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.activities.ViewContactActivity -import com.simplemobiletools.contacts.pro.helpers.* -import com.simplemobiletools.commons.models.contacts.* import com.simplemobiletools.contacts.pro.helpers.DEFAULT_FILE_NAME import com.simplemobiletools.contacts.pro.helpers.VcfExporter @@ -30,7 +29,7 @@ fun SimpleActivity.startCallIntent(recipient: String) { } fun SimpleActivity.tryStartCall(contact: Contact) { - if (baseConfig.showCallConfirmation) { + if (config.showCallConfirmation) { CallConfirmationDialog(this, contact.getNameToDisplay()) { startCall(contact) } @@ -107,7 +106,7 @@ fun BaseSimpleActivity.shareContacts(contacts: ArrayList) { } fun SimpleActivity.handleGenericContactClick(contact: Contact) { - when (baseConfig.onContactClick) { + when (config.onContactClick) { ON_CLICK_CALL_CONTACT -> callContact(contact) ON_CLICK_VIEW_CONTACT -> viewContact(contact) ON_CLICK_EDIT_CONTACT -> editContact(contact) 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 e3434309..b08a7912 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 @@ -11,8 +11,10 @@ import com.simplemobiletools.commons.helpers.VIBER_PACKAGE import com.simplemobiletools.commons.helpers.WHATSAPP_PACKAGE import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.R +import com.simplemobiletools.contacts.pro.helpers.Config import java.io.File +val Context.config: Config get() = Config.newInstance(applicationContext) fun Context.getCachePhotoUri(file: File = getCachePhoto()) = FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.provider", file) @SuppressLint("UseCompatLoadingForDrawables") diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index f3f2d6f7..c286de85 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -17,11 +17,11 @@ import com.simplemobiletools.contacts.pro.activities.MainActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter import com.simplemobiletools.contacts.pro.adapters.GroupsAdapter -import com.simplemobiletools.commons.extensions.baseConfig import com.simplemobiletools.commons.helpers.Converters import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import com.simplemobiletools.commons.models.contacts.* +import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.fragment_layout.view.* import kotlinx.android.synthetic.main.fragment_layout.view.fragment_fab import kotlinx.android.synthetic.main.fragment_layout.view.fragment_list @@ -38,13 +38,13 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) private var lastHashCode = 0 private var contactsIgnoringSearch = ArrayList() private var groupsIgnoringSearch = ArrayList() - private lateinit var config: BaseConfig + private lateinit var config: Config var skipHashComparing = false var forceListRedraw = false fun setupFragment(activity: SimpleActivity) { - config = activity.baseConfig + config = activity.config if (this.activity == null) { this.activity = activity fragment_fab?.beGoneIf(activity is InsertOrEditContactActivity) @@ -124,7 +124,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) this is FavoritesFragment -> { val favorites = contacts.filter { it.starred == 1 } as ArrayList - if (activity!!.baseConfig.isCustomOrderSelected) { + if (activity!!.config.isCustomOrderSelected) { sortByCustomOrder(favorites) } else { favorites @@ -158,7 +158,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun sortByCustomOrder(starred: List): ArrayList { - val favoritesOrder = activity!!.baseConfig.favoritesContactsOrder + val favoritesOrder = activity!!.config.favoritesContactsOrder if (favoritesOrder.isEmpty()) { return ArrayList(starred) @@ -218,7 +218,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } else { (currAdapter as GroupsAdapter).apply { - showContactThumbnails = activity.baseConfig.showContactThumbnails + showContactThumbnails = activity.config.showContactThumbnails updateItems(storedGroups) } } @@ -280,7 +280,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) activity?.apply { val orderIds = items.map { it.id } val orderGsonString = Gson().toJson(orderIds) - baseConfig.favoritesContactsOrder = orderGsonString + config.favoritesContactsOrder = orderGsonString } } @@ -299,7 +299,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } private fun setupLetterFastscroller(contacts: ArrayList) { - val sorting = context.baseConfig.sorting + val sorting = context.config.sorting letter_fastscroller.setupWithRecyclerView(fragment_list, { position -> try { val contact = contacts[position] @@ -308,7 +308,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) sorting and SORT_BY_SURNAME != 0 && contact.surname.isNotEmpty() -> contact.surname sorting and SORT_BY_MIDDLE_NAME != 0 && contact.middleName.isNotEmpty() -> contact.middleName sorting and SORT_BY_FIRST_NAME != 0 && contact.firstName.isNotEmpty() -> contact.firstName - context.baseConfig.startNameWithSurname -> contact.surname + context.config.startNameWithSurname -> contact.surname else -> contact.firstName } 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 new file mode 100644 index 00000000..2edb94fd --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt @@ -0,0 +1,10 @@ +package com.simplemobiletools.contacts.pro.helpers + +import android.content.Context +import com.simplemobiletools.commons.helpers.BaseConfig + +class Config(context: Context) : BaseConfig(context) { + companion object { + fun newInstance(context: Context) = Config(context) + } +} From cb639fabebff19c3c29e376691c60e50ec977f5c Mon Sep 17 00:00:00 2001 From: ismailnurudeen Date: Fri, 24 Feb 2023 11:45:21 +0100 Subject: [PATCH 6/6] fix: undo unnecessary formatting changes. --- .../pro/activities/EditContactActivity.kt | 31 +++++-------------- .../pro/adapters/SelectContactsAdapter.kt | 8 ++--- .../pro/dialogs/ExportContactsDialog.kt | 4 +-- .../contacts/pro/extensions/Context.kt | 3 +- 4 files changed, 11 insertions(+), 35 deletions(-) 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 34318028..10c475fd 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 @@ -219,25 +219,15 @@ class EditContactActivity : ContactActivity() { val properPrimaryColor = getProperPrimaryColor() arrayOf( - contact_numbers_add_new, - contact_emails_add_new, - contact_addresses_add_new, - contact_ims_add_new, - contact_events_add_new, - contact_websites_add_new, - contact_groups_add_new + contact_numbers_add_new, contact_emails_add_new, contact_addresses_add_new, contact_ims_add_new, contact_events_add_new, + contact_websites_add_new, contact_groups_add_new ).forEach { it.applyColorFilter(properPrimaryColor) } arrayOf( - contact_numbers_add_new.background, - contact_emails_add_new.background, - contact_addresses_add_new.background, - contact_ims_add_new.background, - contact_events_add_new.background, - contact_websites_add_new.background, - contact_groups_add_new.background + contact_numbers_add_new.background, contact_emails_add_new.background, contact_addresses_add_new.background, contact_ims_add_new.background, + contact_events_add_new.background, contact_websites_add_new.background, contact_groups_add_new.background ).forEach { it.applyColorFilter(textColor) } @@ -609,18 +599,11 @@ class EditContactActivity : ContactActivity() { startActivityForResult(ringtonePickerIntent, INTENT_SELECT_RINGTONE) } catch (e: Exception) { val currentRingtone = contact!!.ringtone ?: getDefaultAlarmSound(RingtoneManager.TYPE_RINGTONE).uri - SelectAlarmSoundDialog( - this, - currentRingtone, - AudioManager.STREAM_RING, - PICK_RINGTONE_INTENT_ID, - RingtoneManager.TYPE_RINGTONE, - true, + SelectAlarmSoundDialog(this, currentRingtone, AudioManager.STREAM_RING, PICK_RINGTONE_INTENT_ID, RingtoneManager.TYPE_RINGTONE, true, onAlarmPicked = { contact!!.ringtone = it?.uri contact_ringtone.text = it?.title - }, - onAlarmSoundDeleted = {} + }, onAlarmSoundDeleted = {} ) } } @@ -1084,7 +1067,7 @@ class EditContactActivity : ContactActivity() { events = filledEvents, starred = if (isContactStarred()) 1 else 0, notes = contact_notes.value, - websites = filledWebsites + websites = filledWebsites, ) val company = contact_organization_company.value diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt index 5d2841ae..d7e64b07 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/SelectContactsAdapter.kt @@ -20,12 +20,8 @@ import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.* class SelectContactsAdapter( - val activity: SimpleActivity, - var contacts: ArrayList, - private val selectedContacts: ArrayList, - private val allowPickMultiple: Boolean, - recyclerView: MyRecyclerView, - private val itemClick: ((Contact) -> Unit)? = null + val activity: SimpleActivity, var contacts: ArrayList, private val selectedContacts: ArrayList, private val allowPickMultiple: Boolean, + recyclerView: MyRecyclerView, private val itemClick: ((Contact) -> Unit)? = null ) : RecyclerView.Adapter() { private val itemViews = SparseArray() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt index 31370967..fdbab186 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ExportContactsDialog.kt @@ -16,9 +16,7 @@ import kotlinx.android.synthetic.main.dialog_export_contacts.view.* import java.io.File class ExportContactsDialog( - val activity: SimpleActivity, - val path: String, - val hidePath: Boolean, + val activity: SimpleActivity, val path: String, val hidePath: Boolean, private val callback: (file: File, ignoredContactSources: HashSet) -> Unit ) { private var ignoreClicks = false 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 b08a7912..b4f18f1a 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 @@ -26,7 +26,6 @@ fun Context.getPackageDrawable(packageName: String): Drawable { WHATSAPP_PACKAGE -> R.drawable.ic_whatsapp_rect_vector VIBER_PACKAGE -> R.drawable.ic_viber_rect_vector else -> R.drawable.ic_threema_rect_vector - }, - theme + }, theme ) }