Merge pull request #945 from ismailnurudeen/refactor/common-contacts

feat: moved sharable contacts code to commons
This commit is contained in:
Tibor Kaputa 2023-02-24 16:24:00 +01:00 committed by GitHub
commit 2fbd044a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 63 additions and 2784 deletions

View File

@ -24,12 +24,12 @@ import com.bumptech.glide.request.target.Target
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.letterBackgroundColors
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.extensions.shareContacts
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.commons.models.contacts.Contact
abstract class ContactActivity : SimpleActivity() {
protected val PICK_RINGTONE_INTENT_ID = 1500

View File

@ -29,6 +29,10 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.commons.models.contacts.Email
import com.simplemobiletools.commons.models.contacts.Event
import com.simplemobiletools.commons.models.contacts.Organization
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.dialogs.CustomLabelDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog
@ -36,10 +40,6 @@ import com.simplemobiletools.contacts.pro.dialogs.MyDatePickerDialog
import com.simplemobiletools.contacts.pro.dialogs.SelectGroupsDialog
import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.*
import com.simplemobiletools.contacts.pro.models.Email
import com.simplemobiletools.contacts.pro.models.Event
import com.simplemobiletools.contacts.pro.models.Organization
import kotlinx.android.synthetic.main.activity_edit_contact.*
import kotlinx.android.synthetic.main.item_edit_address.view.*
import kotlinx.android.synthetic.main.item_edit_email.view.*

View File

@ -7,19 +7,18 @@ import android.net.Uri
import android.os.Bundle
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter
import com.simplemobiletools.contacts.pro.dialogs.SelectContactsDialog
import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.helpers.GROUP
import com.simplemobiletools.contacts.pro.helpers.LOCATION_GROUP_CONTACTS
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.Group
import com.simplemobiletools.commons.models.contacts.*
import kotlinx.android.synthetic.main.activity_group_contacts.*
class GroupContactsActivity : SimpleActivity(), RemoveFromGroupListener, RefreshContactsListener {

View File

@ -13,19 +13,17 @@ import android.widget.TextView
import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter
import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog
import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getContactPublicUri
import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment
import com.simplemobiletools.contacts.pro.helpers.ADD_NEW_CONTACT_NUMBER
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.helpers.KEY_EMAIL
import com.simplemobiletools.contacts.pro.helpers.KEY_NAME
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.models.Contact
import kotlinx.android.synthetic.main.activity_insert_edit_contact.*
import kotlinx.android.synthetic.main.fragment_contacts.*
import kotlinx.android.synthetic.main.fragment_favorites.*

View File

@ -14,31 +14,28 @@ import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.commons.databases.ContactsDatabase
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.BuildConfig
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter
import com.simplemobiletools.contacts.pro.databases.ContactsDatabase
import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog
import com.simplemobiletools.contacts.pro.dialogs.ExportContactsDialog
import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog
import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getTempFile
import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick
import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment
import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment
import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.helpers.VcfExporter
import com.simplemobiletools.contacts.pro.helpers.tabsList
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.models.Contact
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_contacts.*
import kotlinx.android.synthetic.main.fragment_favorites.*

View File

@ -9,9 +9,6 @@ import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_CALL_CONTACT
import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_EDIT_CONTACT
import com.simplemobiletools.contacts.pro.helpers.ON_CLICK_VIEW_CONTACT
import kotlinx.android.synthetic.main.activity_settings.*
import java.util.*

View File

@ -22,12 +22,12 @@ import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.dialogs.ChooseSocialDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog
import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.*
import kotlinx.android.synthetic.main.activity_view_contact.*
import kotlinx.android.synthetic.main.item_view_address.view.*
import kotlinx.android.synthetic.main.item_view_contact_source.view.*

View File

@ -28,10 +28,12 @@ import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.interfaces.ItemMoveCallback
import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract
import com.simplemobiletools.commons.interfaces.StartReorderDragListener
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.contacts.Contact
import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
@ -41,7 +43,7 @@ import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.commons.models.contacts.*
import java.util.*
class ContactsAdapter(

View File

@ -7,9 +7,9 @@ import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
import com.simplemobiletools.commons.extensions.getProperTextColor
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.commons.models.contacts.ContactSource
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.models.ContactSource
import kotlinx.android.synthetic.main.item_filter_contact_source.view.*
class FilterContactSourcesAdapter(

View File

@ -7,9 +7,7 @@ import android.view.ViewGroup
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getTextSize
import com.simplemobiletools.commons.extensions.highlightTextPart
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.TAB_GROUPS
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -17,11 +15,10 @@ import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.dialogs.RenameGroupDialog
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.models.contacts.Group
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.groupsDB
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.models.Group
import kotlinx.android.synthetic.main.item_group.view.*
import java.util.*

View File

@ -12,11 +12,11 @@ import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.ObjectKey
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.models.Contact
import kotlinx.android.synthetic.main.item_add_favorite_with_number.view.*
class SelectContactsAdapter(

View File

@ -7,8 +7,8 @@ import android.database.MatrixCursor
import android.net.Uri
import com.google.gson.Gson
import com.simplemobiletools.commons.helpers.MyContactsContentProvider
import com.simplemobiletools.commons.helpers.LocalContactsHelper
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.helpers.LocalContactsHelper
class MyContactsContentProvider : ContentProvider() {
override fun insert(uri: Uri, contentValues: ContentValues?) = null

View File

@ -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 ''")
}
}
}
}
}

View File

@ -8,9 +8,9 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.models.contacts.SocialAction
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.extensions.getPackageDrawable
import com.simplemobiletools.contacts.pro.models.SocialAction
import kotlinx.android.synthetic.main.dialog_choose_social.view.*
import kotlinx.android.synthetic.main.item_choose_social.view.*

View File

@ -5,13 +5,12 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.contacts.ContactSource
import com.simplemobiletools.commons.models.contacts.Group
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.extensions.getPrivateContactSource
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.ContactSource
import com.simplemobiletools.contacts.pro.models.Group
import kotlinx.android.synthetic.main.dialog_create_new_group.view.*
class CreateNewGroupDialog(val activity: BaseSimpleActivity, val callback: (newGroup: Group) -> Unit) {

View File

@ -5,15 +5,13 @@ import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.ContactSource
import kotlinx.android.synthetic.main.dialog_export_contacts.view.*
import java.io.File

View File

@ -7,11 +7,10 @@ import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter
import com.simplemobiletools.commons.extensions.getVisibleContactSources
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.ContactSource
import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.*
class FilterContactSourcesDialog(val activity: SimpleActivity, private val callback: () -> Unit) {

View File

@ -2,17 +2,14 @@ package com.simplemobiletools.contacts.pro.dialogs
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getPublicContactSource
import com.simplemobiletools.contacts.pro.extensions.showContactSourcePicker
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.helpers.VcfImporter
import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_FAIL
import kotlinx.android.synthetic.main.dialog_import_contacts.view.*

View File

@ -5,8 +5,8 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.helpers.*
class ManageVisibleFieldsDialog(val activity: BaseSimpleActivity, val callback: (hasSomethingChanged: Boolean) -> Unit) {
private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_fields, null)

View File

@ -8,8 +8,8 @@ import com.simplemobiletools.commons.helpers.TAB_FAVORITES
import com.simplemobiletools.commons.helpers.TAB_GROUPS
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.commons.helpers.ALL_TABS_MASK
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK
class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) {
private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null)

View File

@ -3,11 +3,10 @@ package com.simplemobiletools.contacts.pro.dialogs
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.contacts.Group
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.extensions.groupsDB
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.Group
import kotlinx.android.synthetic.main.dialog_rename_group.view.*
class RenameGroupDialog(val activity: BaseSimpleActivity, val group: Group, val callback: () -> Unit) {

View File

@ -7,8 +7,7 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.adapters.SelectContactsAdapter
import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.commons.models.contacts.*
import kotlinx.android.synthetic.main.dialog_select_contact.view.*
import java.util.*

View File

@ -3,11 +3,11 @@ package com.simplemobiletools.contacts.pro.dialogs
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.models.contacts.Group
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
import com.simplemobiletools.contacts.pro.models.Group
import kotlinx.android.synthetic.main.dialog_select_groups.view.*
import kotlinx.android.synthetic.main.item_checkbox.view.*
import kotlinx.android.synthetic.main.item_textview.view.*

View File

@ -7,18 +7,16 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.CallConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.CONTACT_ID
import com.simplemobiletools.commons.helpers.IS_PRIVATE
import com.simplemobiletools.commons.helpers.PERMISSION_CALL_PHONE
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.contacts.Contact
import com.simplemobiletools.contacts.pro.BuildConfig
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.EditContactActivity
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.activities.ViewContactActivity
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.helpers.DEFAULT_FILE_NAME
import com.simplemobiletools.contacts.pro.helpers.VcfExporter
fun SimpleActivity.startCallIntent(recipient: String) {
handlePermission(PERMISSION_CALL_PHONE) {

View File

@ -2,339 +2,21 @@ package com.simplemobiletools.contacts.pro.extensions
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.ContactsContract
import androidx.core.content.FileProvider
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS
import com.simplemobiletools.commons.helpers.SMT_PRIVATE
import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.extensions.getCachePhoto
import com.simplemobiletools.commons.helpers.SIGNAL_PACKAGE
import com.simplemobiletools.commons.helpers.TELEGRAM_PACKAGE
import com.simplemobiletools.commons.helpers.VIBER_PACKAGE
import com.simplemobiletools.commons.helpers.WHATSAPP_PACKAGE
import com.simplemobiletools.contacts.pro.BuildConfig
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.databases.ContactsDatabase
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.interfaces.ContactsDao
import com.simplemobiletools.contacts.pro.interfaces.GroupsDao
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.ContactSource
import com.simplemobiletools.contacts.pro.models.Organization
import com.simplemobiletools.contacts.pro.models.SocialAction
import com.simplemobiletools.contacts.pro.helpers.Config
import java.io.File
val Context.config: Config get() = Config.newInstance(applicationContext)
val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao()
val Context.groupsDB: GroupsDao get() = ContactsDatabase.getInstance(applicationContext).GroupsDao()
fun Context.getEmptyContact(): Contact {
val originalContactSource = if (hasContactPermissions()) config.lastUsedContactSource else SMT_PRIVATE
val organization = Organization("", "")
return Contact(
0, "", "", "", "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), originalContactSource, 0, 0, "",
null, "", ArrayList(), organization, ArrayList(), ArrayList(), DEFAULT_MIMETYPE, null
)
}
fun Context.sendAddressIntent(address: String) {
val location = Uri.encode(address)
val uri = Uri.parse("geo:0,0?q=$location")
Intent(Intent.ACTION_VIEW, uri).apply {
launchActivityIntent(this)
}
}
fun Context.openWebsiteIntent(url: String) {
val website = if (url.startsWith("http")) {
url
} else {
"https://$url"
}
Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(website)
launchActivityIntent(this)
}
}
fun Context.getLookupUriRawId(dataUri: Uri): Int {
val lookupKey = getLookupKeyFromUri(dataUri)
if (lookupKey != null) {
val uri = lookupContactUri(lookupKey, this)
if (uri != null) {
return getContactUriRawId(uri)
}
}
return -1
}
fun Context.getContactUriRawId(uri: Uri): Int {
val projection = arrayOf(ContactsContract.Contacts.NAME_RAW_CONTACT_ID)
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, null, null, null)
if (cursor!!.moveToFirst()) {
return cursor.getIntValue(ContactsContract.Contacts.NAME_RAW_CONTACT_ID)
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}
return -1
}
// from https://android.googlesource.com/platform/packages/apps/Dialer/+/68038172793ee0e2ab3e2e56ddfbeb82879d1f58/java/com/android/contacts/common/util/UriUtils.java
fun getLookupKeyFromUri(lookupUri: Uri): String? {
return if (!isEncodedContactUri(lookupUri)) {
val segments = lookupUri.pathSegments
if (segments.size < 3) null else Uri.encode(segments[2])
} else {
null
}
}
fun isEncodedContactUri(uri: Uri?): Boolean {
if (uri == null) {
return false
}
val lastPathSegment = uri.lastPathSegment ?: return false
return lastPathSegment == "encoded"
}
fun lookupContactUri(lookup: String, context: Context): Uri? {
val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup)
return try {
ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri)
} catch (e: Exception) {
null
}
}
fun Context.getCachePhoto(): File {
val imagesFolder = File(cacheDir, "my_cache")
if (!imagesFolder.exists()) {
imagesFolder.mkdirs()
}
val file = File(imagesFolder, "Photo_${System.currentTimeMillis()}.jpg")
file.createNewFile()
return file
}
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<ContactSource>): 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<Contact>) {
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<Contact>) {
val emails = ArrayList<String>()
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<Contact>, groupId: Long) {
val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList<Contact>
val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList<Contact>
if (publicContacts.isNotEmpty()) {
ContactsHelper(this).addContactsToGroup(publicContacts, groupId)
}
if (privateContacts.isNotEmpty()) {
LocalContactsHelper(this).addContactsToGroup(privateContacts, groupId)
}
}
fun Context.removeContactsFromGroup(contacts: ArrayList<Contact>, groupId: Long) {
val publicContacts = contacts.filter { !it.isPrivate() }.toMutableList() as ArrayList<Contact>
val privateContacts = contacts.filter { it.isPrivate() }.toMutableList() as ArrayList<Contact>
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<String> {
val sources = getAllContactSources()
val ignoredContactSources = config.ignoredContactSources
return ArrayList(sources).filter { !ignoredContactSources.contains(it.getFullIdentifier()) }
.map { it.name }.toMutableList() as ArrayList<String>
}
fun Context.getAllContactSources(): ArrayList<ContactSource> {
val sources = ContactsHelper(this).getDeviceContactSources()
sources.add(getPrivateContactSource())
return sources.toMutableList() as ArrayList<ContactSource>
}
fun Context.getPrivateContactSource() = ContactSource(SMT_PRIVATE, SMT_PRIVATE, getString(R.string.phone_storage_hidden))
fun Context.getSocialActions(id: Int): ArrayList<SocialAction> {
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<SocialAction>()
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(

View File

@ -2,11 +2,11 @@ package com.simplemobiletools.contacts.pro.fragments
import android.content.Context
import android.util.AttributeSet
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.TAB_FAVORITES
import com.simplemobiletools.contacts.pro.activities.MainActivity
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.dialogs.SelectContactsDialog
import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
override fun fabClicked() {

View File

@ -17,12 +17,11 @@ import com.simplemobiletools.contacts.pro.activities.MainActivity
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.adapters.ContactsAdapter
import com.simplemobiletools.contacts.pro.adapters.GroupsAdapter
import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.getVisibleContactSources
import com.simplemobiletools.commons.helpers.Converters
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.Group
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.extensions.config
import kotlinx.android.synthetic.main.fragment_layout.view.*
import kotlinx.android.synthetic.main.fragment_layout.view.fragment_fab
import kotlinx.android.synthetic.main.fragment_layout.view.fragment_list

View File

@ -7,71 +7,4 @@ class Config(context: Context) : BaseConfig(context) {
companion object {
fun newInstance(context: Context) = Config(context)
}
var ignoredContactSources: HashSet<String>
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()
}

View File

@ -1,29 +1,8 @@
package com.simplemobiletools.contacts.pro.helpers
import android.provider.ContactsContract.CommonDataKinds
import com.simplemobiletools.commons.extensions.normalizeString
import com.simplemobiletools.commons.helpers.TAB_CONTACTS
import com.simplemobiletools.commons.helpers.TAB_FAVORITES
import com.simplemobiletools.commons.helpers.TAB_GROUPS
import com.simplemobiletools.contacts.pro.models.LocalContact
// shared prefs
const val SHOW_CONTACT_THUMBNAILS = "show_contact_thumbnails"
const val SHOW_PHONE_NUMBERS = "show_phone_numbers"
const val SHOW_ONLY_CONTACTS_WITH_NUMBERS = "show_only_contacts_with_numbers"
const val IGNORED_CONTACT_SOURCES = "ignored_contact_sources_2"
const val LAST_USED_CONTACT_SOURCE = "last_used_contact_source"
const val ON_CONTACT_CLICK = "on_contact_click"
const val SHOW_CONTACT_FIELDS = "show_contact_fields"
const val SHOW_TABS = "show_tabs"
const val SHOW_DIALPAD_BUTTON = "show_dialpad_button"
const val SPEED_DIAL = "speed_dial"
const val LAST_EXPORT_PATH = "last_export_path"
const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized"
const val SHOW_PRIVATE_CONTACTS = "show_private_contacts"
const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts"
const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order"
const val FAVORITES_CUSTOM_ORDER_SELECTED = "favorites_custom_order_selected"
const val GROUP = "group"
const val IS_FROM_SIMPLE_CONTACTS = "is_from_simple_contacts"
@ -44,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"
@ -76,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

View File

@ -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<List<Long>>() {}.type
private val stringType = object : TypeToken<List<String>>() {}.type
private val numberType = object : TypeToken<List<PhoneNumber>>() {}.type
private val numberConverterType = object : TypeToken<List<PhoneNumberConverter>>() {}.type
private val emailType = object : TypeToken<List<Email>>() {}.type
private val addressType = object : TypeToken<List<Address>>() {}.type
private val eventType = object : TypeToken<List<Event>>() {}.type
private val imType = object : TypeToken<List<IM>>() {}.type
@TypeConverter
fun jsonToStringList(value: String) = gson.fromJson<ArrayList<String>>(value, stringType)
@TypeConverter
fun stringListToJson(list: ArrayList<String>) = gson.toJson(list)
@TypeConverter
fun jsonToLongList(value: String) = gson.fromJson<ArrayList<Long>>(value, longType)
@TypeConverter
fun longListToJson(list: ArrayList<Long>) = 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<PhoneNumber> {
val numbers = gson.fromJson<ArrayList<PhoneNumber>>(value, numberType)
return if (numbers.any { it.value == null }) {
val phoneNumbers = ArrayList<PhoneNumber>()
val numberConverters = gson.fromJson<ArrayList<PhoneNumberConverter>>(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<PhoneNumber>) = gson.toJson(list)
@TypeConverter
fun jsonToEmailList(value: String) = gson.fromJson<ArrayList<Email>>(value, emailType)
@TypeConverter
fun emailListToJson(list: ArrayList<Email>) = gson.toJson(list)
@TypeConverter
fun jsonToAddressList(value: String) = gson.fromJson<ArrayList<Address>>(value, addressType)
@TypeConverter
fun addressListToJson(list: ArrayList<Address>) = gson.toJson(list)
@TypeConverter
fun jsonToEventList(value: String) = gson.fromJson<ArrayList<Event>>(value, eventType)
@TypeConverter
fun eventListToJson(list: ArrayList<Event>) = gson.toJson(list)
@TypeConverter
fun jsonToIMsList(value: String) = gson.fromJson<ArrayList<IM>>(value, imType)
@TypeConverter
fun IMsListToJson(list: ArrayList<IM>) = gson.toJson(list)
}

View File

@ -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.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.models.Group
import com.simplemobiletools.contacts.pro.models.LocalContact
import com.simplemobiletools.contacts.pro.models.Organization
class LocalContactsHelper(val context: Context) {
fun getAllContacts(favoritesOnly: Boolean = false): ArrayList<Contact> {
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<Contact>
}
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<Contact>, 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<Contact>, 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<Long>) {
ids.chunked(30).forEach {
context.contactsDB.deleteContactIds(it)
}
}
fun toggleFavorites(ids: Array<Int>, 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<Group>): 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<Group>
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<Long>
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<String>
val anniversaries = contact.events.filter { it.type == Event.TYPE_ANNIVERSARY }.map { it.value }.toMutableList() as ArrayList<String>
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)
}
}

View File

@ -12,9 +12,9 @@ import com.simplemobiletools.commons.extensions.getByteArray
import com.simplemobiletools.commons.extensions.getDateTimeFromDateString
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.models.contacts.Contact
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.helpers.VcfExporter.ExportResult.EXPORT_FAIL
import com.simplemobiletools.contacts.pro.models.Contact
import ezvcard.Ezvcard
import ezvcard.VCard
import ezvcard.VCardVersion

View File

@ -7,17 +7,19 @@ import android.provider.ContactsContract.CommonDataKinds.Im
import android.provider.ContactsContract.CommonDataKinds.Phone
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal
import android.widget.Toast
import com.simplemobiletools.commons.extensions.groupsDB
import com.simplemobiletools.commons.extensions.normalizePhoneNumber
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.extensions.getCachePhoto
import com.simplemobiletools.commons.extensions.getCachePhoto
import com.simplemobiletools.contacts.pro.extensions.getCachePhotoUri
import com.simplemobiletools.contacts.pro.extensions.groupsDB
import com.simplemobiletools.commons.helpers.ContactsHelper
import com.simplemobiletools.commons.helpers.DEFAULT_MIMETYPE
import com.simplemobiletools.commons.models.PhoneNumber
import com.simplemobiletools.commons.models.contacts.*
import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_FAIL
import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_OK
import com.simplemobiletools.contacts.pro.helpers.VcfImporter.ImportResult.IMPORT_PARTIAL
import com.simplemobiletools.contacts.pro.models.*
import ezvcard.Ezvcard
import ezvcard.VCard
import ezvcard.util.PartialDate

View File

@ -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<LocalContact>
@Query("SELECT * FROM contacts WHERE starred = 1")
fun getFavoriteContacts(): List<LocalContact>
@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<Long>)
}

