mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Fix a timeline jump triggered by pagination during an interactive scroll. (#2870)
This commit is contained in:
+29
-6
@@ -59,8 +59,7 @@ class TimelineTableViewController: UIViewController {
|
|||||||
var timelineStyle: TimelineStyle
|
var timelineStyle: TimelineStyle
|
||||||
var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>() {
|
var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>() {
|
||||||
didSet {
|
didSet {
|
||||||
if !isLive, isDraggingScrollView {
|
guard canApplySnapshot else {
|
||||||
// Forward pagination doesn't play well with the user scrolling, so we wait for it to stop.
|
|
||||||
hasPendingItems = true
|
hasPendingItems = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -75,13 +74,34 @@ class TimelineTableViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not it is safe to update the data source with the latest items.
|
||||||
|
private var canApplySnapshot: Bool {
|
||||||
|
if isLive {
|
||||||
|
// Backward pagination jumps if items are inserted whilst actively dragging.
|
||||||
|
!isDraggingScrollView
|
||||||
|
} else {
|
||||||
|
// Forward pagination breaks inertial scrolling when fixing the offset.
|
||||||
|
!scrollViewIsScrolling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// There are pending items in `timelineItemsDictionary` that haven't been applied to the data source.
|
/// There are pending items in `timelineItemsDictionary` that haven't been applied to the data source.
|
||||||
private var hasPendingItems = false
|
private var hasPendingItems = false
|
||||||
|
|
||||||
/// The user is dragging the scroll view (or it is still decelerating after a drag).
|
/// The scroll view is scrolling either directly with a drag or indirectly with inertia.
|
||||||
|
private var scrollViewIsScrolling = false {
|
||||||
|
didSet {
|
||||||
|
if !scrollViewIsScrolling, hasPendingItems, !isLive {
|
||||||
|
hasPendingItems = false
|
||||||
|
applySnapshot()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The scroll view is being dragged by the user (doesn't include scrolling with inertia)
|
||||||
private var isDraggingScrollView = false {
|
private var isDraggingScrollView = false {
|
||||||
didSet {
|
didSet {
|
||||||
if !isDraggingScrollView, hasPendingItems {
|
if !isDraggingScrollView, hasPendingItems, isLive {
|
||||||
hasPendingItems = false
|
hasPendingItems = false
|
||||||
applySnapshot()
|
applySnapshot()
|
||||||
}
|
}
|
||||||
@@ -415,18 +435,21 @@ extension TimelineTableViewController: UITableViewDelegate {
|
|||||||
|
|
||||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||||
isDraggingScrollView = true
|
isDraggingScrollView = true
|
||||||
|
scrollViewIsScrolling = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
||||||
sendLastVisibleItemReadReceipt()
|
sendLastVisibleItemReadReceipt()
|
||||||
|
|
||||||
|
isDraggingScrollView = false
|
||||||
if !decelerate {
|
if !decelerate {
|
||||||
isDraggingScrollView = false
|
scrollViewIsScrolling = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||||||
sendLastVisibleItemReadReceipt()
|
sendLastVisibleItemReadReceipt()
|
||||||
isDraggingScrollView = false
|
scrollViewIsScrolling = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
|
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
|
||||||
|
|||||||
Reference in New Issue
Block a user