From 1dd37336f73644f0baa8c5478b66bbce8ea3dd07 Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 09:58:53 +0100 Subject: [PATCH 01/22] add an extra check to avoid saving null contact --- .../contacts/activities/EditContactActivity.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index 38b30572..19afcc74 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -33,10 +33,10 @@ import org.joda.time.format.DateTimeFormat import java.util.* class EditContactActivity : ContactActivity() { - val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME - val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE - val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME - val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY + private val DEFAULT_EMAIL_TYPE = CommonDataKinds.Email.TYPE_HOME + private val DEFAULT_PHONE_NUMBER_TYPE = CommonDataKinds.Phone.TYPE_MOBILE + private val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME + private val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY private val INTENT_TAKE_PHOTO = 1 private val INTENT_CHOOSE_PHOTO = 2 @@ -490,7 +490,7 @@ class EditContactActivity : ContactActivity() { } private fun saveContact() { - if (isSaving) { + if (isSaving || contact == null) { return } From e2d555e3001a59b2aef1fedef2c2a51ac93050b7 Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 10:03:12 +0100 Subject: [PATCH 02/22] make the fragments nullable in main activity --- .../contacts/activities/MainActivity.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index 0dee0381..8b8f0880 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -91,15 +91,15 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { val configShowContactThumbnails = config.showContactThumbnails if (storedShowContactThumbnails != configShowContactThumbnails) { - contacts_fragment.showContactThumbnailsChanged(configShowContactThumbnails) - favorites_fragment.showContactThumbnailsChanged(configShowContactThumbnails) + contacts_fragment?.showContactThumbnailsChanged(configShowContactThumbnails) + favorites_fragment?.showContactThumbnailsChanged(configShowContactThumbnails) } val configTextColor = config.textColor if (storedTextColor != configTextColor) { main_tabs_holder.getTabAt(getOtherViewPagerItem(viewpager.currentItem))?.icon?.applyColorFilter(configTextColor) - contacts_fragment.textColorChanged(configTextColor) - favorites_fragment.textColorChanged(configTextColor) + contacts_fragment?.textColorChanged(configTextColor) + favorites_fragment?.textColorChanged(configTextColor) } val configBackgroundColor = config.backgroundColor @@ -111,14 +111,14 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { if (storedPrimaryColor != configPrimaryColor) { main_tabs_holder.setSelectedTabIndicatorColor(getAdjustedPrimaryColor()) main_tabs_holder.getTabAt(viewpager.currentItem)?.icon?.applyColorFilter(getAdjustedPrimaryColor()) - contacts_fragment.primaryColorChanged() - favorites_fragment.primaryColorChanged() + contacts_fragment?.primaryColorChanged() + favorites_fragment?.primaryColorChanged() } val configStartNameWithSurname = config.startNameWithSurname if (storedStartNameWithSurname != configStartNameWithSurname) { - contacts_fragment.startNameWithSurnameChanged(configStartNameWithSurname) - favorites_fragment.startNameWithSurnameChanged(configStartNameWithSurname) + contacts_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) + favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) } if (!isFirstResume) { From 54396d4bd31f7201a120818cd7f8214a54f0880f Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 10:05:17 +0100 Subject: [PATCH 03/22] update commons to 3.16.10 --- app/build.gradle | 2 +- .../com/simplemobiletools/contacts/activities/MainActivity.kt | 2 +- .../kotlin/com/simplemobiletools/contacts/extensions/Context.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 16c50719..d942bf59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,7 +45,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.14.12' + implementation 'com.simplemobiletools:commons:3.16.10' implementation 'joda-time:joda-time:2.9.9' implementation 'com.facebook.stetho:stetho:1.5.0' implementation 'com.google.code.gson:gson:2.8.2' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index 8b8f0880..eaebb9b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -383,7 +383,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun launchAbout() { val faqItems = arrayListOf(FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons)) - startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_MULTISELECT or LICENSE_JODA or LICENSE_GLIDE or LICENSE_GSON or LICENSE_STETHO, + startAboutActivity(R.string.app_name, LICENSE_MULTISELECT or LICENSE_JODA or LICENSE_GLIDE or LICENSE_GSON or LICENSE_STETHO, BuildConfig.VERSION_NAME, faqItems) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt index 19d18f9b..b242274b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt @@ -9,8 +9,8 @@ import android.os.Build import android.provider.ContactsContract import android.support.v4.content.FileProvider import com.simplemobiletools.commons.extensions.getIntValue -import com.simplemobiletools.commons.extensions.isLollipopPlus import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.helpers.isLollipopPlus import com.simplemobiletools.contacts.BuildConfig import com.simplemobiletools.contacts.R import com.simplemobiletools.contacts.activities.EditContactActivity From 1165550ef4c92c4b0548387baabb0fa1b017d732 Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 13:11:47 +0100 Subject: [PATCH 04/22] fix #81, improve contact handling by lookup key --- app/build.gradle | 2 +- .../contacts/activities/ViewContactActivity.kt | 7 ++++++- .../contacts/helpers/ContactsHelper.kt | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d942bf59..c6cb783b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,7 +45,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.16.10' + implementation 'com.simplemobiletools:commons:3.16.11' implementation 'joda-time:joda-time:2.9.9' implementation 'com.facebook.stetho:stetho:1.5.0' implementation 'com.google.code.gson:gson:2.8.2' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt index f27ef8d8..dbd35dd2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt @@ -65,6 +65,11 @@ class ViewContactActivity : ContactActivity() { val data = intent.data if (data != null) { val rawId = if (data.path.contains("lookup")) { + val lookupKey = getLookupKeyFromUri(data) + if (lookupKey != null) { + contact = ContactsHelper(this).getContactWithLookupKey(lookupKey) + } + getLookupUriRawId(data) } else { getContactUriRawId(data) @@ -76,7 +81,7 @@ class ViewContactActivity : ContactActivity() { } } - if (contactId != 0) { + if (contactId != 0 && contact == null) { contact = ContactsHelper(this).getContactWithId(contactId, intent.getBooleanExtra(IS_PRIVATE, false)) if (contact == null) { toast(R.string.unknown_error_occurred) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index c1423506..00e812e3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -312,14 +312,25 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return activity.dbHelper.getContactWithId(id) } - val uri = ContactsContract.Data.CONTENT_URI - val projection = getContactProjection() val selection = "${ContactsContract.Data.MIMETYPE} = ? AND ${ContactsContract.Data.RAW_CONTACT_ID} = ?" val selectionArgs = arrayOf(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, id.toString()) + return parseContactCursor(selection, selectionArgs) + } + + fun getContactWithLookupKey(key: String): Contact? { + val selection = "${ContactsContract.Data.MIMETYPE} = ? AND ${ContactsContract.Data.LOOKUP_KEY} = ?" + val selectionArgs = arrayOf(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE, key) + return parseContactCursor(selection, selectionArgs) + } + + private fun parseContactCursor(selection: String, selectionArgs: Array): Contact? { + val uri = ContactsContract.Data.CONTENT_URI + val projection = getContactProjection() var cursor: Cursor? = null try { cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) if (cursor?.moveToFirst() == true) { + val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) val firstName = cursor.getStringValue(CommonDataKinds.StructuredName.GIVEN_NAME) ?: "" val middleName = cursor.getStringValue(CommonDataKinds.StructuredName.MIDDLE_NAME) ?: "" val surname = cursor.getStringValue(CommonDataKinds.StructuredName.FAMILY_NAME) ?: "" From 4bd4513ad903bb5ca9b0b03efb91f69587e8ecde Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 13:33:03 +0100 Subject: [PATCH 05/22] fix #82, allow pressing phone number, email, address on the View screen --- .../activities/ViewContactActivity.kt | 27 ++++++++++++++----- .../contacts/extensions/Context.kt | 12 +++++++++ app/src/main/res/layout/item_view_address.xml | 1 + app/src/main/res/layout/item_view_email.xml | 1 + .../res/layout/item_view_phone_number.xml | 1 + 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt index dbd35dd2..ff483eb8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt @@ -166,9 +166,14 @@ class ViewContactActivity : ContactActivity() { val phoneNumbers = contact!!.phoneNumbers phoneNumbers.forEach { layoutInflater.inflate(R.layout.item_view_phone_number, contact_numbers_holder, false).apply { + val phoneNumber = it contact_numbers_holder.addView(this) - contact_number.text = it.value - contact_number_type.setText(getPhoneNumberTextId(it.type)) + contact_number.text = phoneNumber.value + contact_number_type.setText(getPhoneNumberTextId(phoneNumber.type)) + + setOnClickListener { + startCallIntent(phoneNumber.value) + } } } @@ -181,9 +186,14 @@ class ViewContactActivity : ContactActivity() { val emails = contact!!.emails emails.forEach { layoutInflater.inflate(R.layout.item_view_email, contact_emails_holder, false).apply { + val email = it contact_emails_holder.addView(this) - contact_email.text = it.value - contact_email_type.setText(getEmailTextId(it.type)) + contact_email.text = email.value + contact_email_type.setText(getEmailTextId(email.type)) + + setOnClickListener { + sendEmailIntent(email.value) + } } } @@ -196,9 +206,14 @@ class ViewContactActivity : ContactActivity() { val addresses = contact!!.addresses addresses.forEach { layoutInflater.inflate(R.layout.item_view_address, contact_addresses_holder, false).apply { + val address = it contact_addresses_holder.addView(this) - contact_address.text = it.value - contact_address_type.setText(getAddressTextId(it.type)) + contact_address.text = address.value + contact_address_type.setText(getAddressTextId(address.type)) + + setOnClickListener { + sendAddressIntent(address.value) + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt index b242274b..8731909a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Context.kt @@ -61,6 +61,18 @@ fun Context.sendSMSIntent(recipient: String) { } } +fun Context.sendAddressIntent(address: String) { + val location = Uri.encode(address) + val uri = Uri.parse("geo:0,0?q=$location") + + val intent = Intent(Intent.ACTION_VIEW, uri) + if (intent.resolveActivity(packageManager) != null) { + startActivity(intent) + } else { + toast(R.string.no_app_found) + } +} + @TargetApi(Build.VERSION_CODES.LOLLIPOP) fun Context.getLookupUriRawId(dataUri: Uri): Int { val lookupKey = getLookupKeyFromUri(dataUri) diff --git a/app/src/main/res/layout/item_view_address.xml b/app/src/main/res/layout/item_view_address.xml index fce8cbf1..fa3497b8 100644 --- a/app/src/main/res/layout/item_view_address.xml +++ b/app/src/main/res/layout/item_view_address.xml @@ -4,6 +4,7 @@ android:id="@+id/contact_address_holder" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" android:paddingBottom="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"> diff --git a/app/src/main/res/layout/item_view_email.xml b/app/src/main/res/layout/item_view_email.xml index 9de6e320..7169d289 100644 --- a/app/src/main/res/layout/item_view_email.xml +++ b/app/src/main/res/layout/item_view_email.xml @@ -4,6 +4,7 @@ android:id="@+id/contact_email_holder" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" android:paddingBottom="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"> diff --git a/app/src/main/res/layout/item_view_phone_number.xml b/app/src/main/res/layout/item_view_phone_number.xml index d37bf04e..d4dea4a8 100644 --- a/app/src/main/res/layout/item_view_phone_number.xml +++ b/app/src/main/res/layout/item_view_phone_number.xml @@ -4,6 +4,7 @@ android:id="@+id/contact_number_holder" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" android:paddingBottom="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"> From 50904b2dff1e0c5d091d0f2f750002c2671f53ed Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 15:21:22 +0100 Subject: [PATCH 06/22] adding Group icons --- app/src/main/res/drawable-hdpi/ic_group.png | Bin 0 -> 299 bytes app/src/main/res/drawable-xhdpi/ic_group.png | Bin 0 -> 368 bytes app/src/main/res/drawable-xxhdpi/ic_group.png | Bin 0 -> 488 bytes app/src/main/res/drawable-xxxhdpi/ic_group.png | Bin 0 -> 636 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_group.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_group.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_group.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_group.png diff --git a/app/src/main/res/drawable-hdpi/ic_group.png b/app/src/main/res/drawable-hdpi/ic_group.png new file mode 100644 index 0000000000000000000000000000000000000000..ff698afc0f44ec4628bb0b9dd60af34ae62863e6 GIT binary patch literal 299 zcmV+`0o4A9P)51C5gef^Sg^v5V_0$)?jW&aTPb=5v0~vMt^O_LHR;coVcHHM5$XFST|D#7 zlV)ZLg*^_tWOOOb&%Nq0I+$RFIhiTO zXrsie_Qd>AGQ^5G(EEWeF^C#PEJU1@v~WOL_GkvZ3eF-PYx)n*O%xa1pgR)tP;`P! xjzPC7=Aq~+CAvoK1TI=iNK*UrqC9#2E;knCZq*Ueq?-T$002ovPDHLkV1fdrfb{?X literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_group.png b/app/src/main/res/drawable-xhdpi/ic_group.png new file mode 100644 index 0000000000000000000000000000000000000000..323981ccf415027cfa51dc07d8c0ac173f75ce06 GIT binary patch literal 368 zcmV-$0gwKPP)YU7)JxPQThV@LtT9leFM?eNrzTTXVFIy+&hUcpi^xkRXe!qpj!|M8bmpEC?D-5 zpI;IvsNC}#Ps6!O?+yMl9*>8R1|0^ZL^KHroXyc9CRMyFP{cAl#_6#%;aBME-VTKH zaJiv6cKZHL-VQX#VqbjA@MfSx7FXh9!<&HtStR09!<&J0+JT5HE^~V`&?Jk!+};e# za)(Pq#q!1eXt#_Lvyk5#0XgL%UEYSfrcTxNMqmmnAMk-1o1D<5Pr~PL3HP))W`mmZ z%UwPkZv;YixFAL2opZJ)9+xe?RPO{T9PmOOo~bh<-yJF539J!Qgf6Rcum{ykV38+^ z^2oeAPnws&8D%&f1=dwBfmh0q$fcoq36v!mO~VI%QNUlP)9Zu7oaT>t;RCc zR&S4e&uL?@*LdB%S5BJTb1PyPhG7_n@gJdsWe&+vrbLzl5@CI9&KTF!bIC|3Uz;<> z8;vM39m3b2PUGu9}WN^Y!&Xqr66r&okuf$4Q!v zSW#dqgdgveGQY-OM87Dte!Qq9_ITif5ANAzA+&E8#{c;u>m|uL`=oiKNQDYTa$K;- zI!St(Jh?&<{_eX%x=6Cko%3aR#})}XBW~pH8b3N_k`#F~ zCC%Kgd22eq_TfQ}@#Tntx~V5Rzxr&R3BeQdb>FgI8vp06S0)rC7Hejo>U4RKAGN0<`lj$bu}WtwDxi e7=~dO?cy6s)Tk0VSw{f?0000D1G5u9wh1XOCoIyty0h#l-;hay$Pv4#8% zB6M=9Kd9*|81zxNzgKJV}R8D8N6PvnzQN-3q3Qc5YM7^O~wCSAHT zX)w(QQT8+Jo%@?nl|^FQdMr?}@52Me*(Ry)T(<5*18(x?`b=5(Apzs0*XLrey%A7l zn=EZI9As|>ERwakAbTTVl$fk_DdoO51M2uRnfu-hXyDW9-1lZc6QADazBdE9`1H-X z7vP`!g!CuAgHIFIeg1$dFU3Rnm(&A8c<1 zMAYb~yykBN-J1asSNK6vEiMG#n*k9O7U<#DW1fS7_XdD_Biv@0H9B-yW0_l2!tYIh z@F&17H~|C@K!7r1)R<+771n7J)1%EgD=aZfjj_xx$xD1;2R!yBz%izH#b>hgiI+@r zlqluSvX!>C1NLy5$9x3*Tjdd_h)BNUY^3cifHL>_fVEX-C=(^zN!pfuGT;dFbjYip zJm+xI^V+aa0PN=}zsS2TPuNE^;N}eb0f2L?6RIX>2L51QefP zct{aFzy%y&$7i1exK2@B!zH}&-@AZeS`^hLB?mC!zjpyM6xm$|aKeA@0^U(%Zymsp z|K0_(D6&llu-AX@0*Wqj&a?jvAb literal 0 HcmV?d00001 From 93edf90d51088f54c8ced574cecb34abb5cd8954 Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 20:23:15 +0100 Subject: [PATCH 07/22] adding a tab for Groups --- .../contacts/activities/MainActivity.kt | 28 +++++++++++++------ .../contacts/adapters/ViewPagerAdapter.kt | 12 ++++++-- .../contacts/fragments/GroupsFragment.kt | 9 ++++++ app/src/main/res/layout/activity_main.xml | 6 ++++ app/src/main/res/layout/fragment_groups.xml | 8 ++++++ 5 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt create mode 100644 app/src/main/res/layout/fragment_groups.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index eaebb9b8..d20e791b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -26,6 +26,7 @@ import com.simplemobiletools.contacts.dialogs.ImportContactsDialog import com.simplemobiletools.contacts.extensions.config import com.simplemobiletools.contacts.extensions.dbHelper import com.simplemobiletools.contacts.extensions.getTempFile +import com.simplemobiletools.contacts.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.helpers.ContactsHelper import com.simplemobiletools.contacts.helpers.VcfExporter import com.simplemobiletools.contacts.interfaces.RefreshContactsListener @@ -33,6 +34,7 @@ import com.simplemobiletools.contacts.models.Contact import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_contacts.* import kotlinx.android.synthetic.main.fragment_favorites.* +import kotlinx.android.synthetic.main.fragment_groups.* import java.io.FileOutputStream class MainActivity : SimpleActivity(), RefreshContactsListener { @@ -97,7 +99,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { val configTextColor = config.textColor if (storedTextColor != configTextColor) { - main_tabs_holder.getTabAt(getOtherViewPagerItem(viewpager.currentItem))?.icon?.applyColorFilter(configTextColor) + getInactiveTabIndexes(viewpager.currentItem).forEach { + main_tabs_holder.getTabAt(it)?.icon?.applyColorFilter(configTextColor) + } contacts_fragment?.textColorChanged(configTextColor) favorites_fragment?.textColorChanged(configTextColor) } @@ -190,7 +194,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { override fun onQueryTextChange(newText: String): Boolean { if (isSearchOpen) { - getCurrentFragment()?.onSearchQueryChanged(newText) + (getCurrentFragment() as? MyViewPagerFragment)?.onSearchQueryChanged(newText) } return true } @@ -199,20 +203,24 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { MenuItemCompat.setOnActionExpandListener(searchMenuItem, object : MenuItemCompat.OnActionExpandListener { override fun onMenuItemActionExpand(item: MenuItem?): Boolean { - getCurrentFragment()?.onSearchOpened() + (getCurrentFragment() as? MyViewPagerFragment)?.onSearchOpened() isSearchOpen = true return true } override fun onMenuItemActionCollapse(item: MenuItem?): Boolean { - getCurrentFragment()?.onSearchClosed() + (getCurrentFragment() as? MyViewPagerFragment)?.onSearchClosed() isSearchOpen = false return true } }) } - private fun getCurrentFragment() = if (viewpager.currentItem == 0) contacts_fragment else favorites_fragment + private fun getCurrentFragment() = when (viewpager.currentItem) { + 0 -> contacts_fragment + 1 -> favorites_fragment + else -> groups_fragment + } private fun setupTabColors() { val lastUsedPage = config.lastUsedViewPagerPage @@ -221,7 +229,10 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { setSelectedTabIndicatorColor(getAdjustedPrimaryColor()) getTabAt(lastUsedPage)?.select() getTabAt(lastUsedPage)?.icon?.applyColorFilter(getAdjustedPrimaryColor()) - getTabAt(getOtherViewPagerItem(lastUsedPage))?.icon?.applyColorFilter(config.textColor) + + getInactiveTabIndexes(lastUsedPage).forEach { + getTabAt(it)?.icon?.applyColorFilter(config.textColor) + } } } @@ -253,14 +264,15 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } } - private fun getOtherViewPagerItem(used: Int) = if (used == 1) 0 else 1 + private fun getInactiveTabIndexes(activeIndex: Int) = arrayListOf(0, 1, 2).filter { it != activeIndex } private fun initFragments() { viewpager.adapter = ViewPagerAdapter(this) + viewpager.offscreenPageLimit = 2 viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { if (isSearchOpen) { - getCurrentFragment().onSearchQueryChanged("") + (getCurrentFragment() as? MyViewPagerFragment)?.onSearchQueryChanged("") searchMenuItem?.collapseActionView() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ViewPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ViewPagerAdapter.kt index bed555b9..644e71d5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ViewPagerAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ViewPagerAdapter.kt @@ -10,10 +10,10 @@ import com.simplemobiletools.contacts.fragments.MyViewPagerFragment class ViewPagerAdapter(val activity: MainActivity) : PagerAdapter() { override fun instantiateItem(container: ViewGroup, position: Int): Any { - val layout = if (position == 0) R.layout.fragment_contacts else R.layout.fragment_favorites + val layout = getFragment(position) val view = activity.layoutInflater.inflate(layout, container, false) container.addView(view) - (view as MyViewPagerFragment).setupFragment(activity) + (view as? MyViewPagerFragment)?.setupFragment(activity) return view } @@ -21,6 +21,12 @@ class ViewPagerAdapter(val activity: MainActivity) : PagerAdapter() { container.removeView(item as View) } - override fun getCount() = 2 + override fun getCount() = 3 override fun isViewFromObject(view: View, item: Any) = view == item + + private fun getFragment(position: Int) = when (position) { + 0 -> R.layout.fragment_contacts + 1 -> R.layout.fragment_favorites + else -> R.layout.fragment_groups + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt new file mode 100644 index 00000000..7fc1b8ad --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.contacts.fragments + +import android.content.Context +import android.support.design.widget.CoordinatorLayout +import android.util.AttributeSet + +class GroupsFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet) { + +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f3250f88..95c89e52 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -28,6 +28,12 @@ android:layout_height="wrap_content" android:icon="@drawable/ic_star_on"/> + + + + + From 32e7eadbb35aaad3e0a3cb098df6272e728bdc1b Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 20:40:57 +0100 Subject: [PATCH 08/22] add some helper functions for querying device and contact groups --- .../contacts/helpers/ContactsHelper.kt | 67 +++++++++++++++++++ .../contacts/models/Group.kt | 3 + 2 files changed, 70 insertions(+) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 00e812e3..474888e5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -305,6 +305,73 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return notes } + private fun getContactGroups(contactId: Int? = null): SparseArray> { + val groups = SparseArray>() + val uri = ContactsContract.Data.CONTENT_URI + val projection = arrayOf( + ContactsContract.Data.RAW_CONTACT_ID, + CommonDataKinds.GroupMembership.GROUP_ROW_ID + ) + + var selection = "${ContactsContract.Data.MIMETYPE} = ?" + var selectionArgs = arrayOf(CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) + + if (contactId != null) { + selection += " AND ${ContactsContract.Data.RAW_CONTACT_ID} = ?" + selectionArgs = arrayOf(CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE, contactId.toString()) + } + + var cursor: Cursor? = null + try { + cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) + if (cursor?.moveToFirst() == true) { + do { + val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) + val rowId = cursor.getIntValue(CommonDataKinds.GroupMembership.GROUP_ROW_ID) + + if (groups[id] == null) { + groups.put(id, ArrayList()) + } + + groups[id]!!.add(Group(rowId, "")) + } while (cursor.moveToNext()) + } + } catch (e: Exception) { + activity.showErrorToast(e) + } finally { + cursor?.close() + } + + return groups + } + + fun getGroups(): ArrayList { + val groups = ArrayList() + val uri = ContactsContract.Groups.CONTENT_URI + val projection = arrayOf( + ContactsContract.Groups._ID, + ContactsContract.Groups.TITLE + ) + + var cursor: Cursor? = null + try { + cursor = activity.contentResolver.query(uri, projection, null, null, null) + if (cursor?.moveToFirst() == true) { + do { + val id = cursor.getIntValue(ContactsContract.Groups._ID) + val title = cursor.getStringValue(ContactsContract.Groups.TITLE) + groups.add(Group(id, title)) + } while (cursor.moveToNext()) + } + } catch (e: Exception) { + activity.showErrorToast(e) + } finally { + cursor?.close() + } + + return groups + } + fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { if (id == 0) { return null diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt new file mode 100644 index 00000000..736cd5fc --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt @@ -0,0 +1,3 @@ +package com.simplemobiletools.contacts.models + +data class Group(var id: Int, var title: String) From 20a333071ee5f8688acd8c71c3ceb8a657594b9f Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 22:56:13 +0100 Subject: [PATCH 09/22] add a Groups field to contacts --- .../activities/EditContactActivity.kt | 2 +- .../contacts/helpers/ContactsHelper.kt | 33 +++++++++++++------ .../contacts/helpers/DBHelper.kt | 3 +- .../contacts/helpers/VcfImporter.kt | 5 ++- .../contacts/models/Contact.kt | 3 +- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index 19afcc74..5db75b50 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -321,7 +321,7 @@ class EditContactActivity : ContactActivity() { private fun setupNewContact() { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) supportActionBar?.title = resources.getString(R.string.new_contact) - contact = Contact(0, "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), config.lastUsedContactSource, 0, 0, "", null, "") + contact = Contact(0, "", "", "", "", ArrayList(), ArrayList(), ArrayList(), ArrayList(), config.lastUsedContactSource, 0, 0, "", null, "", ArrayList()) contact_source.text = getPublicContactSource(contact!!.source) contact_source.setOnClickListener { showContactSourcePicker(contact!!.source) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 474888e5..0b3a19c4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -57,8 +57,9 @@ class ContactsHelper(val activity: BaseSimpleActivity) { val contactId = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) val thumbnailUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: "" val notes = "" + val groups = ArrayList() val contact = Contact(id, firstName, middleName, surname, photoUri, number, emails, addresses, events, accountName, - starred, contactId, thumbnailUri, null, notes) + starred, contactId, thumbnailUri, null, notes, groups) contacts.put(id, contact) } while (cursor.moveToNext()) } @@ -103,6 +104,13 @@ class ContactsHelper(val activity: BaseSimpleActivity) { contacts[key]?.notes = notes.valueAt(i) } + val groups = getContactGroups(getStoredGroups()) + size = groups.size() + for (i in 0 until size) { + val key = groups.keyAt(i) + contacts[key]?.groups = groups.valueAt(i) + } + activity.dbHelper.getContacts().forEach { contacts.put(it.id, it) } @@ -305,19 +313,19 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return notes } - private fun getContactGroups(contactId: Int? = null): SparseArray> { + private fun getContactGroups(storedGroups: ArrayList, contactId: Int? = null): SparseArray> { val groups = SparseArray>() val uri = ContactsContract.Data.CONTENT_URI val projection = arrayOf( - ContactsContract.Data.RAW_CONTACT_ID, - CommonDataKinds.GroupMembership.GROUP_ROW_ID + ContactsContract.Data.CONTACT_ID, + ContactsContract.Data.DATA1 ) var selection = "${ContactsContract.Data.MIMETYPE} = ?" var selectionArgs = arrayOf(CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) if (contactId != null) { - selection += " AND ${ContactsContract.Data.RAW_CONTACT_ID} = ?" + selection += " AND ${ContactsContract.Data.CONTACT_ID} = ?" selectionArgs = arrayOf(CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE, contactId.toString()) } @@ -326,14 +334,16 @@ class ContactsHelper(val activity: BaseSimpleActivity) { cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) if (cursor?.moveToFirst() == true) { do { - val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID) - val rowId = cursor.getIntValue(CommonDataKinds.GroupMembership.GROUP_ROW_ID) + val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) + val newRowId = cursor.getIntValue(ContactsContract.Data.DATA1) if (groups[id] == null) { groups.put(id, ArrayList()) } - groups[id]!!.add(Group(rowId, "")) + val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: "" + val group = Group(newRowId, groupTitle) + groups[id]!!.add(group) } while (cursor.moveToNext()) } } catch (e: Exception) { @@ -345,7 +355,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return groups } - fun getGroups(): ArrayList { + fun getStoredGroups(): ArrayList { val groups = ArrayList() val uri = ContactsContract.Groups.CONTENT_URI val projection = arrayOf( @@ -391,6 +401,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { } private fun parseContactCursor(selection: String, selectionArgs: Array): Contact? { + val storedGroups = getStoredGroups() val uri = ContactsContract.Data.CONTENT_URI val projection = getContactProjection() var cursor: Cursor? = null @@ -410,8 +421,10 @@ class ContactsHelper(val activity: BaseSimpleActivity) { val accountName = cursor.getStringValue(ContactsContract.RawContacts.ACCOUNT_NAME) ?: "" val starred = cursor.getIntValue(CommonDataKinds.StructuredName.STARRED) val contactId = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) + val groups = getContactGroups(storedGroups, contactId)[contactId] ?: ArrayList() val thumbnailUri = cursor.getStringValue(CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: "" - return Contact(id, firstName, middleName, surname, photoUri, number, emails, addresses, events, accountName, starred, contactId, thumbnailUri, null, notes) + return Contact(id, firstName, middleName, surname, photoUri, number, emails, addresses, events, accountName, starred, contactId, + thumbnailUri, null, notes, groups) } } finally { cursor?.close() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt index 2703ffa8..965c5256 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt @@ -163,8 +163,9 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont val notes = cursor.getStringValue(COL_NOTES) val starred = cursor.getIntValue(COL_STARRED) + val groups = ArrayList() - val contact = Contact(id, firstName, middleName, surname, "", phoneNumbers, emails, addresses, events, SMT_PRIVATE, starred, id, "", photo, notes) + val contact = Contact(id, firstName, middleName, surname, "", phoneNumbers, emails, addresses, events, SMT_PRIVATE, starred, id, "", photo, notes, groups) contacts.add(contact) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt index e644d5eb..602e5160 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/VcfImporter.kt @@ -28,6 +28,7 @@ class VcfImporter(val activity: SimpleActivity) { private var curEmails = ArrayList() private var curEvents = ArrayList() private var curAddresses = ArrayList
() + private var curGroups = ArrayList() private var isGettingPhoto = false private var currentPhotoString = StringBuilder() @@ -234,7 +235,8 @@ class VcfImporter(val activity: SimpleActivity) { } private fun saveContact(source: String) { - val contact = Contact(0, curFirstName, curMiddleName, curSurname, curPhotoUri, curPhoneNumbers, curEmails, curAddresses, curEvents, source, 0, 0, "", null, curNotes) + val contact = Contact(0, curFirstName, curMiddleName, curSurname, curPhotoUri, curPhoneNumbers, curEmails, curAddresses, curEvents, + source, 0, 0, "", null, curNotes, curGroups) if (ContactsHelper(activity).insertContact(contact)) { contactsImported++ } @@ -250,6 +252,7 @@ class VcfImporter(val activity: SimpleActivity) { curEmails = ArrayList() curEvents = ArrayList() curAddresses = ArrayList() + curGroups = ArrayList() isGettingPhoto = false currentPhotoString = StringBuilder() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt index 498e1a52..488f4a14 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt @@ -7,7 +7,8 @@ import com.simplemobiletools.commons.helpers.SORT_DESCENDING data class Contact(val id: Int, var firstName: String, var middleName: String, var surname: String, var photoUri: String, var phoneNumbers: ArrayList, var emails: ArrayList, var addresses: ArrayList
, var events: ArrayList, - var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String) : Comparable { + var source: String, var starred: Int, val contactId: Int, val thumbnailUri: String, var photo: Bitmap?, var notes: String, + var groups: ArrayList) : Comparable { companion object { var sorting = 0 } From 0b2f6e8f043517e544d9d883e48ca0e782bc786b Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 23:24:52 +0100 Subject: [PATCH 10/22] list contact groups at the View screen --- .../activities/ViewContactActivity.kt | 18 +++++++++++++++ .../main/res/layout/activity_view_contact.xml | 22 ++++++++++++++++++- app/src/main/res/layout/item_view_group.xml | 14 ++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/layout/item_view_group.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt index ff483eb8..1bffbd05 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt @@ -19,6 +19,7 @@ import kotlinx.android.synthetic.main.activity_view_contact.* import kotlinx.android.synthetic.main.item_event.view.* import kotlinx.android.synthetic.main.item_view_address.view.* import kotlinx.android.synthetic.main.item_view_email.view.* +import kotlinx.android.synthetic.main.item_view_group.view.* import kotlinx.android.synthetic.main.item_view_phone_number.view.* class ViewContactActivity : ContactActivity() { @@ -119,6 +120,7 @@ class ViewContactActivity : ContactActivity() { contact_event_image.applyColorFilter(textColor) contact_source_image.applyColorFilter(textColor) contact_notes_image.applyColorFilter(textColor) + contact_groups_image.applyColorFilter(textColor) contact_send_sms.setOnClickListener { trySendSMS() } contact_start_call.setOnClickListener { tryStartCall(contact!!) } @@ -159,6 +161,7 @@ class ViewContactActivity : ContactActivity() { setupAddresses() setupEvents() setupNotes() + setupGroups() } private fun setupPhoneNumbers() { @@ -245,5 +248,20 @@ class ViewContactActivity : ContactActivity() { contact_notes.beVisibleIf(notes.isNotEmpty()) } + private fun setupGroups() { + contact_groups_holder.removeAllViews() + val groups = contact!!.groups + groups.forEach { + layoutInflater.inflate(R.layout.item_view_group, contact_groups_holder, false).apply { + val group = it + contact_groups_holder.addView(this) + contact_group.text = group.title + } + } + + contact_groups_image.beVisibleIf(groups.isNotEmpty()) + contact_groups_holder.beVisibleIf(groups.isNotEmpty()) + } + private fun getStarDrawable(on: Boolean) = resources.getDrawable(if (on) R.drawable.ic_star_on_big else R.drawable.ic_star_off_big) } diff --git a/app/src/main/res/layout/activity_view_contact.xml b/app/src/main/res/layout/activity_view_contact.xml index 3a8e9c31..4b081639 100644 --- a/app/src/main/res/layout/activity_view_contact.xml +++ b/app/src/main/res/layout/activity_view_contact.xml @@ -239,6 +239,26 @@ android:paddingTop="@dimen/normal_margin" android:textSize="@dimen/bigger_text_size"/> + + + + + From dbad01e1fc1087a3c0b1766ae976f2553e33a287 Mon Sep 17 00:00:00 2001 From: tibbi Date: Fri, 16 Mar 2018 23:47:57 +0100 Subject: [PATCH 11/22] ignore the default and Favorites group --- .../simplemobiletools/contacts/helpers/ContactsHelper.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 0b3a19c4..2690ce52 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -341,7 +341,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { groups.put(id, ArrayList()) } - val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: "" + val groupTitle = storedGroups.firstOrNull { it.id == newRowId }?.title ?: continue val group = Group(newRowId, groupTitle) groups[id]!!.add(group) } while (cursor.moveToNext()) @@ -363,9 +363,12 @@ class ContactsHelper(val activity: BaseSimpleActivity) { ContactsContract.Groups.TITLE ) + val selection = "${ContactsContract.Groups.AUTO_ADD} = ? AND ${ContactsContract.Groups.FAVORITES} = ?" + val selectionArgs = arrayOf("0", "0") + var cursor: Cursor? = null try { - cursor = activity.contentResolver.query(uri, projection, null, null, null) + cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) if (cursor?.moveToFirst() == true) { do { val id = cursor.getIntValue(ContactsContract.Groups._ID) From 8ad98e7c1205fcf1a2cabe3abc700ea9de1d4847 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 11:08:01 +0100 Subject: [PATCH 12/22] adding a Groups field at Edit Contact Activity --- .../activities/EditContactActivity.kt | 8 ++++ .../main/res/layout/activity_edit_contact.xml | 40 ++++++++++++++++++- app/src/main/res/layout/item_group.xml | 40 +++++++++++++++++++ app/src/main/res/values-de/strings.xml | 3 ++ app/src/main/res/values-fr/strings.xml | 3 ++ app/src/main/res/values-ko-rKR/strings.xml | 3 ++ app/src/main/res/values-pt/strings.xml | 3 ++ app/src/main/res/values-ru/strings.xml | 3 ++ app/src/main/res/values-sk/strings.xml | 3 ++ app/src/main/res/values-sv/strings.xml | 3 ++ app/src/main/res/values-zh-rTW/strings.xml | 3 ++ app/src/main/res/values/strings.xml | 3 ++ 12 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/layout/item_group.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index 5db75b50..f1e4d13a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -166,6 +166,7 @@ class EditContactActivity : ContactActivity() { contact_event_image.applyColorFilter(textColor) contact_notes_image.applyColorFilter(textColor) contact_source_image.applyColorFilter(textColor) + contact_groups_image.applyColorFilter(textColor) val adjustedPrimaryColor = getAdjustedPrimaryColor() contact_number_add_new.applyColorFilter(adjustedPrimaryColor) @@ -176,6 +177,8 @@ class EditContactActivity : ContactActivity() { contact_address_add_new.background.applyColorFilter(textColor) contact_event_add_new.applyColorFilter(adjustedPrimaryColor) contact_event_add_new.background.applyColorFilter(textColor) + contact_groups_add_new.applyColorFilter(adjustedPrimaryColor) + contact_groups_add_new.background.applyColorFilter(textColor) contact_toggle_favorite.setOnClickListener { toggleFavorite() } contact_photo.setOnClickListener { trySetPhoto() } @@ -186,6 +189,7 @@ class EditContactActivity : ContactActivity() { contact_email_add_new.setOnClickListener { addNewEmailField() } contact_address_add_new.setOnClickListener { addNewAddressField() } contact_event_add_new.setOnClickListener { addNewEventField() } + contact_groups_add_new.setOnClickListener { addNewGroupField() } contact_toggle_favorite.apply { setImageDrawable(getStarDrawable(contact!!.starred == 1)) @@ -653,6 +657,10 @@ class EditContactActivity : ContactActivity() { contact_events_holder.addView(eventHolder) } + private fun addNewGroupField() { + + } + private fun toggleFavorite() { val isStarred = isContactStarred() contact_toggle_favorite.apply { diff --git a/app/src/main/res/layout/activity_edit_contact.xml b/app/src/main/res/layout/activity_edit_contact.xml index b5c8cc52..66cbe244 100644 --- a/app/src/main/res/layout/activity_edit_contact.xml +++ b/app/src/main/res/layout/activity_edit_contact.xml @@ -313,6 +313,44 @@ android:textCursorDrawable="@null" android:textSize="@dimen/bigger_text_size"/> + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1e54adbf..d081b4cf 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -6,6 +6,7 @@ Aktualisiere… Gerätespeicher Gerätespeicher (nicht sichtbar für andere Apps) + No groups Neuer Kontakt Kontakt bearbeiten @@ -27,6 +28,8 @@ Beim Klicken auf den Kontakt Kontakt anrufen Kontaktdetails ansehen + Show favorites tab + Show groups tab Email diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 323ce16a..550d4cfb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -6,6 +6,7 @@ Mise à jour… Stockage du téléphone Stockage du téléphone (non visible par d\'autres applis) + No groups Nouveau contact Modifier contact @@ -27,6 +28,8 @@ Sur appui du contact Appeler le contact Voir les détails du contact + Show favorites tab + Show groups tab E-mail diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 9db78c56..308186f8 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -6,6 +6,7 @@ 수정중… Phone storage Phone storage (not visible by other apps) + No groups 새로운 연락처 연락처 수정 @@ -27,6 +28,8 @@ On contact click Call contact View contact details + Show favorites tab + Show groups tab 이메일 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index d932c2b0..da72fda2 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -6,6 +6,7 @@ A atualizar… Armazenamento do telefone Armazenamento do telefone (não visível por outras alicações) + No groups Novo contacto Editar contacto @@ -27,6 +28,8 @@ Ao clicar no contacto Ligar Ver detalhes + Show favorites tab + Show groups tab E-mail diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index cc0a7cc6..6cc1fd68 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -6,6 +6,7 @@ Обновление… Память устройства Память устройства (не видна другим приложениям) + No groups Новый контакт Редактировать контакт @@ -27,6 +28,8 @@ При нажатии на контакт Позвонить контакту Просмотреть подробности о контакте + Show favorites tab + Show groups tab Эл. почта diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 00f2d6fb..9c6f3d29 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -6,6 +6,7 @@ Upravuje sa… Úložisko mobilu Úložisko mobilu (neviditeľné pre ostatné apky) + Žiadne skupiny Nový kontakt Upraviť kontakt @@ -27,6 +28,8 @@ Po kliknutí na kontakt Zavolať kontakt Zobraziť údaje kontaktu + Zobraziť okno s obľúbenými + Zobraziť okno so skupinami Email diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 2d9fa6a1..46506fdf 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -6,6 +6,7 @@ Uppdaterar… Telefonens lagringsutrymme Telefonens lagringsutrymme (inte synligt för andra appar) + No groups Ny kontakt Redigera kontakt @@ -27,6 +28,8 @@ Vid kontakttryckning Ring kontakt Visa kontaktuppgifter + Show favorites tab + Show groups tab E-post diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 061e7bc3..9c67fc1d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -6,6 +6,7 @@ 更新中… 手機空間 手機空間 (其他程式不可見) + No groups 新聯絡人 編輯聯絡人 @@ -27,6 +28,8 @@ 點擊聯絡人 打電話給聯絡人 顯示聯絡人資料 + Show favorites tab + Show groups tab 信箱 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e05a942..ae316966 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,7 @@ Updating… Phone storage Phone storage (not visible by other apps) + No groups New contact Edit contact @@ -27,6 +28,8 @@ On contact click Call contact View contact details + Show favorites tab + Show groups tab Email From 27855ca57415de535b7d11af211d46ddcdd10b4f Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 11:52:14 +0100 Subject: [PATCH 13/22] show only contact groups where System_ID is null --- .../com/simplemobiletools/contacts/helpers/ContactsHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 2690ce52..fd0d67b3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -363,7 +363,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { ContactsContract.Groups.TITLE ) - val selection = "${ContactsContract.Groups.AUTO_ADD} = ? AND ${ContactsContract.Groups.FAVORITES} = ?" + val selection = "${ContactsContract.Groups.AUTO_ADD} = ? AND ${ContactsContract.Groups.FAVORITES} = ? AND ${ContactsContract.Groups.SYSTEM_ID} IS NULL" val selectionArgs = arrayOf("0", "0") var cursor: Cursor? = null From 7e38050342c03eed4b5bc0ec710316f1330b6e95 Mon Sep 17 00:00:00 2001 From: fricyo <30796677+fricyo@users.noreply.github.com> Date: Sun, 18 Mar 2018 22:29:46 +0800 Subject: [PATCH 14/22] Update Translation --- app/src/main/res/values-zh-rTW/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9c67fc1d..53f5ae80 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -6,7 +6,7 @@ 更新中… 手機空間 手機空間 (其他程式不可見) - No groups + 沒有群組 新聯絡人 編輯聯絡人 @@ -28,8 +28,8 @@ 點擊聯絡人 打電話給聯絡人 顯示聯絡人資料 - Show favorites tab - Show groups tab + 顯示我的最愛頁面 + 顯示群組頁面 信箱 From b31e7b0086b752797416841c37a95eb0bef77a74 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 16:57:50 +0100 Subject: [PATCH 15/22] implement a Group picker dialog --- .../activities/EditContactActivity.kt | 31 +++++++-- .../contacts/dialogs/SelectGroupsDialog.kt | 69 +++++++++++++++++++ .../main/res/layout/dialog_select_groups.xml | 17 +++++ app/src/main/res/layout/item_checkbox.xml | 18 +++++ app/src/main/res/layout/item_textview.xml | 11 +++ app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-ko-rKR/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-sk/strings.xml | 1 + app/src/main/res/values-sv/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 14 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt create mode 100644 app/src/main/res/layout/dialog_select_groups.xml create mode 100644 app/src/main/res/layout/item_checkbox.xml create mode 100644 app/src/main/res/layout/item_textview.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index f1e4d13a..fbee0f29 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -20,6 +20,7 @@ import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.contacts.R +import com.simplemobiletools.contacts.dialogs.SelectGroupsDialog import com.simplemobiletools.contacts.extensions.* import com.simplemobiletools.contacts.helpers.* import com.simplemobiletools.contacts.models.* @@ -28,6 +29,7 @@ import kotlinx.android.synthetic.main.item_edit_address.view.* import kotlinx.android.synthetic.main.item_edit_email.view.* import kotlinx.android.synthetic.main.item_edit_phone_number.view.* import kotlinx.android.synthetic.main.item_event.view.* +import kotlinx.android.synthetic.main.item_group.view.* import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import java.util.* @@ -189,7 +191,7 @@ class EditContactActivity : ContactActivity() { contact_email_add_new.setOnClickListener { addNewEmailField() } contact_address_add_new.setOnClickListener { addNewAddressField() } contact_event_add_new.setOnClickListener { addNewEventField() } - contact_groups_add_new.setOnClickListener { addNewGroupField() } + contact_groups_add_new.setOnClickListener { showSelectGroupsDialog() } contact_toggle_favorite.apply { setImageDrawable(getStarDrawable(contact!!.starred == 1)) @@ -363,6 +365,13 @@ class EditContactActivity : ContactActivity() { setupEventTypePicker(this) } } + + if (contact!!.groups.isEmpty()) { + val groupsHolder = contact_groups_holder.getChildAt(0) + (groupsHolder as? ViewGroup)?.contact_group?.apply { + setupGroupsPicker(this) + } + } } private fun setupPhoneNumberTypePicker(numberTypeField: TextView, type: Int = DEFAULT_PHONE_NUMBER_TYPE) { @@ -426,6 +435,16 @@ class EditContactActivity : ContactActivity() { } } + private fun setupGroupsPicker(groupTitleField: TextView, group: Group? = null) { + groupTitleField.apply { + text = group?.title ?: getString(R.string.no_groups) + alpha = if (group == null) 0.5f else 1f + setOnClickListener { + showSelectGroupsDialog() + } + } + } + private fun resetContactEvent(contactEvent: TextView, removeContactEventButton: ImageView) { contactEvent.apply { text = getString(R.string.unknown) @@ -493,6 +512,12 @@ class EditContactActivity : ContactActivity() { } } + private fun showSelectGroupsDialog() { + SelectGroupsDialog(this@EditContactActivity, contact!!.groups) { + + } + } + private fun saveContact() { if (isSaving || contact == null) { return @@ -657,10 +682,6 @@ class EditContactActivity : ContactActivity() { contact_events_holder.addView(eventHolder) } - private fun addNewGroupField() { - - } - private fun toggleFavorite() { val isStarred = isContactStarred() contact_toggle_favorite.apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt new file mode 100644 index 00000000..b0c6b6d8 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt @@ -0,0 +1,69 @@ +package com.simplemobiletools.contacts.dialogs + +import android.support.v7.app.AlertDialog +import android.view.ViewGroup +import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.views.MyAppCompatCheckbox +import com.simplemobiletools.contacts.R +import com.simplemobiletools.contacts.activities.SimpleActivity +import com.simplemobiletools.contacts.helpers.ContactsHelper +import com.simplemobiletools.contacts.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.* +import java.util.* + +class SelectGroupsDialog(val activity: SimpleActivity, val selectedGroups: ArrayList, val callback: (newGroups: ArrayList) -> Unit) { + private val NEW_GROUP_ID = -1 + + private val dialog: AlertDialog? + private val checkboxes = ArrayList() + private val groups = ContactsHelper(activity).getStoredGroups() + + init { + val view = activity.layoutInflater.inflate(R.layout.dialog_select_groups, null) as ViewGroup + groups.forEach { + activity.layoutInflater.inflate(R.layout.item_checkbox, null, false).apply { + checkboxes.add(item_checkbox) + item_checkbox_holder.setOnClickListener { + item_checkbox.toggle() + } + item_checkbox.apply { + isChecked = selectedGroups.contains(it) + text = it.title + tag = it.id + } + view.dialog_groups_holder.addView(this) + } + } + + val newGroup = Group(NEW_GROUP_ID, activity.getString(R.string.create_new_group)) + activity.layoutInflater.inflate(R.layout.item_textview, null, false).item_textview.apply { + text = newGroup.title + tag = newGroup.id + view.dialog_groups_holder.addView(this) + setOnClickListener { + + } + } + + dialog = AlertDialog.Builder(activity) + .setPositiveButton(R.string.ok, { dialog, which -> dialogConfirmed() }) + .setNegativeButton(R.string.cancel, null) + .create().apply { + activity.setupDialogStuff(view, this) + } + } + + private fun dialogConfirmed() { + val selectedGroups = ArrayList() + checkboxes.filter { it.isChecked }.forEach { + val groupId = it.tag as Int + groups.firstOrNull { it.id == groupId }?.apply { + selectedGroups.add(this) + } + } + + callback(selectedGroups) + } +} diff --git a/app/src/main/res/layout/dialog_select_groups.xml b/app/src/main/res/layout/dialog_select_groups.xml new file mode 100644 index 00000000..21a468d9 --- /dev/null +++ b/app/src/main/res/layout/dialog_select_groups.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/layout/item_checkbox.xml b/app/src/main/res/layout/item_checkbox.xml new file mode 100644 index 00000000..8aa72cae --- /dev/null +++ b/app/src/main/res/layout/item_checkbox.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/layout/item_textview.xml b/app/src/main/res/layout/item_textview.xml new file mode 100644 index 00000000..486dfee7 --- /dev/null +++ b/app/src/main/res/layout/item_textview.xml @@ -0,0 +1,11 @@ + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d081b4cf..bda8c04a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -7,6 +7,7 @@ Gerätespeicher Gerätespeicher (nicht sichtbar für andere Apps) No groups + Create a new group Neuer Kontakt Kontakt bearbeiten diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 550d4cfb..b6e38037 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -7,6 +7,7 @@ Stockage du téléphone Stockage du téléphone (non visible par d\'autres applis) No groups + Create a new group Nouveau contact Modifier contact diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 308186f8..612be50b 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -7,6 +7,7 @@ Phone storage Phone storage (not visible by other apps) No groups + Create a new group 새로운 연락처 연락처 수정 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index da72fda2..2d19395b 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -7,6 +7,7 @@ Armazenamento do telefone Armazenamento do telefone (não visível por outras alicações) No groups + Create a new group Novo contacto Editar contacto diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6cc1fd68..c6aecba9 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -7,6 +7,7 @@ Память устройства Память устройства (не видна другим приложениям) No groups + Create a new group Новый контакт Редактировать контакт diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 9c6f3d29..648c6524 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -7,6 +7,7 @@ Úložisko mobilu Úložisko mobilu (neviditeľné pre ostatné apky) Žiadne skupiny + Vytvoriť novú skupinu Nový kontakt Upraviť kontakt diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 46506fdf..3fddf676 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -7,6 +7,7 @@ Telefonens lagringsutrymme Telefonens lagringsutrymme (inte synligt för andra appar) No groups + Create a new group Ny kontakt Redigera kontakt diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9c67fc1d..eb9aa37c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -7,6 +7,7 @@ 手機空間 手機空間 (其他程式不可見) No groups + Create a new group 新聯絡人 編輯聯絡人 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae316966..a941a193 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Phone storage Phone storage (not visible by other apps) No groups + Create a new group New contact Edit contact From 9d9495ea80afdcf1b58580a4cda3f4cac6d6da17 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 17:33:43 +0100 Subject: [PATCH 16/22] properly update contact groups after modifying them --- .../activities/EditContactActivity.kt | 59 ++++++++++++++++++- app/src/main/res/layout/item_group.xml | 1 + 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index fbee0f29..a3d49a7e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -244,6 +244,7 @@ class EditContactActivity : ContactActivity() { setupAddresses() setupNotes() setupEvents() + setupGroups() } private fun setupPhoneNumbers() { @@ -324,6 +325,56 @@ class EditContactActivity : ContactActivity() { } } + private fun setupGroups() { + contact_groups_holder.removeAllViews() + val groups = contact!!.groups + groups.forEachIndexed { index, group -> + var groupHolder = contact_groups_holder.getChildAt(index) + if (groupHolder == null) { + groupHolder = layoutInflater.inflate(R.layout.item_group, contact_groups_holder, false) + contact_groups_holder.addView(groupHolder) + } + + (groupHolder as ViewGroup).apply { + contact_group.apply { + text = group.title + setTextColor(config.textColor) + tag = group.id + alpha = 1f + } + + setOnClickListener { + showSelectGroupsDialog() + } + + contact_group_remove.apply { + beVisible() + applyColorFilter(getAdjustedPrimaryColor()) + background.applyColorFilter(config.textColor) + setOnClickListener { + removeGroup(group.id) + } + } + } + } + + if (groups.isEmpty()) { + layoutInflater.inflate(R.layout.item_group, contact_groups_holder, false).apply { + contact_group.apply { + alpha = 0.5f + text = getString(R.string.no_groups) + setTextColor(config.textColor) + } + + contact_groups_holder.addView(this) + contact_group_remove.beGone() + setOnClickListener { + showSelectGroupsDialog() + } + } + } + } + private fun setupNewContact() { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) supportActionBar?.title = resources.getString(R.string.new_contact) @@ -454,6 +505,11 @@ class EditContactActivity : ContactActivity() { removeContactEventButton.beGone() } + private fun removeGroup(id: Int) { + contact!!.groups = contact!!.groups.filter { it.id != id } as ArrayList + setupGroups() + } + private fun showNumberTypePicker(numberTypeField: TextView) { val items = arrayListOf( RadioItem(CommonDataKinds.Phone.TYPE_MOBILE, getString(R.string.mobile)), @@ -514,7 +570,8 @@ class EditContactActivity : ContactActivity() { private fun showSelectGroupsDialog() { SelectGroupsDialog(this@EditContactActivity, contact!!.groups) { - + contact!!.groups = it + setupGroups() } } diff --git a/app/src/main/res/layout/item_group.xml b/app/src/main/res/layout/item_group.xml index c831a76b..5a5620e1 100644 --- a/app/src/main/res/layout/item_group.xml +++ b/app/src/main/res/layout/item_group.xml @@ -26,6 +26,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/contact_group" + android:layout_alignParentRight="true" android:layout_alignTop="@+id/contact_group" android:layout_centerHorizontal="true" android:layout_marginBottom="@dimen/medium_margin" From 6750512f116fcf24875356a44c3b3bcd2b3bd1d5 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 17:57:43 +0100 Subject: [PATCH 17/22] properly handle contact groups at editing, or inserting a new one --- .../contacts/helpers/ContactsHelper.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index fd0d67b3..4e90a224 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -633,6 +633,24 @@ class ContactsHelper(val activity: BaseSimpleActivity) { operations.add(build()) } + // delete groups + ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).apply { + val selection = "${ContactsContract.Data.RAW_CONTACT_ID} = ? AND ${ContactsContract.Data.MIMETYPE} = ? " + val selectionArgs = arrayOf(contact.id.toString(), CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) + withSelection(selection, selectionArgs) + operations.add(build()) + } + + // add groups + contact.groups.forEach { + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValue(ContactsContract.Data.RAW_CONTACT_ID, contact.id) + withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) + withValue(CommonDataKinds.GroupMembership.GROUP_ROW_ID, it.id) + operations.add(build()) + } + } + // favorite try { val uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, contact.contactId.toString()) @@ -767,6 +785,16 @@ class ContactsHelper(val activity: BaseSimpleActivity) { operations.add(build()) } + // groups + contact.groups.forEach { + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE) + withValue(CommonDataKinds.GroupMembership.GROUP_ROW_ID, it.id) + operations.add(build()) + } + } + // photo (inspired by https://gist.github.com/slightfoot/5985900) var fullSizePhotoData: ByteArray? = null var scaledSizePhotoData: ByteArray? From c3a148282fcea6c3bada70b5b77bc2efb230ca2f Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 19:33:54 +0100 Subject: [PATCH 18/22] implement new group creation --- .../activities/EditContactActivity.kt | 2 +- .../contacts/dialogs/CreateNewGroupDialog.kt | 41 +++++++++++ .../contacts/dialogs/SelectGroupsDialog.kt | 68 ++++++++++++------- .../contacts/helpers/ContactsHelper.kt | 26 +++++-- .../contacts/models/Group.kt | 2 +- .../res/layout/dialog_create_new_group.xml | 28 ++++++++ 6 files changed, 133 insertions(+), 34 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/CreateNewGroupDialog.kt create mode 100644 app/src/main/res/layout/dialog_create_new_group.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index a3d49a7e..e5455c46 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -505,7 +505,7 @@ class EditContactActivity : ContactActivity() { removeContactEventButton.beGone() } - private fun removeGroup(id: Int) { + private fun removeGroup(id: Long) { contact!!.groups = contact!!.groups.filter { it.id != id } as ArrayList setupGroups() } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/CreateNewGroupDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/CreateNewGroupDialog.kt new file mode 100644 index 00000000..5897b671 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/CreateNewGroupDialog.kt @@ -0,0 +1,41 @@ +package com.simplemobiletools.contacts.dialogs + +import android.support.v7.app.AlertDialog +import android.view.View +import com.simplemobiletools.commons.activities.BaseSimpleActivity +import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.extensions.showKeyboard +import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.value +import com.simplemobiletools.contacts.R +import com.simplemobiletools.contacts.helpers.ContactsHelper +import com.simplemobiletools.contacts.models.Group +import kotlinx.android.synthetic.main.dialog_create_new_group.view.* + +class CreateNewGroupDialog(val activity: BaseSimpleActivity, val callback: (newGroup: Group) -> Unit) { + init { + val view = activity.layoutInflater.inflate(R.layout.dialog_create_new_group, null) + + AlertDialog.Builder(activity) + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.cancel, null) + .create().apply { + activity.setupDialogStuff(view, this, R.string.create_new_group) { + showKeyboard(view.group_name) + getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(View.OnClickListener { + val name = view.group_name.value + if (name.isEmpty()) { + activity.toast(R.string.empty_name) + return@OnClickListener + } + + val newGroup = ContactsHelper(activity).createNewGroup(name) + if (newGroup != null) { + callback(newGroup) + } + dismiss() + }) + } + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt index b0c6b6d8..66d1344e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectGroupsDialog.kt @@ -6,6 +6,7 @@ import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.contacts.R import com.simplemobiletools.contacts.activities.SimpleActivity +import com.simplemobiletools.contacts.extensions.config import com.simplemobiletools.contacts.helpers.ContactsHelper import com.simplemobiletools.contacts.models.Group import kotlinx.android.synthetic.main.dialog_select_groups.view.* @@ -14,38 +15,18 @@ import kotlinx.android.synthetic.main.item_textview.view.* import java.util.* class SelectGroupsDialog(val activity: SimpleActivity, val selectedGroups: ArrayList, val callback: (newGroups: ArrayList) -> Unit) { - private val NEW_GROUP_ID = -1 - - private val dialog: AlertDialog? + private val view = activity.layoutInflater.inflate(R.layout.dialog_select_groups, null) as ViewGroup private val checkboxes = ArrayList() private val groups = ContactsHelper(activity).getStoredGroups() + private val config = activity.config + private val dialog: AlertDialog? init { - val view = activity.layoutInflater.inflate(R.layout.dialog_select_groups, null) as ViewGroup groups.forEach { - activity.layoutInflater.inflate(R.layout.item_checkbox, null, false).apply { - checkboxes.add(item_checkbox) - item_checkbox_holder.setOnClickListener { - item_checkbox.toggle() - } - item_checkbox.apply { - isChecked = selectedGroups.contains(it) - text = it.title - tag = it.id - } - view.dialog_groups_holder.addView(this) - } + addGroupCheckbox(it) } - val newGroup = Group(NEW_GROUP_ID, activity.getString(R.string.create_new_group)) - activity.layoutInflater.inflate(R.layout.item_textview, null, false).item_textview.apply { - text = newGroup.title - tag = newGroup.id - view.dialog_groups_holder.addView(this) - setOnClickListener { - - } - } + addCreateNewGroupButton() dialog = AlertDialog.Builder(activity) .setPositiveButton(R.string.ok, { dialog, which -> dialogConfirmed() }) @@ -55,10 +36,45 @@ class SelectGroupsDialog(val activity: SimpleActivity, val selectedGroups: Array } } + private fun addGroupCheckbox(group: Group) { + activity.layoutInflater.inflate(R.layout.item_checkbox, null, false).apply { + checkboxes.add(item_checkbox) + item_checkbox_holder.setOnClickListener { + item_checkbox.toggle() + } + item_checkbox.apply { + isChecked = selectedGroups.contains(group) + text = group.title + tag = group.id + setColors(config.textColor, config.primaryColor, config.backgroundColor) + } + view.dialog_groups_holder.addView(this) + } + } + + private fun addCreateNewGroupButton() { + val newGroup = Group(0, activity.getString(R.string.create_new_group)) + activity.layoutInflater.inflate(R.layout.item_textview, null, false).item_textview.apply { + text = newGroup.title + tag = newGroup.id + setTextColor(config.textColor) + view.dialog_groups_holder.addView(this) + setOnClickListener { + CreateNewGroupDialog(activity) { + selectedGroups.add(it) + groups.add(it) + view.dialog_groups_holder.removeViewAt(view.dialog_groups_holder.childCount - 1) + addGroupCheckbox(it) + addCreateNewGroupButton() + } + } + } + } + private fun dialogConfirmed() { val selectedGroups = ArrayList() checkboxes.filter { it.isChecked }.forEach { - val groupId = it.tag as Int + val groupId = it.tag as Long groups.firstOrNull { it.id == groupId }?.apply { selectedGroups.add(this) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 4e90a224..8aa8bd08 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -13,10 +13,7 @@ import android.provider.ContactsContract.CommonDataKinds.Note import android.provider.MediaStore import android.util.SparseArray import com.simplemobiletools.commons.activities.BaseSimpleActivity -import com.simplemobiletools.commons.extensions.getIntValue -import com.simplemobiletools.commons.extensions.getStringValue -import com.simplemobiletools.commons.extensions.showErrorToast -import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.SORT_BY_FIRST_NAME import com.simplemobiletools.commons.helpers.SORT_BY_MIDDLE_NAME import com.simplemobiletools.commons.helpers.SORT_BY_SURNAME @@ -335,7 +332,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { if (cursor?.moveToFirst() == true) { do { val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID) - val newRowId = cursor.getIntValue(ContactsContract.Data.DATA1) + val newRowId = cursor.getLongValue(ContactsContract.Data.DATA1) if (groups[id] == null) { groups.put(id, ArrayList()) @@ -371,7 +368,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) if (cursor?.moveToFirst() == true) { do { - val id = cursor.getIntValue(ContactsContract.Groups._ID) + val id = cursor.getLongValue(ContactsContract.Groups._ID) val title = cursor.getStringValue(ContactsContract.Groups.TITLE) groups.add(Group(id, title)) } while (cursor.moveToNext()) @@ -385,6 +382,23 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return groups } + fun createNewGroup(title: String): Group? { + try { + val operations = ArrayList() + ContentProviderOperation.newInsert(ContactsContract.Groups.CONTENT_URI).apply { + withValue(ContactsContract.Groups.TITLE, title) + operations.add(build()) + } + + val results = activity.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) + val rawId = ContentUris.parseId(results[0].uri) + return Group(rawId, title) + } catch (e: Exception) { + activity.showErrorToast(e) + } + return null + } + fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { if (id == 0) { return null diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt index 736cd5fc..dbd23558 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Group.kt @@ -1,3 +1,3 @@ package com.simplemobiletools.contacts.models -data class Group(var id: Int, var title: String) +data class Group(var id: Long, var title: String) diff --git a/app/src/main/res/layout/dialog_create_new_group.xml b/app/src/main/res/layout/dialog_create_new_group.xml new file mode 100644 index 00000000..58884ff9 --- /dev/null +++ b/app/src/main/res/layout/dialog_create_new_group.xml @@ -0,0 +1,28 @@ + + + + + + + + From 4294228bfd4a0e6f9508e614688ec9b073802c3b Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 18 Mar 2018 20:40:55 +0100 Subject: [PATCH 19/22] add a helper function for deleting a contact group --- .../contacts/helpers/ContactsHelper.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index 8aa8bd08..dd0abc9c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -399,6 +399,20 @@ class ContactsHelper(val activity: BaseSimpleActivity) { return null } + fun deleteGroup(id: Long) { + try { + val operations = ArrayList() + val uri = ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, id).buildUpon() + .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") + .build() + + operations.add(ContentProviderOperation.newDelete(uri).build()) + activity.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) + } catch (e: Exception) { + activity.showErrorToast(e) + } + } + fun getContactWithId(id: Int, isLocalPrivate: Boolean): Contact? { if (id == 0) { return null From f74376e8ac2812905d3715ae15589c8c605e58f9 Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 19 Mar 2018 10:11:58 +0100 Subject: [PATCH 20/22] create an interface for all fragments --- .../contacts/activities/MainActivity.kt | 20 +++++++++---------- .../contacts/fragments/FavoritesFragment.kt | 2 +- .../contacts/fragments/GroupsFragment.kt | 14 ++++++++++++- .../contacts/fragments/MyViewPagerFragment.kt | 15 +++++++------- .../contacts/interfaces/FragmentInterface.kt | 13 ++++++++++++ 5 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index d20e791b..d7f3df30 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -115,8 +115,8 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { if (storedPrimaryColor != configPrimaryColor) { main_tabs_holder.setSelectedTabIndicatorColor(getAdjustedPrimaryColor()) main_tabs_holder.getTabAt(viewpager.currentItem)?.icon?.applyColorFilter(getAdjustedPrimaryColor()) - contacts_fragment?.primaryColorChanged() - favorites_fragment?.primaryColorChanged() + contacts_fragment?.primaryColorChanged(configPrimaryColor) + favorites_fragment?.primaryColorChanged(configPrimaryColor) } val configStartNameWithSurname = config.startNameWithSurname @@ -130,9 +130,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { initFragments() } - contacts_fragment?.initContacts() + contacts_fragment?.refreshContacts() contacts_fragment?.onActivityResume() - favorites_fragment?.initContacts() + favorites_fragment?.refreshContacts() favorites_fragment?.onActivityResume() } @@ -306,15 +306,15 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun showSortingDialog() { ChangeSortingDialog(this) { - contacts_fragment?.initContacts() - favorites_fragment?.initContacts() + contacts_fragment?.refreshContacts() + favorites_fragment?.refreshContacts() } } fun showFilterDialog() { FilterContactSourcesDialog(this) { contacts_fragment?.forceListRedraw = true - contacts_fragment?.initContacts() + contacts_fragment?.refreshContacts() } } @@ -400,12 +400,12 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } override fun refreshContacts() { - contacts_fragment.initContacts() - favorites_fragment.initContacts() + contacts_fragment.refreshContacts() + favorites_fragment.refreshContacts() } override fun refreshFavorites() { - favorites_fragment?.initContacts() + favorites_fragment?.refreshContacts() } private fun checkWhatsNewDialog() { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt index 3e42d3aa..f4881002 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt @@ -16,7 +16,7 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa private fun showAddFavoritesDialog() { AddFavoritesDialog(activity!!) { - initContacts() + refreshContacts() } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt index 7fc1b8ad..49103e3f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt @@ -3,7 +3,19 @@ package com.simplemobiletools.contacts.fragments import android.content.Context import android.support.design.widget.CoordinatorLayout import android.util.AttributeSet +import com.simplemobiletools.contacts.activities.MainActivity +import com.simplemobiletools.contacts.interfaces.FragmentInterface -class GroupsFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet) { +class GroupsFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet), FragmentInterface { + override fun setupFragment(activity: MainActivity) { + } + override fun textColorChanged(color: Int) { + } + + override fun primaryColorChanged(color: Int) { + } + + override fun refreshContacts() { + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt index 7c767a66..5f34a546 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt @@ -16,10 +16,11 @@ import com.simplemobiletools.contacts.extensions.editContact import com.simplemobiletools.contacts.extensions.tryStartCall import com.simplemobiletools.contacts.extensions.viewContact import com.simplemobiletools.contacts.helpers.* +import com.simplemobiletools.contacts.interfaces.FragmentInterface import com.simplemobiletools.contacts.models.Contact import kotlinx.android.synthetic.main.fragment_layout.view.* -abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet) { +abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet), FragmentInterface { protected var activity: MainActivity? = null private var lastHashCode = 0 private var contactsIgnoringSearch = ArrayList() @@ -27,7 +28,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) var forceListRedraw = false - fun setupFragment(activity: MainActivity) { + override fun setupFragment(activity: MainActivity) { config = activity.config if (this.activity == null) { this.activity = activity @@ -48,17 +49,17 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } - initContacts() + refreshContacts() } - fun textColorChanged(color: Int) { + override fun textColorChanged(color: Int) { (fragment_list.adapter as ContactsAdapter).apply { updateTextColor(color) initDrawables() } } - fun primaryColorChanged() { + override fun primaryColorChanged(color: Int) { fragment_fastscroller.updatePrimaryColor() fragment_fastscroller.updateBubblePrimaryColor() } @@ -66,11 +67,11 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) fun startNameWithSurnameChanged(startNameWithSurname: Boolean) { (fragment_list.adapter as ContactsAdapter).apply { config.sorting = if (startNameWithSurname) SORT_BY_SURNAME else SORT_BY_FIRST_NAME - initContacts() + refreshContacts() } } - fun initContacts() { + override fun refreshContacts() { if (activity == null || activity!!.isActivityDestroyed()) { return } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt new file mode 100644 index 00000000..e4a1c2d3 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt @@ -0,0 +1,13 @@ +package com.simplemobiletools.contacts.interfaces + +import com.simplemobiletools.contacts.activities.MainActivity + +interface FragmentInterface { + fun setupFragment(activity: MainActivity) + + fun textColorChanged(color: Int) + + fun primaryColorChanged(color: Int) + + fun refreshContacts() +} From 53b0632edd84697d365077aed41b512d07f2c213 Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 19 Mar 2018 11:53:20 +0100 Subject: [PATCH 21/22] fetch contacts at app startup only once --- .../contacts/activities/MainActivity.kt | 39 +++++++++---- .../contacts/adapters/ContactsAdapter.kt | 2 +- .../contacts/adapters/ViewPagerAdapter.kt | 10 +++- .../contacts/fragments/FavoritesFragment.kt | 2 +- .../contacts/fragments/GroupsFragment.kt | 3 +- .../contacts/fragments/MyViewPagerFragment.kt | 56 ++++++++----------- .../contacts/helpers/ContactsHelper.kt | 4 +- .../contacts/interfaces/FragmentInterface.kt | 3 +- .../interfaces/RefreshContactsListener.kt | 2 +- 9 files changed, 68 insertions(+), 53 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index d7f3df30..b7735d19 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -130,10 +130,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { initFragments() } - contacts_fragment?.refreshContacts() contacts_fragment?.onActivityResume() - favorites_fragment?.refreshContacts() favorites_fragment?.onActivityResume() + refreshContacts(true, true) } if (hasPermission(PERMISSION_WRITE_CONTACTS)) { @@ -267,7 +266,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = arrayListOf(0, 1, 2).filter { it != activeIndex } private fun initFragments() { - viewpager.adapter = ViewPagerAdapter(this) viewpager.offscreenPageLimit = 2 viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { @@ -288,6 +286,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } }) viewpager.currentItem = config.lastUsedViewPagerPage + refreshContacts(true, true) main_tabs_holder.onTabSelectionChanged( tabUnselectedAction = { @@ -306,15 +305,14 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun showSortingDialog() { ChangeSortingDialog(this) { - contacts_fragment?.refreshContacts() - favorites_fragment?.refreshContacts() + refreshContacts(true, true) } } fun showFilterDialog() { FilterContactSourcesDialog(this) { contacts_fragment?.forceListRedraw = true - contacts_fragment?.refreshContacts() + refreshContacts(true, false) } } @@ -336,7 +334,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { ImportContactsDialog(this, path) { if (it) { runOnUiThread { - refreshContacts() + refreshContacts(true, true) } } } @@ -399,13 +397,32 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { BuildConfig.VERSION_NAME, faqItems) } - override fun refreshContacts() { - contacts_fragment.refreshContacts() - favorites_fragment.refreshContacts() + override fun refreshContacts(refreshContactsTab: Boolean, refreshFavoritesTab: Boolean) { + if (isActivityDestroyed()) { + return + } + + ContactsHelper(this).getContacts { + if (isActivityDestroyed()) { + return@getContacts + } + + if (viewpager.adapter == null) { + viewpager.adapter = ViewPagerAdapter(this, it) + } + + if (refreshContactsTab) { + contacts_fragment?.refreshContacts(it) + } + + if (refreshFavoritesTab) { + favorites_fragment?.refreshContacts(it) + } + } } override fun refreshFavorites() { - favorites_fragment?.refreshContacts() + refreshContacts(false, true) } private fun checkWhatsNewDialog() { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt index 7b704bb6..95a04a55 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/ContactsAdapter.kt @@ -130,7 +130,7 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList) : PagerAdapter() { override fun instantiateItem(container: ViewGroup, position: Int): Any { val layout = getFragment(position) val view = activity.layoutInflater.inflate(layout, container, false) container.addView(view) - (view as? MyViewPagerFragment)?.setupFragment(activity) + (view as FragmentInterface).apply { + setupFragment(activity) + refreshContacts(contacts) + } return view } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt index f4881002..104eaa41 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/FavoritesFragment.kt @@ -16,7 +16,7 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa private fun showAddFavoritesDialog() { AddFavoritesDialog(activity!!) { - refreshContacts() + activity!!.refreshContacts(false, true) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt index 49103e3f..e52fe7e7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/GroupsFragment.kt @@ -5,6 +5,7 @@ import android.support.design.widget.CoordinatorLayout import android.util.AttributeSet import com.simplemobiletools.contacts.activities.MainActivity import com.simplemobiletools.contacts.interfaces.FragmentInterface +import com.simplemobiletools.contacts.models.Contact class GroupsFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet), FragmentInterface { override fun setupFragment(activity: MainActivity) { @@ -16,6 +17,6 @@ class GroupsFragment(context: Context, attributeSet: AttributeSet) : Coordinator override fun primaryColorChanged(color: Int) { } - override fun refreshContacts() { + override fun refreshContacts(contacts: ArrayList) { } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt index 5f34a546..e273e94c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt @@ -15,7 +15,10 @@ import com.simplemobiletools.contacts.extensions.config import com.simplemobiletools.contacts.extensions.editContact import com.simplemobiletools.contacts.extensions.tryStartCall import com.simplemobiletools.contacts.extensions.viewContact -import com.simplemobiletools.contacts.helpers.* +import com.simplemobiletools.contacts.helpers.Config +import com.simplemobiletools.contacts.helpers.ON_CLICK_CALL_CONTACT +import com.simplemobiletools.contacts.helpers.ON_CLICK_EDIT_CONTACT +import com.simplemobiletools.contacts.helpers.ON_CLICK_VIEW_CONTACT import com.simplemobiletools.contacts.interfaces.FragmentInterface import com.simplemobiletools.contacts.models.Contact import kotlinx.android.synthetic.main.fragment_layout.view.* @@ -48,8 +51,6 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) fragment_placeholder_2.text = activity.getString(R.string.add_favorites) } } - - refreshContacts() } override fun textColorChanged(color: Int) { @@ -67,45 +68,34 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) fun startNameWithSurnameChanged(startNameWithSurname: Boolean) { (fragment_list.adapter as ContactsAdapter).apply { config.sorting = if (startNameWithSurname) SORT_BY_SURNAME else SORT_BY_FIRST_NAME - refreshContacts() + this@MyViewPagerFragment.activity!!.refreshContacts(true, true) } } - override fun refreshContacts() { - if (activity == null || activity!!.isActivityDestroyed()) { - return + override fun refreshContacts(contacts: ArrayList) { + if (config.lastUsedContactSource.isEmpty()) { + val grouped = contacts.groupBy { it.source }.maxWith(compareBy { it.value.size }) + config.lastUsedContactSource = grouped?.key ?: "" } - ContactsHelper(activity!!).getContacts { - var contacts = it - if (activity == null || activity!!.isActivityDestroyed()) { - return@getContacts - } - - if (config.lastUsedContactSource.isEmpty()) { - val grouped = contacts.groupBy { it.source }.maxWith(compareBy { it.value.size }) - config.lastUsedContactSource = grouped?.key ?: "" - } - - contacts = if (this is FavoritesFragment) { - contacts.filter { it.starred == 1 } as ArrayList + val filtered = if (this is FavoritesFragment) { + contacts.filter { it.starred == 1 } as ArrayList + } else { + val contactSources = config.displayContactSources + if (config.showAllContacts()) { + contacts } else { - val contactSources = config.displayContactSources - if (config.showAllContacts()) { - contacts - } else { - contacts.filter { contactSources.contains(it.source) } as ArrayList - } + contacts.filter { contactSources.contains(it.source) } as ArrayList } + } - Contact.sorting = config.sorting - contacts.sort() + Contact.sorting = config.sorting + filtered.sort() - if (contacts.hashCode() != lastHashCode) { - lastHashCode = contacts.hashCode() - activity!!.runOnUiThread { - setupContacts(contacts) - } + if (filtered.hashCode() != lastHashCode) { + lastHashCode = filtered.hashCode() + activity?.runOnUiThread { + setupContacts(filtered) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index dd0abc9c..ee8c0980 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -116,7 +116,9 @@ class ContactsHelper(val activity: BaseSimpleActivity) { var resultContacts = ArrayList(contactsSize) (0 until contactsSize).mapTo(resultContacts) { contacts.valueAt(it) } resultContacts = resultContacts.distinctBy { it.contactId } as ArrayList - callback(resultContacts) + activity.runOnUiThread { + callback(resultContacts) + } }.start() } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt index e4a1c2d3..0f49e205 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/FragmentInterface.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.contacts.interfaces import com.simplemobiletools.contacts.activities.MainActivity +import com.simplemobiletools.contacts.models.Contact interface FragmentInterface { fun setupFragment(activity: MainActivity) @@ -9,5 +10,5 @@ interface FragmentInterface { fun primaryColorChanged(color: Int) - fun refreshContacts() + fun refreshContacts(contacts: ArrayList) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/RefreshContactsListener.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/RefreshContactsListener.kt index 3d0c687b..7819aa1f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/RefreshContactsListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/interfaces/RefreshContactsListener.kt @@ -1,7 +1,7 @@ package com.simplemobiletools.contacts.interfaces interface RefreshContactsListener { - fun refreshContacts() + fun refreshContacts(refreshContactsTab: Boolean, refreshFavoritesTab: Boolean) fun refreshFavorites() } From 6abbd15328636e9511d0c9a4bb07c02eda1e20d4 Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 19 Mar 2018 11:54:47 +0100 Subject: [PATCH 22/22] move refreshContacts a bit up --- .../com/simplemobiletools/contacts/activities/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index b7735d19..27a0cadd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -266,6 +266,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun getInactiveTabIndexes(activeIndex: Int) = arrayListOf(0, 1, 2).filter { it != activeIndex } private fun initFragments() { + refreshContacts(true, true) viewpager.offscreenPageLimit = 2 viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { @@ -286,7 +287,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } }) viewpager.currentItem = config.lastUsedViewPagerPage - refreshContacts(true, true) main_tabs_holder.onTabSelectionChanged( tabUnselectedAction = {