diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index c741122794..5587c57cec 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -190,14 +190,14 @@ public struct PresentationGroupCallState: Equatable { } public struct PresentationGroupCallSummaryState: Equatable { - public var info: GroupCallInfo + public var info: GroupCallInfo? public var participantCount: Int public var callState: PresentationGroupCallState public var topParticipants: [GroupCallParticipantsContext.Participant] public var activeSpeakers: Set public init( - info: GroupCallInfo, + info: GroupCallInfo?, participantCount: Int, callState: PresentationGroupCallState, topParticipants: [GroupCallParticipantsContext.Participant], diff --git a/submodules/Display/Source/GridNode.swift b/submodules/Display/Source/GridNode.swift index eaa33503cb..176a547e77 100644 --- a/submodules/Display/Source/GridNode.swift +++ b/submodules/Display/Source/GridNode.swift @@ -899,12 +899,17 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { let itemInBounds = bounds.intersects(item.frame) + var absoluteRect = item.frame if let itemNode = self.itemNodes[item.index] { if itemNode.frame != item.frame { itemNode.frame = item.frame } itemNode.updateLayout(item: self.items[item.index], size: item.frame.size, isVisible: bounds.intersects(item.frame), synchronousLoads: synchronousLoads && itemInBounds) - itemNode.updateAbsoluteRect(item.frame, within: bounds.size) + + if let supernode = self.supernode { + absoluteRect = supernode.convert(itemNode.bounds, from: itemNode) + } + itemNode.updateAbsoluteRect(absoluteRect, within: bounds.size) } else { let itemNode = self.items[item.index].node(layout: presentationLayoutTransition.layout.layout, synchronousLoad: synchronousLoads && itemInBounds) itemNode.frame = item.frame @@ -912,7 +917,11 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { addedNodes = true itemNode.updateLayout(item: self.items[item.index], size: item.frame.size, isVisible: bounds.intersects(item.frame), synchronousLoads: synchronousLoads) self.setupNode?(itemNode) - itemNode.updateAbsoluteRect(item.frame, within: bounds.size) + + if let supernode = self.supernode { + absoluteRect = supernode.convert(itemNode.bounds, from: itemNode) + } + itemNode.updateAbsoluteRect(absoluteRect, within: bounds.size) } } diff --git a/submodules/PeerOnlineMarkerNode/Sources/PeerOnlineMarkerNode.swift b/submodules/PeerOnlineMarkerNode/Sources/PeerOnlineMarkerNode.swift index 6eac978ed7..2cf10eda18 100644 --- a/submodules/PeerOnlineMarkerNode/Sources/PeerOnlineMarkerNode.swift +++ b/submodules/PeerOnlineMarkerNode/Sources/PeerOnlineMarkerNode.swift @@ -9,7 +9,6 @@ private final class VoiceChatIndicatorNode: ASDisplayNode { private let rightLine: ASDisplayNode private var isCurrentlyInHierarchy = true - private var shouldBeAnimating = false var color: UIColor = UIColor(rgb: 0xffffff) { didSet { @@ -64,10 +63,9 @@ private final class VoiceChatIndicatorNode: ASDisplayNode { } private func updateAnimation() { - let shouldBeAnimating = self.isCurrentlyInHierarchy - if shouldBeAnimating != self.shouldBeAnimating { - self.shouldBeAnimating = shouldBeAnimating - if shouldBeAnimating { + if self.isCurrentlyInHierarchy { + if let _ = self.leftLine.layer.animation(forKey: "animation") { + } else { let timingFunctions: [CAMediaTimingFunction] = (0 ..< 5).map { _ in CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) } let leftAnimation = CAKeyframeAnimation(keyPath: "bounds.size.height") @@ -75,6 +73,7 @@ private final class VoiceChatIndicatorNode: ASDisplayNode { leftAnimation.values = [NSNumber(value: 10.0), NSNumber(value: 4.0), NSNumber(value: 8.0), NSNumber(value: 4.0), NSNumber(value: 10.0)] leftAnimation.repeatCount = Float.infinity leftAnimation.duration = 2.2 + leftAnimation.beginTime = 1.0 self.leftLine.layer.add(leftAnimation, forKey: "animation") let centerAnimation = CAKeyframeAnimation(keyPath: "bounds.size.height") @@ -82,6 +81,7 @@ private final class VoiceChatIndicatorNode: ASDisplayNode { centerAnimation.values = [NSNumber(value: 6.0), NSNumber(value: 10.0), NSNumber(value: 4.0), NSNumber(value: 12.0), NSNumber(value: 6.0)] centerAnimation.repeatCount = Float.infinity centerAnimation.duration = 2.2 + centerAnimation.beginTime = 1.0 self.centerLine.layer.add(centerAnimation, forKey: "animation") let rightAnimation = CAKeyframeAnimation(keyPath: "bounds.size.height") @@ -89,12 +89,13 @@ private final class VoiceChatIndicatorNode: ASDisplayNode { rightAnimation.values = [NSNumber(value: 10.0), NSNumber(value: 4.0), NSNumber(value: 8.0), NSNumber(value: 4.0), NSNumber(value: 10.0)] rightAnimation.repeatCount = Float.infinity rightAnimation.duration = 2.2 + rightAnimation.beginTime = 1.0 self.rightLine.layer.add(rightAnimation, forKey: "animation") - } else { - self.leftLine.layer.removeAnimation(forKey: "animation") - self.centerLine.layer.removeAnimation(forKey: "animation") - self.rightLine.layer.removeAnimation(forKey: "animation") } + } else { + self.leftLine.layer.removeAnimation(forKey: "animation") + self.centerLine.layer.removeAnimation(forKey: "animation") + self.rightLine.layer.removeAnimation(forKey: "animation") } } } @@ -124,15 +125,14 @@ public final class PeerOnlineMarkerNode: ASDisplayNode { } public func setImage(_ image: UIImage?, color: UIColor?, transition: ContainedViewLayoutTransition) { - if case let .animated(duration, curve) = transition { - if let snapshotLayer = self.iconNode.layer.snapshotContentTree() { - snapshotLayer.frame = self.iconNode.frame - self.iconNode.layer.insertSublayer(snapshotLayer, at: 0) - - snapshotLayer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: curve.timingFunction, removeOnCompletion: false, completion: { [weak snapshotLayer] _ in - snapshotLayer?.removeFromSuperlayer() - }) - } + if case let .animated(duration, curve) = transition, !self.iconNode.isHidden { + let snapshotLayer = CALayer() + snapshotLayer.contents = self.iconNode.layer.contents + snapshotLayer.frame = self.iconNode.bounds + self.iconNode.layer.insertSublayer(snapshotLayer, at: 0) + snapshotLayer.animateAlpha(from: 1.0, to: 0.0, duration: duration, timingFunction: curve.timingFunction, removeOnCompletion: false, completion: { [weak snapshotLayer] _ in + snapshotLayer?.removeFromSuperlayer() + }) } self.iconNode.image = image if let color = color { @@ -147,7 +147,7 @@ public final class PeerOnlineMarkerNode: ASDisplayNode { if let strongSelf = self { strongSelf.iconNode.frame = CGRect(x: 0.0, y: 0.0, width: size, height: size) - if isVoiceChat { + if online && isVoiceChat { if let _ = strongSelf.animationNode { } else { let animationNode = VoiceChatIndicatorNode() @@ -166,7 +166,7 @@ public final class PeerOnlineMarkerNode: ASDisplayNode { if let strongSelf = self, finished { strongSelf.iconNode.isHidden = !online - if let animationNode = strongSelf.animationNode, !isVoiceChat { + if let animationNode = strongSelf.animationNode, !online { animationNode.removeFromSupernode() } } @@ -174,7 +174,7 @@ public final class PeerOnlineMarkerNode: ASDisplayNode { } else { strongSelf.iconNode.isHidden = !online - if let animationNode = strongSelf.animationNode, !isVoiceChat { + if let animationNode = strongSelf.animationNode, !online { animationNode.removeFromSupernode() } } diff --git a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift index a1d5375a81..3303f67f9f 100644 --- a/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift +++ b/submodules/TelegramCallsUI/Sources/CallStatusBarNode.swift @@ -162,6 +162,7 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { private var currentCallState: PresentationCallState? private var currentGroupCallState: PresentationGroupCallSummaryState? private var currentIsMuted = true + private var currentIsConnecting = true public override init() { self.backgroundNode = CallStatusBarBackgroundNode() @@ -224,13 +225,13 @@ public class CallStatusBarNodeImpl: CallStatusBarNode { self.nameDisplayOrder = presentationData.nameDisplayOrder self.stateDisposable.set( (combineLatest( - account.postbox.loadedPeerWithId(call.peerId), + account.postbox.peerView(id: call.peerId), call.summaryState, call.isMuted ) - |> deliverOnMainQueue).start(next: { [weak self] peer, state, isMuted in + |> deliverOnMainQueue).start(next: { [weak self] view, state, isMuted in if let strongSelf = self { - strongSelf.currentPeer = peer + strongSelf.currentPeer = view.peers[view.peerId] strongSelf.currentGroupCallState = state strongSelf.currentIsMuted = isMuted strongSelf.update() diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 3d12012574..81b496900b 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -571,14 +571,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.statePromise.get() ) |> map { infoState, participantsState, callState -> PresentationGroupCallSummaryState? in - guard let infoState = infoState else { - return nil - } guard let participantsState = participantsState else { return nil } return PresentationGroupCallSummaryState( - info: infoState.info, + info: infoState?.info, participantCount: participantsState.participantCount, callState: callState, topParticipants: participantsState.topParticipants, diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift index aa5b03b77b..ff7490efdc 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift @@ -404,11 +404,9 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.foregroundView.mask = self.maskView self.foregroundView.layer.addSublayer(self.foregroundGradientLayer) - + self.maskView.layer.addSublayer(self.maskGradientLayer) - self.maskView.layer.addSublayer(self.maskProgressLayer) - self.maskView.addSubview(self.maskBlobView) self.maskView.layer.addSublayer(self.maskCircleLayer) @@ -424,10 +422,10 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { } else { let previousValue = self.foregroundGradientLayer.startPoint let newValue: CGPoint - if self.maskBlobView.presentationAudioLevel > 0.1 { - newValue = CGPoint(x: CGFloat.random(in: 0.9 ..< 1.0), y: CGFloat.random(in: 0.0 ..< 0.45)) + if self.maskBlobView.presentationAudioLevel > 0.15 { + newValue = CGPoint(x: CGFloat.random(in: 0.8 ..< 1.0), y: CGFloat.random(in: 0.1 ..< 0.45)) } else { - newValue = CGPoint(x: CGFloat.random(in: 0.7 ..< 0.9), y: CGFloat.random(in: 0.0 ..< 0.45)) + newValue = CGPoint(x: CGFloat.random(in: 0.6 ..< 0.8), y: CGFloat.random(in: 0.1 ..< 0.45)) } self.foregroundGradientLayer.startPoint = newValue diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 07897c77fe..9160d5ae53 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -1447,7 +1447,7 @@ public final class VoiceChatController: ViewController { self.audioOutputNode.update(size: sideButtonSize, content: CallControllerButtonItemNode.Content(appearance: soundAppearance, image: soundImage), text: self.presentationData.strings.VoiceChat_Audio, transition: .animated(duration: 0.3, curve: .linear)) - self.leaveNode.update(size: sideButtonSize, content: CallControllerButtonItemNode.Content(appearance: .color(.custom(0x4d120e)), image: .end), text: self.presentationData.strings.VoiceChat_Leave, transition: .immediate) + self.leaveNode.update(size: sideButtonSize, content: CallControllerButtonItemNode.Content(appearance: .color(.custom(0x602522)), image: .end), text: self.presentationData.strings.VoiceChat_Leave, transition: .immediate) let sideButtonMinimalInset: CGFloat = 16.0 let sideButtonOffset = min(36.0, floor((((layout.size.width - 144.0) / 2.0) - sideButtonSize.width) / 2.0)) @@ -1785,6 +1785,7 @@ public final class VoiceChatController: ViewController { super.viewDidDisappear(animated) self.idleTimerExtensionDisposable.set(nil) + self.onViewDidDisappear?() } func dismissInteractively(completion: (() -> Void)? = nil) { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 8a6434d980..c988fb4c89 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -5278,23 +5278,31 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } - if let peer = peer as? TelegramUser, peer.id != strongSelf.context.account.peerId, let contextController = contextController { - var contextItems: [ContextMenuItem] = [] - - contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesFor(peer.compactDisplayTitle).0, textColor: .primary, icon: { _ in nil }, action: { c, _ in - c.dismiss(completion: { - pinAction(true, false) - }) - }))) - - contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesForMe, textColor: .primary, icon: { _ in nil }, action: { c, _ in - c.dismiss(completion: { + if let peer = peer as? TelegramChannel, case .broadcast = peer.info, let contextController = contextController { + contextController?.dismiss(completion: { + pinAction(true, false) + }) + } else if let peer = peer as? TelegramUser, let contextController = contextController { + if peer.id == strongSelf.context.account.peerId { + contextController?.dismiss(completion: { pinAction(true, true) }) - }))) - - contextController.setItems(.single(contextItems)) - + } else { + var contextItems: [ContextMenuItem] = [] + contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesFor(peer.compactDisplayTitle).0, textColor: .primary, icon: { _ in nil }, action: { c, _ in + c.dismiss(completion: { + pinAction(true, false) + }) + }))) + + contextItems.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_PinMessagesForMe, textColor: .primary, icon: { _ in nil }, action: { c, _ in + c.dismiss(completion: { + pinAction(true, true) + }) + }))) + + contextController.setItems(.single(contextItems)) + } return } else { if let contextController = contextController {