From cc96b2e1988b702e35e929ac8c21f51ecbf47c7c Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 14 May 2022 12:20:44 +0200 Subject: [PATCH] Hide floating date above unread messages line Change-Id: I44b00d41a77c0fe0fd08126502430723541dc7ae --- .../StickyHeaderItemDecoration.kt | 38 ++++++++++++------- .../home/room/detail/TimelineFragment.kt | 13 ++++--- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/vector/src/main/java/de/spiritcroc/recyclerview/StickyHeaderItemDecoration.kt b/vector/src/main/java/de/spiritcroc/recyclerview/StickyHeaderItemDecoration.kt index 758070f4b8..79370ba0ec 100644 --- a/vector/src/main/java/de/spiritcroc/recyclerview/StickyHeaderItemDecoration.kt +++ b/vector/src/main/java/de/spiritcroc/recyclerview/StickyHeaderItemDecoration.kt @@ -15,6 +15,7 @@ import android.view.ViewGroup import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import com.airbnb.epoxy.EpoxyController +import com.airbnb.epoxy.EpoxyModel import org.matrix.android.sdk.api.extensions.orFalse abstract class StickyHeaderItemDecoration( @@ -47,20 +48,29 @@ abstract class StickyHeaderItemDecoration( val currentHeader = getHeaderViewForItem(headerPos, parent) fixLayoutSize(parent, currentHeader) val contactPoint = currentHeader.bottom - val childInContact = getChildInContact(parent, contactPoint, headerPos) - if (childInContact != null && isHeader(parent.getChildAdapterPosition(childInContact))) { - updateOverlaidHeaders(parent, headerPos) - moveHeader(c, currentHeader, childInContact) - return + val childInContact = getChildInContact(parent, contactPoint, headerPos) + val childBelow = getChildInContact(parent, currentHeader.top, headerPos) + val childInContactModel = childInContact?.let { epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(childInContact)) } + val childBelowModel = childBelow?.let { epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(childBelow)) } + + if (childInContact != null) { + if (isHeader(childInContactModel)) { + updateOverlaidHeaders(parent, headerPos) + moveHeader(c, currentHeader, childInContact) + return + } + if (preventOverlay(childInContactModel) || preventOverlay(childBelowModel)) { + // Hide header temporarily + return + } } // Un-hide views early, so we don't get flashing headers while scrolling - val childBellow = getChildInContact(parent, currentHeader.top, headerPos) - val overlaidHeaderPos: Int? = if (childBellow != childInContact && - childBellow != null && - isHeader(parent.getChildAdapterPosition(childBellow)) && - contactPoint - childBellow.bottom < (childBellow.bottom - childBellow.top)/8 + val overlaidHeaderPos: Int? = if (childBelow != childInContact && + childBelow != null && + isHeader(childBelowModel) && + contactPoint - childBelow.bottom < (childBelow.bottom - childBelow.top)/8 ) { null } else { @@ -126,7 +136,9 @@ abstract class StickyHeaderItemDecoration( c.restore() } - abstract fun isHeader(itemPosition: Int): Boolean + abstract fun isHeader(model: EpoxyModel<*>?): Boolean + + open fun preventOverlay(model: EpoxyModel<*>?): Boolean = false private fun getChildInContact(parent: RecyclerView, contactPoint: Int, currentHeaderPos: Int): View? { var childInContact: View? = null @@ -136,7 +148,7 @@ abstract class StickyHeaderItemDecoration( //measure height tolerance with child if child is another header if (currentHeaderPos != i) { - val isChildHeader = isHeader(parent.getChildAdapterPosition(child)) + val isChildHeader = isHeader(epoxyController.adapter.getModelAtPosition(parent.getChildAdapterPosition(child))) if (isChildHeader) { heightTolerance = mStickyHeaderHeight - child.height } @@ -172,7 +184,7 @@ abstract class StickyHeaderItemDecoration( var headerPosition = RecyclerView.NO_POSITION val directionAdd = if (reverse) 1 else -1 do { - if (isHeader(tempPosition)) { + if (isHeader(epoxyController.adapter.getModelAtPosition(tempPosition))) { headerPosition = tempPosition break } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index d3d254ec9c..dc140d0fd9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -179,6 +179,7 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationD import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData +import im.vector.app.features.home.room.detail.timeline.item.TimelineReadMarkerItem import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet @@ -1486,12 +1487,12 @@ class TimelineFragment @Inject constructor( if (vectorPreferences.floatingDate()) { views.timelineRecyclerView.addItemDecoration( object : StickyHeaderItemDecoration(timelineEventController, reverse = true) { - override fun isHeader(itemPosition: Int): Boolean { - if (itemPosition != RecyclerView.NO_POSITION) { - val model = timelineEventController.adapter.getModelAtPosition(itemPosition) - return model is DaySeparatorItem - } - return false + override fun isHeader(model: EpoxyModel<*>?): Boolean { + return model is DaySeparatorItem + } + + override fun preventOverlay(model: EpoxyModel<*>?): Boolean { + return model is TimelineReadMarkerItem } override fun getHeaderViewForItem(headerPosition: Int, parent: RecyclerView): View {