diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 18216f12a..398333e50 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -10425,7 +10425,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 26.08.06; + version = 26.08.07; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3ab4898ca..8907db9bd 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -167,8 +167,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rust-components-swift", "state" : { - "revision" : "bb2701951010f08d39627e99a816f532d42e6f62", - "version" : "26.8.6" + "revision" : "4201e58f36d416dd16673dc7aaebdfbdc90e7d95", + "version" : "26.8.7" } }, { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 23be4f835..f1c3f9128 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -124,9 +124,12 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol } func stop() { - // When navigating away from the room, we need to mark the room as fully read. - // This does not affect the read receipts only the notification count. - Task { await roomProxy.markAsRead(receiptType: .fullyRead) } + Task { + // When navigating away from the room, we need to mark the room as both read + // and fully read for Synapse to clear this room from the app's badge count. + _ = await roomProxy.markAsRead(receiptType: appSettings.sharePresence ? .read : .readPrivate) + _ = await roomProxy.markAsRead(receiptType: .fullyRead) + } // Work around QLPreviewController dismissal issues, see the InteractiveQuickLookModifier. state.bindings.mediaPreviewViewModel = nil } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 90fdcdc89..55f273299 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -362,7 +362,7 @@ class ClientProxy: ClientProxyProtocol { var isLiveKitRTCSupported: Bool { get async { do { - return try await client.isLivekitRtcSupported() + return try await client.isLivekitRtcSupported(fallbackToWellKnown: true) } catch { MXLog.error("Failed checking LiveKit RTC support with error: \(error)") return false diff --git a/SDKMocks/Sources/Generated/SDKGeneratedMocks.swift b/SDKMocks/Sources/Generated/SDKGeneratedMocks.swift index 8844bcfe3..3fd7fc59b 100644 --- a/SDKMocks/Sources/Generated/SDKGeneratedMocks.swift +++ b/SDKMocks/Sources/Generated/SDKGeneratedMocks.swift @@ -1723,34 +1723,48 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { //MARK: - isLivekitRtcSupported - open var isLivekitRtcSupportedThrowableError: Error? - private let isLivekitRtcSupportedCallsCountLock = NSLock() - private var isLivekitRtcSupportedUnderlyingCallsCount = 0 - open var isLivekitRtcSupportedCallsCount: Int { - get { isLivekitRtcSupportedCallsCountLock.withLock { isLivekitRtcSupportedUnderlyingCallsCount } } - set { isLivekitRtcSupportedCallsCountLock.withLock { isLivekitRtcSupportedUnderlyingCallsCount = newValue } } + open var isLivekitRtcSupportedFallbackToWellKnownThrowableError: Error? + private let isLivekitRtcSupportedFallbackToWellKnownCallsCountLock = NSLock() + private var isLivekitRtcSupportedFallbackToWellKnownUnderlyingCallsCount = 0 + open var isLivekitRtcSupportedFallbackToWellKnownCallsCount: Int { + get { isLivekitRtcSupportedFallbackToWellKnownCallsCountLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingCallsCount } } + set { isLivekitRtcSupportedFallbackToWellKnownCallsCountLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingCallsCount = newValue } } } - open var isLivekitRtcSupportedCalled: Bool { - return isLivekitRtcSupportedCallsCount > 0 + open var isLivekitRtcSupportedFallbackToWellKnownCalled: Bool { + return isLivekitRtcSupportedFallbackToWellKnownCallsCount > 0 + } + private let isLivekitRtcSupportedFallbackToWellKnownReceivedFallbackToWellKnownLock = NSLock() + private var isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedFallbackToWellKnown: Bool? + open var isLivekitRtcSupportedFallbackToWellKnownReceivedFallbackToWellKnown: Bool? { + get { isLivekitRtcSupportedFallbackToWellKnownReceivedFallbackToWellKnownLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedFallbackToWellKnown } } + set { isLivekitRtcSupportedFallbackToWellKnownReceivedFallbackToWellKnownLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedFallbackToWellKnown = newValue } } + } + private let isLivekitRtcSupportedFallbackToWellKnownReceivedInvocationsLock = NSLock() + private var isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedInvocations: [Bool] = [] + open var isLivekitRtcSupportedFallbackToWellKnownReceivedInvocations: [Bool] { + get { isLivekitRtcSupportedFallbackToWellKnownReceivedInvocationsLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedInvocations } } + set { isLivekitRtcSupportedFallbackToWellKnownReceivedInvocationsLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedInvocations = newValue } } } - private let isLivekitRtcSupportedReturnValueLock = NSLock() - open var isLivekitRtcSupportedUnderlyingReturnValue: Bool! - open var isLivekitRtcSupportedReturnValue: Bool! { - get { isLivekitRtcSupportedReturnValueLock.withLock { isLivekitRtcSupportedUnderlyingReturnValue } } - set { isLivekitRtcSupportedReturnValueLock.withLock { isLivekitRtcSupportedUnderlyingReturnValue = newValue } } + private let isLivekitRtcSupportedFallbackToWellKnownReturnValueLock = NSLock() + open var isLivekitRtcSupportedFallbackToWellKnownUnderlyingReturnValue: Bool! + open var isLivekitRtcSupportedFallbackToWellKnownReturnValue: Bool! { + get { isLivekitRtcSupportedFallbackToWellKnownReturnValueLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReturnValue } } + set { isLivekitRtcSupportedFallbackToWellKnownReturnValueLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReturnValue = newValue } } } - open var isLivekitRtcSupportedClosure: (() async throws -> Bool)? + open var isLivekitRtcSupportedFallbackToWellKnownClosure: ((Bool) async throws -> Bool)? - open override func isLivekitRtcSupported() async throws -> Bool { - if let error = isLivekitRtcSupportedThrowableError { + open override func isLivekitRtcSupported(fallbackToWellKnown: Bool = false) async throws -> Bool { + if let error = isLivekitRtcSupportedFallbackToWellKnownThrowableError { throw error } - isLivekitRtcSupportedCallsCountLock.withLock { isLivekitRtcSupportedUnderlyingCallsCount += 1 } - if let isLivekitRtcSupportedClosure = isLivekitRtcSupportedClosure { - return try await isLivekitRtcSupportedClosure() + isLivekitRtcSupportedFallbackToWellKnownCallsCountLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingCallsCount += 1 } + isLivekitRtcSupportedFallbackToWellKnownReceivedFallbackToWellKnown = fallbackToWellKnown + isLivekitRtcSupportedFallbackToWellKnownReceivedInvocationsLock.withLock { isLivekitRtcSupportedFallbackToWellKnownUnderlyingReceivedInvocations.append(fallbackToWellKnown) } + if let isLivekitRtcSupportedFallbackToWellKnownClosure = isLivekitRtcSupportedFallbackToWellKnownClosure { + return try await isLivekitRtcSupportedFallbackToWellKnownClosure(fallbackToWellKnown) } else { - return isLivekitRtcSupportedReturnValue + return isLivekitRtcSupportedFallbackToWellKnownReturnValue } } diff --git a/UnitTests/Sources/RoomScreenViewModelTests.swift b/UnitTests/Sources/RoomScreenViewModelTests.swift index 7744059a5..7ec7a762e 100644 --- a/UnitTests/Sources/RoomScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomScreenViewModelTests.swift @@ -11,6 +11,7 @@ import Combine import Foundation import MatrixRustSDK import MatrixRustSDKMocks +import Synchronization import Testing @MainActor @@ -305,10 +306,13 @@ final class RoomScreenViewModelTests { @Test func roomFullyRead() async { - await waitForConfirmation("Wait for fully read") { confirm in + let expectedReceipts: [ReceiptType] = [.read, .fullyRead] + let receivedReceipts = Mutex<[ReceiptType]>([]) + + await waitForConfirmation("Wait for fully read", expectedCount: expectedReceipts.count) { confirm in let roomProxyMock = JoinedRoomProxyMock(.init(id: "MyRoomID")) roomProxyMock.markAsReadReceiptTypeClosure = { readReceiptType in - #expect(readReceiptType == .fullyRead) + receivedReceipts.withLock { $0.append(readReceiptType) } confirm() return .success(()) } @@ -322,6 +326,8 @@ final class RoomScreenViewModelTests { userIndicatorController: UserIndicatorControllerMock()) viewModel.stop() } + + #expect(receivedReceipts.withLock { $0 } == expectedReceipts) } // MARK: - Knock Requests diff --git a/project.yml b/project.yml index 039ed0b50..23abdd29c 100644 --- a/project.yml +++ b/project.yml @@ -74,7 +74,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/element-hq/matrix-rust-components-swift - exactVersion: 26.08.06 + exactVersion: 26.08.07 # path: ../matrix-rust-sdk Compound: path: compound-ios