Apply patch

This commit is contained in:
Ali 2020-07-04 19:10:24 +04:00
parent 2bb0293fb4
commit 28283923fb
4 changed files with 88 additions and 60 deletions

View File

@ -575,7 +575,6 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius
[UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^ [UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^
{ {
_innerIconView.transform = CGAffineTransformIdentity; _innerIconView.transform = CGAffineTransformIdentity;
_decoration.transform = CGAffineTransformIdentity;
snapshotView.transform = CGAffineTransformMakeScale(0.001f, 0.001f); snapshotView.transform = CGAffineTransformMakeScale(0.001f, 0.001f);
} completion:^(__unused BOOL finished) { } completion:^(__unused BOOL finished) {
[snapshotView removeFromSuperview]; [snapshotView removeFromSuperview];
@ -837,11 +836,13 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius
_innerCircleView.image = nil; _innerCircleView.image = nil;
} }
NSTimeInterval t = CACurrentMediaTime(); NSTimeInterval t = CACurrentMediaTime();
_currentLevel = _currentLevel * 0.9f + _inputLevel * 0.1f;
[_decoration tick:_currentLevel];
_currentTranslation = MIN(0.0, _currentTranslation * 0.7f + _targetTranslation * 0.3f);
if (t > _animationStartTime) { if (t > _animationStartTime) {
_currentLevel = _currentLevel * 0.8f + _inputLevel * 0.2f;
_currentTranslation = MIN(0.0, _currentTranslation * 0.7f + _targetTranslation * 0.3f);
CGFloat outerScale = outerCircleMinScale + _currentLevel * (1.0f - outerCircleMinScale); CGFloat outerScale = outerCircleMinScale + _currentLevel * (1.0f - outerCircleMinScale);
CGAffineTransform translation = CGAffineTransformMakeTranslation(0, _currentTranslation); CGAffineTransform translation = CGAffineTransformMakeTranslation(0, _currentTranslation);
CGAffineTransform transform = CGAffineTransformScale(translation, outerScale, outerScale); CGAffineTransform transform = CGAffineTransformScale(translation, outerScale, outerScale);
@ -857,8 +858,6 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius
_innerCircleView.transform = transform; _innerCircleView.transform = transform;
_innerIconWrapperView.transform = transform; _innerIconWrapperView.transform = transform;
_decoration.transform = transform; _decoration.transform = transform;
[_decoration tick:_currentLevel];
} }
} }

View File

