From 39d33d998c659d07bd0e2bf9932b29e8a04e5d95 Mon Sep 17 00:00:00 2001 From: isaac <> Date: Mon, 11 May 2026 19:57:10 +0200 Subject: [PATCH] Fix audio route button --- .../TelegramCallsUI/Sources/CallControllerNodeV2.swift | 9 ++++++++- .../Sources/VideoChatActionButtonComponent.swift | 4 ++-- submodules/TelegramCallsUI/Sources/VideoChatScreen.swift | 7 ++++++- .../Calls/CallScreen/Sources/PrivateCallScreen.swift | 8 +++++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift b/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift index 230815678b..fb75030cf3 100644 --- a/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift +++ b/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift @@ -176,6 +176,7 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP shortName: " ", avatarImage: nil, audioOutput: .internalSpeaker, + canSwitchAudioOutput: true, isLocalAudioMuted: false, isRemoteAudioMuted: false, localVideo: nil, @@ -271,6 +272,11 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP self.currentAudioOutput = currentOutput if var callScreenState = self.callScreenState { + var canSwitchAudioOutput = false + if availableOutputs.count > 1 { + canSwitchAudioOutput = true + } + let mappedOutput: PrivateCallScreen.State.AudioOutput if let currentOutput { switch currentOutput { @@ -301,8 +307,9 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP mappedOutput = .internalSpeaker } - if callScreenState.audioOutput != mappedOutput { + if callScreenState.audioOutput != mappedOutput || callScreenState.canSwitchAudioOutput != canSwitchAudioOutput { callScreenState.audioOutput = mappedOutput + callScreenState.canSwitchAudioOutput = canSwitchAudioOutput self.callScreenState = callScreenState self.update(transition: .animated(duration: 0.3, curve: .spring)) diff --git a/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift index 8ac79574cb..8ce1fde79a 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatActionButtonComponent.swift @@ -156,11 +156,11 @@ final class VideoChatActionButtonComponent: Component { switch component.content { case let .audio(audio, isEnabledValue): var isActive = false + isEnabled = isEnabledValue switch audio { case .none, .builtin: titleText = component.strings.Call_Speaker case .speaker: - isEnabled = isEnabledValue isActive = isEnabledValue titleText = component.strings.Call_Speaker case .headphones: @@ -324,7 +324,7 @@ final class VideoChatActionButtonComponent: Component { } transition.setPosition(view: iconView, position: iconFrame.center) transition.setBounds(view: iconView, bounds: CGRect(origin: CGPoint(), size: iconFrame.size)) - transition.setAlpha(view: iconView, alpha: isEnabled ? 1.0 : 0.6) + transition.setAlpha(view: iconView, alpha: isEnabled ? 1.0 : 0.4) transition.setScale(view: iconView, scale: availableSize.height / 56.0) } diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift index ef8217b3cb..b11c721d82 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift @@ -2619,6 +2619,7 @@ final class VideoChatScreenComponent: Component { let videoButtonContent: VideoChatActionButtonComponent.Content? let videoControlButtonContent: VideoChatActionButtonComponent.Content + let videoControlButtonEnabled: Bool let messageButtonContent: VideoChatActionButtonComponent.Content? var buttonAudio: VideoChatActionButtonComponent.Content.Audio = .speaker @@ -2652,13 +2653,16 @@ final class VideoChatScreenComponent: Component { if let callState = self.callState, let muteState = callState.muteState, !muteState.canUnmute { videoButtonContent = nil videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled) + videoControlButtonEnabled = buttonIsEnabled } else { let isVideoActive = self.callState?.isMyVideoActive ?? false videoButtonContent = .video(isActive: isVideoActive) if isVideoActive { videoControlButtonContent = .rotateCamera + videoControlButtonEnabled = true } else { videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled) + videoControlButtonEnabled = buttonIsEnabled } } @@ -3225,7 +3229,7 @@ final class VideoChatScreenComponent: Component { transition.setPosition(view: microphoneButtonView, position: microphoneButtonFrame.center) transition.setBounds(view: microphoneButtonView, bounds: CGRect(origin: CGPoint(), size: microphoneButtonFrame.size)) } - + let _ = self.speakerButton.update( transition: transition, component: AnyComponent(PlainButtonComponent( @@ -3248,6 +3252,7 @@ final class VideoChatScreenComponent: Component { self.onAudioRoutePressed() } }, + isEnabled: videoControlButtonEnabled, animateAlpha: false )), environment: {}, diff --git a/submodules/TelegramUI/Components/Calls/CallScreen/Sources/PrivateCallScreen.swift b/submodules/TelegramUI/Components/Calls/CallScreen/Sources/PrivateCallScreen.swift index 86d49a667c..98e93cd59c 100644 --- a/submodules/TelegramUI/Components/Calls/CallScreen/Sources/PrivateCallScreen.swift +++ b/submodules/TelegramUI/Components/Calls/CallScreen/Sources/PrivateCallScreen.swift @@ -74,6 +74,7 @@ public final class PrivateCallScreen: OverlayMaskContainerView, AVPictureInPictu public var shortName: String public var avatarImage: UIImage? public var audioOutput: AudioOutput + public var canSwitchAudioOutput: Bool public var isLocalAudioMuted: Bool public var isRemoteAudioMuted: Bool public var localVideo: VideoSource? @@ -90,6 +91,7 @@ public final class PrivateCallScreen: OverlayMaskContainerView, AVPictureInPictu shortName: String, avatarImage: UIImage?, audioOutput: AudioOutput, + canSwitchAudioOutput: Bool, isLocalAudioMuted: Bool, isRemoteAudioMuted: Bool, localVideo: VideoSource?, @@ -105,6 +107,7 @@ public final class PrivateCallScreen: OverlayMaskContainerView, AVPictureInPictu self.shortName = shortName self.avatarImage = avatarImage self.audioOutput = audioOutput + self.canSwitchAudioOutput = canSwitchAudioOutput self.isLocalAudioMuted = isLocalAudioMuted self.isRemoteAudioMuted = isRemoteAudioMuted self.localVideo = localVideo @@ -134,6 +137,9 @@ public final class PrivateCallScreen: OverlayMaskContainerView, AVPictureInPictu if lhs.audioOutput != rhs.audioOutput { return false } + if lhs.canSwitchAudioOutput != rhs.canSwitchAudioOutput { + return false + } if lhs.isLocalAudioMuted != rhs.isLocalAudioMuted { return false } @@ -822,7 +828,7 @@ public final class PrivateCallScreen: OverlayMaskContainerView, AVPictureInPictu self.flipCameraAction?() }), at: 0) } else { - buttons.insert(ButtonGroupView.Button(content: .speaker(audioOutput: params.state.audioOutput), isEnabled: !isTerminated, action: { [weak self] in + buttons.insert(ButtonGroupView.Button(content: .speaker(audioOutput: params.state.audioOutput), isEnabled: !isTerminated && params.state.canSwitchAudioOutput, action: { [weak self] in guard let self else { return }