diff --git a/Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs b/Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs new file mode 100644 index 0000000000..7e5b7f873c Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs b/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs new file mode 100644 index 0000000000..808c218d6e Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs new file mode 100644 index 0000000000..a221fafc74 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs b/Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs deleted file mode 100644 index 3e20f03395..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceHandOff2.tgs b/Telegram/Telegram-iOS/Resources/VoiceHandOff2.tgs deleted file mode 100644 index ed44efc0ba..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/VoiceHandOff2.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs b/Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs deleted file mode 100644 index f0db083d4f..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs new file mode 100644 index 0000000000..2617414f3f Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs b/Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs new file mode 100644 index 0000000000..44a88db65e Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs b/Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs new file mode 100644 index 0000000000..02f6cffa5e Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs b/Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs new file mode 100644 index 0000000000..7a9f2426cd Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs new file mode 100644 index 0000000000..98da6a6ac4 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs new file mode 100644 index 0000000000..8f79ae293d Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs differ diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 380d275cfe..9afdfce8b6 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -187,6 +187,7 @@ public struct PresentationGroupCallState: Equatable { public var title: String? public var raisedHand: Bool public var scheduleTimestamp: Int32? + public var subscribedToScheduled: Bool public init( myPeerId: PeerId, @@ -198,7 +199,8 @@ public struct PresentationGroupCallState: Equatable { recordingStartTimestamp: Int32?, title: String?, raisedHand: Bool, - scheduleTimestamp: Int32? + scheduleTimestamp: Int32?, + subscribedToScheduled: Bool ) { self.myPeerId = myPeerId self.networkState = networkState @@ -210,6 +212,7 @@ public struct PresentationGroupCallState: Equatable { self.title = title self.raisedHand = raisedHand self.scheduleTimestamp = scheduleTimestamp + self.subscribedToScheduled = subscribedToScheduled } } @@ -323,6 +326,7 @@ public protocol PresentationGroupCall: class { var memberEvents: Signal { get } var reconnectedAsEvents: Signal { get } + func toggleScheduledSubscription(_ subscribe: Bool) func schedule(timestamp: Int32) func startScheduled() diff --git a/submodules/SyncCore/Sources/CachedChannelData.swift b/submodules/SyncCore/Sources/CachedChannelData.swift index dff76b59aa..5b994dc253 100644 --- a/submodules/SyncCore/Sources/CachedChannelData.swift +++ b/submodules/SyncCore/Sources/CachedChannelData.swift @@ -160,20 +160,20 @@ public final class CachedChannelData: CachedPeerData { public var accessHash: Int64 public var title: String? public var scheduleTimestamp: Int32? - public var subscribed: Bool + public var subscribedToScheduled: Bool public init( id: Int64, accessHash: Int64, title: String?, scheduleTimestamp: Int32?, - subscribed: Bool + subscribedToScheduled: Bool ) { self.id = id self.accessHash = accessHash self.title = title self.scheduleTimestamp = scheduleTimestamp - self.subscribed = subscribed + self.subscribedToScheduled = subscribedToScheduled } public init(decoder: PostboxDecoder) { @@ -181,7 +181,7 @@ public final class CachedChannelData: CachedPeerData { self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0) self.title = decoder.decodeOptionalStringForKey("title") self.scheduleTimestamp = decoder.decodeOptionalInt32ForKey("scheduleTimestamp") - self.subscribed = decoder.decodeBoolForKey("subscribed", orElse: false) + self.subscribedToScheduled = decoder.decodeBoolForKey("subscribed", orElse: false) } public func encode(_ encoder: PostboxEncoder) { @@ -197,7 +197,7 @@ public final class CachedChannelData: CachedPeerData { } else { encoder.encodeNil(forKey: "scheduleTimestamp") } - encoder.encodeBool(self.subscribed, forKey: "subscribed") + encoder.encodeBool(self.subscribedToScheduled, forKey: "subscribed") } } diff --git a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift index 18b8202cc9..95bfc3281d 100644 --- a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift +++ b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift @@ -406,7 +406,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { strongSelf.joinGroupCall( peerId: groupCallPanelData.peerId, invite: nil, - activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribed: false) + activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribedToScheduled: groupCallPanelData.info.subscribedToScheduled) ) }) if let navigationBar = self.navigationBar { diff --git a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift b/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift index c26f008d51..d8d1414981 100644 --- a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift +++ b/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift @@ -505,7 +505,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize)) } - var joinText = self.strings.VoiceChat_PanelJoin.uppercased() + var joinText = self.strings.VoiceChat_PanelJoin var title = self.strings.VoiceChat_Title var text = self.currentText var isScheduled = false @@ -554,7 +554,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { self.updateJoinButton() } - self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText, font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor) + self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText.uppercased(), font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor) let joinButtonTitleSize = self.joinButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude)) let joinButtonSize = CGSize(width: joinButtonTitleSize.width + 20.0, height: 28.0) diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 165b4b35e9..1ace64c919 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -78,6 +78,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext { streamDcId: nil, title: call.title, scheduleTimestamp: call.scheduleTimestamp, + subscribedToScheduled: call.subscribedToScheduled, recordingStartTimestamp: nil, sortAscending: true ), @@ -121,7 +122,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext { } return GroupCallPanelData( peerId: peerId, - info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, recordingStartTimestamp: nil, sortAscending: state.sortAscending), + info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, subscribedToScheduled: state.subscribedToScheduled, recordingStartTimestamp: nil, sortAscending: state.sortAscending), topParticipants: topParticipants, participantCount: state.totalCount, activeSpeakers: activeSpeakers, @@ -206,7 +207,7 @@ public final class AccountGroupCallContextCacheImpl: AccountGroupCallContextCach } private extension PresentationGroupCallState { - static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?) -> PresentationGroupCallState { + static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?, subscribedToScheduled: Bool) -> PresentationGroupCallState { return PresentationGroupCallState( myPeerId: myPeerId, networkState: .connecting, @@ -217,7 +218,8 @@ private extension PresentationGroupCallState { recordingStartTimestamp: nil, title: title, raisedHand: false, - scheduleTimestamp: scheduleTimestamp + scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled ) } } @@ -511,6 +513,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { private let joinDisposable = MetaDisposable() private let requestDisposable = MetaDisposable() private let startDisposable = MetaDisposable() + private let subscribeDisposable = MetaDisposable() private var groupCallParticipantUpdatesDisposable: Disposable? private let networkStateDisposable = MetaDisposable() @@ -579,7 +582,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId self.schedulePending = initialCall == nil - self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp) + self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp, subscribedToScheduled: initialCall?.subscribedToScheduled ?? false) self.statePromise = ValuePromise(self.stateValue) self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) @@ -734,7 +737,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { addedParticipants.append((ssrc, participantUpdate.jsonParams)) } } - case let .call(isTerminated, _, _, _): + case let .call(isTerminated, _, _, _, _): if isTerminated { strongSelf.markAsCanBeRemoved() } @@ -767,7 +770,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { }) if let initialCall = initialCall, let temporaryParticipantsContext = (self.accountContext.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl)?.impl.syncWith({ impl in - impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribed: initialCall.subscribed)) + impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribedToScheduled: initialCall.subscribedToScheduled)) }) { self.switchToTemporaryParticipantsContext(sourceContext: temporaryParticipantsContext.context.participantsContext, oldMyPeerId: self.joinAsPeerId) } else { @@ -824,6 +827,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.joinDisposable.dispose() self.requestDisposable.dispose() self.startDisposable.dispose() + self.subscribeDisposable.dispose() self.groupCallParticipantUpdatesDisposable?.dispose() self.leaveDisposable.dispose() self.isMutedDisposable.dispose() @@ -1666,6 +1670,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, + subscribedToScheduled: false, recordingStartTimestamp: state.recordingStartTimestamp, sortAscending: state.sortAscending )))) @@ -1987,6 +1992,17 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.callContext?.setIsNoiseSuppressionEnabled(isNoiseSuppressionEnabled) } + public func toggleScheduledSubscription(_ subscribe: Bool) { + guard case let .active(callInfo) = self.internalState, callInfo.scheduleTimestamp != nil else { + return + } + + self.stateValue.subscribedToScheduled = subscribe + + self.subscribeDisposable.set((toggleScheduledGroupCallSubscription(account: self.account, peerId: self.peerId, callId: callInfo.id, accessHash: callInfo.accessHash, subscribe: subscribe) + |> deliverOnMainQueue).start()) + } + public func schedule(timestamp: Int32) { guard self.schedulePending else { return @@ -2270,7 +2286,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } if let value = value { - strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribed: false) + strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribedToScheduled: false) strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl) } else { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift index 754bcc7d2c..9432a2fea2 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift @@ -607,11 +607,11 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.maskProgressLayer.lineCap = .round self.maskProgressLayer.path = path - let circleFrame = CGRect(origin: CGPoint(x: (358 - buttonSize.width) / 2.0, y: (358 - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + let circleFrame = CGRect(origin: CGPoint(x: (areaSize.width - buttonSize.width) / 2.0, y: (areaSize.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath - self.maskCircleLayer.fillColor = white.cgColor self.maskCircleLayer.path = largerCirclePath + self.maskCircleLayer.fillColor = white.cgColor self.maskCircleLayer.isHidden = true updateInHierarchy = { [weak self] value in @@ -971,6 +971,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { CATransaction.commit() } + private var maskIsCircle = true private func setupButtonAnimation() { CATransaction.begin() CATransaction.setDisableActions(true) @@ -982,6 +983,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: floor((self.bounds.height - buttonHeight) / 2.0), width: self.bounds.width, height: buttonHeight), cornerRadius: 10.0).cgPath self.maskCircleLayer.path = path + self.maskIsCircle = false CATransaction.commit() @@ -1001,6 +1003,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { let previousPath = self.maskCircleLayer.path 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) @@ -1144,9 +1147,13 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.updateAnimations() } + var previousSize: CGSize? override func layout() { super.layout() + let sizeUpdated = self.previousSize != self.bounds.size + self.previousSize = self.bounds.size + let bounds = CGRect(x: (self.bounds.width - areaSize.width) / 2.0, y: (self.bounds.height - areaSize.height) / 2.0, width: areaSize.width, height: areaSize.height) let center = bounds.center @@ -1159,7 +1166,17 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.growingForegroundCircleLayer.position = center self.growingForegroundCircleLayer.bounds = self.foregroundCircleLayer.bounds self.maskCircleLayer.frame = self.bounds -// circleFrame.insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + + if sizeUpdated && self.maskIsCircle { + CATransaction.begin() + CATransaction.setDisableActions(true) + let circleFrame = CGRect(origin: CGPoint(x: (self.bounds.width - buttonSize.width) / 2.0, y: (self.bounds.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath + + self.maskCircleLayer.path = largerCirclePath + CATransaction.commit() + } + self.maskProgressLayer.frame = circleFrame.insetBy(dx: -3.0, dy: -3.0) self.foregroundView.frame = self.bounds self.foregroundGradientLayer.frame = self.bounds @@ -1543,22 +1560,22 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .subscribe: switch state { case .unsubscribe: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminder"))) case .mute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand"))) default: break } case .unsubscribe: switch state { case .subscribe: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminder"))) case .mute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand"))) default: break } @@ -1574,7 +1591,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .mute: self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff2"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmuteToRaiseHand"))) default: break } @@ -1585,7 +1602,11 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .unmute: self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMuteToRaiseHand"))) + case .subscribe: + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001)) + case .unsubscribe: + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001)) case .empty: self.alpha = 0.0 default: @@ -1594,7 +1615,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .hand: switch state { case .mute, .unmute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOn"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceRaiseHandToMute"))) default: break } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index a758f3ebb6..2c25d44ef6 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -2438,8 +2438,12 @@ public final class VoiceChatController: ViewController { @objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state { - self.controller?.dismiss(closing: false) - self.controller?.dismissAllTooltips() + if self.isScheduling { + self.dismissScheduled() + } else { + self.controller?.dismiss(closing: false) + self.controller?.dismissAllTooltips() + } } } @@ -2594,7 +2598,7 @@ public final class VoiceChatController: ViewController { self.call.startScheduled() self.transitionToCall() } else { - + self.call.toggleScheduledSubscription(!callState.subscribedToScheduled) } } default: @@ -2670,8 +2674,6 @@ public final class VoiceChatController: ViewController { |> deliverOnMainQueue).start(next: { [weak self] inviteLinks in if let inviteLinks = inviteLinks { self?.presentShare(inviteLinks) - } else { - self?.presentShare(GroupCallInviteLinks(listenerLink: "a", speakerLink: nil)) } }) return @@ -3199,16 +3201,20 @@ public final class VoiceChatController: ViewController { let actionButtonSubtitle: String var actionButtonEnabled = true if let callState = self.callState, !self.isScheduling { - var isScheduled = callState.scheduleTimestamp != nil - if isScheduled { + if callState.scheduleTimestamp != nil { self.ignoreNextConnecting = true if callState.canManageCall { actionButtonState = .scheduled(state: .start) actionButtonTitle = self.presentationData.strings.VoiceChat_StartNow actionButtonSubtitle = "" } else { - actionButtonState = .scheduled(state: .subscribe) - actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder + if callState.subscribedToScheduled { + actionButtonState = .scheduled(state: .unsubscribe) + actionButtonTitle = self.presentationData.strings.VoiceChat_CancelReminder + } else { + actionButtonState = .scheduled(state: .subscribe) + actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder + } actionButtonSubtitle = "" } } else { @@ -3681,6 +3687,7 @@ public final class VoiceChatController: ViewController { @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { let contentOffset = self.listNode.visibleContentOffset() + let isScheduling = self.isScheduling || self.callState?.scheduleTimestamp != nil switch recognizer.state { case .began: let topInset: CGFloat @@ -3696,7 +3703,7 @@ public final class VoiceChatController: ViewController { self.controller?.dismissAllTooltips() case .changed: var translation = recognizer.translation(in: self.contentContainer.view).y - if (self.isScheduling || self.callState?.scheduleTimestamp != nil) && translation < 0.0 { + if isScheduling && translation < 0.0 { return } var topInset: CGFloat = 0.0 @@ -3802,7 +3809,7 @@ public final class VoiceChatController: ViewController { self.controller?.dismiss(closing: false, manual: true) } dismissing = true - } else if !self.isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) { + } else if !isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) { if velocity.y > -1500.0 && !self.isFullscreen { DispatchQueue.main.async { self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) @@ -3819,7 +3826,7 @@ public final class VoiceChatController: ViewController { self.updateFloatingHeaderOffset(offset: self.currentContentOffset ?? 0.0, transition: .animated(duration: 0.3, curve: .easeInOut), completion: { self.animatingExpansion = false }) - } else if !self.isScheduling { + } else if !isScheduling { self.updateIsFullscreen(false) self.animatingExpansion = true self.listNode.scroller.setContentOffset(CGPoint(), animated: false) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift b/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift index 2b0c01617f..a0f81d690a 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift @@ -144,8 +144,8 @@ public final class VoiceChatJoinScreen: ViewController { } else if let cachedData = cachedData as? CachedGroupData { defaultJoinAsPeerId = cachedData.callJoinPeerId } - - let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribed: false) + + let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribedToScheduled: call.info.subscribedToScheduled) if availablePeers.count > 0 && defaultJoinAsPeerId == nil { strongSelf.dismiss() strongSelf.join(activeCall) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift index fe3a71af12..fd2d504c53 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift @@ -136,7 +136,7 @@ final class VoiceChatTimerNode: ASDisplayNode { self.subtitleNode.attributedText = NSAttributedString(string: subtitle, font: Font.with(size: 21.0, design: .round, weight: .semibold, traits: []), textColor: .white) let subtitleSize = self.subtitleNode.updateLayout(size) - self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: timerSize.width, height: subtitleSize.height) + self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: subtitleSize.width, height: subtitleSize.height) self.foregroundView.frame = CGRect(origin: CGPoint(), size: size) } diff --git a/submodules/TelegramCore/Sources/GroupCalls.swift b/submodules/TelegramCore/Sources/GroupCalls.swift index 7c50c6d79a..a0c1c924ee 100644 --- a/submodules/TelegramCore/Sources/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/GroupCalls.swift @@ -12,6 +12,7 @@ public struct GroupCallInfo: Equatable { public var streamDcId: Int32? public var title: String? public var scheduleTimestamp: Int32? + public var subscribedToScheduled: Bool public var recordingStartTimestamp: Int32? public var sortAscending: Bool @@ -23,6 +24,7 @@ public struct GroupCallInfo: Equatable { streamDcId: Int32?, title: String?, scheduleTimestamp: Int32?, + subscribedToScheduled: Bool, recordingStartTimestamp: Int32?, sortAscending: Bool ) { @@ -33,6 +35,7 @@ public struct GroupCallInfo: Equatable { self.streamDcId = streamDcId self.title = title self.scheduleTimestamp = scheduleTimestamp + self.subscribedToScheduled = subscribedToScheduled self.recordingStartTimestamp = recordingStartTimestamp self.sortAscending = sortAscending } @@ -62,6 +65,7 @@ extension GroupCallInfo { streamDcId: streamDcId, title: title, scheduleTimestamp: scheduleDate, + subscribedToScheduled: (flags & (1 << 8)) != 0, recordingStartTimestamp: recordStartDate, sortAscending: (flags & (1 << 6)) != 0 ) @@ -226,9 +230,9 @@ public func createGroupCall(account: Account, peerId: PeerId, title: String?, sc return account.postbox.transaction { transaction -> GroupCallInfo in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else { return cachedData } @@ -271,9 +275,9 @@ public func startScheduledGroupCall(account: Account, peerId: PeerId, callId: In return account.postbox.transaction { transaction -> GroupCallInfo in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else { return cachedData } @@ -315,9 +319,9 @@ public func toggleScheduledGroupCallSubscription(account: Account, peerId: PeerI return account.postbox.transaction { transaction in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else { return cachedData } @@ -373,19 +377,19 @@ public enum GetGroupCallParticipantsError { } public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal { - let sortAscendingValue: Signal<(Bool, Int32?), GetGroupCallParticipantsError> + let sortAscendingValue: Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError> if let sortAscending = sortAscending { - sortAscendingValue = .single((sortAscending, nil)) + sortAscendingValue = .single((sortAscending, nil, false)) } else { sortAscendingValue = getCurrentGroupCall(account: account, callId: callId, accessHash: accessHash) |> mapError { _ -> GetGroupCallParticipantsError in return .generic } - |> mapToSignal { result -> Signal<(Bool, Int32?), GetGroupCallParticipantsError> in + |> mapToSignal { result -> Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError> in guard let result = result else { return .fail(.generic) } - return .single((result.info.sortAscending, result.info.scheduleTimestamp)) + return .single((result.info.sortAscending, result.info.scheduleTimestamp, result.info.subscribedToScheduled)) } } @@ -403,7 +407,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash let version: Int32 let nextParticipantsFetchOffset: String? - let (sortAscendingValue, scheduleTimestamp) = sortAscendingAndScheduleTimestamp + let (sortAscendingValue, scheduleTimestamp, subscribedToScheduled) = sortAscendingAndScheduleTimestamp switch result { case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion): @@ -492,6 +496,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash recordingStartTimestamp: nil, title: nil, scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled, totalCount: totalCount, version: version ) @@ -668,9 +673,9 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal return account.postbox.transaction { transaction -> JoinGroupCallResult in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else { return cachedData } @@ -1011,6 +1016,7 @@ public final class GroupCallParticipantsContext { public var recordingStartTimestamp: Int32? public var title: String? public var scheduleTimestamp: Int32? + public var subscribedToScheduled: Bool public var totalCount: Int public var version: Int32 @@ -1123,7 +1129,7 @@ public final class GroupCallParticipantsContext { } case state(update: StateUpdate) - case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?) + case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?, scheduleTimestamp: Int32?) } public final class MemberEvent { @@ -1313,6 +1319,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, title: strongSelf.stateValue.state.title, scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp, + subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled, totalCount: strongSelf.stateValue.state.totalCount, version: strongSelf.stateValue.state.version ), @@ -1368,11 +1375,12 @@ public final class GroupCallParticipantsContext { for update in updates { if case let .state(update) = update { stateUpdates.append(update) - } else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp) = update { + } else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp, scheduleTimestamp) = update { var state = self.stateValue.state state.defaultParticipantsAreMuted = defaultParticipantsAreMuted state.recordingStartTimestamp = recordingStartTimestamp state.title = title + state.scheduleTimestamp = scheduleTimestamp self.stateValue.state = state } @@ -1446,6 +1454,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, title: strongSelf.stateValue.state.title, scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp, + subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled, totalCount: strongSelf.stateValue.state.totalCount, version: strongSelf.stateValue.state.version ), @@ -1662,6 +1671,7 @@ public final class GroupCallParticipantsContext { let recordingStartTimestamp = strongSelf.stateValue.state.recordingStartTimestamp let title = strongSelf.stateValue.state.title let scheduleTimestamp = strongSelf.stateValue.state.scheduleTimestamp + let subscribedToScheduled = strongSelf.stateValue.state.subscribedToScheduled updatedParticipants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: strongSelf.stateValue.state.sortAscending) }) @@ -1676,6 +1686,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: recordingStartTimestamp, title: title, scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled, totalCount: updatedTotalCount, version: update.version ), diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 5cac66545f..e57096a47b 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -2982,9 +2982,9 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP if let info = GroupCallInfo(call) { transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in if let current = current as? CachedChannelData { - return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) } else if let current = current as? CachedGroupData { - return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) } else { return current } @@ -2997,7 +2997,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange) updatedGroupCallParticipants.append(( info.id, - .call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate) + .call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate, scheduleTimestamp: scheduleDate) )) default: break @@ -3006,7 +3006,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP case let .groupCallDiscarded(callId, _, _): updatedGroupCallParticipants.append(( callId, - .call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil) + .call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil, scheduleTimestamp: nil) )) transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in diff --git a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift index 7ebfa241a6..7e0c426020 100644 --- a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift @@ -306,7 +306,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId if let inputCall = chatFull.call { switch inputCall { case let .inputGroupCall(id, accessHash): - updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false) + updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false) } } @@ -516,7 +516,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId if let inputCall = inputCall { switch inputCall { case let .inputGroupCall(id, accessHash): - updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false) + updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false) } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 1934261113..184f0b6782 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -535,7 +535,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } case .groupPhoneCall, .inviteToGroupPhoneCall: if let activeCall = strongSelf.presentationInterfaceState.activeGroupCallInfo?.activeCall { - strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribed: activeCall.subscribed)) + strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribedToScheduled: activeCall.subscribedToScheduled)) } else { var canManageGroupCalls = false if let channel = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel { @@ -569,7 +569,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) }, error: { [weak self] error in dismissStatus?() diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 681eabb22d..9d3a467201 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4020,7 +4020,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } strongSelf.context.joinGroupCall(peerId: peerId, invite: nil, requestJoinAsPeerId: { result in result(joinAsPeerId) - }, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribed: false)) + }, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribedToScheduled: false)) }, error: { [weak self] error in guard let strongSelf = self else { return @@ -4199,7 +4199,9 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD |> deliverOnMainQueue).start(completed: { [weak self] in if let strongSelf = self, let peer = strongSelf.data?.peer { let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root)) + let controller = UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }) + controller.keepOnParentDismissal = true + strongSelf.controller?.present(controller, in: .window(.root)) strongSelf.controller?.dismiss() } @@ -6642,12 +6644,12 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen { private func dismissAllTooltips() { self.window?.forEachController({ controller in - if let controller = controller as? UndoOverlayController { + if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal { controller.dismissWithCommitAction() } }) self.forEachController({ controller in - if let controller = controller as? UndoOverlayController { + if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal { controller.dismissWithCommitAction() } return true diff --git a/submodules/UndoUI/Sources/UndoOverlayController.swift b/submodules/UndoUI/Sources/UndoOverlayController.swift index bf84710a72..05ef86b7f0 100644 --- a/submodules/UndoUI/Sources/UndoOverlayController.swift +++ b/submodules/UndoUI/Sources/UndoOverlayController.swift @@ -56,6 +56,8 @@ public final class UndoOverlayController: ViewController { private var didPlayPresentationAnimation = false private var dismissed = false + public var keepOnParentDismissal = false + public init(presentationData: PresentationData, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (UndoOverlayAction) -> Bool) { self.presentationData = presentationData self.content = content