Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
overtake 2021-04-08 18:17:09 +04:00
commit c6b5b23f2a
9 changed files with 1802 additions and 1750 deletions

View File

@ -5774,6 +5774,8 @@ Sorry for the inconvenience.";
"VoiceChat.CreateNewVoiceChatText" = "Voice chat ended. Start a new one?";
"VoiceChat.CreateNewVoiceChatStart" = "Start";
"VoiceChat.CreateNewVoiceChatStartNow" = "Start Now";
"VoiceChat.CreateNewVoiceChatSchedule" = "Schedule";
"PUSH_CHAT_VOICECHAT_START" = "%2$@|%1$@ started a voice chat";
"PUSH_CHAT_VOICECHAT_INVITE" = "%2$@|%1$@ invited %3$@ to the voice chat";

View File

@ -300,8 +300,8 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
private func updateJoinButton() {
if self.isScheduled {
let purple = UIColor(rgb: 0x3252ef)
let pink = UIColor(rgb: 0xef436c)
let purple = UIColor(rgb: 0x5d4ed1)
let pink = UIColor(rgb: 0xea436f)
self.joinButtonBackgroundNode.image = generateGradientImage(size: CGSize(width: 100.0, height: 1.0), colors: [purple, pink], locations: [0.0, 1.0], direction: .horizontal)
self.joinButtonBackgroundNode.backgroundColor = nil
} else {

View File

@ -61,7 +61,7 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
private let containerNode: ASDisplayNode
private let backgroundNode: VoiceChatActionButtonBackgroundNode
private let iconNode: VoiceChatActionButtonIconNode
private let titleLabel: ImmediateTextNode
let titleLabel: ImmediateTextNode
private let subtitleLabel: ImmediateTextNode
private let buttonTitleLabel: ImmediateTextNode
@ -1005,14 +1005,17 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode {
self.maskCircleLayer.path = largerCirclePath
self.maskIsCircle = true
self.maskCircleLayer.animateSpring(from: previousPath as AnyObject, to: largerCirclePath as AnyObject, keyPath: "path", duration: 0.42, initialVelocity: 0.0, damping: 104.0)
self.maskCircleLayer.animateSpring(from: previousPath as AnyObject, to: largerCirclePath as AnyObject, keyPath: "path", duration: 0.6, initialVelocity: 0.0, damping: 100.0)
self.maskBlobView.isHidden = false
self.maskBlobView.startAnimating()
self.maskBlobView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.45)
self.maskBlobView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.6, damping: 100.0)
let initialScale: CGFloat = ((self.maskGradientLayer.value(forKeyPath: "presentationLayer.transform.scale.x") as? NSNumber)?.floatValue).flatMap({ CGFloat($0) }) ?? (((self.maskGradientLayer.value(forKeyPath: "transform.scale.x") as? NSNumber)?.floatValue).flatMap({ CGFloat($0) }) ?? 0.8)
self.maskGradientLayer.animateSpring(from: initialScale as NSNumber, to: 0.85 as NSNumber, keyPath: "transform.scale", duration: 0.45)
self.disableGlowAnimations = true
self.maskGradientLayer.removeAllAnimations()
self.maskGradientLayer.animateSpring(from: 0.3 as NSNumber, to: 0.85 as NSNumber, keyPath: "transform.scale", duration: 0.45, completion: { [weak self] _ in
self?.disableGlowAnimations = false
})
}
var isActive = false

View File

