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:^
{
_innerIconView.transform = CGAffineTransformIdentity;
_decoration.transform = CGAffineTransformIdentity;
snapshotView.transform = CGAffineTransformMakeScale(0.001f, 0.001f);
} completion:^(__unused BOOL finished) {
[snapshotView removeFromSuperview];
@ -837,11 +836,13 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius
_innerCircleView.image = nil;
}
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) {
_currentLevel = _currentLevel * 0.8f + _inputLevel * 0.2f;
_currentTranslation = MIN(0.0, _currentTranslation * 0.7f + _targetTranslation * 0.3f);
CGFloat outerScale = outerCircleMinScale + _currentLevel * (1.0f - outerCircleMinScale);
CGAffineTransform translation = CGAffineTransformMakeTranslation(0, _currentTranslation);
CGAffineTransform transform = CGAffineTransformScale(translation, outerScale, outerScale);
@ -857,8 +858,6 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius
_innerCircleView.transform = transform;
_innerIconWrapperView.transform = transform;
_decoration.transform = transform;
[_decoration tick:_currentLevel];
}
}

View File

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

View File

@ -321,6 +321,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private let peekData: ChatPeekTimeout?
private let peekTimerDisposable = MetaDisposable()
private var shouldDisplayDownButton = false
private var hasEmbeddedTitleContent = false
private var isEmbeddedTitleContentHidden = false
@ -2544,6 +2546,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
strongSelf.audioRecorderStatusDisposable = nil
}
strongSelf.updateDownButtonVisibility()
}
}
})
@ -2592,6 +2595,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
videoRecorder.lockVideo()
}
}
strongSelf.updateDownButtonVisibility()
if let previousVideoRecorderValue = previousVideoRecorderValue {
previousVideoRecorderValue.dismissVideo()
@ -3091,32 +3095,33 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
self.chatDisplayNode.historyNode.contentPositionChanged = { [weak self] offset in
if let strongSelf = self {
let offsetAlpha: CGFloat
let plainInputSeparatorAlpha: CGFloat
switch offset {
case let .known(offset):
if offset < 40.0 {
offsetAlpha = 0.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:
guard let strongSelf = self else { return }
let offsetAlpha: CGFloat
let plainInputSeparatorAlpha: CGFloat
switch offset {
case let .known(offset):
if offset < 40.0 {
offsetAlpha = 0.0
} else {
offsetAlpha = 1.0
}
if offset < 4.0 {
plainInputSeparatorAlpha = 0.0
}
strongSelf.chatDisplayNode.navigateButtons.displayDownButton = !offsetAlpha.isZero
strongSelf.chatDisplayNode.updatePlainInputSeparatorAlpha(plainInputSeparatorAlpha, transition: .animated(duration: 0.2, curve: .easeInOut))
} else {
plainInputSeparatorAlpha = 1.0
}
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
@ -7636,6 +7641,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
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) {
self.updateChatPresentationInterfaceState(interactive: false, { 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))
if animateDotAppearing {
audioRecordingDotNode.layer.animateScale(from: 0.3, to: 1, duration: 0.15, delay: 0, removeOnCompletion: false)
audioRecordingDotNode.layer.animateAlpha(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 1, duration: 0.15, delay: 0, completion: { [weak audioRecordingDotNode] finished in
if finished {
let animation = CAKeyframeAnimation(keyPath: "opacity")
animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber]
animation.keyTimes = [0.0 as NSNumber, 0.4546 as NSNumber, 0.9091 as NSNumber, 1 as NSNumber]
animation.duration = 0.5
animation.autoreverses = true
animation.repeatCount = Float.infinity
audioRecordingDotNode?.layer.add(animation, forKey: "recording")
}
})
let dotStartScale: CGFloat = (audioRecordingDotNode.layer.presentation()?.value(forKeyPath: "transform.scale.x") as? CGFloat) ?? 1
audioRecordingDotNode.layer.animateScale(from: dotStartScale, to: 1, duration: 0.15, delay: 0, removeOnCompletion: false)
if audioRecordingDotNode.layer.animation(forKey: "recording") == nil {
audioRecordingDotNode.layer.animateAlpha(from: CGFloat(audioRecordingDotNode.layer.presentation()?.opacity ?? 1), to: 1, duration: 0.15, delay: 0, completion: { [weak audioRecordingDotNode] finished in
if finished {
let animation = CAKeyframeAnimation(keyPath: "opacity")
animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber]
animation.keyTimes = [0.0 as NSNumber, 0.4546 as NSNumber, 0.9091 as NSNumber, 1 as NSNumber]
animation.duration = 0.5
animation.autoreverses = true
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.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false)
}
@ -1103,8 +1105,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
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.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, delay: 0, removeOnCompletion: false) { [weak audioRecordingDotNode] _ in
audioRecordingDotNode.layer.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false)
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()
}