From ab1fcaca6236d9c2772d2481e414814bb529ef1d Mon Sep 17 00:00:00 2001
From: SpiritCroc <dev@spiritcroc.de>
Date: Sun, 1 Aug 2021 12:22:27 +0200
Subject: [PATCH] Scroll to linked message: better control the final scroll
 position

With scrollToPosition(), the layout will only scroll such that the view
is visible *somewhere* on the screen. Defining a precise offset where to
show it is better, so the user can expect where the message will show
up.

Change-Id: Idd25a062c4be8f45ba804e442d63409f279f2a76
---
 .../app/features/home/room/detail/RoomDetailFragment.kt    | 2 +-
 .../home/room/detail/ScrollOnNewMessageCallback.kt         | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
index c2f9c42d84..22a8259cc5 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
@@ -1178,7 +1178,7 @@ class RoomDetailFragment @Inject constructor(
             }
         }
         val stateRestorer = LayoutManagerStateRestorer(layoutManager).register()
-        scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager, timelineEventController)
+        scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager, timelineEventController, views.timelineRecyclerView)
         // Force scroll until the user has scrolled to address the bug where the list would jump during initial loading
         scrollOnNewMessageCallback.initialForceScroll = true
         scrollOnHighlightedEventCallback = ScrollOnHighlightedEventCallback(views.timelineRecyclerView, layoutManager, timelineEventController)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/ScrollOnNewMessageCallback.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/ScrollOnNewMessageCallback.kt
index 25d862e4c8..7df3ed347e 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/ScrollOnNewMessageCallback.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/ScrollOnNewMessageCallback.kt
@@ -16,6 +16,7 @@
 
 package im.vector.app.features.home.room.detail
 
+import android.view.View
 import androidx.recyclerview.widget.LinearLayoutManager
 import im.vector.app.core.platform.DefaultListUpdateCallback
 import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@@ -24,7 +25,8 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
 import java.util.concurrent.CopyOnWriteArrayList
 
 class ScrollOnNewMessageCallback(private val layoutManager: LinearLayoutManager,
-                                 private val timelineEventController: TimelineEventController) : DefaultListUpdateCallback {
+                                 private val timelineEventController: TimelineEventController,
+                                 private val parentView: View) : DefaultListUpdateCallback {
 
     private val newTimelineEventIds = CopyOnWriteArrayList<String>()
     private var forceScroll = false
@@ -62,7 +64,8 @@ class ScrollOnNewMessageCallback(private val layoutManager: LinearLayoutManager,
                 layoutManager.scrollToPositionWithOffset(0, 0)
             } else {
                 timelineEventController.searchPositionOfEvent(scrollToEvent)?.let {
-                    layoutManager.scrollToPosition(it)
+                    // Scroll such that the scrolled-to event is moved up 1/4 of the screen
+                    layoutManager.scrollToPositionWithOffset(it, parentView.measuredHeight / 4)
                 }
             }
             return