@@ -288,6 +288,8 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
288288 private var rightSlowModeInset : CGFloat = 0.0
289289 private var currentTextInputBackgroundWidthOffset : CGFloat = 0.0
290290
291+ private var enableBounceAnimations : Bool = false
292+
291293 public var displayAttachmentMenu : ( ) -> Void = { }
292294 public var sendMessage : ( ) -> Void = { }
293295 public var paste : ( ChatTextInputPanelPasteData ) -> Void = { _ in }
@@ -320,6 +322,8 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
320322
321323 private let hapticFeedback = HapticFeedback ( )
322324
325+ private var currentInputHasText : Bool = false
326+
323327 public var inputTextState : ChatTextInputState {
324328 if let textInputNode = self . textInputNode {
325329 let selectionRange : Range < Int > = textInputNode. selectedRange. location ..< ( textInputNode. selectedRange. location + textInputNode. selectedRange. length)
@@ -636,6 +640,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
636640
637641 self . context = context
638642
643+ self . enableBounceAnimations = true
644+ if let data = context. currentAppConfiguration. with ( { $0 } ) . data, data [ " ios_killswitch_input_bounce " ] != nil {
645+ self . enableBounceAnimations = false
646+ }
647+
639648 self . addSubnode ( self . clippingNode)
640649
641650 self . sendAsAvatarContainerNode. activated = { [ weak self] gesture, _ in
@@ -1416,6 +1425,16 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
14161425 if let textInputNode = self . textInputNode, let attributedText = textInputNode. attributedText, attributedText. length != 0 {
14171426 inputHasText = true
14181427 }
1428+ let inputHadText = self . currentInputHasText
1429+ self . currentInputHasText = inputHasText
1430+
1431+ var useBounceAnimation = inputHasText && !inputHadText
1432+ if accessoryPanel != nil || self . accessoryPanel != nil {
1433+ useBounceAnimation = false
1434+ }
1435+ if !self . enableBounceAnimations {
1436+ useBounceAnimation = false
1437+ }
14191438
14201439 var hasMenuButton = false
14211440 var menuButtonExpanded = false
@@ -1957,7 +1976,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
19571976 }
19581977 menuButtonTitleTransition. updateFrame ( node: self . menuButtonTextNode, frame: CGRect ( origin: CGPoint ( x: 16.0 , y: 11.0 ) , size: menuTextSize) )
19591978 transition. updateAlpha ( node: self . menuButtonTextNode, alpha: menuButtonExpanded ? 1.0 : 0.0 )
1960- transition. updateFrame ( node: self . menuButtonIconNode, frame: CGRect ( x: 5 .0, y: isSendAsButton ? 5.0 : ( 5.0 - UIScreenPixel ) , width: 30 .0, height: 30 .0) )
1979+ transition. updateFrame ( node: self . menuButtonIconNode, frame: CGRect ( x: 7 .0, y: 7.0 , width: 26 .0, height: 26 .0) )
19611980
19621981 transition. updateFrame ( node: self . sendAsAvatarButtonNode, frame: menuButtonFrame)
19631982 transition. updateFrame ( node: self . sendAsAvatarContainerNode, frame: CGRect ( origin: CGPoint ( ) , size: menuButtonFrame. size) )
@@ -2384,7 +2403,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
23842403 transition. updateFrame ( view: self . accessoryPanelContainer, frame: CGRect ( origin: CGPoint ( ) , size: textInputContainerBackgroundFrame. size) )
23852404 transition. updateFrame ( view: self . textInputContainerBackgroundView, frame: CGRect ( origin: CGPoint ( ) , size: textInputContainerBackgroundFrame. size) )
23862405
2387- self . textInputContainerBackgroundView. update ( size: textInputContainerBackgroundFrame. size, cornerRadius: floor ( minimalInputHeight * 0.5 ) , isDark: interfaceState. theme. overallDarkAppearance, tintColor: . init( kind: . panel, color: interfaceState. theme. chat. inputPanel. inputBackgroundColor. withMultipliedAlpha ( 0.7 ) ) , transition: ComponentTransition ( transition) )
2406+ var textInputContainerBackgroundTransition = ComponentTransition ( transition)
2407+ if useBounceAnimation, case let . animated( _, curve) = transition, case . spring = curve {
2408+ textInputContainerBackgroundTransition = textInputContainerBackgroundTransition. withUserData ( GlassBackgroundView . TransitionFlagBounce ( ) )
2409+ }
2410+ self . textInputContainerBackgroundView. update ( size: textInputContainerBackgroundFrame. size, cornerRadius: floor ( minimalInputHeight * 0.5 ) , isDark: interfaceState. theme. overallDarkAppearance, tintColor: . init( kind: . panel, color: interfaceState. theme. chat. inputPanel. inputBackgroundColor. withMultipliedAlpha ( 0.7 ) ) , transition: textInputContainerBackgroundTransition)
23882411
23892412 transition. updateFrame ( layer: self . textInputBackgroundNode. layer, frame: textInputContainerBackgroundFrame)
23902413 transition. updateAlpha ( node: self . textInputBackgroundNode, alpha: audioRecordingItemsAlpha)
@@ -2626,13 +2649,22 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
26262649 }
26272650
26282651 var sendActionButtonsFrame = CGRect ( origin: CGPoint ( x: textInputContainerBackgroundFrame. maxX - sendActionButtonsSize. width, y: textInputContainerBackgroundFrame. maxY - sendActionButtonsSize. height) , size: sendActionButtonsSize)
2652+
2653+ let sendActionsScale : CGFloat
26292654 if inputHasText || hasMediaDraft || hasForward {
2630- transition . updateTransformScale ( node : self . sendActionButtons , scale : CGPoint ( x : 1.0 , y : 1.0 ) )
2655+ sendActionsScale = 1.0
26312656 } else {
2657+ sendActionsScale = 0.001
26322658 sendActionButtonsFrame. origin. x += ( sendActionButtonsSize. width - 3.0 * 2.0 ) * 0.5 - 3.0
2633- transition. updateTransformScale ( node: self . sendActionButtons, scale: CGPoint ( x: 0.001 , y: 0.001 ) )
26342659 }
2635- transition. updatePosition ( node: self . sendActionButtons, position: sendActionButtonsFrame. center)
2660+
2661+ if useBounceAnimation, case let . animated( duration, curve) = transition, case . spring = curve {
2662+ ContainedViewLayoutTransition . animated ( duration: duration, curve: curve) . updateScaleSpring ( layer: self . sendActionButtons. layer, scale: sendActionsScale)
2663+ ContainedViewLayoutTransition . animated ( duration: duration, curve: curve) . updatePositionSpring ( layer: self . sendActionButtons. layer, position: sendActionButtonsFrame. center)
2664+ } else {
2665+ transition. updateTransformScale ( node: self . sendActionButtons, scale: CGPoint ( x: sendActionsScale, y: sendActionsScale) )
2666+ transition. updatePosition ( node: self . sendActionButtons, position: sendActionButtonsFrame. center)
2667+ }
26362668 transition. updateBounds ( node: self . sendActionButtons, bounds: CGRect ( origin: CGPoint ( ) , size: sendActionButtonsFrame. size) )
26372669 if let ( rect, containerSize) = self . absoluteRect {
26382670 self . sendActionButtons. updateAbsoluteRect ( CGRect ( x: rect. origin. x + sendActionButtonsFrame. origin. x, y: rect. origin. y + sendActionButtonsFrame. origin. y, width: sendActionButtonsFrame. width, height: sendActionButtonsFrame. height) , within: containerSize, transition: transition)
@@ -3806,7 +3838,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
38063838 if self . sendActionButtons. sendContainerNode. alpha. isZero && self . rightSlowModeInset. isZero {
38073839 alphaTransition. updateAlpha ( node: self . sendActionButtons. sendContainerNode, alpha: 1.0 )
38083840 blurTransitionIn. animateBlur ( layer: self . sendActionButtons. sendContainerNode. layer, fromRadius: sendButtonBlurOut, toRadius: 0.0 )
3809- transition. animatePositionAdditive ( layer: self . sendActionButtons. sendButton. imageNode. layer, offset: CGPoint ( x: - 18 .0, y: 14 .0) )
3841+ transition. animatePositionAdditive ( layer: self . sendActionButtons. sendButton. imageNode. layer, offset: CGPoint ( x: - 22 .0, y: 18 .0) )
38103842 if let sendButtonRadialStatusNode = self . sendActionButtons. sendButtonRadialStatusNode {
38113843 alphaTransition. updateAlpha ( node: sendButtonRadialStatusNode, alpha: 1.0 )
38123844 }
0 commit comments