View File

@ -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<Group>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertOrUpdate(group: Group): Long
@Query("DELETE FROM groups WHERE id = :id")
fun deleteGroupId(id: Long)
}

View File

@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.pro.interfaces
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.commons.models.contacts.*
interface RefreshContactsListener {
fun refreshContacts(refreshTabsMask: Int)

View File

@ -1,6 +1,6 @@
package com.simplemobiletools.contacts.pro.interfaces
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.commons.models.contacts.*
interface RemoveFromGroupListener {
fun removeFromGroup(contacts: ArrayList<Contact>)

View File

@ -1,3 +0,0 @@
package com.simplemobiletools.contacts.pro.models
data class Address(var value: String, var type: Int, var label: String)

View File

@ -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<PhoneNumber>, var emails: ArrayList<Email>, var addresses: ArrayList<Address>,
var events: ArrayList<Event>, var source: String, var starred: Int, var contactId: Int, var thumbnailUri: String, var photo: Bitmap?, var notes: String,
var groups: ArrayList<Group>, var organization: Organization, var websites: ArrayList<String>, var IMs: ArrayList<IM>, var mimetype: String,
var ringtone: String?
) :
Comparable<Contact> {
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()
}

View File

@ -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"
}
}
}

View File

@ -1,3 +0,0 @@
package com.simplemobiletools.contacts.pro.models
data class Email(var value: String, var type: Int, var label: String)

