mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Display an icon in the room header for rooms with shared history (#5016)
* feat: Display an icon in the room header for rooms with shared history * fix: Apply suggestions from code review - Simplifies `isRoomHistoryShared` expressions using type inferrence. - Adds failure messages to unit test. Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> * fix: Remove extension method in favour of field on configuration. * fix: Distinguish between `shared` and `worldReadable` icons. * refactor: Use `RoomHistorySharingState` enum with extension methods --------- Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
@@ -327,6 +327,7 @@
|
|||||||
386720B603F87D156DB01FB2 /* VoiceMessageMediaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40076C770A5FB83325252973 /* VoiceMessageMediaManager.swift */; };
|
386720B603F87D156DB01FB2 /* VoiceMessageMediaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40076C770A5FB83325252973 /* VoiceMessageMediaManager.swift */; };
|
||||||
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
||||||
3895969759E68FAB90C63EF7 /* ElementCallServiceConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */; };
|
3895969759E68FAB90C63EF7 /* ElementCallServiceConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */; };
|
||||||
|
38E0F9A4CB5237F039A2EEE6 /* RoomHistorySharingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722013E20EEED73553EC6F8D /* RoomHistorySharingState.swift */; };
|
||||||
3982C505960006B341CFD0C6 /* UserDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D0EA07BD545CC9F234DB8D /* UserDetailsEditScreenModels.swift */; };
|
3982C505960006B341CFD0C6 /* UserDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D0EA07BD545CC9F234DB8D /* UserDetailsEditScreenModels.swift */; };
|
||||||
3982E60F9C126437D5E488A3 /* PillContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6314FDC51DA25712D9A81 /* PillContextTests.swift */; };
|
3982E60F9C126437D5E488A3 /* PillContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6314FDC51DA25712D9A81 /* PillContextTests.swift */; };
|
||||||
39A987B3E41B976D1DF944C6 /* CallScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */; };
|
39A987B3E41B976D1DF944C6 /* CallScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */; };
|
||||||
@@ -2163,6 +2164,7 @@
|
|||||||
71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
||||||
71D52BAA5BADB06E5E8C295D /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
|
71D52BAA5BADB06E5E8C295D /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
|
||||||
71E2E5103702D13361D09100 /* UserProfileScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModelTests.swift; sourceTree = "<group>"; };
|
71E2E5103702D13361D09100 /* UserProfileScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
|
722013E20EEED73553EC6F8D /* RoomHistorySharingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHistorySharingState.swift; sourceTree = "<group>"; };
|
||||||
723B055A57857BFF0F18D9CB /* test_rotated_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = test_rotated_image.jpg; sourceTree = "<group>"; };
|
723B055A57857BFF0F18D9CB /* test_rotated_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = test_rotated_image.jpg; sourceTree = "<group>"; };
|
||||||
72614BFF35B8394C6E13F55A /* TimelineItemStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemStatusView.swift; sourceTree = "<group>"; };
|
72614BFF35B8394C6E13F55A /* TimelineItemStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemStatusView.swift; sourceTree = "<group>"; };
|
||||||
726E901DF76393E335FD7E8E /* ManageAuthorizedSpacesScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageAuthorizedSpacesScreenViewModel.swift; sourceTree = "<group>"; };
|
726E901DF76393E335FD7E8E /* ManageAuthorizedSpacesScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageAuthorizedSpacesScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -4030,6 +4032,7 @@
|
|||||||
C07851F4EA81AA3339806A7B /* KnockRequestProxyProtocol.swift */,
|
C07851F4EA81AA3339806A7B /* KnockRequestProxyProtocol.swift */,
|
||||||
D78C13EF5035879B6131030F /* Room.swift */,
|
D78C13EF5035879B6131030F /* Room.swift */,
|
||||||
B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */,
|
B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */,
|
||||||
|
722013E20EEED73553EC6F8D /* RoomHistorySharingState.swift */,
|
||||||
40A66E8BC8D9AE4A08EFB2DF /* RoomInfoProxy.swift */,
|
40A66E8BC8D9AE4A08EFB2DF /* RoomInfoProxy.swift */,
|
||||||
14517E5597594956FCE1950D /* RoomInfoProxyProtocol.swift */,
|
14517E5597594956FCE1950D /* RoomInfoProxyProtocol.swift */,
|
||||||
974AEAF3FE0C577A6C04AD6E /* RoomPermissions.swift */,
|
974AEAF3FE0C577A6C04AD6E /* RoomPermissions.swift */,
|
||||||
@@ -8459,6 +8462,7 @@
|
|||||||
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
||||||
8DF0EBD97753033C715D716E /* RoomFlowCoordinatorStateMachine.swift in Sources */,
|
8DF0EBD97753033C715D716E /* RoomFlowCoordinatorStateMachine.swift in Sources */,
|
||||||
9C63171267E22FEB288EC860 /* RoomHeaderView.swift in Sources */,
|
9C63171267E22FEB288EC860 /* RoomHeaderView.swift in Sources */,
|
||||||
|
38E0F9A4CB5237F039A2EEE6 /* RoomHistorySharingState.swift in Sources */,
|
||||||
5C8804B4F25903516E2DAB81 /* RoomInfoProxy.swift in Sources */,
|
5C8804B4F25903516E2DAB81 /* RoomInfoProxy.swift in Sources */,
|
||||||
432EA37BDC97CEDBAB7B23A6 /* RoomInfoProxyProtocol.swift in Sources */,
|
432EA37BDC97CEDBAB7B23A6 /* RoomInfoProxyProtocol.swift in Sources */,
|
||||||
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */,
|
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct JoinedRoomProxyMockConfiguration {
|
|||||||
var canonicalAlias: String?
|
var canonicalAlias: String?
|
||||||
var alternativeAliases: [String] = []
|
var alternativeAliases: [String] = []
|
||||||
var pinnedEventIDs: Set<String> = []
|
var pinnedEventIDs: Set<String> = []
|
||||||
|
var historyVisibility: RoomHistoryVisibility = .shared
|
||||||
|
|
||||||
var timelineStartReached = false
|
var timelineStartReached = false
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ extension RoomInfoProxyMock {
|
|||||||
unreadMentionsCount = 0
|
unreadMentionsCount = 0
|
||||||
pinnedEventIDs = configuration.pinnedEventIDs
|
pinnedEventIDs = configuration.pinnedEventIDs
|
||||||
joinRule = configuration.joinRule
|
joinRule = configuration.joinRule
|
||||||
historyVisibility = .shared
|
historyVisibility = configuration.historyVisibility
|
||||||
|
|
||||||
powerLevels = RoomPowerLevelsProxyMock(configuration: configuration.powerLevelsConfiguration)
|
powerLevels = RoomPowerLevelsProxyMock(configuration: configuration.powerLevelsConfiguration)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct RoomHeaderView: View {
|
|||||||
var roomSubtitle: String?
|
var roomSubtitle: String?
|
||||||
let roomAvatar: RoomAvatar
|
let roomAvatar: RoomAvatar
|
||||||
var dmRecipientVerificationState: UserIdentityVerificationState?
|
var dmRecipientVerificationState: UserIdentityVerificationState?
|
||||||
|
var roomHistorySharingState: RoomHistorySharingState?
|
||||||
|
|
||||||
let mediaProvider: MediaProviderProtocol?
|
let mediaProvider: MediaProviderProtocol?
|
||||||
|
|
||||||
@@ -63,6 +64,11 @@ struct RoomHeaderView: View {
|
|||||||
if let dmRecipientVerificationState {
|
if let dmRecipientVerificationState {
|
||||||
VerificationBadge(verificationState: dmRecipientVerificationState, size: .xSmall, relativeTo: .compound.bodyMDSemibold)
|
VerificationBadge(verificationState: dmRecipientVerificationState, size: .xSmall, relativeTo: .compound.bodyMDSemibold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let historySharingIcon {
|
||||||
|
CompoundIcon(historySharingIcon, size: .xSmall, relativeTo: .compound.bodyMDSemibold)
|
||||||
|
.foregroundStyle(.compound.iconInfoPrimary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,6 +79,14 @@ struct RoomHeaderView: View {
|
|||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
.accessibilityIdentifier(A11yIdentifiers.roomScreen.avatar)
|
.accessibilityIdentifier(A11yIdentifiers.roomScreen.avatar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var historySharingIcon: KeyPath<CompoundIcons, Image>? {
|
||||||
|
switch roomHistorySharingState {
|
||||||
|
case .shared: \.history
|
||||||
|
case .worldReadable: \.userProfileSolid
|
||||||
|
case .none: nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RoomHeaderView {
|
extension RoomHeaderView {
|
||||||
@@ -106,19 +120,26 @@ struct RoomHeaderView_Previews: PreviewProvider, TestablePreview {
|
|||||||
makeHeader(avatarURL: .mockMXCAvatar,
|
makeHeader(avatarURL: .mockMXCAvatar,
|
||||||
roomSubtitle: "Subtitle",
|
roomSubtitle: "Subtitle",
|
||||||
verificationState: .verified)
|
verificationState: .verified)
|
||||||
|
makeHeader(avatarURL: .mockMXCAvatar, verificationState: .notVerified, historySharingState: .shared)
|
||||||
|
makeHeader(avatarURL: .mockMXCAvatar, verificationState: .notVerified, historySharingState: .worldReadable)
|
||||||
|
makeHeader(avatarURL: .mockMXCAvatar, verificationState: .verified, historySharingState: .shared)
|
||||||
|
makeHeader(avatarURL: .mockMXCAvatar, verificationState: .verificationViolation, historySharingState: .worldReadable)
|
||||||
}
|
}
|
||||||
.previewLayout(.sizeThatFits)
|
.previewLayout(.sizeThatFits)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func makeHeader(avatarURL: URL?,
|
static func makeHeader(avatarURL: URL?,
|
||||||
roomSubtitle: String? = nil,
|
roomSubtitle: String? = nil,
|
||||||
verificationState: UserIdentityVerificationState) -> some View {
|
verificationState: UserIdentityVerificationState,
|
||||||
|
historySharingState: RoomHistorySharingState? = nil) -> some View {
|
||||||
RoomHeaderView(roomName: "Some Room name",
|
RoomHeaderView(roomName: "Some Room name",
|
||||||
roomSubtitle: roomSubtitle,
|
roomSubtitle: roomSubtitle,
|
||||||
roomAvatar: .room(id: "1",
|
roomAvatar: .room(id: "1",
|
||||||
name: "Some Room Name",
|
name: "Some Room Name",
|
||||||
avatarURL: avatarURL),
|
avatarURL: avatarURL),
|
||||||
dmRecipientVerificationState: verificationState,
|
dmRecipientVerificationState: verificationState,
|
||||||
|
roomHistorySharingState: historySharingState,
|
||||||
|
|
||||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
import OrderedCollections
|
import OrderedCollections
|
||||||
|
|
||||||
enum RoomScreenViewModelAction: Equatable {
|
enum RoomScreenViewModelAction: Equatable {
|
||||||
@@ -80,6 +81,9 @@ struct RoomScreenViewState: BindableState {
|
|||||||
(canAcceptKnocks || canDeclineKnocks || canBan)
|
(canAcceptKnocks || canDeclineKnocks || canBan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If `enableKeyShareOnInvite` is set, determines the current history sharing state.
|
||||||
|
var roomHistorySharingState: RoomHistorySharingState?
|
||||||
|
|
||||||
var footerDetails: RoomScreenFooterViewDetails?
|
var footerDetails: RoomScreenFooterViewDetails?
|
||||||
|
|
||||||
var bindings = RoomScreenViewStateBindings()
|
var bindings = RoomScreenViewStateBindings()
|
||||||
|
|||||||
@@ -67,10 +67,17 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
self.initialSelectedPinnedEventID = initialSelectedPinnedEventID
|
self.initialSelectedPinnedEventID = initialSelectedPinnedEventID
|
||||||
pinnedEventStringBuilder = .pinnedEventStringBuilder(userID: roomProxy.ownUserID)
|
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,
|
let viewState = RoomScreenViewState(roomTitle: roomProxy.infoPublisher.value.displayName ?? roomProxy.id,
|
||||||
roomAvatar: roomProxy.infoPublisher.value.avatar,
|
roomAvatar: roomProxy.infoPublisher.value.avatar,
|
||||||
hasOngoingCall: roomProxy.infoPublisher.value.hasRoomCall,
|
hasOngoingCall: roomProxy.infoPublisher.value.hasRoomCall,
|
||||||
hasSuccessor: roomProxy.infoPublisher.value.successor != nil)
|
hasSuccessor: roomProxy.infoPublisher.value.successor != nil,
|
||||||
|
roomHistorySharingState: roomHistorySharingState)
|
||||||
super.init(initialViewState: appHooks.roomScreenHook.update(viewState),
|
super.init(initialViewState: appHooks.roomScreenHook.update(viewState),
|
||||||
mediaProvider: userSession.mediaProvider)
|
mediaProvider: userSession.mediaProvider)
|
||||||
|
|
||||||
@@ -342,6 +349,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
state.canDeclineKnocks = powerLevels.canOwnUserKick()
|
state.canDeclineKnocks = powerLevels.canOwnUserKick()
|
||||||
state.canBan = powerLevels.canOwnUserBan()
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupPinnedEventsTimelineItemProviderIfNeeded() {
|
private func setupPinnedEventsTimelineItemProviderIfNeeded() {
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ struct RoomScreen: View {
|
|||||||
RoomHeaderView(roomName: context.viewState.roomTitle,
|
RoomHeaderView(roomName: context.viewState.roomTitle,
|
||||||
roomAvatar: context.viewState.roomAvatar,
|
roomAvatar: context.viewState.roomAvatar,
|
||||||
dmRecipientVerificationState: context.viewState.dmRecipientVerificationState,
|
dmRecipientVerificationState: context.viewState.dmRecipientVerificationState,
|
||||||
|
roomHistorySharingState: context.viewState.roomHistorySharingState,
|
||||||
mediaProvider: context.mediaProvider) {
|
mediaProvider: context.mediaProvider) {
|
||||||
context.send(viewAction: .displayRoomDetails)
|
context.send(viewAction: .displayRoomDetails)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct ThreadTimelineScreenViewState: BindableState {
|
|||||||
var roomAvatar: RoomAvatar
|
var roomAvatar: RoomAvatar
|
||||||
var canSendMessage = true
|
var canSendMessage = true
|
||||||
var dmRecipientVerificationState: UserIdentityVerificationState?
|
var dmRecipientVerificationState: UserIdentityVerificationState?
|
||||||
|
var roomHistorySharingState: RoomHistorySharingState?
|
||||||
|
|
||||||
var bindings = ThreadTimelineScreenViewStateBindings()
|
var bindings = ThreadTimelineScreenViewStateBindings()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct ThreadTimelineScreen: View {
|
|||||||
roomSubtitle: context.viewState.roomTitle,
|
roomSubtitle: context.viewState.roomTitle,
|
||||||
roomAvatar: context.viewState.roomAvatar,
|
roomAvatar: context.viewState.roomAvatar,
|
||||||
dmRecipientVerificationState: context.viewState.dmRecipientVerificationState,
|
dmRecipientVerificationState: context.viewState.dmRecipientVerificationState,
|
||||||
|
roomHistorySharingState: context.viewState.roomHistorySharingState,
|
||||||
mediaProvider: context.mediaProvider) {
|
mediaProvider: context.mediaProvider) {
|
||||||
// There is no action but the iOS 26 designs have it looking like a button.
|
// There is no action but the iOS 26 designs have it looking like a button.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2026 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// 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.
|
||||||
|
enum RoomHistorySharingState: Equatable {
|
||||||
|
/// The feature flag is set, and the room history visibility is set to `shared`.
|
||||||
|
case shared
|
||||||
|
/// The feature flag is set, and the room history visibility is set to `world_readable`.
|
||||||
|
case worldReadable
|
||||||
|
}
|
||||||
@@ -134,4 +134,20 @@ extension RoomInfoProxyProtocol {
|
|||||||
// And finally return whatever the first alternative alias is
|
// And finally return whatever the first alternative alias is
|
||||||
return alternativeAliases.first
|
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.
|
||||||
|
var historySharingState: RoomHistorySharingState? {
|
||||||
|
guard isEncrypted else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return switch historyVisibility {
|
||||||
|
case .shared:
|
||||||
|
.shared
|
||||||
|
case .worldReadable:
|
||||||
|
.worldReadable
|
||||||
|
default:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7e0e6a96f699edf80a25da1158581da37cfa3ee2e44a404c51a20a9305c77f77
|
oid sha256:25d819f52ad5fb46aacca695198b7d2fa275a7b205c08bdebc8c1724cf6a2c4b
|
||||||
size 101376
|
size 191605
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7e0e6a96f699edf80a25da1158581da37cfa3ee2e44a404c51a20a9305c77f77
|
oid sha256:25d819f52ad5fb46aacca695198b7d2fa275a7b205c08bdebc8c1724cf6a2c4b
|
||||||
size 101376
|
size 191605
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:37b7a926dcf3071ff7a5eed78141438240ebd99e2d4fb0b474156d0f261580d3
|
oid sha256:ee0792530f8ff2020d174a79b0d6f2edd6ec3f970d01f71cc54292ad91b7fc4a
|
||||||
size 76207
|
size 145478
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:37b7a926dcf3071ff7a5eed78141438240ebd99e2d4fb0b474156d0f261580d3
|
oid sha256:ee0792530f8ff2020d174a79b0d6f2edd6ec3f970d01f71cc54292ad91b7fc4a
|
||||||
size 76207
|
size 145478
|
||||||
|
|||||||
@@ -438,4 +438,94 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - History Sharing
|
||||||
|
|
||||||
|
func testRoomWithSharedHistoryDoesNotDisplayBadgeIfFeatureFlagNotSet() async throws {
|
||||||
|
ServiceLocator.shared.settings.enableKeyShareOnInvite = false
|
||||||
|
|
||||||
|
var configuration = JoinedRoomProxyMockConfiguration(historyVisibility: .joined)
|
||||||
|
let infoSubject = CurrentValueSubject<RoomInfoProxyProtocol, Never>(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: 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: 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRoomWithSharedHistoryDisplaysBadgeWhenFeatureFlagSet() async throws {
|
||||||
|
ServiceLocator.shared.settings.enableKeyShareOnInvite = true
|
||||||
|
|
||||||
|
var configuration = JoinedRoomProxyMockConfiguration(isEncrypted: false, historyVisibility: .joined)
|
||||||
|
let infoSubject = CurrentValueSubject<RoomInfoProxyProtocol, Never>(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: 1,
|
||||||
|
message: "The icon should be hidden 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 deferredInvisibleUnencrypted = deferFailure(viewModel.context.$viewState,
|
||||||
|
timeout: 1,
|
||||||
|
message: "The icon should not be shown when the room is unencrypted") { viewState in
|
||||||
|
viewState.roomHistorySharingState != nil
|
||||||
|
}
|
||||||
|
try await deferredInvisibleUnencrypted.fulfill()
|
||||||
|
|
||||||
|
configuration.isEncrypted = true
|
||||||
|
infoSubject.send(RoomInfoProxyMock(configuration))
|
||||||
|
let deferredShared = deferFulfillment(viewModel.context.$viewState,
|
||||||
|
message: "The icon should be shown when the room history visibility is .shared") { viewState in
|
||||||
|
viewState.roomHistorySharingState == .shared
|
||||||
|
}
|
||||||
|
try await deferredShared.fulfill()
|
||||||
|
|
||||||
|
configuration.historyVisibility = .worldReadable
|
||||||
|
infoSubject.send(RoomInfoProxyMock(configuration))
|
||||||
|
let deferredWorldReadable = deferFulfillment(viewModel.context.$viewState,
|
||||||
|
message: "The icon should be shown when the room history visibility is .worldReadable") { viewState in
|
||||||
|
viewState.roomHistorySharingState == .worldReadable
|
||||||
|
}
|
||||||
|
try await deferredWorldReadable.fulfill()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user