Hide floating date above unread messages line

Change-Id: I44b00d41a77c0fe0fd08126502430723541dc7ae
This commit is contained in:
SpiritCroc 2022-05-14 12:20:44 +02:00
parent 3201c629c4
commit cc96b2e198
2 changed files with 32 additions and 19 deletions

View file

@ -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
}

View file

@ -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 {