diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 6ee55d1c3..0b94ec3bf 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -548,6 +548,7 @@ 6C98153D60FF9B648C166C27 /* TimelineItemMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91FFE1F410969ECB23FE9BB2 /* TimelineItemMenu.swift */; }; 6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3005886F00029F058DB62BE /* StartChatScreenCoordinator.swift */; }; 6DC8E43BA04AC2AC4EB2EB97 /* AnalyticsPromptScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18486B87745B1811E7FBD3D2 /* AnalyticsPromptScreenModels.swift */; }; + 6E03A710799E6C65C0AB36BC /* TargetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D829FD8958376614504B18 /* TargetConfiguration.swift */; }; 6E391F7F628D984AF44385D9 /* RoomAttachmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 128501375217576AF0FE3E92 /* RoomAttachmentPicker.swift */; }; 6E47D126DD7585E8F8237CE7 /* LoadableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */; }; 6E4E401BE97AC241DA7C7716 /* AppLockSetupSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502F986D57158674172C58E3 /* AppLockSetupSettingsScreenModels.swift */; }; @@ -691,6 +692,7 @@ 8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */; }; 88356DE7F2AD243AB10C7B7A /* Signposter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752A0EB49BF5BCEA37EDF7A3 /* Signposter.swift */; }; 887AC93C523AEFB640EA5EC8 /* TextBasedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E33FD32BBC44D703C7AE4F9 /* TextBasedRoomTimelineItem.swift */; }; + 88A3FBBC3D67996863DB9CAF /* TargetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D829FD8958376614504B18 /* TargetConfiguration.swift */; }; 88CBF1595E39CE697928DE48 /* SFNumberedListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB5FF7A09B79B0C6B528F7C /* SFNumberedListView.swift */; }; 88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */; }; 890F0D453FE388756479AC97 /* AnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C687844F60BFF532D49A994C /* AnalyticsTests.swift */; }; @@ -961,6 +963,7 @@ C02DE5F62C81FB9E173C3D2F /* TimelineMediaPreviewDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0AD0C652385F69FA90FAF5 /* TimelineMediaPreviewDataSourceTests.swift */; }; C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B99E13633862847D8B7E2815 /* StartChatScreenModels.swift */; }; C08AAE7563E0722C9383F51C /* RoomMembersListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B8E176484A89BAC389D4076 /* RoomMembersListScreen.swift */; }; + C097D5453640E27D397943CB /* TargetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D829FD8958376614504B18 /* TargetConfiguration.swift */; }; C0B97FFEC0083F3A36609E61 /* TimelineItemMacContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = A243A6E6207297123E60DE48 /* TimelineItemMacContextMenu.swift */; }; C11939FDC40716C4387275A4 /* NotificationSettingsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */; }; C11D4A49DC29D89CE2BB31B8 /* MediaEventsTimelineScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976ED77B772F50C4BAD757E7 /* MediaEventsTimelineScreenViewModel.swift */; }; @@ -2215,6 +2218,7 @@ B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = ""; }; B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; + B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = ""; }; B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = ""; }; @@ -3056,7 +3060,6 @@ isa = PBXGroup; children = ( 01C4C7DB37597D7D8379511A /* Assets.xcassets */, - D174C6E7DCA00AAFC0169925 /* ElementCall */, A0C06C0F6A8621B22BFAEB56 /* Localizations */, 8AEA6A91159FA0D3EAFCCB0D /* Sounds */, ); @@ -5057,6 +5060,7 @@ B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */, 7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */, 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */, + B5D829FD8958376614504B18 /* TargetConfiguration.swift */, 780F74C73E826685A9DB289B /* Navigation */, 703929219780FFABAC6380AA /* Windowing */, ); @@ -5491,13 +5495,6 @@ path = ShareExtension; sourceTree = ""; }; - D174C6E7DCA00AAFC0169925 /* ElementCall */ = { - isa = PBXGroup; - children = ( - ); - path = ElementCall; - sourceTree = ""; - }; D382E465AF067C1BF888BF8E /* View */ = { isa = PBXGroup; children = ( @@ -6640,6 +6637,7 @@ 7573D682F089205F7F1D96CF /* SessionDirectories.swift in Sources */, 422E8D182CA688D4565CD1E1 /* String.swift in Sources */, 6EC7A40A537CFB3D526A111C /* Strings.swift in Sources */, + 88A3FBBC3D67996863DB9CAF /* TargetConfiguration.swift in Sources */, 719E7AAD1F8E68F68F30FECD /* Task.swift in Sources */, E0FB26262689F04D66A949D7 /* TestablePreview.swift in Sources */, B81840E45D8746A4692DA774 /* Tracing.swift in Sources */, @@ -6812,6 +6810,7 @@ DAF63A9CF9932CA8F6830F11 /* ShareExtensionModels.swift in Sources */, 5AA81A4E2D40A32A9E7F71F2 /* ShareExtensionView.swift in Sources */, 5AC5CD6D893073EE4D9A277E /* ShareExtensionViewController.swift in Sources */, + 6E03A710799E6C65C0AB36BC /* TargetConfiguration.swift in Sources */, 89DF67AECBF9D0EE0DDB7737 /* Tracing.swift in Sources */, 03BD83E8BDD23AE059802E0D /* UITestsScreenIdentifier.swift in Sources */, 26252AA9AED64010788F4C26 /* UIView.swift in Sources */, @@ -7567,6 +7566,7 @@ 066A1E9B94723EE9F3038044 /* Strings.swift in Sources */, FF34BF2AF731340AF9414A18 /* SwipeRightAction.swift in Sources */, 3B98049F56025726FB646ABD /* SwipeToReplyView.swift in Sources */, + C097D5453640E27D397943CB /* TargetConfiguration.swift in Sources */, E290C78E7F09F47FD2662986 /* Task.swift in Sources */, 1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */, 47305C0911C9E1AA774A4000 /* TemplateScreenCoordinator.swift in Sources */, @@ -8549,7 +8549,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 25.03.06; + version = 25.03.13; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index aa0295c09..992843531 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -149,8 +149,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rust-components-swift", "state" : { - "revision" : "861fdd7ca4c4ca94de386c6b9b0b7d648944c0bb", - "version" : "25.3.6" + "revision" : "8f2da37eb65525a62b33c93edb41549ad94107e3", + "version" : "25.3.13" } }, { diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index e8b436ef9..605f28feb 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -69,7 +69,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg let appSettings = appHooks.appSettingsHook.configure(AppSettings()) - MXLog.configure(currentTarget: "elementx", filePrefix: nil, logLevel: appSettings.logLevel) + Target.mainApp.configure(logLevel: appSettings.logLevel) let appName = InfoPlistReader.main.bundleDisplayName let appVersion = InfoPlistReader.main.bundleShortVersionString diff --git a/ElementX/Sources/Application/TargetConfiguration.swift b/ElementX/Sources/Application/TargetConfiguration.swift new file mode 100644 index 000000000..c929e2ffe --- /dev/null +++ b/ElementX/Sources/Application/TargetConfiguration.swift @@ -0,0 +1,42 @@ +// +// Copyright 2022-2024 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import MatrixRustSDK + +enum Target: String { + case mainApp = "elementx" + case nse + case shareExtension = "shareextension" + case tests + + private static var isConfigured = false + + func configure(logLevel: LogLevel) { + guard !Self.isConfigured else { + return + } + + switch self { + case .mainApp: + let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, currentTarget: rawValue, filePrefix: nil) + initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: false) + case .nse: + let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, currentTarget: rawValue, filePrefix: rawValue) + initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: true) + case .shareExtension: + let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, currentTarget: rawValue, filePrefix: rawValue) + initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: true) + case .tests: + let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, currentTarget: rawValue, filePrefix: rawValue) + initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: false) + } + + MXLog.configure(currentTarget: rawValue) + + Self.isConfigured = true + } +} diff --git a/ElementX/Sources/Mocks/BannedRoomProxyMock.swift b/ElementX/Sources/Mocks/BannedRoomProxyMock.swift index 8d327b05c..54be2a298 100644 --- a/ElementX/Sources/Mocks/BannedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/BannedRoomProxyMock.swift @@ -29,6 +29,7 @@ extension BannedRoomProxyMock { extension RoomInfo { @MainActor init(_ configuration: BannedRoomProxyMockConfiguration) { self.init(id: configuration.id, + encryptionState: .notEncrypted, creator: nil, displayName: configuration.name, rawName: nil, diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index bb5db1e65..763247f87 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -6212,11 +6212,6 @@ class InvitedRoomProxyMock: InvitedRoomProxyProtocol, @unchecked Sendable { } } class JoinedRoomProxyMock: JoinedRoomProxyProtocol, @unchecked Sendable { - var isEncrypted: Bool { - get { return underlyingIsEncrypted } - set(value) { underlyingIsEncrypted = value } - } - var underlyingIsEncrypted: Bool! var infoPublisher: CurrentValuePublisher { get { return underlyingInfoPublisher } set(value) { underlyingInfoPublisher = value } diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index bd497c429..bbc3c250e 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -473,15 +473,15 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { } } } - open var cachedAvatarUrlClosure: (() throws -> String?)? + open var cachedAvatarUrlClosure: (() async throws -> String?)? - open override func cachedAvatarUrl() throws -> String? { + open override func cachedAvatarUrl() async throws -> String? { if let error = cachedAvatarUrlThrowableError { throw error } cachedAvatarUrlCallsCount += 1 if let cachedAvatarUrlClosure = cachedAvatarUrlClosure { - return try cachedAvatarUrlClosure() + return try await cachedAvatarUrlClosure() } else { return cachedAvatarUrlReturnValue } @@ -1404,12 +1404,12 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { } } } - open var getNotificationSettingsClosure: (() -> NotificationSettings)? + open var getNotificationSettingsClosure: (() async -> NotificationSettings)? - open override func getNotificationSettings() -> NotificationSettings { + open override func getNotificationSettings() async -> NotificationSettings { getNotificationSettingsCallsCount += 1 if let getNotificationSettingsClosure = getNotificationSettingsClosure { - return getNotificationSettingsClosure() + return await getNotificationSettingsClosure() } else { return getNotificationSettingsReturnValue } @@ -1559,6 +1559,81 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { } } + //MARK: - getRoom + + open var getRoomRoomIdThrowableError: Error? + var getRoomRoomIdUnderlyingCallsCount = 0 + open var getRoomRoomIdCallsCount: Int { + get { + if Thread.isMainThread { + return getRoomRoomIdUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = getRoomRoomIdUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + getRoomRoomIdUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + getRoomRoomIdUnderlyingCallsCount = newValue + } + } + } + } + open var getRoomRoomIdCalled: Bool { + return getRoomRoomIdCallsCount > 0 + } + open var getRoomRoomIdReceivedRoomId: String? + open var getRoomRoomIdReceivedInvocations: [String] = [] + + var getRoomRoomIdUnderlyingReturnValue: Room? + open var getRoomRoomIdReturnValue: Room? { + get { + if Thread.isMainThread { + return getRoomRoomIdUnderlyingReturnValue + } else { + var returnValue: Room?? = nil + DispatchQueue.main.sync { + returnValue = getRoomRoomIdUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + getRoomRoomIdUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + getRoomRoomIdUnderlyingReturnValue = newValue + } + } + } + } + open var getRoomRoomIdClosure: ((String) throws -> Room?)? + + open override func getRoom(roomId: String) throws -> Room? { + if let error = getRoomRoomIdThrowableError { + throw error + } + getRoomRoomIdCallsCount += 1 + getRoomRoomIdReceivedRoomId = roomId + DispatchQueue.main.async { + self.getRoomRoomIdReceivedInvocations.append(roomId) + } + if let getRoomRoomIdClosure = getRoomRoomIdClosure { + return try getRoomRoomIdClosure(roomId) + } else { + return getRoomRoomIdReturnValue + } + } + //MARK: - getRoomPreviewFromRoomAlias open var getRoomPreviewFromRoomAliasRoomAliasThrowableError: Error? @@ -4111,8 +4186,8 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { open var urlForOidcOidcConfigurationPromptCalled: Bool { return urlForOidcOidcConfigurationPromptCallsCount > 0 } - open var urlForOidcOidcConfigurationPromptReceivedArguments: (oidcConfiguration: OidcConfiguration, prompt: OidcPrompt)? - open var urlForOidcOidcConfigurationPromptReceivedInvocations: [(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt)] = [] + open var urlForOidcOidcConfigurationPromptReceivedArguments: (oidcConfiguration: OidcConfiguration, prompt: OidcPrompt?)? + open var urlForOidcOidcConfigurationPromptReceivedInvocations: [(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt?)] = [] var urlForOidcOidcConfigurationPromptUnderlyingReturnValue: OidcAuthorizationData! open var urlForOidcOidcConfigurationPromptReturnValue: OidcAuthorizationData! { @@ -4138,9 +4213,9 @@ open class ClientSDKMock: MatrixRustSDK.Client, @unchecked Sendable { } } } - open var urlForOidcOidcConfigurationPromptClosure: ((OidcConfiguration, OidcPrompt) async throws -> OidcAuthorizationData)? + open var urlForOidcOidcConfigurationPromptClosure: ((OidcConfiguration, OidcPrompt?) async throws -> OidcAuthorizationData)? - open override func urlForOidc(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt) async throws -> OidcAuthorizationData { + open override func urlForOidc(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt?) async throws -> OidcAuthorizationData { if let error = urlForOidcOidcConfigurationPromptThrowableError { throw error } @@ -11486,6 +11561,71 @@ open class RoomSDKMock: MatrixRustSDK.Room, @unchecked Sendable { enableSendQueueEnableClosure?(enable) } + //MARK: - encryptionState + + var encryptionStateUnderlyingCallsCount = 0 + open var encryptionStateCallsCount: Int { + get { + if Thread.isMainThread { + return encryptionStateUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = encryptionStateUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + encryptionStateUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + encryptionStateUnderlyingCallsCount = newValue + } + } + } + } + open var encryptionStateCalled: Bool { + return encryptionStateCallsCount > 0 + } + + var encryptionStateUnderlyingReturnValue: EncryptionState! + open var encryptionStateReturnValue: EncryptionState! { + get { + if Thread.isMainThread { + return encryptionStateUnderlyingReturnValue + } else { + var returnValue: EncryptionState? = nil + DispatchQueue.main.sync { + returnValue = encryptionStateUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + encryptionStateUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + encryptionStateUnderlyingReturnValue = newValue + } + } + } + } + open var encryptionStateClosure: (() -> EncryptionState)? + + open override func encryptionState() -> EncryptionState { + encryptionStateCallsCount += 1 + if let encryptionStateClosure = encryptionStateClosure { + return encryptionStateClosure() + } else { + return encryptionStateReturnValue + } + } + //MARK: - forget open var forgetThrowableError: Error? @@ -12062,71 +12202,6 @@ open class RoomSDKMock: MatrixRustSDK.Room, @unchecked Sendable { } } - //MARK: - inviter - - var inviterUnderlyingCallsCount = 0 - open var inviterCallsCount: Int { - get { - if Thread.isMainThread { - return inviterUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = inviterUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - inviterUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - inviterUnderlyingCallsCount = newValue - } - } - } - } - open var inviterCalled: Bool { - return inviterCallsCount > 0 - } - - var inviterUnderlyingReturnValue: RoomMember? - open var inviterReturnValue: RoomMember? { - get { - if Thread.isMainThread { - return inviterUnderlyingReturnValue - } else { - var returnValue: RoomMember?? = nil - DispatchQueue.main.sync { - returnValue = inviterUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - inviterUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - inviterUnderlyingReturnValue = newValue - } - } - } - } - open var inviterClosure: (() async -> RoomMember?)? - - open override func inviter() async -> RoomMember? { - inviterCallsCount += 1 - if let inviterClosure = inviterClosure { - return await inviterClosure() - } else { - return inviterReturnValue - } - } - //MARK: - isDirect var isDirectUnderlyingCallsCount = 0 @@ -12181,86 +12256,17 @@ open class RoomSDKMock: MatrixRustSDK.Room, @unchecked Sendable { } } } - open var isDirectClosure: (() -> Bool)? + open var isDirectClosure: (() async -> Bool)? - open override func isDirect() -> Bool { + open override func isDirect() async -> Bool { isDirectCallsCount += 1 if let isDirectClosure = isDirectClosure { - return isDirectClosure() + return await isDirectClosure() } else { return isDirectReturnValue } } - //MARK: - isEncrypted - - open var isEncryptedThrowableError: Error? - var isEncryptedUnderlyingCallsCount = 0 - open var isEncryptedCallsCount: Int { - get { - if Thread.isMainThread { - return isEncryptedUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isEncryptedUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isEncryptedUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isEncryptedUnderlyingCallsCount = newValue - } - } - } - } - open var isEncryptedCalled: Bool { - return isEncryptedCallsCount > 0 - } - - var isEncryptedUnderlyingReturnValue: Bool! - open var isEncryptedReturnValue: Bool! { - get { - if Thread.isMainThread { - return isEncryptedUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isEncryptedUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isEncryptedUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isEncryptedUnderlyingReturnValue = newValue - } - } - } - } - open var isEncryptedClosure: (() throws -> Bool)? - - open override func isEncrypted() throws -> Bool { - if let error = isEncryptedThrowableError { - throw error - } - isEncryptedCallsCount += 1 - if let isEncryptedClosure = isEncryptedClosure { - return try isEncryptedClosure() - } else { - return isEncryptedReturnValue - } - } - //MARK: - isPublic var isPublicUnderlyingCallsCount = 0 @@ -12672,6 +12678,75 @@ open class RoomSDKMock: MatrixRustSDK.Room, @unchecked Sendable { try await kickUserUserIdReasonClosure?(userId, reason) } + //MARK: - latestEncryptionState + + open var latestEncryptionStateThrowableError: Error? + var latestEncryptionStateUnderlyingCallsCount = 0 + open var latestEncryptionStateCallsCount: Int { + get { + if Thread.isMainThread { + return latestEncryptionStateUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = latestEncryptionStateUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + latestEncryptionStateUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + latestEncryptionStateUnderlyingCallsCount = newValue + } + } + } + } + open var latestEncryptionStateCalled: Bool { + return latestEncryptionStateCallsCount > 0 + } + + var latestEncryptionStateUnderlyingReturnValue: EncryptionState! + open var latestEncryptionStateReturnValue: EncryptionState! { + get { + if Thread.isMainThread { + return latestEncryptionStateUnderlyingReturnValue + } else { + var returnValue: EncryptionState? = nil + DispatchQueue.main.sync { + returnValue = latestEncryptionStateUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + latestEncryptionStateUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + latestEncryptionStateUnderlyingReturnValue = newValue + } + } + } + } + open var latestEncryptionStateClosure: (() async throws -> EncryptionState)? + + open override func latestEncryptionState() async throws -> EncryptionState { + if let error = latestEncryptionStateThrowableError { + throw error + } + latestEncryptionStateCallsCount += 1 + if let latestEncryptionStateClosure = latestEncryptionStateClosure { + return try await latestEncryptionStateClosure() + } else { + return latestEncryptionStateReturnValue + } + } + //MARK: - leave open var leaveThrowableError: Error? @@ -16880,75 +16955,6 @@ open class RoomListItemSDKMock: MatrixRustSDK.RoomListItem, @unchecked Sendable try await initTimelineEventTypeFilterInternalIdPrefixClosure?(eventTypeFilter, internalIdPrefix) } - //MARK: - invitedRoom - - open var invitedRoomThrowableError: Error? - var invitedRoomUnderlyingCallsCount = 0 - open var invitedRoomCallsCount: Int { - get { - if Thread.isMainThread { - return invitedRoomUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = invitedRoomUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - invitedRoomUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - invitedRoomUnderlyingCallsCount = newValue - } - } - } - } - open var invitedRoomCalled: Bool { - return invitedRoomCallsCount > 0 - } - - var invitedRoomUnderlyingReturnValue: Room! - open var invitedRoomReturnValue: Room! { - get { - if Thread.isMainThread { - return invitedRoomUnderlyingReturnValue - } else { - var returnValue: Room? = nil - DispatchQueue.main.sync { - returnValue = invitedRoomUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - invitedRoomUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - invitedRoomUnderlyingReturnValue = newValue - } - } - } - } - open var invitedRoomClosure: (() throws -> Room)? - - open override func invitedRoom() throws -> Room { - if let error = invitedRoomThrowableError { - throw error - } - invitedRoomCallsCount += 1 - if let invitedRoomClosure = invitedRoomClosure { - return try invitedRoomClosure() - } else { - return invitedRoomReturnValue - } - } - //MARK: - isDirect var isDirectUnderlyingCallsCount = 0 @@ -17003,12 +17009,12 @@ open class RoomListItemSDKMock: MatrixRustSDK.RoomListItem, @unchecked Sendable } } } - open var isDirectClosure: (() -> Bool)? + open var isDirectClosure: (() async -> Bool)? - open override func isDirect() -> Bool { + open override func isDirect() async -> Bool { isDirectCallsCount += 1 if let isDirectClosure = isDirectClosure { - return isDirectClosure() + return await isDirectClosure() } else { return isDirectReturnValue } diff --git a/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift b/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift index 35df16145..2edea75cc 100644 --- a/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift @@ -33,6 +33,7 @@ extension InvitedRoomProxyMock { extension RoomInfo { @MainActor init(_ configuration: InvitedRoomProxyMockConfiguration) { self.init(id: configuration.id, + encryptionState: .notEncrypted, creator: nil, displayName: configuration.name, rawName: nil, diff --git a/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift b/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift index 7d4030f1d..6573a1b0a 100644 --- a/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift @@ -52,8 +52,7 @@ extension JoinedRoomProxyMock { self.init() id = configuration.id - isEncrypted = configuration.isEncrypted - + timeline = TimelineProxyMock(.init(isAutoUpdating: configuration.shouldUseAutoUpdatingTimeline, timelineStartReached: configuration.timelineStartReached)) @@ -137,6 +136,7 @@ extension JoinedRoomProxyMock { extension RoomInfo { @MainActor init(_ configuration: JoinedRoomProxyMockConfiguration) { self.init(id: configuration.id, + encryptionState: configuration.isEncrypted ? .encrypted : .notEncrypted, creator: nil, displayName: configuration.name, rawName: configuration.name, diff --git a/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift b/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift index 241a446cd..02db85717 100644 --- a/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift @@ -29,6 +29,7 @@ extension KnockedRoomProxyMock { extension RoomInfo { @MainActor init(_ configuration: KnockedRoomProxyMockConfiguration) { self.init(id: configuration.id, + encryptionState: .notEncrypted, creator: nil, displayName: configuration.name, rawName: nil, diff --git a/ElementX/Sources/Other/Logging/ExtensionLogger.swift b/ElementX/Sources/Other/Logging/ExtensionLogger.swift index 99ee45858..bbc31b699 100644 --- a/ElementX/Sources/Other/Logging/ExtensionLogger.swift +++ b/ElementX/Sources/Other/Logging/ExtensionLogger.swift @@ -9,8 +9,6 @@ import Foundation import MatrixRustSDK enum ExtensionLogger { - private static var isConfigured = false - /// Memory formatter, uses exact 2 fraction digits and no grouping private static var numberFormatter: NumberFormatter { let formatter = NumberFormatter() @@ -66,15 +64,6 @@ enum ExtensionLogger { return "\(formattedStr) MB" } - static func configure(currentTarget: String, logLevel: LogLevel) { - guard !isConfigured else { - return - } - isConfigured = true - - MXLog.configure(currentTarget: currentTarget, filePrefix: currentTarget, logLevel: logLevel) - } - static func logMemory(with tag: String) { MXLog.info("\(tag) Memory: footprint: \(formattedMemoryFootprint) - available: \(formattedMemoryAvailable)") } diff --git a/ElementX/Sources/Other/Logging/MXLog.swift b/ElementX/Sources/Other/Logging/MXLog.swift index d24fdf3dc..36d797f30 100644 --- a/ElementX/Sources/Other/Logging/MXLog.swift +++ b/ElementX/Sources/Other/Logging/MXLog.swift @@ -14,29 +14,14 @@ import MatrixRustSDK Its purpose is to provide a common entry for customizing logging and should be used throughout the code. */ enum MXLog { - private enum Constants { - static let target = "elementx" - } - - // Rust side crashes if invoking setupTracing multiple times - private static var didConfigureOnce = false - private static var rootSpan: Span! private static var currentTarget: String! - static func configure(currentTarget: String, - filePrefix: String?, - logLevel: LogLevel) { - guard !didConfigureOnce else { return } - - Tracing.setup(logLevel: logLevel, currentTarget: currentTarget, filePrefix: filePrefix) - + static func configure(currentTarget: String) { self.currentTarget = currentTarget rootSpan = Span(file: #file, line: #line, level: .info, target: self.currentTarget, name: "root") rootSpan.enter() - - didConfigureOnce = true } static func createSpan(_ name: String, @@ -134,10 +119,6 @@ enum MXLog { function: String = #function, line: Int = #line, column: Int = #column) -> Span { - guard didConfigureOnce else { - fatalError() - } - if Span.current().isNone() { rootSpan.enter() } @@ -152,7 +133,7 @@ enum MXLog { function: String = #function, line: Int = #line, column: Int = #column) { - guard didConfigureOnce else { + guard let rootSpan else { return } diff --git a/ElementX/Sources/Other/Logging/Tracing.swift b/ElementX/Sources/Other/Logging/Tracing.swift index 659f7cdd8..0f798ab70 100644 --- a/ElementX/Sources/Other/Logging/Tracing.swift +++ b/ElementX/Sources/Other/Logging/Tracing.swift @@ -23,7 +23,7 @@ enum Tracing { static let fileExtension = "log" - static func setup(logLevel: LogLevel, currentTarget: String, filePrefix: String?) { + static func buildConfiguration(logLevel: LogLevel, currentTarget: String, filePrefix: String?) -> TracingConfiguration { let fileName = if let filePrefix { "\(Tracing.filePrefix)-\(filePrefix)" } else { @@ -38,13 +38,13 @@ enum Tracing { // the logs contain any sensitive data. See `integration-tests.yml` let level: LogLevel = ProcessInfo.isRunningIntegrationTests ? .trace : logLevel - setupTracing(config: .init(logLevel: level.rustLogLevel, - extraTargets: [currentTarget], - writeToStdoutOrSystem: true, - writeToFiles: .init(path: logsDirectory.path(percentEncoded: false), - filePrefix: fileName, - fileSuffix: fileExtension, - maxFiles: maxFiles))) + return .init(logLevel: level.rustLogLevel, + extraTargets: [currentTarget], + writeToStdoutOrSystem: true, + writeToFiles: .init(path: logsDirectory.path(percentEncoded: false), + filePrefix: fileName, + fileSuffix: fileExtension, + maxFiles: maxFiles)) } /// A list of all log file URLs, sorted chronologically. This is only public for testing purposes, within diff --git a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift index 9eac3d99d..b965b3e99 100644 --- a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift @@ -43,7 +43,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType, super.init(initialViewState: MediaUploadPreviewScreenViewState(url: url, title: title, shouldShowCaptionWarning: shouldShowCaptionWarning, - isRoomEncrypted: roomProxy.isEncrypted)) + isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted)) } override func process(viewAction: MediaUploadPreviewScreenViewAction) { diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift index 942a07a20..1997799bd 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift @@ -38,8 +38,8 @@ struct DMRecipientInfo { struct RoomDetailsScreenViewState: BindableState { var details: RoomDetails - let isEncrypted: Bool - let isDirect: Bool + var isEncrypted: Bool + var isDirect: Bool var permalink: URL? var topic: AttributedString? diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index 5c373fc07..d865d1277 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -65,7 +65,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr let topic = attributedStringBuilder.fromPlain(roomProxy.infoPublisher.value.topic) super.init(initialViewState: .init(details: roomProxy.details, - isEncrypted: roomProxy.isEncrypted, + isEncrypted: roomProxy.infoPublisher.value.isEncrypted, isDirect: roomProxy.infoPublisher.value.isDirect, topic: topic, topicSummary: topic?.unattributedStringByReplacingNewlinesWithSpaces(), @@ -208,13 +208,18 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr } private func updateRoomInfo(_ roomInfo: RoomInfoProxy) { + state.isEncrypted = roomInfo.isEncrypted + state.isDirect = roomInfo.isDirect + state.bindings.isFavourite = roomInfo.isFavourite + + state.joinedMembersCount = roomInfo.joinedMembersCount + state.details = roomProxy.details let topic = attributedStringBuilder.fromPlain(roomInfo.topic) state.topic = topic state.topicSummary = topic?.unattributedStringByReplacingNewlinesWithSpaces() - state.joinedMembersCount = roomInfo.joinedMembersCount - state.bindings.isFavourite = roomInfo.isFavourite + switch roomInfo.joinRule { case .knock, .knockRestricted: state.isKnockableRoom = true @@ -250,7 +255,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr } private func updateMemberIdentityVerificationStates() async { - guard roomProxy.isEncrypted else { + guard roomProxy.infoPublisher.value.isEncrypted else { // We don't care about identity statuses on non-encrypted rooms return } @@ -309,7 +314,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr private func fetchRoomNotificationSettings() async { do { let notificationMode = try await notificationSettingsProxy.getNotificationSettings(roomId: roomProxy.id, - isEncrypted: roomProxy.isEncrypted, + isEncrypted: roomProxy.infoPublisher.value.isEncrypted, isOneToOne: roomProxy.infoPublisher.value.activeMembersCount == 2) state.notificationSettingsState = .loaded(settings: notificationMode) } catch { @@ -327,7 +332,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr case .mute: do { try await notificationSettingsProxy.unmuteRoom(roomId: roomProxy.id, - isEncrypted: roomProxy.isEncrypted, + isEncrypted: roomProxy.infoPublisher.value.isEncrypted, isOneToOne: roomProxy.infoPublisher.value.activeMembersCount == 2) } catch { state.bindings.alertInfo = AlertInfo(id: .alert, diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift index bcd327ca7..68a833d7c 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift @@ -120,7 +120,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe for member in members { var verificationState: UserIdentityVerificationState = .notVerified - if roomProxy.isEncrypted, // We don't care about identity statuses on non-encrypted rooms + if roomProxy.infoPublisher.value.isEncrypted, // We don't care about identity statuses on non-encrypted rooms case let .success(userIdentity) = await clientProxy.userIdentity(for: member.userID), let userIdentity { verificationState = userIdentity.verificationState diff --git a/ElementX/Sources/Screens/RoomNotificationSettingsScreen/RoomNotificationSettingsScreenViewModel.swift b/ElementX/Sources/Screens/RoomNotificationSettingsScreen/RoomNotificationSettingsScreenViewModel.swift index 41da6fb7c..1b3613756 100644 --- a/ElementX/Sources/Screens/RoomNotificationSettingsScreen/RoomNotificationSettingsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomNotificationSettingsScreen/RoomNotificationSettingsScreenViewModel.swift @@ -75,11 +75,14 @@ class RoomNotificationSettingsScreenViewModel: RoomNotificationSettingsScreenVie } private func fetchRoomNotificationSettings() async { - state.shouldDisplayMentionsOnlyDisclaimer = roomProxy.isEncrypted ? await !notificationSettingsProxy.canPushEncryptedEventsToDevice() : false + let isEncrypted = roomProxy.infoPublisher.value.isEncrypted + + state.shouldDisplayMentionsOnlyDisclaimer = isEncrypted ? await !notificationSettingsProxy.canPushEncryptedEventsToDevice() : false + do { // `isOneToOne` here is not the same as `isDirect` on the room. From the point of view of the push rule, a one-to-one room is a room with exactly two active members. let settings = try await notificationSettingsProxy.getNotificationSettings(roomId: roomProxy.id, - isEncrypted: roomProxy.isEncrypted, + isEncrypted: isEncrypted, isOneToOne: roomProxy.infoPublisher.value.activeMembersCount == 2) guard !Task.isCancelled else { return } state.notificationSettingsState = .loaded(settings: settings) diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarModels.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarModels.swift index 2d3f2e975..f2442045d 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarModels.swift @@ -73,7 +73,7 @@ struct ComposerToolbarViewState: BindableState { var audioPlayerState: AudioPlayerState var audioRecorderState: AudioRecorderState - let isRoomEncrypted: Bool + var isRoomEncrypted: Bool var bindings: ComposerToolbarViewStateBindings diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift index 385a16661..0dff14972 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift @@ -62,13 +62,18 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool mentionBuilder = MentionBuilder() attributedStringBuilder = AttributedStringBuilder(cacheKey: "Composer", mentionBuilder: mentionBuilder) - super.init(initialViewState: ComposerToolbarViewState(audioPlayerState: .init(id: .recorderPreview, - title: L10n.commonVoiceMessage, - duration: 0), + super.init(initialViewState: ComposerToolbarViewState(audioPlayerState: .init(id: .recorderPreview, title: L10n.commonVoiceMessage, duration: 0), audioRecorderState: .init(), - isRoomEncrypted: roomProxy.isEncrypted, + isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted, bindings: .init()), mediaProvider: mediaProvider) + + roomProxy.infoPublisher + .map(\.isEncrypted) + .receive(on: DispatchQueue.main) + .removeDuplicates() + .weakAssign(to: \.state.isRoomEncrypted, on: self) + .store(in: &cancellables) context.$viewState .map(\.composerMode) diff --git a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift index 5a38d60b1..81106395e 100644 --- a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift +++ b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift @@ -29,7 +29,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType, self.userIndicatorController = userIndicatorController super.init(initialViewState: SecurityAndPrivacyScreenViewState(serverName: clientProxy.userIDServerName ?? "", accessType: roomProxy.infoPublisher.value.joinRule.toSecurityAndPrivacyRoomAccessType, - isEncryptionEnabled: roomProxy.isEncrypted, + isEncryptionEnabled: roomProxy.infoPublisher.value.isEncrypted, historyVisibility: roomProxy.infoPublisher.value.historyVisibility.toSecurityAndPrivacyHistoryVisibility)) setupRoomDirectoryVisibility() diff --git a/ElementX/Sources/Services/Authentication/AuthenticationService.swift b/ElementX/Sources/Services/Authentication/AuthenticationService.swift index 9fd201d56..021c855d7 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationService.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationService.swift @@ -91,7 +91,8 @@ class AuthenticationService: AuthenticationServiceProtocol { func urlForOIDCLogin() async -> Result { guard let client else { return .failure(.oidcError(.urlFailure)) } do { - let oidcData = try await client.urlForOidc(oidcConfiguration: appSettings.oidcConfiguration.rustValue, prompt: .consent) + let oidcData = try await client.urlForOidc(oidcConfiguration: appSettings.oidcConfiguration.rustValue, + prompt: .consent) return .success(OIDCAuthorizationDataProxy(underlyingData: oidcData)) } catch { MXLog.error("Failed to get URL for OIDC login: \(error)") diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 85dea85d0..dfca7b176 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -148,7 +148,7 @@ class ClientProxy: ClientProxyProtocol { mediaLoader = MediaLoader(client: client) - notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings()) + notificationSettings = await NotificationSettingsProxy(notificationSettings: client.getNotificationSettings()) secureBackupController = SecureBackupController(encryption: client.encryption()) @@ -525,11 +525,11 @@ class ClientProxy: ClientProxyProtocol { } func roomSummaryForIdentifier(_ identifier: String) -> RoomSummary? { - staticRoomSummaryProvider.roomListPublisher.value.first(where: { $0.id == identifier }) + staticRoomSummaryProvider.roomListPublisher.value.first { $0.id == identifier } } func roomSummaryForAlias(_ alias: String) -> RoomSummary? { - staticRoomSummaryProvider.roomListPublisher.value.first(where: { $0.canonicalAlias == alias || $0.alternativeAliases.contains(alias) }) + staticRoomSummaryProvider.roomListPublisher.value.first { $0.canonicalAlias == alias || $0.alternativeAliases.contains(alias) } } func loadUserDisplayName() async -> Result { @@ -806,16 +806,13 @@ class ClientProxy: ClientProxyProtocol { private func loadUserAvatarURLFromCache() { loadCachedAvatarURLTask = Task { - let urlString = await Task.dispatch(on: clientQueue) { - do { - return try self.client.cachedAvatarUrl() - } catch { - MXLog.error("Failed to look for the avatar url in the cache: \(error)") - return nil - } + do { + let urlString = try await self.client.cachedAvatarUrl() + guard !Task.isCancelled else { return } + self.userAvatarURLSubject.value = urlString.flatMap(URL.init) + } catch { + MXLog.error("Failed to look for the avatar url in the cache: \(error)") } - guard !Task.isCancelled else { return } - self.userAvatarURLSubject.value = urlString.flatMap(URL.init) } } diff --git a/ElementX/Sources/Services/ElementCall/ElementCallWidgetDriver.swift b/ElementX/Sources/Services/ElementCall/ElementCallWidgetDriver.swift index dfa1e3bb6..ae072ad02 100644 --- a/ElementX/Sources/Services/ElementCall/ElementCallWidgetDriver.swift +++ b/ElementX/Sources/Services/ElementCall/ElementCallWidgetDriver.swift @@ -70,7 +70,7 @@ class ElementCallWidgetDriver: WidgetCapabilitiesProvider, ElementCallWidgetDriv return .failure(.roomInvalid) } - let useEncryption = (try? room.isEncrypted()) ?? false + let useEncryption = await (try? room.latestEncryptionState() == .encrypted) ?? false let widgetSettings: WidgetSettings do { diff --git a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift index dd4ce7ce5..380c1a1df 100644 --- a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift @@ -100,10 +100,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol { var ownUserID: String { room.ownUserId() } var info: RoomInfoProxy { infoSubject.value } - var isEncrypted: Bool { - (try? room.isEncrypted()) ?? false - } - init(roomListService: RoomListServiceProtocol, roomListItem: RoomListItemProtocol, room: RoomProtocol) async throws { @@ -116,6 +112,14 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol { Task { await updateMembers() + + // Try to update the encryption state if it's unknown. + // This is an edge case as sliding sync should pass + // that information down to the room info on the rust side. + if room.encryptionState() == .unknown { + MXLog.error("The encryption state should almost always be known.") + _ = try? await room.latestEncryptionState() + } } } @@ -142,7 +146,7 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol { await subscribeToKnockRequests() - if isEncrypted { // This is actually blocking on the rust side and might make network requests + if infoPublisher.value.isEncrypted { subscribeToIdentityStatusChanges() } } diff --git a/ElementX/Sources/Services/Room/RoomInfoProxy.swift b/ElementX/Sources/Services/Room/RoomInfoProxy.swift index 26808d7f4..8254820d5 100644 --- a/ElementX/Sources/Services/Room/RoomInfoProxy.swift +++ b/ElementX/Sources/Services/Room/RoomInfoProxy.swift @@ -42,6 +42,13 @@ struct RoomInfoProxy: BaseRoomInfoProxyProtocol { return .room(id: id, name: displayName, avatarURL: avatarURL) } + // Here we're assuming unknown rooms are unencrypted. + // Fortunately https://github.com/matrix-org/matrix-rust-sdk/pull/4778 makes that very much of an edge case and we + // also automatically start a `latestEncryptionState` fetch if needed. + // In the worst case, even if we are to assume a room is unencrypted, the SDK will still determine the correct + // state before any message is sent. + var isEncrypted: Bool { roomInfo.encryptionState == .encrypted } + var isDirect: Bool { roomInfo.isDirect } var isPublic: Bool { roomInfo.isPublic } var isSpace: Bool { roomInfo.isSpace } diff --git a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift index 47221db0b..1e135decc 100644 --- a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -63,8 +63,6 @@ enum KnockRequestsState { // sourcery: AutoMockable protocol JoinedRoomProxyProtocol: RoomProxyProtocol { - var isEncrypted: Bool { get } - var infoPublisher: CurrentValuePublisher { get } var membersPublisher: CurrentValuePublisher<[RoomMemberProxyProtocol], Never> { get } @@ -190,7 +188,7 @@ extension JoinedRoomProxyProtocol { name: infoPublisher.value.displayName, avatar: infoPublisher.value.avatar, canonicalAlias: infoPublisher.value.canonicalAlias, - isEncrypted: isEncrypted, + isEncrypted: infoPublisher.value.isEncrypted, isPublic: infoPublisher.value.isPublic, isDirect: infoPublisher.value.isDirect) } diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index c981eae53..bb0beb860 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -30,7 +30,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, SecureWindowManagerDelegate windowManager.delegate = self - MXLog.configure(currentTarget: "uitests", filePrefix: nil, logLevel: .debug) + MXLog.configure(currentTarget: "uitests") ServiceLocator.shared.register(userIndicatorController: UserIndicatorController()) diff --git a/NSE/Sources/NotificationServiceExtension.swift b/NSE/Sources/NotificationServiceExtension.swift index 33a88bdbc..00b8c7279 100644 --- a/NSE/Sources/NotificationServiceExtension.swift +++ b/NSE/Sources/NotificationServiceExtension.swift @@ -78,12 +78,12 @@ class NotificationServiceExtension: UNNotificationServiceExtension { // - NotificationID could not be resolved return contentHandler(request.content) } + + Target.nse.configure(logLevel: settings.logLevel) handler = contentHandler modifiedContent = request.content.mutableCopy() as? UNMutableNotificationContent - - ExtensionLogger.configure(currentTarget: "nse", logLevel: settings.logLevel) - + MXLog.info("\(tag) #########################################") ExtensionLogger.logMemory(with: tag) MXLog.info("\(tag) Payload came: \(request.content.userInfo)") diff --git a/NSE/SupportingFiles/target.yml b/NSE/SupportingFiles/target.yml index f9bfd21fb..e9120e804 100644 --- a/NSE/SupportingFiles/target.yml +++ b/NSE/SupportingFiles/target.yml @@ -83,6 +83,7 @@ targets: - path: ../../ElementX/Sources/AppHooks/AppHooks.swift - path: ../../ElementX/Sources/AppHooks/Hooks/ClientBuilderHook.swift - path: ../../ElementX/Sources/Application/AppSettings.swift + - path: ../../ElementX/Sources/Application/TargetConfiguration.swift - path: ../../ElementX/Sources/Generated/Assets.swift - path: ../../ElementX/Sources/Generated/Strings.swift - path: ../../ElementX/Sources/Other/Avatars.swift diff --git a/ShareExtension/Sources/ShareExtensionViewController.swift b/ShareExtension/Sources/ShareExtensionViewController.swift index e06a53552..d78cbee05 100644 --- a/ShareExtension/Sources/ShareExtensionViewController.swift +++ b/ShareExtension/Sources/ShareExtensionViewController.swift @@ -15,11 +15,11 @@ class ShareExtensionViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + Target.shareExtension.configure(logLevel: appSettings.logLevel) + addChild(hostingController) view.addMatchedSubview(hostingController.view) hostingController.didMove(toParent: self) - - MXLog.configure(currentTarget: "shareextension", filePrefix: "shareextension", logLevel: appSettings.logLevel) } override func viewDidAppear(_ animated: Bool) { diff --git a/ShareExtension/SupportingFiles/target.yml b/ShareExtension/SupportingFiles/target.yml index df6bbb96d..e30f067bd 100644 --- a/ShareExtension/SupportingFiles/target.yml +++ b/ShareExtension/SupportingFiles/target.yml @@ -80,6 +80,7 @@ targets: - path: ../SupportingFiles - path: ../../ElementX/Sources/ShareExtension - path: ../../ElementX/Sources/Application/AppSettings.swift + - path: ../../ElementX/Sources/Application/TargetConfiguration.swift - path: ../../ElementX/Sources/Other/Extensions/Bundle.swift - path: ../../ElementX/Sources/Other/Extensions/FileManager.swift - path: ../../ElementX/Sources/Other/Extensions/NSItemProvider.swift diff --git a/UnitTests/Sources/LoggingTests.swift b/UnitTests/Sources/LoggingTests.swift index bcf5cced7..3caf1050c 100644 --- a/UnitTests/Sources/LoggingTests.swift +++ b/UnitTests/Sources/LoggingTests.swift @@ -22,7 +22,7 @@ class LoggingTests: XCTestCase { let target = "tests" XCTAssertTrue(Tracing.logFiles.isEmpty) - MXLog.configure(currentTarget: target, filePrefix: target, logLevel: .info) + Target.tests.configure(logLevel: .info) // There is something weird with Rust logging where the file writing handle doesn't // notice that the file it is writing to was deleted, so we can't run these checks @@ -179,7 +179,7 @@ class LoggingTests: XCTestCase { contentType: nil)) // When logging that value - MXLog.configure(currentTarget: "tests", filePrefix: nil, logLevel: .info) + Target.tests.configure(logLevel: .info) MXLog.info(textMessage) MXLog.info(noticeMessage) diff --git a/project.yml b/project.yml index 34614b49a..0e78dbfdb 100644 --- a/project.yml +++ b/project.yml @@ -59,7 +59,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/element-hq/matrix-rust-components-swift - exactVersion: 25.03.06 + exactVersion: 25.03.13 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios