diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index f04e426222..a9d3693875 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -305,6 +305,7 @@ public protocol PresentationGroupCall: class { var isMuted: Signal { get } var memberEvents: Signal { get } + var reconnectedAsEvents: Signal { get } func reconnect(with invite: String) func reconnect(as peerId: PeerId) diff --git a/submodules/TelegramAudio/Sources/ManagedAudioSession.swift b/submodules/TelegramAudio/Sources/ManagedAudioSession.swift index 2c6d6f4522..4b9831dcd3 100644 --- a/submodules/TelegramAudio/Sources/ManagedAudioSession.swift +++ b/submodules/TelegramAudio/Sources/ManagedAudioSession.swift @@ -422,7 +422,7 @@ public final class ManagedAudioSession { if let strongSelf = self { for holder in strongSelf.holders { if holder.id == id && holder.active { - strongSelf.setup(type: audioSessionType, outputMode: holder.outputMode, activateNow: true) + strongSelf.setup(type: audioSessionType, outputMode: holder.outputMode, activateNow: false) break } } @@ -501,7 +501,7 @@ public final class ManagedAudioSession { } } } - + public func dropAll() { self.queue.async { self.updateHolders(interruption: true) diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index f514eff7eb..db86ace852 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -355,12 +355,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { private var invite: String? private var joinAsPeerId: PeerId private var ignorePreviousJoinAsPeerId: (PeerId, UInt32)? + private var reconnectingAsPeer: Peer? public private(set) var isVideo: Bool private var temporaryJoinTimestamp: Int32 private var temporaryActivityTimestamp: Double? private var temporaryActivityRank: Int? + private var temporaryRaiseHandRating: Int64? + private var temporaryHasRaiseHand: Bool = false private var temporaryMuteState: GroupCallParticipantsContext.Participant.MuteState? private var internalState: InternalState = .requesting @@ -489,6 +492,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { return self.memberEventsPipe.signal() } private let memberEventsPipeDisposable = MetaDisposable() + + private let reconnectedAsEventsPipe = ValuePipe() + public var reconnectedAsEvents: Signal { + return self.reconnectedAsEventsPipe.signal() + } private let joinDisposable = MetaDisposable() private let requestDisposable = MetaDisposable() @@ -884,8 +892,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { ssrc: nil, jsonParams: nil, joinTimestamp: strongSelf.temporaryJoinTimestamp, - raiseHandRating: nil, - hasRaiseHand: false, + raiseHandRating: strongSelf.temporaryRaiseHandRating, + hasRaiseHand: strongSelf.temporaryHasRaiseHand, activityTimestamp: strongSelf.temporaryActivityTimestamp, activityRank: strongSelf.temporaryActivityRank, muteState: strongSelf.temporaryMuteState ?? GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false), @@ -965,8 +973,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { ssrc: nil, jsonParams: nil, joinTimestamp: strongSelf.temporaryJoinTimestamp, - raiseHandRating: nil, - hasRaiseHand: false, + raiseHandRating: strongSelf.temporaryRaiseHandRating, + hasRaiseHand: strongSelf.temporaryHasRaiseHand, activityTimestamp: strongSelf.temporaryActivityTimestamp, activityRank: strongSelf.temporaryActivityRank, muteState: strongSelf.temporaryMuteState ?? GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false), @@ -1084,13 +1092,20 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { let peerAdminIds: Signal<[PeerId], NoError> let peerId = strongSelf.peerId if strongSelf.peerId.namespace == Namespaces.Peer.CloudChannel { - peerAdminIds = strongSelf.account.postbox.transaction { transaction -> [PeerId] in - var result: [PeerId] = [] - if let entry = transaction.retrieveItemCacheEntry(id: cachedChannelAdminRanksEntryId(peerId: peerId)) as? CachedChannelAdminRanks { - result = Array(entry.ranks.keys) - } - return result + peerAdminIds = Signal { subscriber in + let (disposable, _) = strongSelf.accountContext.peerChannelMemberCategoriesContextsManager.admins(postbox: strongSelf.accountContext.account.postbox, network: strongSelf.accountContext.account.network, accountPeerId: strongSelf.accountContext.account.peerId, peerId: peerId, updated: { list in + var peerIds = Set() + for item in list.list { + if let adminInfo = item.participant.adminInfo, adminInfo.rights.rights.contains(.canManageCalls) { + peerIds.insert(item.peer.id) + } + } + subscriber.putNext(Array(peerIds)) + }) + return disposable } + |> distinctUntilChanged + |> runOn(.mainQueue()) } else { peerAdminIds = strongSelf.account.postbox.transaction { transaction -> [PeerId] in var result: [PeerId] = [] @@ -1218,6 +1233,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { strongSelf.toneRenderer = toneRenderer toneRenderer.setAudioSessionActive(strongSelf.isAudioSessionActive) } + + if let peer = strongSelf.reconnectingAsPeer { + strongSelf.reconnectingAsPeer = nil + strongSelf.reconnectedAsEventsPipe.putNext(peer) + } } })) @@ -1438,8 +1458,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { ssrc: nil, jsonParams: nil, joinTimestamp: strongSelf.temporaryJoinTimestamp, - raiseHandRating: nil, - hasRaiseHand: false, + raiseHandRating: strongSelf.temporaryRaiseHandRating, + hasRaiseHand: strongSelf.temporaryHasRaiseHand, activityTimestamp: strongSelf.temporaryActivityTimestamp, activityRank: strongSelf.temporaryActivityRank, muteState: strongSelf.temporaryMuteState ?? GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false), @@ -1764,6 +1784,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { guard let strongSelf = self, let _ = myPeer else { return } + + strongSelf.reconnectingAsPeer = myPeer let previousPeerId = strongSelf.joinAsPeerId if let localSsrc = strongSelf.currentLocalSsrc { @@ -1777,6 +1799,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { strongSelf.temporaryJoinTimestamp = participant.joinTimestamp strongSelf.temporaryActivityTimestamp = participant.activityTimestamp strongSelf.temporaryActivityRank = participant.activityRank + strongSelf.temporaryRaiseHandRating = participant.raiseHandRating + strongSelf.temporaryHasRaiseHand = participant.hasRaiseHand strongSelf.temporaryMuteState = participant.muteState } } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 9b47564032..a3b6703637 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -721,6 +721,7 @@ public final class VoiceChatController: ViewController { private let inviteDisposable = MetaDisposable() private let memberEventsDisposable = MetaDisposable() + private let reconnectedAsEventsDisposable = MetaDisposable() private let voiceSourcesDisposable = MetaDisposable() private var requestedVideoSources = Set() @@ -1601,6 +1602,14 @@ public final class VoiceChatController: ViewController { strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: event.peer, text: strongSelf.presentationData.strings.VoiceChat_PeerJoinedText(event.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), action: { _ in return false }) } })) + + self.reconnectedAsEventsDisposable.set((self.call.reconnectedAsEvents + |> deliverOnMainQueue).start(next: { [weak self] peer in + guard let strongSelf = self else { + return + } + strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), action: { _ in return false }) + })) self.voiceSourcesDisposable.set((self.call.incomingVideoSources |> deliverOnMainQueue).start(next: { [weak self] sources in @@ -1720,6 +1729,7 @@ public final class VoiceChatController: ViewController { self.myAudioLevelDisposable?.dispose() self.inviteDisposable.dispose() self.memberEventsDisposable.dispose() + self.reconnectedAsEventsDisposable.dispose() self.voiceSourcesDisposable.dispose() } @@ -1970,8 +1980,6 @@ public final class VoiceChatController: ViewController { if peer.peer.id != myPeerId { strongSelf.call.reconnect(as: peer.peer.id) - - strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer.peer, text: strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(peer.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), action: { _ in return false }) } }))) diff --git a/submodules/TelegramCore/Sources/ManagedAutoremoveMessageOperations.swift b/submodules/TelegramCore/Sources/ManagedAutoremoveMessageOperations.swift index 97a0385d1d..6fea6b7b9d 100644 --- a/submodules/TelegramCore/Sources/ManagedAutoremoveMessageOperations.swift +++ b/submodules/TelegramCore/Sources/ManagedAutoremoveMessageOperations.swift @@ -43,7 +43,7 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox, isRe return Signal { _ in let helper = Atomic(value: ManagedAutoremoveMessageOperationsHelper()) - let timeOffsetOnce = Signal { subscriber in + /*let timeOffsetOnce = Signal { subscriber in subscriber.putNext(network.globalTimeDifference) return EmptyDisposable } @@ -59,7 +59,9 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox, isRe |> map { value -> Double in round(value) } - |> distinctUntilChanged + |> distinctUntilChanged*/ + + let timeOffset: Signal = .single(0.0) let disposable = combineLatest(timeOffset, postbox.timestampBasedMessageAttributesView(tag: isRemove ? 0 : 1)).start(next: { timeOffset, view in let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(TimestampBasedMessageAttributesEntry, MetaDisposable)]) in @@ -72,8 +74,10 @@ func managedAutoremoveMessageOperations(network: Network, postbox: Postbox, isRe for (entry, disposable) in beginOperations { let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + timeOffset + let delay = max(0.0, Double(entry.timestamp) - timestamp) + Logger.shared.log("Autoremove", "Scheduling autoremove for \(entry.messageId) at \(entry.timestamp) (in \(delay) seconds)") let signal = Signal.complete() - |> suspendAwareDelay(max(0.0, Double(entry.timestamp) - timestamp), queue: Queue.concurrentDefaultQueue()) + |> suspendAwareDelay(delay, queue: Queue.concurrentDefaultQueue()) |> then(postbox.transaction { transaction -> Void in if let message = transaction.getMessage(entry.messageId) { if message.id.peerId.namespace == Namespaces.Peer.SecretChat || isRemove {