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)