From bc32a05a2c7ce15c1fc8e37b5abcbeaaf715e40f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:43:18 +0100 Subject: [PATCH] Promote "history sharing on invite" out of developer options (#5480) * Enable key-share-on-invite irrespective of feature flag * Remove feature-flag dep: warning on starting chat with new people * Remove feature-flag dep: invite from room member details * Remove feature-flag dep: warning on new users in invite screen * Remove feature-flag dep: from room details screen * Remove feature-flag dep: starting chat from user profile screen * Remove feature-flag dep: timeline info on forwarded keys * Remove feature-flag dep: RoomScreenModel * Remove `enableKeyShareOnInvite` from AppSettings * Remove `enableKeyShareOnInvite` feature flag * Remove outdated comments * Update preview test room snapshots as their header now includes the history sharing icon --- .../Application/Settings/AppSettings.swift | 6 --- .../Other/Extensions/ClientBuilder.swift | 3 +- .../InviteUsersScreenViewModel.swift | 9 +--- .../RoomDetailsScreenViewModel.swift | 17 +------- .../View/RoomDetailsScreen.swift | 4 -- .../RoomMemberDetailsScreenViewModel.swift | 2 +- .../Screens/RoomScreen/RoomScreenModels.swift | 2 +- .../RoomScreen/RoomScreenViewModel.swift | 16 +------- .../DeveloperOptionsScreenModels.swift | 1 - .../View/DeveloperOptionsScreen.swift | 10 ----- .../StartChatScreenViewModel.swift | 19 ++++----- .../Screens/Timeline/TimelineModels.swift | 2 - .../Screens/Timeline/TimelineViewModel.swift | 1 - .../Style/TimelineItemBubbledStylerView.swift | 1 - .../Style/TimelineItemSendInfoLabel.swift | 7 ++-- .../UserProfileScreenViewModel.swift | 16 +++----- .../AuthenticationClientFactory.swift | 2 - .../Room/RoomHistorySharingState.swift | 3 +- .../Services/Room/RoomInfoProxyProtocol.swift | 3 +- .../UserSession/UserSessionStore.swift | 1 - NSE/Sources/NSEUserSession.swift | 1 - .../roomScreen.Normal-iPad-en-GB.png | 4 +- .../roomScreen.Normal-iPad-pseudo.png | 4 +- .../roomScreen.Normal-iPhone-en-GB.png | 4 +- .../roomScreen.Normal-iPhone-pseudo.png | 4 +- .../roomScreen.Read-only-iPad-en-GB.png | 4 +- .../roomScreen.Read-only-iPad-pseudo.png | 4 +- .../roomScreen.Read-only-iPhone-en-GB.png | 4 +- .../roomScreen.Read-only-iPhone-pseudo.png | 4 +- .../roomScreen.Tombstoned-iPad-en-GB.png | 4 +- .../roomScreen.Tombstoned-iPad-pseudo.png | 4 +- .../roomScreen.Tombstoned-iPhone-en-GB.png | 4 +- .../roomScreen.Tombstoned-iPhone-pseudo.png | 4 +- .../Sources/InviteUsersViewModelTests.swift | 4 -- .../RoomDetailsScreenViewModelTests.swift | 29 +------------ .../RoomMemberDetailsViewModelTests.swift | 2 - .../Sources/RoomScreenViewModelTests.swift | 41 +------------------ .../Sources/StartChatViewModelTests.swift | 2 - .../UserProfileScreenViewModelTests.swift | 2 - 39 files changed, 53 insertions(+), 201 deletions(-) diff --git a/ElementX/Sources/Application/Settings/AppSettings.swift b/ElementX/Sources/Application/Settings/AppSettings.swift index 3baff8111..3662ba22c 100644 --- a/ElementX/Sources/Application/Settings/AppSettings.swift +++ b/ElementX/Sources/Application/Settings/AppSettings.swift @@ -23,7 +23,6 @@ protocol CommonSettingsProtocol: AnyObject { var bugReportRageshakeURL: RemotePreference { get } var enableOnlySignedDeviceIsolationMode: Bool { get } - var enableKeyShareOnInvite: Bool { get } var threadsEnabled: Bool { get } var hideQuietNotificationAlerts: Bool { get } } @@ -76,7 +75,6 @@ final class AppSettings { case fuzzyRoomListSearchEnabled case lowPriorityFilterEnabled case enableOnlySignedDeviceIsolationMode - case enableKeyShareOnInvite case knockingEnabled case threadsEnabled case roomThreadListEnabled @@ -433,10 +431,6 @@ final class AppSettings { @UserPreference(key: UserDefaultsKeys.enableOnlySignedDeviceIsolationMode, defaultValue: false, storageType: .userDefaults(store)) var enableOnlySignedDeviceIsolationMode - /// Configuration to enable encrypted history sharing on invite, and accepting keys from inviters. - @UserPreference(key: UserDefaultsKeys.enableKeyShareOnInvite, defaultValue: false, storageType: .userDefaults(store)) - var enableKeyShareOnInvite - @UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store)) var knockingEnabled diff --git a/ElementX/Sources/Other/Extensions/ClientBuilder.swift b/ElementX/Sources/Other/Extensions/ClientBuilder.swift index bfccd3870..f22837b29 100644 --- a/ElementX/Sources/Other/Extensions/ClientBuilder.swift +++ b/ElementX/Sources/Other/Extensions/ClientBuilder.swift @@ -17,7 +17,6 @@ extension ClientBuilder { sessionDelegate: ClientSessionDelegate, appHooks: AppHooks, enableOnlySignedDeviceIsolationMode: Bool, - enableKeyShareOnInvite: Bool, requestTimeout: UInt64? = 30000, maxRequestRetryTime: UInt64? = nil, threadsEnabled: Bool) -> ClientBuilder { @@ -40,7 +39,7 @@ extension ClientBuilder { builder = builder .autoEnableCrossSigning(autoEnableCrossSigning: true) .backupDownloadStrategy(backupDownloadStrategy: .afterDecryptionFailure) - .enableShareHistoryOnInvite(enableShareHistoryOnInvite: enableKeyShareOnInvite) + .enableShareHistoryOnInvite(enableShareHistoryOnInvite: true) .autoEnableBackups(autoEnableBackups: true) } diff --git a/ElementX/Sources/Screens/InviteUsersScreen/InviteUsersScreenViewModel.swift b/ElementX/Sources/Screens/InviteUsersScreen/InviteUsersScreenViewModel.swift index 720d622ca..f5f20290b 100644 --- a/ElementX/Sources/Screens/InviteUsersScreen/InviteUsersScreenViewModel.swift +++ b/ElementX/Sources/Screens/InviteUsersScreen/InviteUsersScreenViewModel.swift @@ -61,8 +61,7 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr case .cancel: actionsSubject.send(.dismiss) case .proceed: - guard appSettings.enableKeyShareOnInvite, - roomProxy.details.historySharingState != RoomHistorySharingState.hidden, + guard roomProxy.details.historySharingState != RoomHistorySharingState.hidden, !state.usersToConfirm.isEmpty, !state.isSkippable else { inviteUsers(state.selectedUsers.map(\.userID), roomProxy: roomProxy) @@ -107,11 +106,7 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr } private func inviteUsers(_ users: [String], roomProxy: JoinedRoomProxyProtocol) { - if appSettings.enableKeyShareOnInvite { - showLoadingIndicator(title: L10n.screenRoomDetailsInvitePeoplePreparing, message: L10n.screenRoomDetailsInvitePeopleDontClose) - } else { - showLoadingIndicator() - } + showLoadingIndicator(title: L10n.screenRoomDetailsInvitePeoplePreparing, message: L10n.screenRoomDetailsInvitePeopleDontClose) Task { defer { diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index acd183d35..54a3e3472 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -61,13 +61,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr let topic = attributedStringBuilder.fromPlain(roomProxy.infoPublisher.value.topic) - // Clear details.historySharingState manually while we are still behind a feature flag. - var details = roomProxy.details - if !appSettings.enableKeyShareOnInvite { - details.historySharingState = nil - } - - super.init(initialViewState: .init(details: details, + super.init(initialViewState: .init(details: roomProxy.details, isEncrypted: roomProxy.infoPublisher.value.isEncrypted, isDirect: roomProxy.infoPublisher.value.isDirect, topic: topic, @@ -280,14 +274,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr state.joinedMembersCount = roomInfo.joinedMembersCount state.details = roomProxy.details - - // Set state.details.historySharingState manually while we are still behind - // a feature flag. - if appSettings.enableKeyShareOnInvite { - state.details.historySharingState = roomInfo.historySharingState - } else { - state.details.historySharingState = nil - } + state.details.historySharingState = roomInfo.historySharingState let topic = attributedStringBuilder.fromPlain(roomInfo.topic) state.topic = topic diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index 37630ca5a..e796d6542 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -374,7 +374,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { } private static func makeGenericRoomViewModel(historyVisibility: RoomHistoryVisibility) -> RoomDetailsScreenViewModel { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true ServiceLocator.shared.settings.knockingEnabled = true let knockRequests: [KnockRequestProxyMock] = [.init()] @@ -418,7 +417,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { } private static func makeSimpleRoomViewModel() -> RoomDetailsScreenViewModel { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true ServiceLocator.shared.settings.knockingEnabled = true let knockRequests: [KnockRequestProxyMock] = [.init()] @@ -448,8 +446,6 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { } private static func makeDMViewModel(verificationState: UserIdentityVerificationState) -> RoomDetailsScreenViewModel { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true - let members: [RoomMemberProxyMock] = [ .mockMe, .mockDan diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift index 82511a6ec..d2ab70763 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift @@ -200,7 +200,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro case .success(let roomID): if let roomID { actionsSubject.send(.openDirectChat(roomID: roomID)) - } else if appSettings.enableKeyShareOnInvite, roomProxy.details.historySharingState != RoomHistorySharingState.hidden { + } else if roomProxy.details.historySharingState != RoomHistorySharingState.hidden { Task { let identity = await self.userSession.clientProxy.userIdentity(for: roomMemberProxy.userID, fallBackToServer: false) let user: UserProfileProxy = .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift index 0381f74d9..f37aa05c9 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift @@ -94,7 +94,7 @@ struct RoomScreenViewState: BindableState { (canAcceptKnocks || canDeclineKnocks || canBan) } - /// If `enableKeyShareOnInvite` is set, determines the current history sharing state. + /// The current history sharing state. var roomHistorySharingState: RoomHistorySharingState? var footerDetails: RoomScreenFooterViewDetails? diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index b90318d8f..4cd98475f 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -67,18 +67,12 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol self.initialSelectedPinnedEventID = initialSelectedPinnedEventID pinnedEventStringBuilder = .pinnedEventStringBuilder(userID: roomProxy.ownUserID) - let roomHistorySharingState: RoomHistorySharingState? = if appSettings.enableKeyShareOnInvite { - roomProxy.infoPublisher.value.historySharingState - } else { - nil - } - let viewState = RoomScreenViewState(roomTitle: roomProxy.infoPublisher.value.displayName ?? roomProxy.id, roomAvatar: roomProxy.infoPublisher.value.avatar, hasOngoingCall: roomProxy.infoPublisher.value.hasRoomCall, isDirectOneToOneRoom: roomProxy.isDirectOneToOneRoom, hasSuccessor: roomProxy.infoPublisher.value.successor != nil, - roomHistorySharingState: roomHistorySharingState) + roomHistorySharingState: roomProxy.infoPublisher.value.historySharingState) super.init(initialViewState: appHooks.roomScreenHook.update(viewState), mediaProvider: userSession.mediaProvider) @@ -371,13 +365,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol state.canBan = powerLevels.canOwnUserBan() } - // This causes the UI to become inconsistent with the user's mental model if the user - // does not restart the app after disabling the feature flag. We can probably ignore - // such cases, since we explicitly ask for an app restart in the caption of the feature - // flag switch. - if appSettings.enableKeyShareOnInvite { - state.roomHistorySharingState = roomInfo.historySharingState - } + state.roomHistorySharingState = roomInfo.historySharingState } private func setupPinnedEventsTimelineItemProviderIfNeeded() { diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift index c68e11b21..e59a4b391 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift @@ -55,7 +55,6 @@ protocol DeveloperOptionsProtocol: AnyObject { var traceLogPacks: Set { get set } var enableOnlySignedDeviceIsolationMode: Bool { get set } - var enableKeyShareOnInvite: Bool { get set } var hideQuietNotificationAlerts: Bool { get set } var focusEventOnNotificationTap: Bool { get set } var automaticBackPaginationEnabled: Bool { get set } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift index faa9f0a6a..4c4244ac7 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift @@ -113,16 +113,6 @@ struct DeveloperOptionsScreen: View { Text("This setting controls how end-to-end encryption (E2EE) keys are exchanged. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.") } - Section { - Toggle(isOn: $context.enableKeyShareOnInvite) { - Text("Share encrypted history with new members") - Text("Requires app reboot") - } - } footer: { - Text("When inviting a user to an encrypted room that has history visibility set to \"shared\", share encrypted history with that user, and accept encrypted history when you are invited to such a room.") - Text("WARNING: this feature is EXPERIMENTAL and not all security precautions are implemented. Do not enable on production accounts.") - } - Section("Element Call remote URL override") { TextField("Leave empty to use EC locally", text: $elementCallURLOverrideString) .autocorrectionDisabled(true) diff --git a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift index f7fc802e4..ba94862aa 100644 --- a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift @@ -67,20 +67,15 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie hideLoadingIndicator() actionsSubject.send(.showRoom(roomID: roomId)) case .success: - if appSettings.enableKeyShareOnInvite { - Task { - // If an error occured while fetching the identity, assume they are unknown. - let isUnknown = if case .success(let identity) = await self.userSession.clientProxy.userIdentity(for: user.userID, fallBackToServer: false) { - identity == nil - } else { - true - } - self.state.bindings.selectedUserToInvite = UserToInvite(user: user, isUnknown: isUnknown) - hideLoadingIndicator() + Task { + // If an error occured while fetching the identity, assume they are unknown. + let isUnknown = if case .success(let identity) = await self.userSession.clientProxy.userIdentity(for: user.userID, fallBackToServer: false) { + identity == nil + } else { + true } - } else { + self.state.bindings.selectedUserToInvite = UserToInvite(user: user, isUnknown: isUnknown) hideLoadingIndicator() - state.bindings.selectedUserToInvite = UserToInvite(user: user, isUnknown: false) } case .failure: hideLoadingIndicator() diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index bbf9c4261..eff01e5de 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -144,8 +144,6 @@ struct TimelineViewState: BindableState { var mapTilerConfiguration: MapTilerConfiguration - var enableKeyShareOnInvite: Bool - var stoppedLiveLocationIDs: Set = [] var bindings: TimelineViewStateBindings diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index d08aca665..f803249a8 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -107,7 +107,6 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { emojiProvider: emojiProvider, linkMetadataProvider: hideTimelineMedia ? nil : linkMetadataProvider, mapTilerConfiguration: appSettings.mapTilerConfiguration, - enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite, bindings: .init(reactionsCollapsed: [:])), mediaProvider: userSession.mediaProvider) diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift index 3d7fd9f77..65e6b4914 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift @@ -335,7 +335,6 @@ private extension TimelineItemKeyForwarder { struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview { static let viewModel: TimelineViewModel = { let appSettings = AppSettings() - appSettings.enableKeyShareOnInvite = true appSettings.threadsEnabled = true let roomProxy = JoinedRoomProxyMock(.init()) diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemSendInfoLabel.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemSendInfoLabel.swift index 85e580885..931097eee 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemSendInfoLabel.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemSendInfoLabel.swift @@ -15,8 +15,7 @@ extension View { adjustedDeliveryStatus: TimelineItemDeliveryStatus?, context: TimelineViewModel.Context) -> some View { modifier(TimelineItemSendInfoModifier(sendInfo: .init(timelineItem: timelineItem, - adjustedDeliveryStatus: adjustedDeliveryStatus, - enableKeyShareOnInvite: context.viewState.enableKeyShareOnInvite), + adjustedDeliveryStatus: adjustedDeliveryStatus), context: context)) } } @@ -150,7 +149,7 @@ private struct TimelineItemSendInfo { } private extension TimelineItemSendInfo { - init(timelineItem: EventBasedTimelineItemProtocol, adjustedDeliveryStatus: TimelineItemDeliveryStatus?, enableKeyShareOnInvite: Bool) { + init(timelineItem: EventBasedTimelineItemProtocol, adjustedDeliveryStatus: TimelineItemDeliveryStatus?) { itemID = timelineItem.id localizedString = timelineItem.localizedSendInfo @@ -158,7 +157,7 @@ private extension TimelineItemSendInfo { .sendingFailed } else if let authenticity = timelineItem.properties.encryptionAuthenticity { .encryptionAuthenticity(authenticity) - } else if enableKeyShareOnInvite, let forwarder = timelineItem.properties.encryptionForwarder { + } else if let forwarder = timelineItem.properties.encryptionForwarder { .encryptionForwarder(forwarder) } else { nil diff --git a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift index 595bbeafd..7f55cd17e 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift @@ -127,17 +127,13 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr if let roomID { actionsSubject.send(.openDirectChat(roomID: roomID)) } else { - if appSettings.enableKeyShareOnInvite { - Task { - let isUnknown = if case let .success(identity) = await userSession.clientProxy.userIdentity(for: userProfile.userID, fallBackToServer: false) { - identity == nil - } else { - true - } - state.bindings.inviteConfirmationUser = .init(user: userProfile, isUnknown: isUnknown) + Task { + let isUnknown = if case let .success(identity) = await userSession.clientProxy.userIdentity(for: userProfile.userID, fallBackToServer: false) { + identity == nil + } else { + true } - } else { - state.bindings.inviteConfirmationUser = .init(user: userProfile, isUnknown: false) + state.bindings.inviteConfirmationUser = .init(user: userProfile, isUnknown: isUnknown) } } case .failure: diff --git a/ElementX/Sources/Services/Authentication/AuthenticationClientFactory.swift b/ElementX/Sources/Services/Authentication/AuthenticationClientFactory.swift index 0716dcd2c..8cf274d73 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationClientFactory.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationClientFactory.swift @@ -38,7 +38,6 @@ struct AuthenticationClientFactory: AuthenticationClientFactoryProtocol { sessionDelegate: clientSessionDelegate, appHooks: appHooks, enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode, - enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite, threadsEnabled: appSettings.threadsEnabled) .sqliteStore(config: .init(dataPath: sessionDirectories.dataPath, cachePath: sessionDirectories.cachePath) .passphrase(passphrase: passphrase)) @@ -56,7 +55,6 @@ struct AuthenticationClientFactory: AuthenticationClientFactoryProtocol { sessionDelegate: clientSessionDelegate, appHooks: appHooks, enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode, - enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite, threadsEnabled: appSettings.threadsEnabled) .inMemoryStore() .serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress) diff --git a/ElementX/Sources/Services/Room/RoomHistorySharingState.swift b/ElementX/Sources/Services/Room/RoomHistorySharingState.swift index 0eee0480f..483ec2f86 100644 --- a/ElementX/Sources/Services/Room/RoomHistorySharingState.swift +++ b/ElementX/Sources/Services/Room/RoomHistorySharingState.swift @@ -5,8 +5,7 @@ // Please see LICENSE files in the repository root for full details. // -/// Enumeration of the two possible cases in which history sharing under MSC4268 is enabled. These -/// variants implicitly assume that the feature flag, `enableKeyShareOnInvite`, is set. +/// Enumeration of the two possible cases in which history sharing under MSC4268 is enabled. enum RoomHistorySharingState: Equatable { /// The feature flag is set, and the room history visibility is either `invited` or `joined`. New /// members of the room cannot read the room history. diff --git a/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift index b208b3feb..a329ba197 100644 --- a/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift @@ -136,8 +136,7 @@ extension RoomInfoProxyProtocol { return alternativeAliases.first } - /// If present, the state of history sharing in this room. This *does not* consider the `enableKeyShareOnInvite` - /// feature flag, so consumers should be careful to check the flag is true before utilising this property. + /// If present, the state of history sharing in this room. var historySharingState: RoomHistorySharingState? { guard isEncrypted else { return nil diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index 2d432d79e..8bcd97110 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -136,7 +136,6 @@ class UserSessionStore: UserSessionStoreProtocol { sessionDelegate: keychainController, appHooks: appHooks, enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode, - enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite, threadsEnabled: appSettings.threadsEnabled) .sqliteStore(config: .init(dataPath: credentials.restorationToken.sessionDirectories.dataPath, cachePath: credentials.restorationToken.sessionDirectories.cachePath) diff --git a/NSE/Sources/NSEUserSession.swift b/NSE/Sources/NSEUserSession.swift index a72457240..97a728ed9 100644 --- a/NSE/Sources/NSEUserSession.swift +++ b/NSE/Sources/NSEUserSession.swift @@ -73,7 +73,6 @@ final class NSEUserSession: NSEUserSessionProtocol { sessionDelegate: clientSessionDelegate, appHooks: appHooks, enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode, - enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite, requestTimeout: 15000, maxRequestRetryTime: 5000, threadsEnabled: appSettings.threadsEnabled) diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-en-GB.png index f1294863b..1e5daac57 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:207bd394067c340f9e4b076fd16bd4343316bcd9d8d4d374cd236e47c164e145 -size 292240 +oid sha256:089b0d9a304c3f40792be121ff4d186cd627fbac7c6cefcde1a055ea5fed4c32 +size 293242 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-pseudo.png index e1adc9907..4b9ea5e36 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6147dbb4bc53ade67de4805d0c1d98c9cd6efb741cb61bad36fb64979ac1d883 -size 299890 +oid sha256:f3466a09ca0cf44e1277df51a1d7087140528f8215c9c1822646450e93cb31b7 +size 301071 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-en-GB.png index 078fdd86c..2b60edacc 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85c53cd872455164e11487873edd381bcf6571a49c54cd5a66eb305b46d79f71 -size 177231 +oid sha256:3ac4854adf7c566ce1de1183b0e70644d6451698bbeeb67e894676da661e4cfa +size 178126 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-pseudo.png index e4ab5d764..4e03f8360 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Normal-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0b83a35c2fbbd563df35d28c005fa9f27a89a54ebaeb8f86b705488a1f34c17 -size 177978 +oid sha256:32fe31fc8d11c757017183ef709f9e295f95447749b795306b89ef4823b08601 +size 178855 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-en-GB.png index c369b0920..1c88c89a2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92ff74f286a559e4346753371af24b1df1573b14f4c83675f73fb3337fda73cd -size 291851 +oid sha256:38e268637715a7155390f76471957b6db4de180ca472e1118f2cdf68743c16f7 +size 292930 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-pseudo.png index 857e6f5e0..36c639953 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8cc07152be380cfe9e49788fba97efaef630692ac7565ae2351deaa4181a6d29 -size 302027 +oid sha256:9b134060f2886bd68c6c0b61be6248ef6d3165e4b4e3e8b5998e1ef943f36ed4 +size 303186 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-en-GB.png index 243da38b4..3dc4c06e9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2bcd291f0d52f8d3c6bbb9895ec9e557b8a7a56f884d530cd91f8ff333d0404a -size 178411 +oid sha256:348acf96fccb8263d3b15faf60ac48bf566e0973c5336f91b29cd44969e99d6c +size 179321 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-pseudo.png index af9a60ca6..016f3966a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Read-only-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7bd1f293a3defcc41f51afceea1892cd70a8fc3dec76e32b815d2c8ade54cac4 -size 182434 +oid sha256:6c8407aa04edb63d1295594fb626ea4b913f36dce94c1e12967f79d563b44d75 +size 183279 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png index 5800c598a..82074b07c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b0c5f8e8d167ddc5f00adbf8cd3f19aae03bcb68817a6fccb1af21c1b800a03 -size 350621 +oid sha256:6bde61b7ff9a65b26419c35eeabef756ad4e2c76b5cea99392774c3c174138c4 +size 351572 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png index 0f3b897ad..751e5c171 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ceb2e3a809131e13d42cd68586e3b171bd080001c4400ed923dc4e25d7592fcb -size 364270 +oid sha256:79a62923cdaea57cc20a1867a7d334f67d8f13c9d9e95a4264745d70c0f67115 +size 365168 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-en-GB.png index 43b96a83b..c281f1aed 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2da0576e9ed07c84367669e5e357f5597c041513079421b5df20588ca5cc76d -size 205437 +oid sha256:0311bc192551d8f7859c6ed616d0925e49d8e81bd6d63ec7821aa7069e7012ea +size 206286 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-pseudo.png index 6d20b0cc4..ad7b53d13 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:359c5ac971a59aaa709189e21249ca3527c0d5892204e1a5007fe7b630c56a18 -size 210703 +oid sha256:2d9d5cb4c421d1d7d164c4c4db0c20bf879f4969a1d66213114b108b6b7b1b7c +size 211593 diff --git a/UnitTests/Sources/InviteUsersViewModelTests.swift b/UnitTests/Sources/InviteUsersViewModelTests.swift index 4662281b2..6241fdac1 100644 --- a/UnitTests/Sources/InviteUsersViewModelTests.swift +++ b/UnitTests/Sources/InviteUsersViewModelTests.swift @@ -103,8 +103,6 @@ final class InviteUsersScreenViewModelTests { @Test func invitingUnknownUsersOpensConfirmationDialog() async throws { - appSettings.enableKeyShareOnInvite = true - let mockedMembers: [RoomMemberProxyMock] = [.mockAlice, .mockBob] let roomProxy = JoinedRoomProxyMock(.init(name: "test", members: mockedMembers)) roomProxy.inviteUserIDReturnValue = .success(()) @@ -138,8 +136,6 @@ final class InviteUsersScreenViewModelTests { @Test func removeButtonRemovesUnknownUsers() async throws { - appSettings.enableKeyShareOnInvite = true - let mockedMembers: [RoomMemberProxyMock] = [.mockAlice, .mockBob] let roomProxy = JoinedRoomProxyMock(.init(name: "test", members: mockedMembers)) roomProxy.inviteUserIDReturnValue = .success(()) diff --git a/UnitTests/Sources/RoomDetailsScreenViewModelTests.swift b/UnitTests/Sources/RoomDetailsScreenViewModelTests.swift index ac0905332..8c9a4b476 100644 --- a/UnitTests/Sources/RoomDetailsScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomDetailsScreenViewModelTests.swift @@ -791,34 +791,7 @@ struct RoomDetailsScreenViewModelTests { // MARK: - History Sharing @Test - mutating func historySharingPillDoesNotAppearIfFeatureFlagNotSet() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = false - - let configuration = JoinedRoomProxyMockConfiguration(historyVisibility: .shared) - let infoSubject = CurrentValueSubject(RoomInfoProxyMock(configuration)) - let roomProxyMock = JoinedRoomProxyMock(configuration) - roomProxyMock.underlyingInfoPublisher = infoSubject.asCurrentValuePublisher() - - viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock, - userSession: UserSessionMock(.init()), - analyticsService: ServiceLocator.shared.analytics, - userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxyMock, - attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()), - appSettings: ServiceLocator.shared.settings) - - let deferredInvisible = deferFailure(context.observe(\.viewState), - timeout: .seconds(1), - message: "The pill should not be shown as the feature flag is not set") { state in - state.details.historySharingState != nil - } - try await deferredInvisible.fulfill() - } - - @Test - mutating func historySharingPillDisplayedIfHistoryVisibilityShared() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true - + mutating func historySharingPillDisplayed() async throws { let configuration = JoinedRoomProxyMockConfiguration(historyVisibility: .shared) let infoSubject = CurrentValueSubject(RoomInfoProxyMock(configuration)) let roomProxyMock = JoinedRoomProxyMock(configuration) diff --git a/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift b/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift index 5371c7464..337c5d36b 100644 --- a/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift +++ b/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift @@ -163,7 +163,6 @@ struct RoomMemberDetailsViewModelTests { let waitForMemberToLoad = deferFulfillment(context.$viewState) { $0.memberDetails != nil } try await waitForMemberToLoad.fulfill() - ServiceLocator.shared.settings.enableKeyShareOnInvite = true clientProxy.directRoomForUserIDReturnValue = .success(nil) clientProxy.userIdentityForFallBackToServerReturnValue = .success(UserIdentityProxyMock(configuration: .init(verificationState: .notVerified))) @@ -185,7 +184,6 @@ struct RoomMemberDetailsViewModelTests { let waitForMemberToLoad = deferFulfillment(context.$viewState) { $0.memberDetails != nil } try await waitForMemberToLoad.fulfill() - ServiceLocator.shared.settings.enableKeyShareOnInvite = true clientProxy.directRoomForUserIDReturnValue = .success(nil) clientProxy.userIdentityForFallBackToServerReturnValue = .failure(.forbiddenAccess) diff --git a/UnitTests/Sources/RoomScreenViewModelTests.swift b/UnitTests/Sources/RoomScreenViewModelTests.swift index 44dfcf652..a254b36f5 100644 --- a/UnitTests/Sources/RoomScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomScreenViewModelTests.swift @@ -452,46 +452,7 @@ final class RoomScreenViewModelTests { // MARK: - History Sharing @Test - func roomWithSharedHistoryDoesNotDisplayBadgeIfFeatureFlagNotSet() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = false - - var configuration = JoinedRoomProxyMockConfiguration(historyVisibility: .joined) - let infoSubject = CurrentValueSubject(RoomInfoProxyMock(configuration)) - let roomProxyMock = JoinedRoomProxyMock(configuration) - - // setup the room proxy actions publisher - roomProxyMock.underlyingInfoPublisher = infoSubject.asCurrentValuePublisher() - let viewModel = RoomScreenViewModel(userSession: UserSessionMock(.init()), - roomProxy: roomProxyMock, - initialSelectedPinnedEventID: nil, - ongoingCallRoomIDPublisher: .init(.init(nil)), - appSettings: ServiceLocator.shared.settings, - appHooks: AppHooks(), - analyticsService: ServiceLocator.shared.analytics, - userIndicatorController: ServiceLocator.shared.userIndicatorController) - self.viewModel = viewModel - - let deferredInvisible = deferFailure(viewModel.context.$viewState, - timeout: .seconds(1), - message: "The icon should not be shown when the room history visibility is not .shared or .worldReadable") { viewState in - viewState.roomHistorySharingState != nil - } - try await deferredInvisible.fulfill() - - configuration.historyVisibility = .shared - infoSubject.send(RoomInfoProxyMock(configuration)) - let deferredShared = deferFailure(viewModel.context.$viewState, - timeout: .seconds(1), - message: "The icon should not be shown when the room history visibility is .shared, since the flag isn't set") { viewState in - viewState.roomHistorySharingState != nil - } - try await deferredShared.fulfill() - } - - @Test - func roomWithSharedHistoryDisplaysBadgeWhenFeatureFlagSet() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true - + func roomWithSharedHistoryDisplaysBadge() async throws { var configuration = JoinedRoomProxyMockConfiguration(isEncrypted: false, historyVisibility: .joined) let infoSubject = CurrentValueSubject(RoomInfoProxyMock(configuration)) let roomProxyMock = JoinedRoomProxyMock(configuration) diff --git a/UnitTests/Sources/StartChatViewModelTests.swift b/UnitTests/Sources/StartChatViewModelTests.swift index 3570b4538..aff2d69ae 100644 --- a/UnitTests/Sources/StartChatViewModelTests.swift +++ b/UnitTests/Sources/StartChatViewModelTests.swift @@ -89,7 +89,6 @@ struct StartChatScreenViewModelTests { @Test func inviteConfirmationFetchesIdentity() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true clientProxy.directRoomForUserIDReturnValue = .success(nil) clientProxy.userIdentityForFallBackToServerReturnValue = .success(UserIdentityProxyMock(configuration: .init(verificationState: .notVerified))) @@ -105,7 +104,6 @@ struct StartChatScreenViewModelTests { @Test func inviteConfirmationFallsBackToUnknownIdentityOnFailure() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true clientProxy.directRoomForUserIDReturnValue = .success(nil) clientProxy.userIdentityForFallBackToServerReturnValue = .failure(.forbiddenAccess) diff --git a/UnitTests/Sources/UserProfileScreenViewModelTests.swift b/UnitTests/Sources/UserProfileScreenViewModelTests.swift index b9c76075b..fae3259d3 100644 --- a/UnitTests/Sources/UserProfileScreenViewModelTests.swift +++ b/UnitTests/Sources/UserProfileScreenViewModelTests.swift @@ -57,8 +57,6 @@ struct UserProfileScreenViewModelTests { @Test func startingDmWithUnknownUserFetchesIdentity() async throws { - ServiceLocator.shared.settings.enableKeyShareOnInvite = true - let profile = UserProfileProxy.mockAlice let clientProxy = ClientProxyMock(.init())