@ -30,7 +30,7 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration
minScale: 0.55, minScale: 0.55,
maxScale: 0.9, maxScale: 0.9,
scaleSpeed: 0.2, scaleSpeed: 0.2,
isCircle: true isCircle: false
) )
private let bigBlob = BlobView( private let bigBlob = BlobView(
pointsCount: 8, pointsCount: 8,
@ -41,7 +41,7 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration
minScale: 0.55, minScale: 0.55,
maxScale: 1, maxScale: 1,
scaleSpeed: 0.2, scaleSpeed: 0.2,
isCircle: true isCircle: false
) )
override init(frame: CGRect) { override init(frame: CGRect) {
@ -65,13 +65,19 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration
func updateLevel(_ level: CGFloat) { func updateLevel(_ level: CGFloat) {
let normalizedLevel = min(1, max(level / Constants.maxLevel, 0)) let normalizedLevel = min(1, max(level / Constants.maxLevel, 0))
smallBlob.updateSpeedLevel(to: normalizedLevel)
mediumBlob.updateSpeedLevel(to: normalizedLevel)
bigBlob.updateSpeedLevel(to: normalizedLevel)
}
func tick(_ level: CGFloat) {
let normalizedLevel = min(1, max(level / Constants.maxLevel, 0))
smallBlob.level = normalizedLevel smallBlob.level = normalizedLevel
mediumBlob.level = normalizedLevel mediumBlob.level = normalizedLevel
bigBlob.level = normalizedLevel bigBlob.level = normalizedLevel
} }
func tick(_ level: CGFloat) { }
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
@ -104,17 +110,18 @@ final class BlobView: UIView {
let maxScale: CGFloat let maxScale: CGFloat
let scaleSpeed: CGFloat let scaleSpeed: CGFloat
var scaleLevelsToBalance = [CGFloat]()
// If true ignores randomness and pointsCount // If true ignores randomness and pointsCount
let isCircle: Bool let isCircle: Bool
var level: CGFloat = 0 { var level: CGFloat = 0 {
didSet { didSet {
speedLevel = max(level, speedLevel) CATransaction.begin()
scaleLevel = max(level, scaleLevel) CATransaction.setDisableActions(true)
let lv = minScale + (maxScale - minScale) * level
if abs(scaleLevel - lastScaleLevel) > 0.4 { shapeLayer.transform = CATransform3DMakeScale(lv, lv, 1)
animateToNewScale() CATransaction.commit()
}
} }
} }
@ -190,18 +197,27 @@ final class BlobView: UIView {
shapeLayer.fillColor = color.cgColor shapeLayer.fillColor = color.cgColor
} }
func updateSpeedLevel(to newSpeedLevel: CGFloat) {
speedLevel = max(speedLevel, newSpeedLevel)
}
func startAnimating() { func startAnimating() {
animateToNewShape() animateToNewShape()
animateToNewScale()
} }
func animateToNewScale() { func animateToNewScale() {
let isDownscale = lastScaleLevel > scaleLevel let scaleLevelForAnimation: CGFloat = {
lastScaleLevel = scaleLevel if scaleLevelsToBalance.isEmpty {
return 0
}
return scaleLevelsToBalance.reduce(0, +) / CGFloat(scaleLevelsToBalance.count)
}()
let isDownscale = lastScaleLevel > scaleLevelForAnimation
lastScaleLevel = scaleLevelForAnimation
shapeLayer.pop_removeAnimation(forKey: "scale") shapeLayer.pop_removeAnimation(forKey: "scale")
let currentScale = minScale + (maxScale - minScale) * scaleLevel let currentScale = minScale + (maxScale - minScale) * scaleLevelForAnimation
let scaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)! let scaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)!
scaleAnimation.toValue = CGPoint(x: currentScale, y: currentScale) scaleAnimation.toValue = CGPoint(x: currentScale, y: currentScale)
scaleAnimation.duration = isDownscale ? 0.45 : CFTimeInterval(scaleSpeed) scaleAnimation.duration = isDownscale ? 0.45 : CFTimeInterval(scaleSpeed)
@ -213,6 +229,7 @@ final class BlobView: UIView {
shapeLayer.pop_add(scaleAnimation, forKey: "scale") shapeLayer.pop_add(scaleAnimation, forKey: "scale")
scaleLevel = 0 scaleLevel = 0
scaleLevelsToBalance.removeAll()
} }
func animateToNewShape() { func animateToNewShape() {

View File

@ -321,6 +321,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private let peekData: ChatPeekTimeout? private let peekData: ChatPeekTimeout?
private let peekTimerDisposable = MetaDisposable() private let peekTimerDisposable = MetaDisposable()
private var shouldDisplayDownButton = false
private var hasEmbeddedTitleContent = false private var hasEmbeddedTitleContent = false
private var isEmbeddedTitleContentHidden = false private var isEmbeddedTitleContentHidden = false
@ -2544,6 +2546,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else { } else {
strongSelf.audioRecorderStatusDisposable = nil strongSelf.audioRecorderStatusDisposable = nil
} }
strongSelf.updateDownButtonVisibility()
} }
} }
}) })
@ -2592,6 +2595,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
videoRecorder.lockVideo() videoRecorder.lockVideo()
} }
} }
strongSelf.updateDownButtonVisibility()
if let previousVideoRecorderValue = previousVideoRecorderValue { if let previousVideoRecorderValue = previousVideoRecorderValue {
previousVideoRecorderValue.dismissVideo() previousVideoRecorderValue.dismissVideo()
@ -3091,32 +3095,33 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in
if let strongSelf = self { guard let strongSelf = self else { return }
let offsetAlpha: CGFloat
let plainInputSeparatorAlpha: CGFloat let offsetAlpha: CGFloat
switch offset { let plainInputSeparatorAlpha: CGFloat
case let .known(offset): switch offset {
if offset < 40.0 { case let .known(offset):
offsetAlpha = 0.0 if offset < 40.0 {
} else {
offsetAlpha = 1.0
}
if offset < 4.0 {
plainInputSeparatorAlpha = 0.0
} else {
plainInputSeparatorAlpha = 1.0
}
case .unknown:
offsetAlpha = 1.0
plainInputSeparatorAlpha = 1.0
case .none:
offsetAlpha = 0.0 offsetAlpha = 0.0
} else {
offsetAlpha = 1.0
}
if offset < 4.0 {
plainInputSeparatorAlpha = 0.0 plainInputSeparatorAlpha = 0.0
} } else {
plainInputSeparatorAlpha = 1.0
strongSelf.chatDisplayNode.navigateButtons.displayDownButton = !offsetAlpha.isZero }
strongSelf.chatDisplayNode.updatePlainInputSeparatorAlpha(plainInputSeparatorAlpha, transition: .animated(duration: 0.2, curve: .easeInOut)) case .unknown:
offsetAlpha = 1.0
plainInputSeparatorAlpha = 1.0
case .none:
offsetAlpha = 0.0
plainInputSeparatorAlpha = 0.0
} }
strongSelf.shouldDisplayDownButton = !offsetAlpha.isZero
strongSelf.updateDownButtonVisibility()
strongSelf.chatDisplayNode.updatePlainInputSeparatorAlpha(plainInputSeparatorAlpha, transition: .animated(duration: 0.2, curve: .easeInOut))
} }
self.chatDisplayNode.historyNode.scrolledToIndex = { [weak self] toIndex in self.chatDisplayNode.historyNode.scrolledToIndex = { [weak self] toIndex in
@ -7636,6 +7641,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.chatDisplayNode.historyNode.scrollToEndOfHistory() self.chatDisplayNode.historyNode.scrollToEndOfHistory()
} }
func updateDownButtonVisibility() {
let recordingMediaMessage = self.audioRecorderValue != nil || self.videoRecorderValue != nil
self.chatDisplayNode.navigateButtons.displayDownButton = self.shouldDisplayDownButton && !recordingMediaMessage
}
func updateTextInputState(_ textInputState: ChatTextInputState) { func updateTextInputState(_ textInputState: ChatTextInputState) {
self.updateChatPresentationInterfaceState(interactive: false, { state in self.updateChatPresentationInterfaceState(interactive: false, { state in
state.updatedInterfaceState({ state in state.updatedInterfaceState({ state in

View File

@ -1055,20 +1055,22 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
audioRecordingDotNode.frame = CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - 44 + 1), size: CGSize(width: 40.0, height: 40)) audioRecordingDotNode.frame = CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - 44 + 1), size: CGSize(width: 40.0, height: 40))
if animateDotAppearing { if animateDotAppearing {
audioRecordingDotNode.layer.animateScale(from: 0.3, to: 1, duration: 0.15, delay: 0, removeOnCompletion: false) let dotStartScale: CGFloat = (audioRecordingDotNode.layer.presentation()?.value(forKeyPath: "transform.scale.x") as? CGFloat) ?? 1
audioRecordingDotNode.layer.animateAlpha(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 1, duration: 0.15, delay: 0, completion: { [weak audioRecordingDotNode] finished in audioRecordingDotNode.layer.animateScale(from: dotStartScale, to: 1, duration: 0.15, delay: 0, removeOnCompletion: false)
if finished { if audioRecordingDotNode.layer.animation(forKey: "recording") == nil {
let animation = CAKeyframeAnimation(keyPath: "opacity") audioRecordingDotNode.layer.animateAlpha(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 1, duration: 0.15, delay: 0, completion: { [weak audioRecordingDotNode] finished in
animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber] if finished {
animation.keyTimes = [0.0 as NSNumber, 0.4546 as NSNumber, 0.9091 as NSNumber, 1 as NSNumber] let animation = CAKeyframeAnimation(keyPath: "opacity")
animation.duration = 0.5 animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber]
animation.autoreverses = true animation.keyTimes = [0.0 as NSNumber, 0.4546 as NSNumber, 0.9091 as NSNumber, 1 as NSNumber]
animation.repeatCount = Float.infinity animation.duration = 0.5
animation.autoreverses = true
audioRecordingDotNode?.layer.add(animation, forKey: "recording") animation.repeatCount = Float.infinity
}
}) audioRecordingDotNode?.layer.add(animation, forKey: "recording")
}
})
}
self.attachmentButton.layer.animateAlpha(from: CGFloat(self.attachmentButton.layer.presentation()?.opacity ?? 1), to: 0, duration: 0.15, delay: 0, removeOnCompletion: false) self.attachmentButton.layer.animateAlpha(from: CGFloat(self.attachmentButton.layer.presentation()?.opacity ?? 1), to: 0, duration: 0.15, delay: 0, removeOnCompletion: false)
self.attachmentButton.layer.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false) self.attachmentButton.layer.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false)
} }
@ -1103,8 +1105,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
self?.audioRecordingDotNode = nil self?.audioRecordingDotNode = nil
audioRecordingDotNode.layer.animateScale(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false) audioRecordingDotNode.layer.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false)
audioRecordingDotNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, delay: 0, removeOnCompletion: false) { [weak audioRecordingDotNode] _ in audioRecordingDotNode.layer.animateAlpha(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 0.0, duration: 0.15, delay: 0, removeOnCompletion: false) { [weak audioRecordingDotNode] _ in
audioRecordingDotNode?.removeFromSupernode() audioRecordingDotNode?.removeFromSupernode()
} }