Recent actions improvements

This commit is contained in:
Ilya Laktyushin
2024-04-23 12:01:28 +04:00
parent 076eb7be4d
commit 914dbc46f6
145 changed files with 295 additions and 215 deletions

View File

@@ -2154,7 +2154,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
let beginReplay = { [weak self] in
if let strongSelf = self {
strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateCrossfade: options.contains(.AnimateCrossfade), animateFullTransition: options.contains(.AnimateFullTransition), synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, completion: {
strongSelf.replayOperations(animated: animated, animateAlpha: options.contains(.AnimateAlpha), animateCrossfade: options.contains(.AnimateCrossfade), animateFullTransition: options.contains(.AnimateFullTransition), synchronous: options.contains(.Synchronous), synchronousLoads: options.contains(.PreferSynchronousResourceLoading), animateTopItemVerticalOrigin: options.contains(.AnimateTopItemPosition), operations: updatedOperations, requestItemInsertionAnimationsIndices: options.contains(.RequestItemInsertionAnimations) ? insertedIndexSet : Set(), scrollToItem: scrollToItem, additionalScrollDistance: additionalScrollDistance, updateSizeAndInsets: updateSizeAndInsets, stationaryItemIndex: stationaryItemIndex, updateOpaqueState: updateOpaqueState, forceInvertOffsetDirection: options.contains(.InvertOffsetDirection), completion: {
if options.contains(.PreferSynchronousDrawing) {
self?.recursivelyEnsureDisplaySynchronously(true)
}
@@ -2377,7 +2377,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
}
}
private func insertNodeAtIndex(animated: Bool, animateAlpha: Bool, animateFullTransition: Bool, forceAnimateInsertion: Bool, previousFrame: CGRect?, nodeIndex: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void), timestamp: Double, listInsets: UIEdgeInsets, visibleBounds: CGRect) {
private func insertNodeAtIndex(animated: Bool, animateAlpha: Bool, animateFullTransition: Bool, forceAnimateInsertion: Bool, previousFrame: CGRect?, nodeIndex: Int, offsetDirection: ListViewInsertionOffsetDirection, node: ListViewItemNode, layout: ListViewItemNodeLayout, apply: () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void), timestamp: Double, listInsets: UIEdgeInsets, visibleBounds: CGRect, forceInvertOffsetDirection: Bool) {
let insertionOrigin = self.referencePointForInsertionAtIndex(nodeIndex)
let nodeOrigin: CGPoint
@@ -2400,7 +2400,11 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
if let accessoryItemNode = node.accessoryItemNode {
node.layoutAccessoryItemNode(accessoryItemNode, leftInset: listInsets.left, rightInset: listInsets.right)
}
apply().1(ListViewItemApply(isOnScreen: visibleBounds.intersects(nodeFrame), timestamp: timestamp))
let applyContext = ListViewItemApply(isOnScreen: visibleBounds.intersects(nodeFrame), timestamp: timestamp)
apply().1(applyContext)
let invertOffsetDirection = forceInvertOffsetDirection
self.itemNodes.insert(node, at: nodeIndex)
var offsetHeight = node.apparentHeight
@@ -2426,7 +2430,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
takenAnimation = true
if abs(layout.size.height - previousApparentHeight) > CGFloat.ulpOfOne {
node.addApparentHeightAnimation(layout.size.height, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp, update: { [weak node] progress, currentValue in
node.addApparentHeightAnimation(layout.size.height, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp, invertOffsetDirection: invertOffsetDirection, update: { [weak node] progress, currentValue in
if let node = node {
node.animateFrameTransition(progress, currentValue)
}
@@ -2453,7 +2457,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
node.addHeightAnimation(0.0, duration: duration * UIView.animationDurationFactor(), beginAt: timestamp)
}
if node.animationForKey("apparentHeight") == nil || !(node is ListViewTempItemNode) {
node.addApparentHeightAnimation(0.0, duration: duration * UIView.animationDurationFactor(), beginAt: timestamp, update: { [weak node] progress, currentValue in
node.addApparentHeightAnimation(0.0, duration: duration * UIView.animationDurationFactor(), beginAt: timestamp, invertOffsetDirection: invertOffsetDirection, update: { [weak node] progress, currentValue in
if let node = node {
node.animateFrameTransition(progress, currentValue)
}
@@ -2484,7 +2488,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
} else {
if !nodeFrame.size.height.isEqual(to: node.apparentHeight) {
let addAnimation = previousFrame?.height != nodeFrame.size.height
node.addApparentHeightAnimation(nodeFrame.size.height, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp, update: { [weak node] progress, currentValue in
node.addApparentHeightAnimation(nodeFrame.size.height, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp, invertOffsetDirection: invertOffsetDirection, update: { [weak node] progress, currentValue in
if let node = node, addAnimation {
node.animateFrameTransition(progress, currentValue)
}
@@ -2517,13 +2521,13 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
node.addTransitionOffsetAnimation(0.0, duration: insertionAnimationDuration * UIView.animationDurationFactor(), beginAt: timestamp)
}
}
node.animateInsertion(timestamp, duration: insertionAnimationDuration * UIView.animationDurationFactor(), short: false)
node.animateInsertion(timestamp, duration: insertionAnimationDuration * UIView.animationDurationFactor(), options: ListViewItemAnimationOptions(short: invertOffsetDirection))
}
}
} else if animateAlpha {
if previousFrame == nil {
if forceAnimateInsertion {
node.animateInsertion(timestamp, duration: insertionAnimationDuration * UIView.animationDurationFactor(), short: true)
node.animateInsertion(timestamp, duration: insertionAnimationDuration * UIView.animationDurationFactor(), options: ListViewItemAnimationOptions(short: true))
} else if animateFullTransition {
node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
node.layer.animateScale(from: 0.7, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
@@ -2617,7 +2621,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
}
}
private func replayOperations(animated: Bool, animateAlpha: Bool, animateCrossfade: Bool, animateFullTransition: Bool, synchronous: Bool, synchronousLoads: Bool, animateTopItemVerticalOrigin: Bool, operations: [ListViewStateOperation], requestItemInsertionAnimationsIndices: Set<Int>, scrollToItem originalScrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemIndex: Int?, updateOpaqueState: Any?, completion: () -> Void) {
private func replayOperations(animated: Bool, animateAlpha: Bool, animateCrossfade: Bool, animateFullTransition: Bool, synchronous: Bool, synchronousLoads: Bool, animateTopItemVerticalOrigin: Bool, operations: [ListViewStateOperation], requestItemInsertionAnimationsIndices: Set<Int>, scrollToItem originalScrollToItem: ListViewScrollToItem?, additionalScrollDistance: CGFloat, updateSizeAndInsets: ListViewUpdateSizeAndInsets?, stationaryItemIndex: Int?, updateOpaqueState: Any?, forceInvertOffsetDirection: Bool = false, completion: () -> Void) {
var scrollToItem: ListViewScrollToItem?
var isExperimentalSnapToScrollToItem = false
if let originalScrollToItem = originalScrollToItem {
@@ -2745,7 +2749,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
updatedPreviousFrame = nil
}
self.insertNodeAtIndex(animated: nodeAnimated, animateAlpha: animateAlpha, animateFullTransition: animateFullTransition, forceAnimateInsertion: forceAnimateInsertion, previousFrame: updatedPreviousFrame, nodeIndex: index, offsetDirection: offsetDirection, node: node, layout: layout, apply: apply, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds)
self.insertNodeAtIndex(animated: nodeAnimated, animateAlpha: animateAlpha, animateFullTransition: animateFullTransition, forceAnimateInsertion: forceAnimateInsertion, previousFrame: updatedPreviousFrame, nodeIndex: index, offsetDirection: offsetDirection, node: node, layout: layout, apply: apply, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds, forceInvertOffsetDirection: forceInvertOffsetDirection)
hadInserts = true
hadChangesToItemNodes = true
if let _ = updatedPreviousFrame {
@@ -2806,10 +2810,10 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
if let height = height, let previousLayout = previousLayout {
if takenPreviousNodes.contains(referenceNode) {
let tempNode = ListViewTempItemNode(layerBacked: true)
self.insertNodeAtIndex(animated: false, animateAlpha: false, animateFullTransition: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: tempNode, layout: ListViewItemNodeLayout(contentSize: CGSize(width: self.visibleSize.width, height: height), insets: UIEdgeInsets()), apply: { return (nil, { _ in }) }, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds)
self.insertNodeAtIndex(animated: false, animateAlpha: false, animateFullTransition: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: tempNode, layout: ListViewItemNodeLayout(contentSize: CGSize(width: self.visibleSize.width, height: height), insets: UIEdgeInsets()), apply: { return (nil, { _ in }) }, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds, forceInvertOffsetDirection: forceInvertOffsetDirection)
} else {
referenceNode.index = nil
self.insertNodeAtIndex(animated: false, animateAlpha: false, animateFullTransition: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: referenceNode, layout: previousLayout, apply: { return (nil, { _ in }) }, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds)
self.insertNodeAtIndex(animated: false, animateAlpha: false, animateFullTransition: false, forceAnimateInsertion: false, previousFrame: nil, nodeIndex: index, offsetDirection: offsetDirection, node: referenceNode, layout: previousLayout, apply: { return (nil, { _ in }) }, timestamp: timestamp, listInsets: listInsets, visibleBounds: visibleBounds, forceInvertOffsetDirection: forceInvertOffsetDirection)
if let verticalScrollIndicator = self.verticalScrollIndicator {
self.insertSubnode(referenceNode, belowSubnode: verticalScrollIndicator)
} else {
@@ -2888,7 +2892,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
let applyContext = ListViewItemApply(isOnScreen: visibleBounds.intersects(apparentFrame), timestamp: timestamp)
apply().1(applyContext)
let invertOffsetDirection = applyContext.invertOffsetDirection
let invertOffsetDirection = applyContext.invertOffsetDirection || forceInvertOffsetDirection
var offsetRanges = OffsetRanges()
@@ -3056,7 +3060,7 @@ open class ListView: ASDisplayNode, ASScrollViewDelegate, ASGestureRecognizerDel
}
} else if let stationaryItemIndex = stationaryItemIndex {
for itemNode in self.itemNodes {
if let index = itemNode.index , index == stationaryItemIndex {
if let index = itemNode.index, index == stationaryItemIndex {
for (previousNode, previousFrame) in previousApparentFrames {
if previousNode === itemNode {
let offset = previousFrame.frame.minY - itemNode.frame.minY

View File

@@ -130,6 +130,7 @@ public struct ListViewDeleteAndInsertOptions: OptionSet {
public static let AnimateCrossfade = ListViewDeleteAndInsertOptions(rawValue: 256)
public static let ForceUpdate = ListViewDeleteAndInsertOptions(rawValue: 512)
public static let AnimateFullTransition = ListViewDeleteAndInsertOptions(rawValue: 1024)
public static let InvertOffsetDirection = ListViewDeleteAndInsertOptions(rawValue: 2048)
}
public struct ListViewUpdateSizeAndInsets {

View File

@@ -51,7 +51,7 @@ public struct ListViewItemConfigureNodeFlags: OptionSet {
}
public final class ListViewItemApply {
public let isOnScreen: Bool
public private(set) var isOnScreen: Bool
public let timestamp: Double?
public private(set) var invertOffsetDirection: Bool = false
@@ -63,6 +63,10 @@ public final class ListViewItemApply {
public func setInvertOffsetDirection() {
self.invertOffsetDirection = true
}
public func setIsOffscreen() {
self.isOnScreen = false
}
}
public protocol ListViewItem {

View File

@@ -15,6 +15,16 @@ var testSpringFreeResistance: CGFloat = 0.676197171211243
var testSpringResistanceScrollingLimits: (CGFloat, CGFloat) = (0.1, 1.0)
var testSpringScrollingResistance: CGFloat = 0.6721
public struct ListViewItemAnimationOptions {
public let short: Bool
public let invertOffsetDirection: Bool
public init(short: Bool = false, invertOffsetDirection: Bool = false) {
self.short = short
self.invertOffsetDirection = invertOffsetDirection
}
}
struct ListViewItemSpring {
let stiffness: CGFloat
let damping: CGFloat
@@ -577,7 +587,7 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode {
self.setAnimationForKey("transitionOffset", animation: animation)
}
open func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
open func animateInsertion(_ currentTimestamp: Double, duration: Double, options: ListViewItemAnimationOptions) {
}
open func animateAdded(_ currentTimestamp: Double, duration: Double) {