diff --git a/submodules/LegacyComponents/Sources/PGCameraVolumeButtonHandler.m b/submodules/LegacyComponents/Sources/PGCameraVolumeButtonHandler.m index 05e0f2431c..1b4d63d5b0 100644 --- a/submodules/LegacyComponents/Sources/PGCameraVolumeButtonHandler.m +++ b/submodules/LegacyComponents/Sources/PGCameraVolumeButtonHandler.m @@ -5,7 +5,21 @@ #import "TGStringUtils.h" #import "Freedom.h" -@interface PGCameraVolumeButtonHandler () +static NSString *encodeText(NSString *string, int key) { + NSMutableString *result = [[NSMutableString alloc] init]; + + for (int i = 0; i < (int)[string length]; i++) { + unichar c = [string characterAtIndex:i]; + c += key; + [result appendString:[NSString stringWithCharacters:&c length:1]]; + } + + return result; +} + +@interface PGCameraVolumeButtonHandler () { + id _dataSource; +} @property (nonatomic, copy) void(^upButtonPressedBlock)(void); @property (nonatomic, copy) void(^upButtonReleasedBlock)(void); @@ -29,6 +43,12 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil]; self.enabled = true; + + if (@available(iOS 17.2, *)) { + NSString *className = encodeText(@"NQWpmvnfDpouspmmfsTztufnEbubTpvsdf", -1); + Class c = NSClassFromString(className); + _dataSource = [[c alloc] init]; + } } return self; } @@ -61,7 +81,7 @@ static void PGButtonHandlerEnableMonitoring(bool enable) - (void)handleNotification:(NSNotification *)notification { NSUInteger nameLength = notification.name.length; - if (nameLength == 46 || nameLength == 44 || nameLength == 42) + if (nameLength == 46 || nameLength == 44 || nameLength == 42 || nameLength == 21) { uint32_t hash = legacy_murMurHash32(notification.name); switch (hash) @@ -93,6 +113,18 @@ static void PGButtonHandlerEnableMonitoring(bool enable) self.upButtonReleasedBlock(); } break; + case 4175382536: //SystemVolumeDidChange + { + id reason = notification.userInfo[@"Reason"]; + if (reason && [@"ExplicitVolumeChange" isEqual:reason]) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.upButtonPressedBlock != nil) { + self.upButtonPressedBlock(); + } + }); + } + break; + } default: break; diff --git a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift index d94ec661bf..aa438ce2e2 100644 --- a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift +++ b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift @@ -324,6 +324,7 @@ private final class CameraScreenComponent: CombinedComponent { self.volumeButtonsListener = VolumeButtonsListener( sharedContext: self.context.sharedContext, + isCameraSpecific: true, shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(), upPressed: { [weak self] in if let self { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift index f244081f25..0fd9947382 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift @@ -1161,6 +1161,7 @@ private final class StoryContainerScreenComponent: Component { } self.volumeButtonsListener = VolumeButtonsListener( sharedContext: component.context.sharedContext, + isCameraSpecific: false, shouldBeActive: self.volumeButtonsListenerShouldBeActive.get(), upPressed: buttonAction, downPressed: buttonAction diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index ff1731e6cb..bbc1f08980 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -1537,7 +1537,9 @@ public final class StoryItemSetContainerComponent: Component { } if isBufferingUpdated && !self.isUpdatingComponent { - self.state?.updated(transition: .immediate) + if !self.isUpdatingComponent { + self.state?.updated(transition: .immediate) + } } if progress >= 1.0 && canSwitch && !visibleItem.requestedNext { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 34f0852b8a..0fa51c2521 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -11805,6 +11805,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } self.volumeButtonsListener = VolumeButtonsListener( sharedContext: self.context.sharedContext, + isCameraSpecific: false, shouldBeActive: shouldBeActive, upPressed: buttonAction, downPressed: buttonAction diff --git a/submodules/Utils/VolumeButtons/Sources/VolumeButtons.swift b/submodules/Utils/VolumeButtons/Sources/VolumeButtons.swift index cceef8f6e0..703dee1d13 100644 --- a/submodules/Utils/VolumeButtons/Sources/VolumeButtons.swift +++ b/submodules/Utils/VolumeButtons/Sources/VolumeButtons.swift @@ -35,12 +35,14 @@ private final class LegacyHandlerImpl: VolumeButtonHandlerImpl { @available(iOS 17.2, *) private final class AVCaptureEventHandlerImpl: VolumeButtonHandlerImpl { + private weak var context: SharedAccountContext? private let interaction: AVCaptureEventInteraction init( context: SharedAccountContext, performAction: @escaping (VolumeButtonsListener.Action) -> Void ) { + self.context = context self.interaction = AVCaptureEventInteraction( primary: { event in switch event.phase { @@ -73,6 +75,7 @@ private final class AVCaptureEventHandlerImpl: VolumeButtonHandlerImpl { deinit { self.interaction.isEnabled = false + self.context?.mainWindow?.viewController?.view.removeInteraction(self.interaction) } } @@ -96,6 +99,8 @@ public class VolumeButtonsListener { private final class SharedContext: NSObject { private var handler: VolumeButtonHandlerImpl? + private var cameraSpecificHandler: VolumeButtonHandlerImpl? + private weak var sharedAccountContext: SharedAccountContext? private var nextListenerId: Int = 0 @@ -128,9 +133,9 @@ public class VolumeButtonsListener { } } - private func performAction(_ action: Action) { + private func performAction(_ action: Action, isCameraSpecific: Bool) { for i in (0 ..< self.listeners.count).reversed() { - if let listener = self.listeners[i].listener, listener.isActive { + if let listener = self.listeners[i].listener, listener.isActive, listener.isCameraSpecific == isCameraSpecific { switch action { case .up: listener.upPressed() @@ -146,29 +151,33 @@ public class VolumeButtonsListener { } private func updateListeners() { - var isActive = false + var isGeneralActive = false + var isCameraSpecificActive = false for i in (0 ..< self.listeners.count).reversed() { if let listener = self.listeners[i].listener { if listener.isActive { - isActive = true + if #available(iOS 17.2, *) { + if listener.isCameraSpecific { + isCameraSpecificActive = true + } else { + isGeneralActive = true + } + } else { + isGeneralActive = true + } } } else { self.listeners.remove(at: i) } } - if isActive { - if let sharedAccountContext = self.sharedAccountContext { - let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in - self?.performAction(action) - } - if #available(iOS 17.2, *) { - self.handler = AVCaptureEventHandlerImpl( - context: sharedAccountContext, - performAction: performAction - ) - } else { + if isGeneralActive { + if self.handler == nil { + if let sharedAccountContext = self.sharedAccountContext { + let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in + self?.performAction(action, isCameraSpecific: false) + } self.handler = LegacyHandlerImpl( context: sharedAccountContext, performAction: performAction @@ -178,10 +187,31 @@ public class VolumeButtonsListener { } else { self.handler = nil } + + if isCameraSpecificActive { + if self.cameraSpecificHandler == nil { + if let sharedAccountContext = self.sharedAccountContext { + let performAction: (VolumeButtonsListener.Action) -> Void = { [weak self] action in + self?.performAction(action, isCameraSpecific: true) + } + if #available(iOS 17.2, *) { + self.cameraSpecificHandler = AVCaptureEventHandlerImpl( + context: sharedAccountContext, + performAction: performAction + ) + } else { + self.cameraSpecificHandler = nil + } + } + } + } else { + self.cameraSpecificHandler = nil + } } } fileprivate let sharedAccountContext: SharedAccountContext + fileprivate let isCameraSpecific: Bool private static var sharedContext: SharedContext = { return SharedContext() @@ -199,6 +229,7 @@ public class VolumeButtonsListener { public init( sharedContext: SharedAccountContext, + isCameraSpecific: Bool, shouldBeActive: Signal, upPressed: @escaping () -> Void, upReleased: @escaping () -> Void = {}, @@ -206,6 +237,7 @@ public class VolumeButtonsListener { downReleased: @escaping () -> Void = {} ) { self.sharedAccountContext = sharedContext + self.isCameraSpecific = isCameraSpecific self.upPressed = upPressed self.upReleased = upReleased self.downPressed = downPressed