From 8f49323648f1a016f923d8dd2ad9a3a9a8f21af3 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Wed, 18 Jan 2023 13:47:12 -0400 Subject: [PATCH] Extract adapter creation from ContactSearchMediator. --- .../contacts/paged/ContactSearchAdapter.kt | 23 +++++++++ .../contacts/paged/ContactSearchItems.kt | 36 +++++++------- .../contacts/paged/ContactSearchMediator.kt | 49 ++++++++++++++----- 3 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt new file mode 100644 index 000000000..4f7d3a4e2 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchAdapter.kt @@ -0,0 +1,23 @@ +package org.thoughtcrime.securesms.contacts.paged + +import android.view.View +import org.thoughtcrime.securesms.util.adapter.mapping.PagingMappingAdapter + +/** + * Default contact search adapter, using the models defined in `ContactSearchItems` + */ +class ContactSearchAdapter( + displayCheckBox: Boolean, + displaySmsTag: ContactSearchItems.DisplaySmsTag, + recipientListener: (View, ContactSearchData.KnownRecipient, Boolean) -> Unit, + storyListener: (View, ContactSearchData.Story, Boolean) -> Unit, + storyContextMenuCallbacks: ContactSearchItems.StoryContextMenuCallbacks, + expandListener: (ContactSearchData.Expand) -> Unit +) : PagingMappingAdapter() { + init { + ContactSearchItems.registerStoryItems(this, displayCheckBox, storyListener, storyContextMenuCallbacks) + ContactSearchItems.registerKnownRecipientItems(this, displayCheckBox, displaySmsTag, recipientListener) + ContactSearchItems.registerHeaders(this) + ContactSearchItems.registerExpands(this, expandListener) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchItems.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchItems.kt index 678cb68f6..b2a6f2656 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchItems.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchItems.kt @@ -45,6 +45,18 @@ object ContactSearchItems { ) } + fun registerKnownRecipientItems( + mappingAdapter: MappingAdapter, + displayCheckBox: Boolean, + displaySmsTag: DisplaySmsTag, + recipientListener: (View, ContactSearchData.KnownRecipient, Boolean) -> Unit + ) { + mappingAdapter.registerFactory( + RecipientModel::class.java, + LayoutFactory({ KnownRecipientViewHolder(it, displayCheckBox, displaySmsTag, recipientListener) }, R.layout.contact_search_item) + ) + } + fun registerHeaders(mappingAdapter: MappingAdapter) { mappingAdapter.registerFactory( HeaderModel::class.java, @@ -52,21 +64,7 @@ object ContactSearchItems { ) } - fun register( - mappingAdapter: MappingAdapter, - displayCheckBox: Boolean, - displaySmsTag: DisplaySmsTag, - recipientListener: RecipientClickListener, - storyListener: StoryClickListener, - storyContextMenuCallbacks: StoryContextMenuCallbacks, - expandListener: (ContactSearchData.Expand) -> Unit - ) { - registerStoryItems(mappingAdapter, displayCheckBox, storyListener, storyContextMenuCallbacks) - mappingAdapter.registerFactory( - RecipientModel::class.java, - LayoutFactory({ KnownRecipientViewHolder(it, displayCheckBox, displaySmsTag, recipientListener) }, R.layout.contact_search_item) - ) - registerHeaders(mappingAdapter) + fun registerExpands(mappingAdapter: MappingAdapter, expandListener: (ContactSearchData.Expand) -> Unit) { mappingAdapter.registerFactory( ExpandModel::class.java, LayoutFactory({ ExpandViewHolder(it, expandListener) }, R.layout.contacts_expand_item) @@ -90,7 +88,7 @@ object ContactSearchItems { /** * Story Model */ - private class StoryModel(val story: ContactSearchData.Story, val isSelected: Boolean, val hasBeenNotified: Boolean) : MappingModel { + class StoryModel(val story: ContactSearchData.Story, val isSelected: Boolean, val hasBeenNotified: Boolean) : MappingModel { override fun areItemsTheSame(newItem: StoryModel): Boolean { return newItem.story == story @@ -226,7 +224,7 @@ object ContactSearchItems { /** * Recipient model */ - private class RecipientModel(val knownRecipient: ContactSearchData.KnownRecipient, val isSelected: Boolean, val shortSummary: Boolean) : MappingModel { + class RecipientModel(val knownRecipient: ContactSearchData.KnownRecipient, val isSelected: Boolean, val shortSummary: Boolean) : MappingModel { override fun areItemsTheSame(newItem: RecipientModel): Boolean { return newItem.knownRecipient == knownRecipient @@ -363,7 +361,7 @@ object ContactSearchItems { /** * Mapping Model for section headers */ - private class HeaderModel(val header: ContactSearchData.Header) : MappingModel { + class HeaderModel(val header: ContactSearchData.Header) : MappingModel { override fun areItemsTheSame(newItem: HeaderModel): Boolean { return header.sectionKey == newItem.header.sectionKey } @@ -407,7 +405,7 @@ object ContactSearchItems { /** * Mapping Model for expandable content rows. */ - private class ExpandModel(val expand: ContactSearchData.Expand) : MappingModel { + class ExpandModel(val expand: ContactSearchData.Expand) : MappingModel { override fun areItemsTheSame(newItem: ExpandModel): Boolean { return expand.contactSearchKey == newItem.expand.contactSearchKey } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchMediator.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchMediator.kt index f20c7cd10..737edb15c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchMediator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchMediator.kt @@ -27,26 +27,23 @@ class ContactSearchMediator( displaySmsTag: ContactSearchItems.DisplaySmsTag, mapStateToConfiguration: (ContactSearchState) -> ContactSearchConfiguration, private val contactSelectionPreFilter: (View?, Set) -> Set = { _, s -> s }, - performSafetyNumberChecks: Boolean = true + performSafetyNumberChecks: Boolean = true, + adapterFactory: AdapterFactory = DefaultAdapterFactory ) { private val viewModel: ContactSearchViewModel = ViewModelProvider(fragment, ContactSearchViewModel.Factory(selectionLimits, ContactSearchRepository(), performSafetyNumberChecks)).get(ContactSearchViewModel::class.java) init { + val adapter = adapterFactory.create( + displayCheckBox, + displaySmsTag, + this::toggleSelection, + this::toggleStorySelection, + StoryContextMenuCallbacks() + ) { viewModel.expandSection(it.sectionKey) } - val adapter = PagingMappingAdapter() recyclerView.adapter = adapter - ContactSearchItems.register( - mappingAdapter = adapter, - displayCheckBox = displayCheckBox, - displaySmsTag = displaySmsTag, - recipientListener = this::toggleSelection, - storyListener = this::toggleStorySelection, - storyContextMenuCallbacks = StoryContextMenuCallbacks(), - expandListener = { viewModel.expandSection(it.sectionKey) } - ) - val dataAndSelection: LiveData, Set>> = LiveDataUtil.combineLatest( viewModel.data, viewModel.selectionState, @@ -143,4 +140,32 @@ class ContactSearchMediator( .show() } } + + /** + * Wraps the construction of a PagingMappingAdapter so that it can + * be swapped for another implementation, allow listeners to be wrapped, etc. + */ + fun interface AdapterFactory { + fun create( + displayCheckBox: Boolean, + displaySmsTag: ContactSearchItems.DisplaySmsTag, + recipientListener: (View, ContactSearchData.KnownRecipient, Boolean) -> Unit, + storyListener: (View, ContactSearchData.Story, Boolean) -> Unit, + storyContextMenuCallbacks: ContactSearchItems.StoryContextMenuCallbacks, + expandListener: (ContactSearchData.Expand) -> Unit + ): PagingMappingAdapter + } + + private object DefaultAdapterFactory : AdapterFactory { + override fun create( + displayCheckBox: Boolean, + displaySmsTag: ContactSearchItems.DisplaySmsTag, + recipientListener: (View, ContactSearchData.KnownRecipient, Boolean) -> Unit, + storyListener: (View, ContactSearchData.Story, Boolean) -> Unit, + storyContextMenuCallbacks: ContactSearchItems.StoryContextMenuCallbacks, + expandListener: (ContactSearchData.Expand) -> Unit + ): PagingMappingAdapter { + return ContactSearchAdapter(displayCheckBox, displaySmsTag, recipientListener, storyListener, storyContextMenuCallbacks, expandListener) + } + } }