@@ -565,21 +565,27 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
565565 )
566566 }
567567
568- /// The height to lay the sheet out at: the stop it is resting at, moved by however far the
569- /// grabber drag has taken it. Past either stop the drag is damped, so the sheet stays under the
570- /// finger without growing off-screen or collapsing to nothing before the release decides.
571- private func tapbacksPickerHeight( size: CGSize , insets: UIEdgeInsets ) -> CGFloat {
568+ /// Where to lay the sheet out: the stop it is resting at, moved by however far the grabber drag
569+ /// has taken it.
570+ ///
571+ /// Between the two stops the drag changes the sheet's height, so more of the grid comes into
572+ /// view as it rises; above the top stop that is damped hard, since there is nowhere left to go.
573+ /// Below the resting stop the sheet stops shrinking and slides down the screen instead, one to
574+ /// one with the finger — a sheet on its way out should look like it is leaving, and shrinking
575+ /// it there would drop grid rows a few at a time instead.
576+ private func tapbacksPickerGeometry( size: CGSize , insets: UIEdgeInsets ) -> ( height: CGFloat , bottomOverscroll: CGFloat ) {
572577 let collapsed = self . tapbacksPickerCollapsedHeight ( size: size, bottomInset: insets. bottom)
573578 let expanded = self . tapbacksPickerExpandedHeight ( size: size, insets: insets)
574579 let resting = self . tapbacksPickerIsExpanded ? expanded : collapsed
575580 // Dragging up is a negative translation and has to make the sheet taller.
576- var height = resting - self . tapbacksPickerDragOffset
577- if height > expanded {
578- height = expanded + ( height - expanded) * 0.15
579- } else if height < collapsed {
580- height = collapsed - ( collapsed - height) * 0.25
581+ let rawHeight = resting - self . tapbacksPickerDragOffset
582+ if rawHeight > expanded {
583+ return ( expanded + ( rawHeight - expanded) * 0.15 , 0.0 )
584+ } else if rawHeight < collapsed {
585+ return ( collapsed, collapsed - rawHeight)
586+ } else {
587+ return ( rawHeight, 0.0 )
581588 }
582- return max ( EmojiStatusSelectionComponent . bottomDockHeaderHeight + insets. bottom, height)
583589 }
584590
585591 /// Drags the Tapbacks sheet between its two stops. Only the 44pt header drags — the recognizer
@@ -626,9 +632,11 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
626632 shouldExpand = abs ( currentHeight - expanded) < abs ( currentHeight - collapsed)
627633 }
628634
629- // Pulled down off the collapsed stop: the sheet is on its way out, which is what this
630- // gesture does to every other sheet in the app.
631- if !wasExpanded, !shouldExpand, ( currentHeight < collapsed - 40.0 ) || ( velocity > Self . tapbacksPickerDismissVelocity) {
635+ // Thrown down hard from either stop, or dragged well below the resting one: the sheet
636+ // closes back to the reaction pill, the same thing its close button does. Distance only
637+ // counts from the resting stop — from the top stop a slow drag down has a stop of its
638+ // own to land on first.
639+ if !shouldExpand, ( velocity > Self . tapbacksPickerDismissVelocity) || ( !wasExpanded && currentHeight < collapsed - 40.0 ) {
632640 self . collapse ( )
633641 return
634642 }
@@ -1885,7 +1893,10 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
18851893 }
18861894
18871895 let pickerContainerWidth = tapbacksBottomPickerActive ? size. width : actualBackgroundFrame. width
1888- let pickerContainerHeight = tapbacksBottomPickerActive ? self . tapbacksPickerHeight ( size: size, insets: insets) : self . emojiContentHeight
1896+ let pickerGeometry : ( height: CGFloat , bottomOverscroll: CGFloat ) = tapbacksBottomPickerActive
1897+ ? self . tapbacksPickerGeometry ( size: size, insets: insets)
1898+ : ( height: self . emojiContentHeight, bottomOverscroll: 0.0 )
1899+ let pickerContainerHeight = pickerGeometry. height
18891900
18901901 var pickerDockStyle : EmojiStatusSelectionComponent . BottomDockStyle ?
18911902 var pickerDismiss : ( ( ) -> Void ) ?
@@ -2034,7 +2045,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
20342045 let componentFrame : CGRect
20352046 if tapbacksBottomPickerActive {
20362047 componentFrame = CGRect (
2037- origin: CGPoint ( x: 0.0 , y: size. height - pickerContainerHeight) ,
2048+ origin: CGPoint ( x: 0.0 , y: size. height - pickerContainerHeight + pickerGeometry . bottomOverscroll ) ,
20382049 size: CGSize ( width: pickerContainerWidth, height: pickerContainerHeight)
20392050 )
20402051 } else {
0 commit comments