Merge commit 'b12d85debffe3e3a6181ec0cc728e5b55e9c9881'

This commit is contained in:
Ali 2021-03-11 21:12:19 +04:00
commit dd6d223b1c
24 changed files with 120 additions and 44 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -314,7 +314,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
let previousAlpha = node.alpha let previousAlpha = node.alpha
node.alpha = alpha node.alpha = alpha
if animated { if animated {
node.layer.animateAlpha(from: previousAlpha, to: alpha, duration: alpha.isZero ? 0.18 : 0.32, timingFunction: alpha.isZero ? CAMediaTimingFunctionName.easeOut.rawValue : CAMediaTimingFunctionName.easeInEaseOut.rawValue) node.layer.animateAlpha(from: previousAlpha, to: alpha, duration: alpha.isZero ? 0.08 : 0.32, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue)
} }
if let inputNode = node as? ShareInputFieldNode, alpha.isZero { if let inputNode = node as? ShareInputFieldNode, alpha.isZero {

View File

@ -40,6 +40,7 @@ swift_library(
"//submodules/PeerInfoUI:PeerInfoUI", "//submodules/PeerInfoUI:PeerInfoUI",
"//submodules/AnimatedCountLabelNode:AnimatedCountLabelNode", "//submodules/AnimatedCountLabelNode:AnimatedCountLabelNode",
"//submodules/DeviceProximity:DeviceProximity", "//submodules/DeviceProximity:DeviceProximity",
"//submodules/ManagedAnimationNode:ManagedAnimationNode",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -321,7 +321,9 @@ public class CallStatusBarNodeImpl: CallStatusBarNode {
var segments: [AnimatedCountLabelNode.Segment] = [] var segments: [AnimatedCountLabelNode.Segment] = []
if let presentationData = self.presentationData { if let presentationData = self.presentationData {
if let currentPeer = self.currentPeer { if let voiceChatTitle = self.currentGroupCallState?.info?.title, !title.isEmpty {
title = voiceChatTitle
} else if let currentPeer = self.currentPeer {
title = currentPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) title = currentPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
} }
var membersCount: Int32? var membersCount: Int32?

View File

@ -6,6 +6,7 @@ import SwiftSignalKit
import LegacyComponents import LegacyComponents
import AnimationUI import AnimationUI
import AppBundle import AppBundle
import ManagedAnimationNode
private let titleFont = Font.regular(15.0) private let titleFont = Font.regular(15.0)
private let subtitleFont = Font.regular(13.0) private let subtitleFont = Font.regular(13.0)
@ -46,8 +47,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
let bottomNode: ASDisplayNode let bottomNode: ASDisplayNode
private let containerNode: ASDisplayNode private let containerNode: ASDisplayNode
private let backgroundNode: VoiceChatActionButtonBackgroundNode private let backgroundNode: VoiceChatActionButtonBackgroundNode
private let iconNode: VoiceChatMicrophoneNode private let iconNode: VoiceChatActionButtonIconNode
private let raiseHandNode: VoiceChatRaiseHandNode
private let titleLabel: ImmediateTextNode private let titleLabel: ImmediateTextNode
private let subtitleLabel: ImmediateTextNode private let subtitleLabel: ImmediateTextNode
@ -86,7 +86,6 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
if self.pressing { if self.pressing {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring) let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring)
transition.updateTransformScale(node: self.iconNode, scale: snap ? 0.5 : 0.9) transition.updateTransformScale(node: self.iconNode, scale: snap ? 0.5 : 0.9)
transition.updateTransformScale(node: self.raiseHandNode, scale: snap ? 0.5 : 0.9)
switch state { switch state {
case let .active(state): case let .active(state):
@ -102,7 +101,6 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
} else { } else {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring) let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring)
transition.updateTransformScale(node: self.iconNode, scale: snap ? 0.5 : 1.0) transition.updateTransformScale(node: self.iconNode, scale: snap ? 0.5 : 1.0)
transition.updateTransformScale(node: self.raiseHandNode, scale: snap ? 0.5 : 1.0)
self.wasActiveWhenPressed = false self.wasActiveWhenPressed = false
} }
} }
@ -112,8 +110,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
self.bottomNode = ASDisplayNode() self.bottomNode = ASDisplayNode()
self.containerNode = ASDisplayNode() self.containerNode = ASDisplayNode()
self.backgroundNode = VoiceChatActionButtonBackgroundNode() self.backgroundNode = VoiceChatActionButtonBackgroundNode()
self.iconNode = VoiceChatMicrophoneNode() self.iconNode = VoiceChatActionButtonIconNode()
self.raiseHandNode = VoiceChatRaiseHandNode(color: nil)
self.titleLabel = ImmediateTextNode() self.titleLabel = ImmediateTextNode()
self.subtitleLabel = ImmediateTextNode() self.subtitleLabel = ImmediateTextNode()
@ -127,7 +124,6 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
self.addSubnode(self.containerNode) self.addSubnode(self.containerNode)
self.containerNode.addSubnode(self.backgroundNode) self.containerNode.addSubnode(self.backgroundNode)
self.containerNode.addSubnode(self.iconNode) self.containerNode.addSubnode(self.iconNode)
self.containerNode.addSubnode(self.raiseHandNode)
self.highligthedChanged = { [weak self] pressing in self.highligthedChanged = { [weak self] pressing in
if let strongSelf = self { if let strongSelf = self {
@ -137,11 +133,9 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
if pressing { if pressing {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring) let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring)
transition.updateTransformScale(node: strongSelf.iconNode, scale: snap ? 0.5 : 0.9) transition.updateTransformScale(node: strongSelf.iconNode, scale: snap ? 0.5 : 0.9)
transition.updateTransformScale(node: strongSelf.raiseHandNode, scale: snap ? 0.5 : 0.9)
} else if !strongSelf.pressing { } else if !strongSelf.pressing {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring) let transition: ContainedViewLayoutTransition = .animated(duration: 0.25, curve: .spring)
transition.updateTransformScale(node: strongSelf.iconNode, scale: snap ? 0.5 : 1.0) transition.updateTransformScale(node: strongSelf.iconNode, scale: snap ? 0.5 : 1.0)
transition.updateTransformScale(node: strongSelf.raiseHandNode, scale: snap ? 0.5 : 1.0)
} }
} }
} }
@ -235,41 +229,39 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
transition.updateAlpha(layer: self.backgroundNode.maskProgressLayer, alpha: 1.0) transition.updateAlpha(layer: self.backgroundNode.maskProgressLayer, alpha: 1.0)
} }
let iconSize = CGSize(width: 68.0, height: 68.0) let iconSize = CGSize(width: 100.0, height: 100.0)
self.iconNode.bounds = CGRect(origin: CGPoint(), size: iconSize) self.iconNode.bounds = CGRect(origin: CGPoint(), size: iconSize)
self.iconNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0) self.iconNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
let raiseHandSize = CGSize(width: 68.0, height: 68.0)
self.raiseHandNode.bounds = CGRect(origin: CGPoint(), size: raiseHandSize)
self.raiseHandNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
} }
private var previousIcon: VoiceChatActionButtonIconAnimationState?
private func applyIconParams() { private func applyIconParams() {
guard let (_, _, state, _, _, _, _, snap) = self.currentParams else { guard let (_, _, state, _, _, _, _, snap) = self.currentParams else {
return return
} }
var iconMuted = true let icon: VoiceChatActionButtonIconAnimationState
var speakIcon = false
let iconColor: UIColor = UIColor(rgb: 0xffffff)
switch state { switch state {
case let .active(state): case let .active(state):
switch state { switch state {
case .on: case .on:
iconMuted = false icon = .unmute
case .muted:
icon = .mute
case .cantSpeak: case .cantSpeak:
speakIcon = true icon = .hand
default:
break
} }
case .connecting: case .connecting:
break if let previousIcon = previousIcon {
icon = previousIcon
} else {
icon = .mute
}
} }
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut) self.previousIcon = icon
transition.updateAlpha(node: self.raiseHandNode, alpha: speakIcon ? 1.0 : 0.0)
transition.updateAlpha(node: self.iconNode, alpha: speakIcon ? 0.0 : 1.0)
self.iconNode.update(state: VoiceChatMicrophoneNode.State(muted: iconMuted, filled: true, color: iconColor), animated: true) self.iconNode.enqueueState(icon)
// self.iconNode.update(state: VoiceChatMicrophoneNode.State(muted: iconMuted, filled: true, color: iconColor), animated: true)
} }
func update(snap: Bool, animated: Bool) { func update(snap: Bool, animated: Bool) {
@ -336,7 +328,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
} }
func playAnimation() { func playAnimation() {
self.raiseHandNode.playRandomAnimation() self.iconNode.playRandomAnimation()
} }
} }
@ -768,6 +760,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
growthAnimation.duration = 0.15 growthAnimation.duration = 0.15
growthAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) growthAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
growthAnimation.isRemovedOnCompletion = false growthAnimation.isRemovedOnCompletion = false
growthAnimation.fillMode = .forwards
CATransaction.setCompletionBlock { CATransaction.setCompletionBlock {
self.animatingDisappearance = false self.animatingDisappearance = false
@ -862,6 +855,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
CATransaction.begin() CATransaction.begin()
CATransaction.setDisableActions(true) CATransaction.setDisableActions(true)
self.foregroundCircleLayer.isHidden = false self.foregroundCircleLayer.isHidden = false
self.foregroundCircleLayer.transform = CATransform3DMakeScale(1.0, 1.0, 1.0)
self.maskCircleLayer.isHidden = false self.maskCircleLayer.isHidden = false
self.maskProgressLayer.isHidden = true self.maskProgressLayer.isHidden = true
self.maskGradientLayer.isHidden = false self.maskGradientLayer.isHidden = false
@ -882,14 +876,18 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
CATransaction.begin() CATransaction.begin()
let shrinkAnimation = CABasicAnimation(keyPath: "transform.scale") let shrinkAnimation = CABasicAnimation(keyPath: "transform.scale")
shrinkAnimation.fromValue = 1.0 shrinkAnimation.fromValue = 1.0
shrinkAnimation.toValue = 0.0 shrinkAnimation.toValue = 0.00001
shrinkAnimation.duration = 0.15 shrinkAnimation.duration = 0.15
shrinkAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) shrinkAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
shrinkAnimation.isRemovedOnCompletion = false
shrinkAnimation.fillMode = .forwards
CATransaction.setCompletionBlock { CATransaction.setCompletionBlock {
CATransaction.begin() CATransaction.begin()
CATransaction.setDisableActions(true) CATransaction.setDisableActions(true)
self.foregroundCircleLayer.isHidden = true self.foregroundCircleLayer.isHidden = true
self.foregroundCircleLayer.transform = CATransform3DMakeScale(0.0, 0.0, 1.0)
self.foregroundCircleLayer.removeAllAnimations()
CATransaction.commit() CATransaction.commit()
} }
@ -906,6 +904,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
func updateAnimations() { func updateAnimations() {
if !self.isCurrentlyInHierarchy { if !self.isCurrentlyInHierarchy {
self.foregroundGradientLayer.removeAllAnimations() self.foregroundGradientLayer.removeAllAnimations()
self.growingForegroundCircleLayer.removeAllAnimations()
self.maskGradientLayer.removeAllAnimations() self.maskGradientLayer.removeAllAnimations()
self.maskProgressLayer.removeAllAnimations() self.maskProgressLayer.removeAllAnimations()
self.maskBlobView.stopAnimating() self.maskBlobView.stopAnimating()
@ -1377,6 +1376,68 @@ final class BlobView: UIView {
} }
} }
enum VoiceChatActionButtonIconAnimationState: Equatable {
case unmute
case mute
case hand
}
final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
private var iconState: VoiceChatActionButtonIconAnimationState = .mute
init() {
super.init(size: CGSize(width: 100.0, height: 100.0))
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.1))
}
func enqueueState(_ state: VoiceChatActionButtonIconAnimationState) {
guard self.iconState != state else {
return
}
let previousState = self.iconState
self.iconState = state
switch previousState {
case .unmute:
switch state {
case .mute:
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMute")))
case .hand:
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOn")))
case .unmute:
break
}
case .mute:
switch state {
case .unmute:
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute")))
case .hand:
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOn")))
case .mute:
break
}
case .hand:
switch state {
case .mute, .unmute:
self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandoff")))
case .hand:
break
}
}
}
func playRandomAnimation() {
if case .hand = self.iconState {
if let animationName = ["VoiceHand_1", "VoiceHand_2", "VoiceHand_3", "VoiceHand_4", "VoiceHand_5", "VoiceHand_6", "VoiceHand_7"].randomElement() {
self.trackTo(item: ManagedAnimationItem(source: .local(animationName)))
}
}
}
}
final class VoiceChatRaiseHandNode: ASDisplayNode { final class VoiceChatRaiseHandNode: ASDisplayNode {
private let animationNode: AnimationNode private let animationNode: AnimationNode
private let color: UIColor? private let color: UIColor?

View File

@ -1623,13 +1623,15 @@ public final class VoiceChatController: ViewController {
let presentationData = strongSelf.presentationData let presentationData = strongSelf.presentationData
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
for peer in peers { if peers.count > 1 {
if peer.peer.id == myPeerId { for peer in peers {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_DisplayAs, textLayout: .secondLineWithValue(peer.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: peer.peer, size: avatarSize)), action: { c, _ in if peer.peer.id == myPeerId {
c.setItems(displayAsItems()) items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_DisplayAs, textLayout: .secondLineWithValue(peer.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)), icon: { _ in nil }, iconSource: ContextMenuActionItemIconSource(size: avatarSize, signal: peerAvatarCompleteImage(account: strongSelf.context.account, peer: peer.peer, size: avatarSize)), action: { c, _ in
}))) c.setItems(displayAsItems())
items.append(.separator) })))
break items.append(.separator)
break
}
} }
} }

View File

@ -162,8 +162,12 @@ private final class VoiceChatTitleEditInputFieldNode: ASDisplayNode, ASEditableT
} }
@objc func clearPressed() { @objc func clearPressed() {
self.placeholderNode.isHidden = false
self.clearButton.isHidden = true
self.textInputNode.attributedText = nil self.textInputNode.attributedText = nil
self.deactivateInput() self.deactivateInput()
self.updateHeight?()
} }
} }
@ -424,7 +428,10 @@ func voiceChatTitleEditController(sharedContext: SharedAccountContext, account:
return return
} }
dismissImpl?(true) dismissImpl?(true)
apply(contentNode.value)
let previousValue = value ?? ""
let newValue = contentNode.value
apply(previousValue != newValue ? newValue : nil)
} }
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode) let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long