mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Always show security and privacy, and just hide the knocking jojn rule option through the feature flag
This commit is contained in:
+3
-1
@@ -13,6 +13,7 @@ struct SecurityAndPrivacyScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let appSetting: AppSettings
|
||||
}
|
||||
|
||||
enum SecurityAndPrivacyScreenCoordinatorAction {
|
||||
@@ -32,7 +33,8 @@ final class SecurityAndPrivacyScreenCoordinator: CoordinatorProtocol {
|
||||
init(parameters: SecurityAndPrivacyScreenCoordinatorParameters) {
|
||||
viewModel = SecurityAndPrivacyScreenViewModel(roomProxy: parameters.roomProxy,
|
||||
clientProxy: parameters.clientProxy,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
appSettings: parameters.appSetting)
|
||||
}
|
||||
|
||||
func start() {
|
||||
|
||||
+13
-1
@@ -17,6 +17,13 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
var currentSettings: SecurityAndPrivacySettings
|
||||
var bindings: SecurityAndPrivacyScreenViewStateBindings
|
||||
var canonicalAlias: String?
|
||||
var isKnockingEnabled: Bool
|
||||
var isSpace: Bool
|
||||
|
||||
var canEditAddress = false
|
||||
var canEditJoinRule = false
|
||||
var canEnableEncryption = false
|
||||
var canEditHistoryVisibility = false
|
||||
|
||||
private var hasChanges: Bool {
|
||||
currentSettings != bindings.desiredSettings
|
||||
@@ -42,8 +49,13 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
init(serverName: String,
|
||||
accessType: SecurityAndPrivacyRoomAccessType,
|
||||
isEncryptionEnabled: Bool,
|
||||
historyVisibility: SecurityAndPrivacyHistoryVisibility) {
|
||||
historyVisibility: SecurityAndPrivacyHistoryVisibility,
|
||||
isSpace: Bool,
|
||||
isKnockingEnabled: Bool) {
|
||||
self.serverName = serverName
|
||||
self.isKnockingEnabled = isKnockingEnabled
|
||||
self.isSpace = isSpace
|
||||
|
||||
let settings = SecurityAndPrivacySettings(accessType: accessType,
|
||||
isEncryptionEnabled: isEncryptionEnabled,
|
||||
historyVisibility: historyVisibility)
|
||||
|
||||
+41
-3
@@ -16,6 +16,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SecurityAndPrivacyScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SecurityAndPrivacyScreenViewModelAction, Never> {
|
||||
@@ -24,14 +25,23 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
|
||||
init(roomProxy: JoinedRoomProxyProtocol,
|
||||
clientProxy: ClientProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appSettings: AppSettings) {
|
||||
self.roomProxy = roomProxy
|
||||
self.clientProxy = clientProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appSettings = appSettings
|
||||
|
||||
super.init(initialViewState: SecurityAndPrivacyScreenViewState(serverName: clientProxy.userIDServerName ?? "",
|
||||
accessType: roomProxy.infoPublisher.value.joinRule.toSecurityAndPrivacyRoomAccessType,
|
||||
isEncryptionEnabled: roomProxy.infoPublisher.value.isEncrypted,
|
||||
historyVisibility: roomProxy.infoPublisher.value.historyVisibility.toSecurityAndPrivacyHistoryVisibility))
|
||||
historyVisibility: roomProxy.infoPublisher.value.historyVisibility.toSecurityAndPrivacyHistoryVisibility,
|
||||
isSpace: roomProxy.infoPublisher.value.isSpace,
|
||||
isKnockingEnabled: appSettings.knockingEnabled))
|
||||
|
||||
if let powerLevels = roomProxy.infoPublisher.value.powerLevels {
|
||||
setupPermissions(powerLevels: powerLevels)
|
||||
}
|
||||
|
||||
setupRoomDirectoryVisibility()
|
||||
setupSubscriptions()
|
||||
@@ -82,7 +92,8 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
|
||||
let userIDServerName = clientProxy.userIDServerName
|
||||
|
||||
roomProxy.infoPublisher
|
||||
let infoPublisher = roomProxy.infoPublisher
|
||||
infoPublisher
|
||||
.compactMap { roomInfo in
|
||||
guard let userIDServerName else {
|
||||
return nil
|
||||
@@ -96,6 +107,33 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
.receive(on: DispatchQueue.main)
|
||||
.weakAssign(to: \.state.canonicalAlias, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
infoPublisher
|
||||
.compactMap(\.powerLevels)
|
||||
.removeDuplicates { $0.userPowerLevels == $1.userPowerLevels && $0.values == $1.values }
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] powerLevels in
|
||||
self?.setupPermissions(powerLevels: powerLevels)
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
infoPublisher
|
||||
.map(\.isSpace)
|
||||
.removeDuplicates()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.weakAssign(to: \.state.isSpace, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
appSettings.$knockingEnabled
|
||||
.weakAssign(to: \.state.isKnockingEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func setupPermissions(powerLevels: RoomPowerLevelsProxyProtocol) {
|
||||
state.canEditAddress = powerLevels.canOwnUser(sendStateEvent: .roomAliases)
|
||||
state.canEditJoinRule = powerLevels.canOwnUser(sendStateEvent: .roomJoinRules)
|
||||
state.canEditHistoryVisibility = powerLevels.canOwnUser(sendStateEvent: .roomHistoryVisibility)
|
||||
state.canEnableEncryption = powerLevels.canOwnUser(sendStateEvent: .roomEncryption)
|
||||
}
|
||||
|
||||
private func setupRoomDirectoryVisibility() {
|
||||
|
||||
+103
-26
@@ -14,8 +14,11 @@ struct SecurityAndPrivacyScreen: View {
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
roomAccessSection
|
||||
if context.desiredSettings.accessType != .inviteOnly {
|
||||
if context.viewState.canEditJoinRule {
|
||||
roomAccessSection
|
||||
}
|
||||
|
||||
if context.desiredSettings.accessType != .inviteOnly, context.viewState.canEditAddress {
|
||||
if let canonicalAlias = context.viewState.canonicalAlias {
|
||||
visibilitySection
|
||||
addressSection(canonicalAlias: canonicalAlias)
|
||||
@@ -25,8 +28,15 @@ struct SecurityAndPrivacyScreen: View {
|
||||
addAddressSection
|
||||
}
|
||||
}
|
||||
encryptionSection
|
||||
historySection
|
||||
|
||||
if !context.viewState.isSpace {
|
||||
if context.viewState.canEnableEncryption {
|
||||
encryptionSection
|
||||
}
|
||||
if context.viewState.canEditHistoryVisibility {
|
||||
historySection
|
||||
}
|
||||
}
|
||||
}
|
||||
.compoundList()
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -40,9 +50,12 @@ struct SecurityAndPrivacyScreen: View {
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .inviteOnly) { context.desiredSettings.accessType = .inviteOnly })
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyAskToJoinOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .askToJoin) { context.desiredSettings.accessType = .askToJoin })
|
||||
if context.viewState.isKnockingEnabled || context.viewState.currentSettings.accessType == .askToJoin {
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyAskToJoinOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .askToJoin) { context.desiredSettings.accessType = .askToJoin })
|
||||
.disabled(!context.viewState.isKnockingEnabled)
|
||||
}
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .anyone) { context.desiredSettings.accessType = .anyone })
|
||||
@@ -187,28 +200,76 @@ struct SecurityAndPrivacyScreen: View {
|
||||
// MARK: - Previews
|
||||
|
||||
struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let inviteOnlyViewModel = SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(joinRule: .invite)),
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static let inviteOnlyViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(members: .allMembersAsCreator,
|
||||
joinRule: .invite)),
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static let publicViewModel = SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
joinRule: .public,
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static let publicViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: .public,
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static let publicNoAddressViewModel = SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
joinRule: .public)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static let publicNoAddressViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: .public)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static let restrictedViewModel = SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
joinRule: .restricted(rules: []),
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static let restrictedViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: .restricted(rules: []),
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static let askToJoinViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
appSettings.knockingEnabled = true
|
||||
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: .knock,
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: appSettings)
|
||||
}()
|
||||
|
||||
static let publicSpaceViewModel = {
|
||||
AppSettings.resetAllSettings()
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isSpace: true,
|
||||
isEncrypted: false,
|
||||
canonicalAlias: "#space:matrix.org",
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: .public,
|
||||
isVisibleInPublicDirectory: true)),
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
@@ -236,5 +297,21 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
state.currentSettings.isVisibileInRoomDirectory == true
|
||||
})
|
||||
.previewDisplayName("Restricted room")
|
||||
|
||||
NavigationStack {
|
||||
SecurityAndPrivacyScreen(context: askToJoinViewModel.context)
|
||||
}
|
||||
.snapshotPreferences(expect: restrictedViewModel.context.$viewState.map { state in
|
||||
state.currentSettings.isVisibileInRoomDirectory == true
|
||||
})
|
||||
.previewDisplayName("Ask to join room")
|
||||
|
||||
NavigationStack {
|
||||
SecurityAndPrivacyScreen(context: publicSpaceViewModel.context)
|
||||
}
|
||||
.snapshotPreferences(expect: restrictedViewModel.context.$viewState.map { state in
|
||||
state.currentSettings.isVisibileInRoomDirectory == true
|
||||
})
|
||||
.previewDisplayName("Public space")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user