Files
letro-ios/ElementX/Sources/Screens/EditRoomAddressScreen/View/EditRoomAddressScreen.swift
Mauro 79332cb30a Security and privacy part 2 (#3637)
* handling the history visibility flag

* better logic to handle visibility

* better handling of the visibility options state

* added some copies, and the public room directory

visibility state

* completed the UI

added also the preview tests

* improved the handling of the directory visibility

* added the space users case

and improved handling of the access -> vsibility reaction. Also added a simple error handling for the public directory toggle

* added the edit room address view

but is missing its full implementation

* implement the UI for the edit room address screen

* implemented error checking

when editing the address

* updated preview tests and improved code

* typo fix

* Fix various issues after rebasing.

* Fix build errors and broken snapshot tests

* Adopt latest room privacy and canonical alias setting APIs

* Add support for creating and editing the room's alias.

* Add support for saving room privacy setting changes.

* Fix room alias screen snapshot tests following recent changes.

---------

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
2025-01-15 11:50:08 +02:00

115 lines
5.2 KiB
Swift

//
// Copyright 2022-2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Compound
import SwiftUI
struct EditRoomAddressScreen: View {
@ObservedObject var context: EditRoomAddressScreenViewModel.Context
var body: some View {
Form {
Section {
EditRoomAddressListRow(aliasLocalPart: $context.desiredAliasLocalPart,
serverName: context.viewState.serverName, shouldDisplayError: context.viewState.aliasErrors.errorDescription != nil)
.onChange(of: context.desiredAliasLocalPart) { _, newAliasLocalPart in
context.desiredAliasLocalPart = newAliasLocalPart.lowercased()
}
.onSubmit {
if context.viewState.canSave {
context.send(viewAction: .save)
}
}
} footer: {
VStack(alignment: .leading, spacing: 12) {
if let errorDescription = context.viewState.aliasErrors.errorDescription {
Label(errorDescription, icon: \.error, iconSize: .xSmall, relativeTo: .compound.bodySM)
.foregroundStyle(.compound.textCriticalPrimary)
.font(.compound.bodySM)
}
Text(L10n.screenCreateRoomRoomAddressSectionFooter)
.compoundListSectionFooter()
.font(.compound.bodySM)
}
}
}
.compoundList()
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(L10n.screenEditRoomAddressTitle)
.toolbar { toolbar }
}
@ToolbarContentBuilder
var toolbar: some ToolbarContent {
ToolbarItem(placement: .confirmationAction) {
Button(L10n.actionSave) {
context.send(viewAction: .save)
}
.disabled(!context.viewState.canSave)
}
ToolbarItem(placement: .cancellationAction) {
Button(L10n.actionCancel) {
context.send(viewAction: .cancel)
}
}
}
}
// MARK: - Previews
struct EditRoomAddressScreen_Previews: PreviewProvider, TestablePreview {
static let noAliasviewModel = EditRoomAddressScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Room Name")),
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
userIndicatorController: UserIndicatorControllerMock())
static let aliasviewModel = EditRoomAddressScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Room Name", canonicalAlias: "#room-alias:matrix.org")),
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
userIndicatorController: UserIndicatorControllerMock())
static let invalidSymbolsViewModel = EditRoomAddressScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Room Name", canonicalAlias: "#room#-alias:matrix.org")),
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org")),
userIndicatorController: UserIndicatorControllerMock())
static let alreadyExistingViewModel = {
let clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org"))
clientProxy.isAliasAvailableReturnValue = .success(false)
return EditRoomAddressScreenViewModel(initialViewState: .init(serverName: "matrix.org",
bindings: .init(desiredAliasLocalPart: "whatever")),
roomProxy: JoinedRoomProxyMock(.init(name: "Room Name")),
clientProxy: clientProxy,
userIndicatorController: UserIndicatorControllerMock())
}()
static var previews: some View {
NavigationStack {
EditRoomAddressScreen(context: noAliasviewModel.context)
}
.previewDisplayName("No alias")
NavigationStack {
EditRoomAddressScreen(context: aliasviewModel.context)
}
.previewDisplayName("With alias")
NavigationStack {
EditRoomAddressScreen(context: invalidSymbolsViewModel.context)
}
.snapshotPreferences(expect: invalidSymbolsViewModel.context.$viewState.map { state in
!state.aliasErrors.isEmpty
})
.previewDisplayName("Invalid symbols")
NavigationStack {
EditRoomAddressScreen(context: alreadyExistingViewModel.context)
}
.snapshotPreferences(expect: alreadyExistingViewModel.context.$viewState.map { state in
!state.aliasErrors.isEmpty
})
.previewDisplayName("Already existing")
}
}