View File

@ -1,3 +0,0 @@
package com.simplemobiletools.contacts.pro.models
data class Event(var value: String, var type: Int)

View File

@ -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
}

View File

@ -1,3 +0,0 @@
package com.simplemobiletools.contacts.pro.models
data class IM(var value: String, var type: Int, var label: String)

View File

@ -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<PhoneNumber>,
@ColumnInfo(name = "emails") var emails: ArrayList<Email>,
@ColumnInfo(name = "events") var events: ArrayList<Event>,
@ColumnInfo(name = "starred") var starred: Int,
@ColumnInfo(name = "addresses") var addresses: ArrayList<Address>,
@ColumnInfo(name = "notes") var notes: String,
@ColumnInfo(name = "groups") var groups: ArrayList<Long>,
@ColumnInfo(name = "company") var company: String,
@ColumnInfo(name = "job_position") var jobPosition: String,
@ColumnInfo(name = "websites") var websites: ArrayList<String>,
@ColumnInfo(name = "ims") var IMs: ArrayList<IM>,
@ColumnInfo(name = "ringtone") var ringtone: String?
) {
override fun equals(other: Any?) = id == (other as? LocalContact?)?.id
override fun hashCode() = id ?: 0
}

View File

@ -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()
}

View File

@ -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)

View File

@ -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)