Show skip to bottom FAB while scrolling down (#752)
This commit is contained in:
parent
8ef5c60e2e
commit
7575cb286e
|
@ -12,6 +12,7 @@ Improvements 🙌:
|
||||||
- Improve devices list screen
|
- Improve devices list screen
|
||||||
- Add settings for rageshake sensibility
|
- Add settings for rageshake sensibility
|
||||||
- Fix autocompletion issues and add support for rooms, groups, and emoji (#780)
|
- Fix autocompletion issues and add support for rooms, groups, and emoji (#780)
|
||||||
|
- Show skip to bottom FAB while scrolling down (#752)
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
- Change the way RiotX identifies a session to allow the SDK to support several sessions with the same user (#800)
|
- Change the way RiotX identifies a session to allow the SDK to support several sessions with the same user (#800)
|
||||||
|
|
|
@ -24,11 +24,9 @@ internal class Debouncer(private val handler: Handler) {
|
||||||
private val runnables = HashMap<String, Runnable>()
|
private val runnables = HashMap<String, Runnable>()
|
||||||
|
|
||||||
fun debounce(identifier: String, millis: Long, r: Runnable): Boolean {
|
fun debounce(identifier: String, millis: Long, r: Runnable): Boolean {
|
||||||
if (runnables.containsKey(identifier)) {
|
|
||||||
// debounce
|
// debounce
|
||||||
val old = runnables[identifier]
|
cancel(identifier)
|
||||||
handler.removeCallbacks(old)
|
|
||||||
}
|
|
||||||
insertRunnable(identifier, r, millis)
|
insertRunnable(identifier, r, millis)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -37,6 +35,14 @@ internal class Debouncer(private val handler: Handler) {
|
||||||
handler.removeCallbacksAndMessages(null)
|
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) {
|
private fun insertRunnable(identifier: String, r: Runnable, millis: Long) {
|
||||||
val chained = Runnable {
|
val chained = Runnable {
|
||||||
handler.post(r)
|
handler.post(r)
|
||||||
|
|
|
@ -474,21 +474,31 @@ class RoomDetailFragment @Inject constructor(
|
||||||
it.dispatchTo(scrollOnNewMessageCallback)
|
it.dispatchTo(scrollOnNewMessageCallback)
|
||||||
it.dispatchTo(scrollOnHighlightedEventCallback)
|
it.dispatchTo(scrollOnHighlightedEventCallback)
|
||||||
updateJumpToReadMarkerViewVisibility()
|
updateJumpToReadMarkerViewVisibility()
|
||||||
updateJumpToBottomViewVisibility()
|
maybeShowJumpToBottomViewVisibilityWithDelay()
|
||||||
}
|
}
|
||||||
timelineEventController.addModelBuildListener(modelBuildListener)
|
timelineEventController.addModelBuildListener(modelBuildListener)
|
||||||
recyclerView.adapter = timelineEventController.adapter
|
recyclerView.adapter = timelineEventController.adapter
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
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) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
when (newState) {
|
when (newState) {
|
||||||
RecyclerView.SCROLL_STATE_IDLE -> {
|
RecyclerView.SCROLL_STATE_IDLE -> {
|
||||||
updateJumpToBottomViewVisibility()
|
maybeShowJumpToBottomViewVisibilityWithDelay()
|
||||||
}
|
}
|
||||||
RecyclerView.SCROLL_STATE_DRAGGING,
|
RecyclerView.SCROLL_STATE_DRAGGING,
|
||||||
RecyclerView.SCROLL_STATE_SETTLING -> {
|
RecyclerView.SCROLL_STATE_SETTLING -> Unit
|
||||||
jumpToBottomView.hide()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -547,15 +557,19 @@ class RoomDetailFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateJumpToBottomViewVisibility() {
|
private fun maybeShowJumpToBottomViewVisibilityWithDelay() {
|
||||||
debouncer.debounce("jump_to_bottom_visibility", 250, Runnable {
|
debouncer.debounce("jump_to_bottom_visibility", 250, Runnable {
|
||||||
|
maybeShowJumpToBottomViewVisibility()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maybeShowJumpToBottomViewVisibility() {
|
||||||
Timber.v("First visible: ${layoutManager.findFirstCompletelyVisibleItemPosition()}")
|
Timber.v("First visible: ${layoutManager.findFirstCompletelyVisibleItemPosition()}")
|
||||||
if (layoutManager.findFirstVisibleItemPosition() != 0) {
|
if (layoutManager.findFirstVisibleItemPosition() != 0) {
|
||||||
jumpToBottomView.show()
|
jumpToBottomView.show()
|
||||||
} else {
|
} else {
|
||||||
jumpToBottomView.hide()
|
jumpToBottomView.hide()
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupComposer() {
|
private fun setupComposer() {
|
||||||
|
|
Loading…
Reference in New Issue