diff --git a/CHANGES.md b/CHANGES.md
index bb132982d8..3087b7405c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -12,6 +12,7 @@ Improvements 🙌:
  - Improve devices list screen
  - Add settings for rageshake sensibility
  - Fix autocompletion issues and add support for rooms, groups, and emoji (#780)
+ - Show skip to bottom FAB while scrolling down (#752)
 
 Other changes:
  - Change the way RiotX identifies a session to allow the SDK to support several sessions with the same user (#800)
diff --git a/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt b/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
index b02e3c9366..2f5db57ccb 100644
--- a/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
+++ b/vector/src/main/java/im/vector/riotx/core/utils/Debouncer.kt
@@ -24,11 +24,9 @@ internal class Debouncer(private val handler: Handler) {
     private val runnables = HashMap<String, Runnable>()
 
     fun debounce(identifier: String, millis: Long, r: Runnable): Boolean {
-        if (runnables.containsKey(identifier)) {
-            // debounce
-            val old = runnables[identifier]
-            handler.removeCallbacks(old)
-        }
+        // debounce
+        cancel(identifier)
+
         insertRunnable(identifier, r, millis)
         return true
     }
@@ -37,6 +35,14 @@ internal class Debouncer(private val handler: Handler) {
         handler.removeCallbacksAndMessages(null)
     }
 
+    fun cancel(identifier: String) {
+        if (runnables.containsKey(identifier)) {
+            val old = runnables[identifier]
+            handler.removeCallbacks(old)
+            runnables.remove(identifier)
+        }
+    }
+
     private fun insertRunnable(identifier: String, r: Runnable, millis: Long) {
         val chained = Runnable {
             handler.post(r)
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
index 4414c48205..4e29aa2f89 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
@@ -474,21 +474,31 @@ class RoomDetailFragment @Inject constructor(
             it.dispatchTo(scrollOnNewMessageCallback)
             it.dispatchTo(scrollOnHighlightedEventCallback)
             updateJumpToReadMarkerViewVisibility()
-            updateJumpToBottomViewVisibility()
+            maybeShowJumpToBottomViewVisibilityWithDelay()
         }
         timelineEventController.addModelBuildListener(modelBuildListener)
         recyclerView.adapter = timelineEventController.adapter
 
         recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+                debouncer.cancel("jump_to_bottom_visibility")
+
+                val scrollingToPast = dy < 0
+
+                if (scrollingToPast) {
+                    jumpToBottomView.hide()
+                } else {
+                    maybeShowJumpToBottomViewVisibility()
+                }
+            }
+
             override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                 when (newState) {
                     RecyclerView.SCROLL_STATE_IDLE     -> {
-                        updateJumpToBottomViewVisibility()
+                        maybeShowJumpToBottomViewVisibilityWithDelay()
                     }
                     RecyclerView.SCROLL_STATE_DRAGGING,
-                    RecyclerView.SCROLL_STATE_SETTLING -> {
-                        jumpToBottomView.hide()
-                    }
+                    RecyclerView.SCROLL_STATE_SETTLING -> Unit
                 }
             }
         })
@@ -547,17 +557,21 @@ class RoomDetailFragment @Inject constructor(
         }
     }
 
-    private fun updateJumpToBottomViewVisibility() {
+    private fun maybeShowJumpToBottomViewVisibilityWithDelay() {
         debouncer.debounce("jump_to_bottom_visibility", 250, Runnable {
-            Timber.v("First visible: ${layoutManager.findFirstCompletelyVisibleItemPosition()}")
-            if (layoutManager.findFirstVisibleItemPosition() != 0) {
-                jumpToBottomView.show()
-            } else {
-                jumpToBottomView.hide()
-            }
+            maybeShowJumpToBottomViewVisibility()
         })
     }
 
+    private fun maybeShowJumpToBottomViewVisibility() {
+        Timber.v("First visible: ${layoutManager.findFirstCompletelyVisibleItemPosition()}")
+        if (layoutManager.findFirstVisibleItemPosition() != 0) {
+            jumpToBottomView.show()
+        } else {
+            jumpToBottomView.hide()
+        }
+    }
+
     private fun setupComposer() {
         autoCompleter.setup(composerLayout.composerEditText, this)