Fix various CFv2 scrolling issues.

This commit is contained in:
Cody Henthorne
2023-07-20 16:50:10 -04:00
committed by GitHub
parent 4520ff78ff
commit b53cad2808
4 changed files with 22 additions and 21 deletions

View File

@@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.conversation.ConversationAdapterBridge import org.thoughtcrime.securesms.conversation.ConversationAdapterBridge
import org.thoughtcrime.securesms.conversation.ConversationAdapterBridge.PulseRequest import org.thoughtcrime.securesms.conversation.ConversationAdapterBridge.PulseRequest
import org.thoughtcrime.securesms.conversation.v2.items.InteractiveConversationElement import org.thoughtcrime.securesms.conversation.v2.items.InteractiveConversationElement
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.ThemeUtil import org.thoughtcrime.securesms.util.ThemeUtil
import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.ViewUtil
@@ -570,7 +571,7 @@ class MultiselectItemDecoration(
} }
private fun RecyclerView.getMultiselectableChildren(): Sequence<Multiselectable> { private fun RecyclerView.getMultiselectableChildren(): Sequence<Multiselectable> {
return if (FeatureFlags.useConversationFragmentV2()) { return if (SignalStore.internalValues().useConversationItemV2()) {
children.map { getChildViewHolder(it) }.filterIsInstance<Multiselectable>() children.map { getChildViewHolder(it) }.filterIsInstance<Multiselectable>()
} else { } else {
children.filterIsInstance<Multiselectable>() children.filterIsInstance<Multiselectable>()
@@ -578,7 +579,7 @@ class MultiselectItemDecoration(
} }
private fun RecyclerView.getInteractableChildren(): Sequence<InteractiveConversationElement> { private fun RecyclerView.getInteractableChildren(): Sequence<InteractiveConversationElement> {
return if (FeatureFlags.useConversationFragmentV2()) { return if (SignalStore.internalValues().useConversationItemV2()) {
children.map { getChildViewHolder(it) }.filterIsInstance<InteractiveConversationElement>() children.map { getChildViewHolder(it) }.filterIsInstance<InteractiveConversationElement>()
} else { } else {
children.filterIsInstance<InteractiveConversationElement>() children.filterIsInstance<InteractiveConversationElement>()
@@ -586,7 +587,7 @@ class MultiselectItemDecoration(
} }
private fun resolveMultiselectable(parent: RecyclerView, child: View): Multiselectable? { private fun resolveMultiselectable(parent: RecyclerView, child: View): Multiselectable? {
return if (FeatureFlags.useConversationFragmentV2()) { return if (SignalStore.internalValues().useConversationItemV2()) {
parent.getChildViewHolder(child) as? Multiselectable parent.getChildViewHolder(child) as? Multiselectable
} else { } else {
child as? Multiselectable child as? Multiselectable

View File

@@ -168,11 +168,6 @@ class ConversationAdapterV2(
notifyItemRangeChanged(0, itemCount) notifyItemRangeChanged(0, itemCount)
} }
/** [messagePosition] is one-based index and adapter is zero-based. */
fun getAdapterPositionForMessagePosition(messagePosition: Int): Int {
return messagePosition - 1
}
fun getLastVisibleConversationMessage(position: Int): ConversationMessage? { fun getLastVisibleConversationMessage(position: Int): ConversationMessage? {
return try { return try {
getConversationMessage(position) ?: getConversationMessage(position - 1) getConversationMessage(position) ?: getConversationMessage(position - 1)

View File

@@ -49,7 +49,6 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.doOnNextLayout
import androidx.core.view.doOnPreDraw import androidx.core.view.doOnPreDraw
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@@ -135,6 +134,7 @@ import org.thoughtcrime.securesms.conversation.AttachmentKeyboardButton
import org.thoughtcrime.securesms.conversation.BadDecryptLearnMoreDialog import org.thoughtcrime.securesms.conversation.BadDecryptLearnMoreDialog
import org.thoughtcrime.securesms.conversation.ConversationAdapter import org.thoughtcrime.securesms.conversation.ConversationAdapter
import org.thoughtcrime.securesms.conversation.ConversationBottomSheetCallback import org.thoughtcrime.securesms.conversation.ConversationBottomSheetCallback
import org.thoughtcrime.securesms.conversation.ConversationData
import org.thoughtcrime.securesms.conversation.ConversationHeaderView import org.thoughtcrime.securesms.conversation.ConversationHeaderView
import org.thoughtcrime.securesms.conversation.ConversationIntents import org.thoughtcrime.securesms.conversation.ConversationIntents
import org.thoughtcrime.securesms.conversation.ConversationIntents.ConversationScreenType import org.thoughtcrime.securesms.conversation.ConversationIntents.ConversationScreenType
@@ -757,12 +757,7 @@ class ConversationFragment :
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.doOnSuccess { state -> .doOnSuccess { state ->
SignalLocalMetrics.ConversationOpen.onDataLoaded() SignalLocalMetrics.ConversationOpen.onDataLoaded()
binding.conversationItemRecycler.doOnNextLayout { moveToStartPosition(state.meta)
layoutManager.scrollToPositionWithOffset(
adapter.getAdapterPositionForMessagePosition(state.meta.getStartPosition()),
binding.conversationItemRecycler.height
)
}
conversationItemDecorations.setFirstUnreadCount(state.meta.unreadCount) conversationItemDecorations.setFirstUnreadCount(state.meta.unreadCount)
} }
.flatMapObservable { it.items.data } .flatMapObservable { it.items.data }
@@ -1411,9 +1406,8 @@ class ConversationFragment :
) )
scrollToPositionDelegate = ScrollToPositionDelegate( scrollToPositionDelegate = ScrollToPositionDelegate(
binding.conversationItemRecycler, recyclerView = binding.conversationItemRecycler,
adapter::canJumpToPosition, canJumpToPosition = adapter::canJumpToPosition
adapter::getAdapterPositionForMessagePosition
) )
adapter.setPagingController(viewModel.pagingController) adapter.setPagingController(viewModel.pagingController)
@@ -2106,6 +2100,18 @@ class ConversationFragment :
//region Scroll Handling //region Scroll Handling
private fun moveToStartPosition(meta: ConversationData) {
scrollToPositionDelegate.requestScrollPosition(
position = meta.getStartPosition(),
smooth = true,
scrollStrategy = if (meta.shouldJumpToMessage()) {
jumpAndPulseScrollStrategy
} else {
ScrollToPositionDelegate.DefaultScrollStrategy
}
)
}
/** /**
* Requests a jump to the desired position, and ensures that the position desired will be visible on the screen. * Requests a jump to the desired position, and ensures that the position desired will be visible on the screen.
*/ */

View File

@@ -298,16 +298,15 @@ class ConversationRepository(
oldConversationRepository.markGiftBadgeRevealed(messageId) oldConversationRepository.markGiftBadgeRevealed(messageId)
} }
/** Quoted Message position is a zero-based index, so we need to convert it to 1-based */
fun getQuotedMessagePosition(threadId: Long, quote: Quote): Single<Int> { fun getQuotedMessagePosition(threadId: Long, quote: Quote): Single<Int> {
return Single.fromCallable { return Single.fromCallable {
SignalDatabase.messages.getQuotedMessagePosition(threadId, quote.id, quote.author) + 1 SignalDatabase.messages.getQuotedMessagePosition(threadId, quote.id, quote.author)
}.subscribeOn(Schedulers.io()) }.subscribeOn(Schedulers.io())
} }
fun getMessageResultPosition(threadId: Long, messageResult: MessageResult): Single<Int> { fun getMessageResultPosition(threadId: Long, messageResult: MessageResult): Single<Int> {
return Single.fromCallable { return Single.fromCallable {
SignalDatabase.messages.getMessagePositionInConversation(threadId, messageResult.receivedTimestampMs) + 1 SignalDatabase.messages.getMessagePositionInConversation(threadId, messageResult.receivedTimestampMs)
}.subscribeOn(Schedulers.io()) }.subscribeOn(Schedulers.io())
} }