Fix audio route button

This commit is contained in:
isaac 2026-05-11 19:57:10 +02:00
parent 9e3c16cde5
commit 39d33d998c
4 changed files with 23 additions and 5 deletions

View file

@ -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))

View file

@ -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)
}

View file

@ -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: {},

View file

@ -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
}