From 1a3722f6c47f6cd59cbac1ff073928e2140696cd Mon Sep 17 00:00:00 2001 From: Naveen Singh Date: Sat, 24 Jan 2026 08:26:55 +0530 Subject: [PATCH 1/2] feat: open contact details when tapping profile photo Refs: https://github.com/FossifyOrg/Contacts/issues/452 --- CHANGELOG.md | 3 ++ .../activities/GroupContactsActivity.kt | 13 +++++-- .../contacts/adapters/ContactsAdapter.kt | 37 ++++++++++++------- .../contacts/fragments/ContactsFragment.kt | 11 ++++-- .../contacts/fragments/FavoritesFragment.kt | 11 ++++-- .../ripple_selector_background_circle.xml | 9 +++++ .../drawable/selector_clickable_circle.xml | 13 +++++++ 7 files changed, 74 insertions(+), 23 deletions(-) create mode 100644 app/src/main/res/drawable/ripple_selector_background_circle.xml create mode 100644 app/src/main/res/drawable/selector_clickable_circle.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a701d07c..7ae4ea789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Tapping contact photo in lists now launches the contact details page ([#452]) ### Fixed - Fixed incorrect spacing between prefix and last name ([#157]) @@ -118,6 +120,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#339]: https://github.com/FossifyOrg/Contacts/issues/339 [#360]: https://github.com/FossifyOrg/Contacts/issues/360 [#415]: https://github.com/FossifyOrg/Contacts/issues/415 +[#452]: https://github.com/FossifyOrg/Contacts/issues/452 [Unreleased]: https://github.com/FossifyOrg/Contacts/compare/1.5.0...HEAD [1.5.0]: https://github.com/FossifyOrg/Contacts/compare/1.4.0...1.5.0 diff --git a/app/src/main/kotlin/org/fossify/contacts/activities/GroupContactsActivity.kt b/app/src/main/kotlin/org/fossify/contacts/activities/GroupContactsActivity.kt index 14e1117f2..591ceedb9 100644 --- a/app/src/main/kotlin/org/fossify/contacts/activities/GroupContactsActivity.kt +++ b/app/src/main/kotlin/org/fossify/contacts/activities/GroupContactsActivity.kt @@ -17,6 +17,7 @@ import org.fossify.contacts.adapters.ContactsAdapter import org.fossify.contacts.databinding.ActivityGroupContactsBinding import org.fossify.contacts.dialogs.SelectContactsDialog import org.fossify.contacts.extensions.handleGenericContactClick +import org.fossify.contacts.extensions.viewContact import org.fossify.contacts.helpers.GROUP import org.fossify.contacts.helpers.LOCATION_GROUP_CONTACTS import org.fossify.contacts.interfaces.RefreshContactsListener @@ -153,10 +154,14 @@ class GroupContactsActivity : SimpleActivity(), RemoveFromGroupListener, Refresh recyclerView = binding.groupContactsList, location = LOCATION_GROUP_CONTACTS, removeListener = this, - refreshListener = this - ) { - contactClicked(it as Contact) - }.apply { + refreshListener = this, + itemClick = { + contactClicked(it as Contact) + }, + profileIconClick = { + viewContact(it as Contact) + } + ).apply { binding.groupContactsList.adapter = this } diff --git a/app/src/main/kotlin/org/fossify/contacts/adapters/ContactsAdapter.kt b/app/src/main/kotlin/org/fossify/contacts/adapters/ContactsAdapter.kt index 0c936e0bf..162dd040c 100644 --- a/app/src/main/kotlin/org/fossify/contacts/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/org/fossify/contacts/adapters/ContactsAdapter.kt @@ -47,6 +47,7 @@ import org.fossify.contacts.helpers.* import org.fossify.contacts.interfaces.RefreshContactsListener import org.fossify.contacts.interfaces.RemoveFromGroupListener import java.util.Collections +import androidx.core.graphics.drawable.toDrawable class ContactsAdapter( activity: SimpleActivity, @@ -58,7 +59,8 @@ class ContactsAdapter( private val location: Int, private val removeListener: RemoveFromGroupListener?, private val enableDrag: Boolean = false, - itemClick: (Any) -> Unit + itemClick: (Any) -> Unit, + private val profileIconClick: ((Any) -> Unit)? = null ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { private val NEW_GROUP_ID = -1 @@ -350,11 +352,7 @@ class ContactsAdapter( .error(placeholderImage) val size = activity.resources.getDimension(org.fossify.commons.R.dimen.shortcut_size).toInt() - val itemToLoad: Any? = if (contact.photoUri.isNotEmpty()) { - contact.photoUri - } else { - contact.photo - } + val itemToLoad: Any? = contact.photoUri.ifEmpty { contact.photo } val builder = Glide.with(activity) .asDrawable() @@ -424,10 +422,27 @@ class ContactsAdapter( } } - findViewById(org.fossify.commons.R.id.item_contact_image).beVisibleIf(showContactThumbnails) + findViewById(org.fossify.commons.R.id.item_contact_image).apply { + beVisibleIf(showContactThumbnails) + if (profileIconClick != null && viewType != VIEW_TYPE_GRID) { + setBackgroundResource(R.drawable.selector_clickable_circle) + setOnClickListener { + if (!actModeCallback.isSelectable) { + profileIconClick.invoke(contact) + } else { + holder.viewClicked(contact) + } + } + setOnLongClickListener { + holder.viewLongClicked() + true + } + } + } if (showContactThumbnails) { - val placeholderImage = BitmapDrawable(resources, SimpleContactsHelper(context).getContactLetterIcon(fullName)) + val placeholderImage = + SimpleContactsHelper(context).getContactLetterIcon(fullName).toDrawable(resources) if (contact.photoUri.isEmpty() && contact.photo == null) { findViewById(org.fossify.commons.R.id.item_contact_image).setImageDrawable(placeholderImage) } else { @@ -437,11 +452,7 @@ class ContactsAdapter( .error(placeholderImage) .centerCrop() - val itemToLoad: Any? = if (contact.photoUri.isNotEmpty()) { - contact.photoUri - } else { - contact.photo - } + val itemToLoad: Any? = contact.photoUri.ifEmpty { contact.photo } Glide.with(activity) .load(itemToLoad) diff --git a/app/src/main/kotlin/org/fossify/contacts/fragments/ContactsFragment.kt b/app/src/main/kotlin/org/fossify/contacts/fragments/ContactsFragment.kt index 9b31890e3..951794e66 100644 --- a/app/src/main/kotlin/org/fossify/contacts/fragments/ContactsFragment.kt +++ b/app/src/main/kotlin/org/fossify/contacts/fragments/ContactsFragment.kt @@ -14,6 +14,7 @@ import org.fossify.contacts.adapters.ContactsAdapter import org.fossify.contacts.databinding.FragmentContactsBinding import org.fossify.contacts.databinding.FragmentLettersLayoutBinding import org.fossify.contacts.extensions.config +import org.fossify.contacts.extensions.viewContact import org.fossify.contacts.helpers.LOCATION_CONTACTS_TAB import org.fossify.contacts.interfaces.RefreshContactsListener @@ -58,9 +59,13 @@ class ContactsFragment(context: Context, attributeSet: AttributeSet) : MyViewPag removeListener = null, recyclerView = innerBinding.fragmentList, enableDrag = false, - ) { - (activity as RefreshContactsListener).contactClicked(it as Contact) - }.apply { + itemClick = { + (activity as RefreshContactsListener).contactClicked(it as Contact) + }, + profileIconClick = { + activity?.viewContact(it as Contact) + } + ).apply { innerBinding.fragmentList.adapter = this } diff --git a/app/src/main/kotlin/org/fossify/contacts/fragments/FavoritesFragment.kt b/app/src/main/kotlin/org/fossify/contacts/fragments/FavoritesFragment.kt index 563f800f2..8c1d95dec 100644 --- a/app/src/main/kotlin/org/fossify/contacts/fragments/FavoritesFragment.kt +++ b/app/src/main/kotlin/org/fossify/contacts/fragments/FavoritesFragment.kt @@ -21,6 +21,7 @@ import org.fossify.contacts.databinding.FragmentFavoritesBinding import org.fossify.contacts.databinding.FragmentLettersLayoutBinding import org.fossify.contacts.dialogs.SelectContactsDialog import org.fossify.contacts.extensions.config +import org.fossify.contacts.extensions.viewContact import org.fossify.contacts.helpers.LOCATION_FAVORITES_TAB import org.fossify.contacts.interfaces.RefreshContactsListener @@ -79,9 +80,13 @@ class FavoritesFragment(context: Context, attributeSet: AttributeSet) : MyViewPa removeListener = null, recyclerView = innerBinding.fragmentList, enableDrag = true, - ) { - (activity as RefreshContactsListener).contactClicked(it as Contact) - }.apply { + itemClick = { + (activity as RefreshContactsListener).contactClicked(it as Contact) + }, + profileIconClick = { + activity?.viewContact(it as Contact) + } + ).apply { innerBinding.fragmentList.adapter = this setupZoomListener(zoomListener) onDragEndListener = { diff --git a/app/src/main/res/drawable/ripple_selector_background_circle.xml b/app/src/main/res/drawable/ripple_selector_background_circle.xml new file mode 100644 index 000000000..8168bf123 --- /dev/null +++ b/app/src/main/res/drawable/ripple_selector_background_circle.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/selector_clickable_circle.xml b/app/src/main/res/drawable/selector_clickable_circle.xml new file mode 100644 index 000000000..df971ed73 --- /dev/null +++ b/app/src/main/res/drawable/selector_clickable_circle.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From f1de9bbf82ee2e5384adcc389dd770ee7b716e3f Mon Sep 17 00:00:00 2001 From: Naveen Singh Date: Sat, 24 Jan 2026 08:50:05 +0530 Subject: [PATCH 2/2] fix: use proper attribute --- app/src/main/res/drawable/selector_clickable_circle.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/drawable/selector_clickable_circle.xml b/app/src/main/res/drawable/selector_clickable_circle.xml index df971ed73..e1225a7d7 100644 --- a/app/src/main/res/drawable/selector_clickable_circle.xml +++ b/app/src/main/res/drawable/selector_clickable_circle.xml @@ -4,7 +4,7 @@ - +