From 7e909f2bee4a2ae189202f04753c1bdb1f50cb5d Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Mon, 10 Jul 2023 13:51:07 -0300 Subject: [PATCH] Add InternalSettings option for ConversationItem V2. --- .../app/internal/InternalSettingsFragment.kt | 8 ++ .../app/internal/InternalSettingsState.kt | 3 +- .../app/internal/InternalSettingsViewModel.kt | 8 +- .../conversation/ConversationFragment.java | 9 ++- .../conversation/v2/ConversationAdapterV2.kt | 79 ++++++++++++++++--- .../securesms/keyvalue/InternalValues.java | 9 +++ 6 files changed, 102 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index 4639230be3..283d63cfdf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -623,6 +623,14 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter viewModel.setUseConversationFragmentV2(!state.useConversationFragmentV2) } ) + + switchPref( + title = DSLSettingsText.from("Use V2 ConversationItem"), + isChecked = state.useConversationItemV2, + onClick = { + viewModel.setUseConversationItemV2(!state.useConversationItemV2) + } + ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt index 9750043b04..ed21317236 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt @@ -22,5 +22,6 @@ data class InternalSettingsState( val disableStorageService: Boolean, val canClearOnboardingState: Boolean, val pnpInitialized: Boolean, - val useConversationFragmentV2: Boolean + val useConversationFragmentV2: Boolean, + val useConversationItemV2: Boolean ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt index 5d3e33420d..2458254802 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt @@ -109,6 +109,11 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito refresh() } + fun setUseConversationItemV2(enabled: Boolean) { + SignalStore.internalValues().setUseConversationItemV2(enabled) + refresh() + } + fun addSampleReleaseNote() { repository.addSampleReleaseNote() } @@ -136,7 +141,8 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito disableStorageService = SignalStore.internalValues().storageServiceDisabled(), canClearOnboardingState = SignalStore.storyValues().hasDownloadedOnboardingStory && Stories.isFeatureEnabled(), pnpInitialized = SignalStore.misc().hasPniInitializedDevices(), - useConversationFragmentV2 = SignalStore.internalValues().useConversationFragmentV2() + useConversationFragmentV2 = SignalStore.internalValues().useConversationFragmentV2(), + useConversationItemV2 = SignalStore.internalValues().useConversationItemV2() ) fun onClearOnboardingState() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index ee1fbee821..476bfa943a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -273,8 +273,13 @@ public class ConversationFragment extends LoggingFragment implements Multiselect FrameLayout parent = new FrameLayout(context); parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)); - CachedInflater.from(context).cacheUntilLimit(R.layout.v2_conversation_item_text_only_incoming, parent, 25); - CachedInflater.from(context).cacheUntilLimit(R.layout.v2_conversation_item_text_only_outgoing, parent, 25); + if (SignalStore.internalValues().useConversationFragmentV2() && SignalStore.internalValues().useConversationItemV2()) { + CachedInflater.from(context).cacheUntilLimit(R.layout.v2_conversation_item_text_only_incoming, parent, 25); + CachedInflater.from(context).cacheUntilLimit(R.layout.v2_conversation_item_text_only_outgoing, parent, 25); + } else { + CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_received_text_only, parent, 25); + CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_sent_text_only, parent, 25); + } CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_received_multimedia, parent, 10); CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_sent_multimedia, parent, 10); CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_update, parent, 5); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt index f70568f32c..096f02d17b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt @@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.databinding.V2ConversationItemTextOnlyIncoming import org.thoughtcrime.securesms.databinding.V2ConversationItemTextOnlyOutgoingBinding import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer import org.thoughtcrime.securesms.groups.v2.GroupDescriptionUtil +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.messagerequests.MessageRequestState import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter @@ -91,25 +92,37 @@ class ConversationAdapterV2( ConversationUpdateViewHolder(view) } - registerFactory(OutgoingTextOnly::class.java) { parent -> - val view = CachedInflater.from(parent.context).inflate(R.layout.v2_conversation_item_text_only_outgoing, parent, false) - V2TextOnlyViewHolder(V2ConversationItemTextOnlyOutgoingBinding.bind(view).bridge(), this) - } - registerFactory(OutgoingMedia::class.java) { parent -> val view = CachedInflater.from(parent.context).inflate(R.layout.conversation_item_sent_multimedia, parent, false) OutgoingMediaViewHolder(view) } - registerFactory(IncomingTextOnly::class.java) { parent -> - val view = CachedInflater.from(parent.context).inflate(R.layout.v2_conversation_item_text_only_incoming, parent, false) - V2TextOnlyViewHolder(V2ConversationItemTextOnlyIncomingBinding.bind(view).bridge(), this) - } - registerFactory(IncomingMedia::class.java) { parent -> val view = CachedInflater.from(parent.context).inflate(R.layout.conversation_item_received_multimedia, parent, false) IncomingMediaViewHolder(view) } + + if (SignalStore.internalValues().useConversationItemV2()) { + registerFactory(OutgoingTextOnly::class.java) { parent -> + val view = CachedInflater.from(parent.context).inflate(R.layout.v2_conversation_item_text_only_outgoing, parent, false) + V2TextOnlyViewHolder(V2ConversationItemTextOnlyOutgoingBinding.bind(view).bridge(), this) + } + + registerFactory(IncomingTextOnly::class.java) { parent -> + val view = CachedInflater.from(parent.context).inflate(R.layout.v2_conversation_item_text_only_incoming, parent, false) + V2TextOnlyViewHolder(V2ConversationItemTextOnlyIncomingBinding.bind(view).bridge(), this) + } + } else { + registerFactory(OutgoingTextOnly::class.java) { parent -> + val view = CachedInflater.from(parent.context).inflate(R.layout.conversation_item_sent_text_only, parent, false) + OutgoingTextOnlyViewHolder(view) + } + + registerFactory(IncomingTextOnly::class.java) { parent -> + val view = CachedInflater.from(parent.context).inflate(R.layout.conversation_item_received_text_only, parent, false) + IncomingTextOnlyViewHolder(view) + } + } } override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { @@ -272,6 +285,29 @@ class ConversationAdapterV2( } } + private inner class OutgoingTextOnlyViewHolder(itemView: View) : ConversationViewHolder(itemView) { + override fun bind(model: OutgoingTextOnly) { + bindable.setEventListener(clickListener) + bindable.bind( + lifecycleOwner, + model.conversationMessage, + previousMessage, + nextMessage, + glideRequests, + Locale.getDefault(), + _selected, + model.conversationMessage.threadRecipient, + searchQuery, + false, + hasWallpaper && displayMode.displayWallpaper(), + true, // isMessageRequestAccepted, + model.conversationMessage == inlineContent, + colorizer, + displayMode + ) + } + } + private inner class OutgoingMediaViewHolder(itemView: View) : ConversationViewHolder(itemView) { override fun bind(model: OutgoingMedia) { bindable.setEventListener(clickListener) @@ -295,6 +331,29 @@ class ConversationAdapterV2( } } + private inner class IncomingTextOnlyViewHolder(itemView: View) : ConversationViewHolder(itemView) { + override fun bind(model: IncomingTextOnly) { + bindable.setEventListener(clickListener) + bindable.bind( + lifecycleOwner, + model.conversationMessage, + previousMessage, + nextMessage, + glideRequests, + Locale.getDefault(), + _selected, + model.conversationMessage.threadRecipient, + searchQuery, + false, + hasWallpaper && displayMode.displayWallpaper(), + true, // isMessageRequestAccepted, + model.conversationMessage == inlineContent, + colorizer, + displayMode + ) + } + } + private inner class IncomingMediaViewHolder(itemView: View) : ConversationViewHolder(itemView) { override fun bind(model: IncomingMedia) { bindable.setEventListener(clickListener) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java index 2a9405dd36..f62d3bf943 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.java @@ -30,6 +30,7 @@ public final class InternalValues extends SignalStoreValues { public static final String FORCE_WEBSOCKET_MODE = "internal.force_websocket_mode"; public static final String LAST_SCROLL_POSITION = "internal.last_scroll_position"; public static final String CONVERSATION_FRAGMENT_V2 = "internal.conversation_fragment_v2"; + public static final String CONVERSATION_ITEM_V2 = "internal.conversation_item_v2"; InternalValues(KeyValueStore store) { super(store); @@ -198,4 +199,12 @@ public final class InternalValues extends SignalStoreValues { public boolean useConversationFragmentV2() { return FeatureFlags.internalUser() && getBoolean(CONVERSATION_FRAGMENT_V2, false); } + + public void setUseConversationItemV2(boolean useConversationFragmentV2) { + putBoolean(CONVERSATION_ITEM_V2, useConversationFragmentV2); + } + + public boolean useConversationItemV2() { + return FeatureFlags.internalUser() && getBoolean(CONVERSATION_ITEM_V2, false); + } }