@ -2311,42 +2311,47 @@ public final class VoiceChatController: ViewController {
}
private func transitionToScheduled() {
let springDuration: Double = 0.6
let springDamping: CGFloat = 100.0
self.optionsButton.alpha = 1.0
self.optionsButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.optionsButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.42, damping: 104.0)
self.optionsButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, damping: springDamping)
self.optionsButton.isUserInteractionEnabled = true
self.closeButton.alpha = 1.0
self.closeButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.closeButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.42, damping: 104.0)
self.closeButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, damping: springDamping)
self.closeButton.isUserInteractionEnabled = true
self.audioButton.alpha = 1.0
self.audioButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.audioButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.42, damping: 104.0)
self.audioButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, damping: springDamping)
self.audioButton.isUserInteractionEnabled = true
self.leaveButton.alpha = 1.0
self.leaveButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.leaveButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.42, damping: 104.0)
self.leaveButton.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, damping: springDamping)
self.leaveButton.isUserInteractionEnabled = true
self.scheduleCancelButton.alpha = 0.0
self.scheduleCancelButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
self.scheduleCancelButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15)
self.scheduleCancelButton.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: 26.0), duration: 0.2, removeOnCompletion: false, additive: true)
self.actionButton.titleLabel.layer.animatePosition(from: CGPoint(x: 0.0, y: -26.0), to: CGPoint(), duration: 0.2, additive: true)
if let pickerView = self.pickerView {
pickerView.alpha = 0.0
pickerView.layer.animateScale(from: 1.0, to: 0.1, duration: 0.2)
pickerView.layer.animateScale(from: 1.0, to: 0.25, duration: 0.15, removeOnCompletion: false)
pickerView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
pickerView.isUserInteractionEnabled = false
}
self.timerNode.alpha = 1.0
self.timerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.timerNode.layer.animateSpring(from: 0.4 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.3, damping: 104.0)
self.timerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
self.timerNode.animateIn()
self.updateTitle(transition: .animated(duration: 0.2, curve: .easeInOut))
self.updateTitle(slide: true, transition: .animated(duration: 0.2, curve: .easeInOut))
}
private func transitionToCall() {
@ -2354,6 +2359,7 @@ public final class VoiceChatController: ViewController {
self.listNode.alpha = 1.0
self.listNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.listNode.isUserInteractionEnabled = true
self.timerNode.alpha = 0.0
self.timerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
@ -2939,7 +2945,7 @@ public final class VoiceChatController: ViewController {
self.updateTitle(transition: transition)
}
private func updateTitle(transition: ContainedViewLayoutTransition) {
private func updateTitle(slide: Bool = false, transition: ContainedViewLayoutTransition) {
guard let (layout, _) = self.validLayout else {
return
}
@ -2976,7 +2982,7 @@ public final class VoiceChatController: ViewController {
size.width = floor(min(size.width, size.height) * 0.5)
}
self.titleNode.update(size: CGSize(width: size.width, height: 44.0), title: title, subtitle: subtitle, transition: transition)
self.titleNode.update(size: CGSize(width: size.width, height: 44.0), title: title, subtitle: subtitle, slide: slide, transition: transition)
}
private func updateButtons(animated: Bool) {
@ -3393,6 +3399,7 @@ public final class VoiceChatController: ViewController {
if self.callState?.scheduleTimestamp != nil && self.listNode.alpha > 0.0 {
self.listNode.alpha = 0.0
self.listNode.isUserInteractionEnabled = false
self.backgroundNode.backgroundColor = panelBackgroundColor
self.updateIsFullscreen(false)
}

View File

@ -26,10 +26,18 @@ final class VoiceChatTimerNode: ASDisplayNode {
private var updateTimer: SwiftSignalKit.Timer?
private let hierarchyTrackingNode: HierarchyTrackingNode
private var isCurrentlyInHierarchy = false
init(strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) {
self.strings = strings
self.dateTimeFormat = dateTimeFormat
var updateInHierarchy: ((Bool) -> Void)?
self.hierarchyTrackingNode = HierarchyTrackingNode({ value in
updateInHierarchy?(value)
})
self.titleNode = ImmediateTextNode()
self.subtitleNode = ImmediateTextNode()
@ -37,7 +45,10 @@ final class VoiceChatTimerNode: ASDisplayNode {
super.init()
self.addSubnode(self.hierarchyTrackingNode)
self.allowsGroupOpacity = true
self.isUserInteractionEnabled = false
self.foregroundGradientLayer.type = .radial
self.foregroundGradientLayer.colors = [pink.cgColor, purple.cgColor, purple.cgColor]
@ -53,6 +64,13 @@ final class VoiceChatTimerNode: ASDisplayNode {
self.addSubnode(self.subtitleNode)
self.maskView.addSubnode(self.timerNode)
updateInHierarchy = { [weak self] value in
if let strongSelf = self {
strongSelf.isCurrentlyInHierarchy = value
strongSelf.updateAnimations()
}
}
}
deinit {
@ -60,7 +78,15 @@ final class VoiceChatTimerNode: ASDisplayNode {
}
func animateIn() {
self.foregroundView.layer.animateSpring(from: 0.01 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.42, damping: 104.0)
self.foregroundView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.6, damping: 100.0)
}
private func updateAnimations() {
if self.isInHierarchy {
self.setupGradientAnimations()
} else {
self.foregroundGradientLayer.removeAllAnimations()
}
}
private func setupGradientAnimations() {
@ -78,9 +104,9 @@ final class VoiceChatTimerNode: ASDisplayNode {
animation.toValue = newValue
CATransaction.setCompletionBlock { [weak self] in
// if let isCurrentlyInHierarchy = self?.isCurrentlyInHierarchy, isCurrentlyInHierarchy {
if let isCurrentlyInHierarchy = self?.isCurrentlyInHierarchy, isCurrentlyInHierarchy {
self?.setupGradientAnimations()
// }
}
}
self.foregroundGradientLayer.add(animation, forKey: "movement")
@ -90,7 +116,7 @@ final class VoiceChatTimerNode: ASDisplayNode {
func update(size: CGSize, scheduleTime: Int32?, transition: ContainedViewLayoutTransition) {
if self.validLayout == nil {
self.setupGradientAnimations()
self.updateAnimations()
}
self.validLayout = size

View File

@ -65,7 +65,7 @@ final class VoiceChatTitleNode: ASDisplayNode {
self.tapped?()
}
func update(size: CGSize, title: String, subtitle: String, transition: ContainedViewLayoutTransition) {
func update(size: CGSize, title: String, subtitle: String, slide: Bool, transition: ContainedViewLayoutTransition) {
var titleUpdated = false
if let previousTitle = self.titleNode.attributedText?.string {
titleUpdated = previousTitle != title
@ -80,6 +80,14 @@ final class VoiceChatTitleNode: ASDisplayNode {
})
self.titleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
if slide {
self.infoNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let offset: CGFloat = 16.0
snapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -offset), duration: 0.2, removeOnCompletion: false, additive: true)
self.titleNode.layer.animatePosition(from: CGPoint(x: 0.0, y: offset), to: CGPoint(), duration: 0.2, additive: true)
self.infoNode.layer.animatePosition(from: CGPoint(x: 0.0, y: offset), to: CGPoint(), duration: 0.2, additive: true)
}
}
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.medium(17.0), textColor: UIColor(rgb: 0xffffff))

View File

@ -553,7 +553,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if canManageGroupCalls {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatStart, action: {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatStartNow, action: {
if let strongSelf = self {
var dismissStatus: (() -> Void)?
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: {
@ -589,7 +589,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
dismissStatus?()
}))
}
})]), in: .window(.root))
}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatSchedule, action: {
if let strongSelf = self {
strongSelf.context.scheduleGroupCall(peerId: message.id.peerId)
}
}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
}
}
return true