From 6d1732d8303da6d48ef23580171e5836d9581e1f Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Thu, 13 Mar 2025 00:34:46 +0100 Subject: [PATCH 1/2] Fix default to speaker (cherry picked from commit 950c3d9f1e20eeea79feeda7fbe1dfc3f1187b6d) --- .../Sources/PresentationCall.swift | 38 ++++++++++++++++++- .../Sources/PresentationGroupCall.swift | 2 +- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index 382f61463e..de7be12e55 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -19,6 +19,8 @@ public final class SharedCallAudioContext { let audioDevice: OngoingCallContext.AudioDevice? let callKitIntegration: CallKitIntegration? + private let defaultToSpeaker: Bool + private var audioSessionDisposable: Disposable? private var audioSessionShouldBeActiveDisposable: Disposable? private var isAudioSessionActiveDisposable: Disposable? @@ -40,10 +42,17 @@ public final class SharedCallAudioContext { } private let audioSessionShouldBeActive = Promise(true) + private var initialSetupTimer: Foundation.Timer? - init(audioSession: ManagedAudioSession, callKitIntegration: CallKitIntegration?) { + init(audioSession: ManagedAudioSession, callKitIntegration: CallKitIntegration?, defaultToSpeaker: Bool = false) { self.callKitIntegration = callKitIntegration self.audioDevice = OngoingCallContext.AudioDevice.create(enableSystemMute: false) + self.defaultToSpeaker = defaultToSpeaker + + if defaultToSpeaker { + self.didSetCurrentAudioOutputValue = true + self.currentAudioOutputValue = .speaker + } var didReceiveAudioOutputs = false self.audioSessionDisposable = audioSession.push(audioSessionType: .voiceCall, manualActivate: { [weak self] control in @@ -72,6 +81,27 @@ public final class SharedCallAudioContext { audioSessionActive = .single(true) } self.isAudioSessionActivePromise.set(audioSessionActive) + + self.initialSetupTimer?.invalidate() + self.initialSetupTimer = Foundation.Timer(timeInterval: 0.5, repeats: false, block: { [weak self] _ in + guard let self else { + return + } + + if self.defaultToSpeaker, let audioSessionControl = self.audioSessionControl { + self.currentAudioOutputValue = .speaker + self.didSetCurrentAudioOutputValue = true + + if let callKitIntegration = self.callKitIntegration { + if self.didSetCurrentAudioOutputValue { + callKitIntegration.applyVoiceChatOutputMode(outputMode: .custom(self.currentAudioOutputValue)) + } + } else { + audioSessionControl.setOutputMode(.custom(self.currentAudioOutputValue)) + audioSessionControl.setup(synchronous: true) + } + } + }) } } }, deactivate: { [weak self] _ in @@ -160,9 +190,13 @@ public final class SharedCallAudioContext { self.audioSessionShouldBeActiveDisposable?.dispose() self.isAudioSessionActiveDisposable?.dispose() self.audioOutputStateDisposable?.dispose() + self.initialSetupTimer?.invalidate() } func setCurrentAudioOutput(_ output: AudioSessionOutput) { + self.initialSetupTimer?.invalidate() + self.initialSetupTimer = nil + guard self.currentAudioOutputValue != output else { return } @@ -427,7 +461,7 @@ public final class PresentationCallImpl: PresentationCall { if let data = context.currentAppConfiguration.with({ $0 }).data, let _ = data["ios_killswitch_disable_call_device"] { self.sharedAudioContext = nil } else { - self.sharedAudioContext = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration) + self.sharedAudioContext = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration, defaultToSpeaker: startWithVideo || initialState?.type == .video) } if let _ = self.sharedAudioContext { diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 8893bb0cf0..7374021ee5 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -1134,7 +1134,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } if useSharedAudio { - let sharedAudioContextValue = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration) + let sharedAudioContextValue = SharedCallAudioContext(audioSession: audioSession, callKitIntegration: callKitIntegration, defaultToSpeaker: true) sharedAudioContext = sharedAudioContextValue } } From c6718b3a5e333073a946aa29615463af265c0d76 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 13 Mar 2025 15:31:01 +0400 Subject: [PATCH 2/2] Various fixes --- .../PeerInfoScreen/Sources/PeerInfoHeaderNode.swift | 4 ++-- .../Sources/PeerInfoGiftsPaneNode.swift | 2 +- .../WebAppLaunchConfirmationController.swift | 13 ++++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index 0033cb9aa8..33e58a316f 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -2326,9 +2326,9 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.backgroundBannerView.addSubview(backgroundCoverView) } if additive { - transition.updateFrameAdditive(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: -bannerInset, y: bannerFrame.height - backgroundCoverSize.height - bannerInset), size: backgroundCoverSize)) + transition.updateFrameAdditive(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: -bannerInset, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize)) } else { - transition.updateFrame(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: -bannerInset, y: bannerFrame.height - backgroundCoverSize.height - bannerInset), size: backgroundCoverSize)) + transition.updateFrame(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: -bannerInset, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize)) } if backgroundCoverAnimateIn { if !self.isAvatarExpanded { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift index 66026f44ab..c0709e9684 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift @@ -379,7 +379,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr let optionSpacing: CGFloat = 10.0 let itemsSideInset = params.sideInset + 16.0 - let defaultItemsInRow = params.size.width > params.size.height || params.size.width > 414.0 ? 5 : 3 + let defaultItemsInRow = params.size.width > params.size.height || params.size.width > 480.0 ? 5 : 3 let itemsInRow = max(1, min(starsProducts.count, defaultItemsInRow)) let defaultOptionWidth = (params.size.width - itemsSideInset * 2.0 - optionSpacing * CGFloat(defaultItemsInRow - 1)) / CGFloat(defaultItemsInRow) let optionWidth = (params.size.width - itemsSideInset * 2.0 - optionSpacing * CGFloat(itemsInRow - 1)) / CGFloat(itemsInRow) diff --git a/submodules/WebUI/Sources/WebAppLaunchConfirmationController.swift b/submodules/WebUI/Sources/WebAppLaunchConfirmationController.swift index 263e8c9b01..ba371f9632 100644 --- a/submodules/WebUI/Sources/WebAppLaunchConfirmationController.swift +++ b/submodules/WebUI/Sources/WebAppLaunchConfirmationController.swift @@ -218,8 +218,16 @@ private final class WebAppLaunchConfirmationAlertContentNode: AlertContentNode { let titleSize = self.titleNode.updateLayout(CGSize(width: size.width - 32.0, height: size.height)) var totalWidth = titleSize.width - if self.peer.isVerified { - let statusContent: EmojiStatusComponent.Content = .verified(fillColor: self.presentationTheme.list.itemCheckColors.fillColor, foregroundColor: self.presentationTheme.list.itemCheckColors.foregroundColor, sizeType: .large) + var statusContent: EmojiStatusComponent.Content? + if self.peer.isScam { + statusContent = .text(color: self.presentationTheme.list.itemDestructiveColor, string: self.strings.Message_ScamAccount.uppercased()) + } else if self.peer.isFake { + statusContent = .text(color: self.presentationTheme.list.itemDestructiveColor, string: self.strings.Message_FakeAccount.uppercased()) + } else if self.peer.isVerified { + statusContent = .verified(fillColor: self.presentationTheme.list.itemCheckColors.fillColor, foregroundColor: self.presentationTheme.list.itemCheckColors.foregroundColor, sizeType: .large) + } + + if let statusContent { let titleCredibilityIconTransition: ComponentTransition = .immediate let titleCredibilityIconView: ComponentHostView @@ -247,7 +255,6 @@ private final class WebAppLaunchConfirmationAlertContentNode: AlertContentNode { ) totalWidth += titleIconSize.width + 2.0 - titleCredibilityIconTransition.setFrame(view: titleCredibilityIconView, frame: CGRect(origin: CGPoint(x:floorToScreenPixels((size.width - totalWidth) / 2.0) + titleSize.width + 2.0, y: origin.y), size: titleIconSize)) }