diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 557d209f39..0d0983bb68 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -168,6 +168,26 @@ public protocol PresentationCall: class { func makeOutgoingVideoView(completion: @escaping (PresentationCallVideoView?) -> Void) } +public struct VoiceChatConfiguration { + public static var defaultValue: VoiceChatConfiguration { + return VoiceChatConfiguration(videoParticipantsMaxCount: 30) + } + + public let videoParticipantsMaxCount: Int32 + + fileprivate init(videoParticipantsMaxCount: Int32) { + self.videoParticipantsMaxCount = videoParticipantsMaxCount + } + + public static func with(appConfiguration: AppConfiguration) -> VoiceChatConfiguration { + if let data = appConfiguration.data, let value = data["groupcall_video_participants_max"] as? Double { + return VoiceChatConfiguration(videoParticipantsMaxCount: Int32(value)) + } else { + return .defaultValue + } + } +} + public struct PresentationGroupCallState: Equatable { public enum NetworkState { case connecting @@ -191,6 +211,7 @@ public struct PresentationGroupCallState: Equatable { public var scheduleTimestamp: Int32? public var subscribedToScheduled: Bool public var isVideoEnabled: Bool + public var isVideoWatchersLimitReached: Bool public init( myPeerId: PeerId, @@ -204,7 +225,8 @@ public struct PresentationGroupCallState: Equatable { raisedHand: Bool, scheduleTimestamp: Int32?, subscribedToScheduled: Bool, - isVideoEnabled: Bool + isVideoEnabled: Bool, + isVideoWatchersLimitReached: Bool ) { self.myPeerId = myPeerId self.networkState = networkState @@ -218,6 +240,7 @@ public struct PresentationGroupCallState: Equatable { self.scheduleTimestamp = scheduleTimestamp self.subscribedToScheduled = subscribedToScheduled self.isVideoEnabled = isVideoEnabled + self.isVideoWatchersLimitReached = isVideoWatchersLimitReached } } diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 517546ee1a..7eb23db7d5 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -245,7 +245,8 @@ private extension PresentationGroupCallState { raisedHand: false, scheduleTimestamp: scheduleTimestamp, subscribedToScheduled: subscribedToScheduled, - isVideoEnabled: false + isVideoEnabled: false, + isVideoWatchersLimitReached: false ) } } @@ -1781,7 +1782,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { guard let strongSelf = self else { return } - + let appConfiguration = strongSelf.accountContext.currentAppConfiguration.with({ $0 }) + let configuration = VoiceChatConfiguration.with(appConfiguration: appConfiguration) + strongSelf.participantsContext?.updateAdminIds(adminIds) var topParticipants: [GroupCallParticipantsContext.Participant] = [] @@ -1859,6 +1862,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } var otherParticipantsWithVideo = 0 + var videoWatchingParticipants = 0 for participant in participants { var participant = participant @@ -1950,6 +1954,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { strongSelf.stateValue.muteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false) strongSelf.genericCallContext?.setIsMuted(true) } + + if participant.joinedVideo { + videoWatchingParticipants += 1 + } } else { if let ssrc = participant.ssrc { if let volume = participant.volume { @@ -1969,6 +1977,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { if participant.videoDescription != nil || participant.presentationDescription != nil { otherParticipantsWithVideo += 1 } + if participant.joinedVideo { + videoWatchingParticipants += 1 + } } if let index = updatedInvitedPeers.firstIndex(of: participant.peer.id) { @@ -1994,6 +2005,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { strongSelf.stateValue.title = state.title strongSelf.stateValue.scheduleTimestamp = state.scheduleTimestamp strongSelf.stateValue.isVideoEnabled = state.isVideoEnabled && otherParticipantsWithVideo < state.unmutedVideoLimit + strongSelf.stateValue.isVideoWatchersLimitReached = videoWatchingParticipants >= configuration.videoParticipantsMaxCount strongSelf.summaryInfoState.set(.single(SummaryInfoState(info: GroupCallInfo( id: callInfo.id, diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index a4bcbd5bac..c8cd1f27a2 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -43,26 +43,6 @@ let bottomAreaHeight: CGFloat = 206.0 private let fullscreenBottomAreaHeight: CGFloat = 80.0 private let bottomGradientHeight: CGFloat = 70.0 -public struct VoiceChatConfiguration { - static var defaultValue: VoiceChatConfiguration { - return VoiceChatConfiguration(videoParticipantsMaxCount: 30) - } - - public let videoParticipantsMaxCount: Int32 - - fileprivate init(videoParticipantsMaxCount: Int32) { - self.videoParticipantsMaxCount = videoParticipantsMaxCount - } - - static func with(appConfiguration: AppConfiguration) -> VoiceChatConfiguration { - if let data = appConfiguration.data, let value = data["groupcall_video_participants_max"] as? Double { - return VoiceChatConfiguration(videoParticipantsMaxCount: Int32(value)) - } else { - return .defaultValue - } - } -} - func decorationCornersImage(top: Bool, bottom: Bool, dark: Bool) -> UIImage? { if !top && !bottom { return nil @@ -5031,7 +5011,7 @@ public final class VoiceChatController: ViewController { gridTileItems.removeAll() tileItems.append(VoiceChatTileItem(account: self.context.account, peer: peer, videoEndpointId: "", videoReady: false, videoTimeouted: true, isVideoLimit: true, videoLimit: configuration.videoParticipantsMaxCount, isPaused: false, isOwnScreencast: false, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder, speaking: false, secondary: false, isTablet: false, icon: .none, text: .none, additionalText: nil, action: {}, contextAction: nil, getVideo: { _ in return nil }, getAudioLevel: nil)) - } else if let callState = self.callState, !tileItems.isEmpty && !callState.isVideoEnabled && self.connectedOnce && (callState.canManageCall || callState.adminIds.contains(self.context.account.peerId)) { + } else if let callState = self.callState, !tileItems.isEmpty && callState.isVideoWatchersLimitReached && self.connectedOnce && (callState.canManageCall || callState.adminIds.contains(self.context.account.peerId)) { reachedLimit = true } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift index f344a2694d..1b8b43df66 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTileGridNode.swift @@ -336,6 +336,10 @@ final class VoiceChatTilesGridItemNode: ListViewItemNode { } let _ = textApply() + if !transition.isAnimated && currentItem?.reachedLimit != item.reachedLimit { + strongSelf.backgroundNode.layer.removeAllAnimations() + strongSelf.limitLabel.layer.removeAllAnimations() + } transition.updateFrame(node: strongSelf.limitLabel, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((params.width - textLayout.size.width) / 2.0), y: gridSize.height + 10.0), size: textLayout.size)) transition.updateAlpha(node: strongSelf.limitLabel, alpha: item.reachedLimit ? 1.0 : 0.0) }