diff --git a/ElementX/Sources/Application/AppMediator.swift b/ElementX/Sources/Application/AppMediator.swift index bb60ae3ab..720fcabbc 100644 --- a/ElementX/Sources/Application/AppMediator.swift +++ b/ElementX/Sources/Application/AppMediator.swift @@ -18,14 +18,32 @@ import UIKit class AppMediator: AppMediatorProtocol { private let windowManager: WindowManagerProtocol + + init(windowManager: WindowManagerProtocol) { + self.windowManager = windowManager + } // UIApplication.State won't update if we store this e.g. in the constructor private var application: UIApplication { UIApplication.shared } + + @MainActor + var appState: UIApplication.State { + switch application.applicationState { + case .active: + windowManager.mainWindow.traitCollection.activeAppearance == .active ? .active : .inactive + case .inactive: + .inactive + case .background: + .background + default: + .inactive + } + } - init(windowManager: WindowManagerProtocol) { - self.windowManager = windowManager + var backgroundTimeRemaining: TimeInterval { + application.backgroundTimeRemaining } func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier { @@ -47,22 +65,8 @@ class AppMediator: AppMediatorProtocol { open(url) } - - var backgroundTimeRemaining: TimeInterval { - application.backgroundTimeRemaining - } - - @MainActor - var appState: UIApplication.State { - switch application.applicationState { - case .active: - windowManager.mainWindow.traitCollection.activeAppearance == .active ? .active : .inactive - case .inactive: - .inactive - case .background: - .background - default: - .inactive - } + + func setIdleTimerDisabled(_ disabled: Bool) { + application.isIdleTimerDisabled = disabled } } diff --git a/ElementX/Sources/Application/AppMediatorProtocol.swift b/ElementX/Sources/Application/AppMediatorProtocol.swift index e9387cad3..7812d2d8d 100644 --- a/ElementX/Sources/Application/AppMediatorProtocol.swift +++ b/ElementX/Sources/Application/AppMediatorProtocol.swift @@ -19,6 +19,10 @@ import UIKit // sourcery: AutoMockable protocol AppMediatorProtocol { + var appState: UIApplication.State { get } + + var backgroundTimeRemaining: TimeInterval { get } + func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier) @@ -26,10 +30,8 @@ protocol AppMediatorProtocol { func open(_ url: URL) func openAppSettings() - - var backgroundTimeRemaining: TimeInterval { get } - - var appState: UIApplication.State { get } + + func setIdleTimerDisabled(_ disabled: Bool) } extension UIApplication.State: CustomStringConvertible { diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 5b40afb16..e4de14ff6 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -748,16 +748,16 @@ class AppLockServiceMock: AppLockServiceProtocol { } } class AppMediatorMock: AppMediatorProtocol { - var backgroundTimeRemaining: TimeInterval { - get { return underlyingBackgroundTimeRemaining } - set(value) { underlyingBackgroundTimeRemaining = value } - } - var underlyingBackgroundTimeRemaining: TimeInterval! var appState: UIApplication.State { get { return underlyingAppState } set(value) { underlyingAppState = value } } var underlyingAppState: UIApplication.State! + var backgroundTimeRemaining: TimeInterval { + get { return underlyingBackgroundTimeRemaining } + set(value) { underlyingBackgroundTimeRemaining = value } + } + var underlyingBackgroundTimeRemaining: TimeInterval! //MARK: - beginBackgroundTask @@ -936,6 +936,45 @@ class AppMediatorMock: AppMediatorProtocol { openAppSettingsCallsCount += 1 openAppSettingsClosure?() } + //MARK: - setIdleTimerDisabled + + var setIdleTimerDisabledUnderlyingCallsCount = 0 + var setIdleTimerDisabledCallsCount: Int { + get { + if Thread.isMainThread { + return setIdleTimerDisabledUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = setIdleTimerDisabledUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + setIdleTimerDisabledUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + setIdleTimerDisabledUnderlyingCallsCount = newValue + } + } + } + } + var setIdleTimerDisabledCalled: Bool { + return setIdleTimerDisabledCallsCount > 0 + } + var setIdleTimerDisabledReceivedDisabled: Bool? + var setIdleTimerDisabledReceivedInvocations: [Bool] = [] + var setIdleTimerDisabledClosure: ((Bool) -> Void)? + + func setIdleTimerDisabled(_ disabled: Bool) { + setIdleTimerDisabledCallsCount += 1 + setIdleTimerDisabledReceivedDisabled = disabled + setIdleTimerDisabledReceivedInvocations.append(disabled) + setIdleTimerDisabledClosure?(disabled) + } } class AudioConverterMock: AudioConverterProtocol { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift index c5e746538..74c460f3f 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift @@ -50,7 +50,12 @@ class RoomScreenInteractionHandler { actionsSubject.eraseToAnyPublisher() } - private var voiceMessageRecorderObserver: AnyCancellable? + private var voiceMessageRecorderObserver: AnyCancellable? { + didSet { + appMediator.setIdleTimerDisabled(voiceMessageRecorderObserver != nil) + } + } + private var canCurrentUserRedactOthers = false private var canCurrentUserRedactSelf = false private var resumeVoiceMessagePlaybackAfterScrubbing = false @@ -405,6 +410,7 @@ class RoomScreenInteractionHandler { func stopRecordingVoiceMessage() async { await voiceMessageRecorder.stopRecording() + voiceMessageRecorderObserver = nil } func cancelRecordingVoiceMessage() async { diff --git a/changelog.d/2707.change b/changelog.d/2707.change new file mode 100644 index 000000000..1cb67f3d8 --- /dev/null +++ b/changelog.d/2707.change @@ -0,0 +1 @@ +Prevent the app from locking while recording a voice message \ No newline at end of file