diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2911142e8..833d27851 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -111,8 +111,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-rust-components-swift", "state" : { - "revision" : "9eee9ba2f14eaa4981759295790bcbdbdebca747", - "version" : "1.0.48-alpha" + "revision" : "9650501c92a1ed802a757f2c6807a36d59619f43", + "version" : "1.0.49-alpha" } }, { diff --git a/ElementX/Sources/Other/AccessibilityIdentifiers.swift b/ElementX/Sources/Other/AccessibilityIdentifiers.swift index d2e1e2810..a50b2945a 100644 --- a/ElementX/Sources/Other/AccessibilityIdentifiers.swift +++ b/ElementX/Sources/Other/AccessibilityIdentifiers.swift @@ -27,6 +27,7 @@ struct A11yIdentifiers { static let sessionVerificationScreen = SessionVerificationScreen() static let softLogoutScreen = SoftLogoutScreen() static let startChatScreen = StartChatScreen() + static let roomMemberDetailsScreen = RoomMemberDetailsScreen() struct BugReportScreen { let report = "bug_report-report" @@ -98,4 +99,9 @@ struct A11yIdentifiers { let closeStartChat = "start_chat-close" let inviteFriends = "start_chat-invite_friends" } + + struct RoomMemberDetailsScreen { + let ignore = "room_member_details-ignore" + let unignore = "room_member_details-unignore" + } } diff --git a/ElementX/Sources/Other/Extensions/Sequence.swift b/ElementX/Sources/Other/Extensions/Sequence.swift deleted file mode 100644 index d53518cdb..000000000 --- a/ElementX/Sources/Other/Extensions/Sequence.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2023 New Vector Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation - -extension Sequence { - func asyncMap(_ transform: @escaping (Element) async -> T) async -> [T] { - await withTaskGroup(of: T.self) { group in - var transformedElements = [T]() - - for element in self { - group.addTask { - await transform(element) - } - } - - for await transformedElement in group { - transformedElements.append(transformedElement) - } - - return transformedElements - } - } -} diff --git a/ElementX/Sources/Other/SwiftUI/Form Styles/FormButtonStyles.swift b/ElementX/Sources/Other/SwiftUI/Form Styles/FormButtonStyles.swift index 2348aa691..47fd65a92 100644 --- a/ElementX/Sources/Other/SwiftUI/Form Styles/FormButtonStyles.swift +++ b/ElementX/Sources/Other/SwiftUI/Form Styles/FormButtonStyles.swift @@ -19,13 +19,16 @@ import SwiftUI /// A view to be added on the trailing edge of a form row. enum FormRowAccessory: View { case navigationLink + case progressView var body: some View { switch self { case .navigationLink: - return Image(systemName: "chevron.forward") + Image(systemName: "chevron.forward") .font(.element.subheadlineBold) .foregroundColor(.element.quaternaryContent) + case .progressView: + ProgressView() } } } diff --git a/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsModels.swift b/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsModels.swift index 4d71877b3..055fefd67 100644 --- a/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsModels.swift +++ b/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsModels.swift @@ -25,6 +25,7 @@ struct RoomMemberDetailsViewState: BindableState { let isAccountOwner: Bool let permalink: URL? var isIgnored: Bool + var isProcessingIgnoreRequest = false var bindings: RoomMemberDetailsViewStateBindings } @@ -34,7 +35,7 @@ struct RoomMemberDetailsViewStateBindings { var errorAlert: ErrorAlertItem? } -struct IgnoreUserAlertItem: AlertItem { +struct IgnoreUserAlertItem: AlertItem, Equatable { enum Action { case ignore case unignore @@ -73,8 +74,8 @@ struct IgnoreUserAlertItem: AlertItem { } enum RoomMemberDetailsViewAction { - case showUnblockAlert - case showBlockAlert + case showUnignoreAlert + case showIgnoreAlert case ignoreConfirmed case unignoreConfirmed case copyUserLink diff --git a/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsViewModel.swift b/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsViewModel.swift index 85af77ece..d2f201f9e 100644 --- a/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberDetails/RoomMemberDetailsViewModel.swift @@ -39,9 +39,9 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta override func process(viewAction: RoomMemberDetailsViewAction) async { switch viewAction { - case .showUnblockAlert: + case .showUnignoreAlert: state.bindings.ignoreUserAlert = .init(action: .unignore) - case .showBlockAlert: + case .showIgnoreAlert: state.bindings.ignoreUserAlert = .init(action: .ignore) case .copyUserLink: copyUserLink() @@ -64,7 +64,10 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta } private func ignoreUser() async { - switch await roomMemberProxy.ignoreUser() { + state.isProcessingIgnoreRequest = true + let result = await roomMemberProxy.ignoreUser() + state.isProcessingIgnoreRequest = false + switch result { case .success: state.isIgnored = true case .failure: @@ -73,7 +76,10 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta } private func unignoreUser() async { - switch await roomMemberProxy.unignoreUser() { + state.isProcessingIgnoreRequest = true + let result = await roomMemberProxy.unignoreUser() + state.isProcessingIgnoreRequest = false + switch result { case .success: state.isIgnored = false case .failure: diff --git a/ElementX/Sources/Screens/RoomMemberDetails/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetails/View/RoomMemberDetailsScreen.swift index e7dd8652e..f9829093c 100644 --- a/ElementX/Sources/Screens/RoomMemberDetails/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetails/View/RoomMemberDetailsScreen.swift @@ -23,10 +23,9 @@ struct RoomMemberDetailsScreen: View { Form { headerSection - // TODO: Uncomment when the feature is ready -// if !context.viewState.isAccountOwner { -// blockUserSection -// } + if !context.viewState.isAccountOwner { + blockUserSection + } } .scrollContentBackground(.hidden) .background(Color.element.formBackground.ignoresSafeArea()) @@ -77,18 +76,22 @@ struct RoomMemberDetailsScreen: View { Section { if context.viewState.isIgnored { Button { - context.send(viewAction: .showUnblockAlert) + context.send(viewAction: .showUnignoreAlert) } label: { Label(L10n.screenRoomMemberDetailsUnblockUser, systemImage: "slash.circle") } - .buttonStyle(FormButtonStyle(accessory: nil)) + .accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.unignore) + .buttonStyle(FormButtonStyle(accessory: context.viewState.isProcessingIgnoreRequest ? .progressView : nil)) + .disabled(context.viewState.isProcessingIgnoreRequest) } else { Button(role: .destructive) { - context.send(viewAction: .showBlockAlert) + context.send(viewAction: .showIgnoreAlert) } label: { Label(L10n.screenRoomMemberDetailsBlockUser, systemImage: "slash.circle") } - .buttonStyle(FormButtonStyle(accessory: nil)) + .accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.ignore) + .buttonStyle(FormButtonStyle(accessory: context.viewState.isProcessingIgnoreRequest ? .progressView : nil)) + .disabled(context.viewState.isProcessingIgnoreRequest) } } .formSectionStyle() diff --git a/ElementX/Sources/Services/Room/RoomProxy.swift b/ElementX/Sources/Services/Room/RoomProxy.swift index 9a283bd75..5a1013490 100644 --- a/ElementX/Sources/Services/Room/RoomProxy.swift +++ b/ElementX/Sources/Services/Room/RoomProxy.swift @@ -278,12 +278,17 @@ class RoomProxy: RoomProxyProtocol { return members } - let proxiedMembers = await members.asyncMap { RoomMemberProxy(member: $0, backgroundTaskService: self.backgroundTaskService) } + let proxiedMembers = buildRoomMemberProxies(members: members) return .success(proxiedMembers) } catch { return .failure(.failedRetrievingMembers) } } + + @MainActor + private func buildRoomMemberProxies(members: [RoomMember]) -> [RoomMemberProxy] { + members.map { RoomMemberProxy(member: $0, backgroundTaskService: backgroundTaskService) } + } func retryDecryption(for sessionID: String) async { await Task.dispatch(on: .global()) { [weak self] in diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index e3f64edeb..b928a5c75 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -318,6 +318,16 @@ class MockScreen: Identifiable { let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockMe, mediaProvider: MockMediaProvider())) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator + case .roomMemberDetails: + let navigationStackCoordinator = NavigationStackCoordinator() + let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockAlice, mediaProvider: MockMediaProvider())) + navigationStackCoordinator.setRootCoordinator(coordinator) + return navigationStackCoordinator + case .roomMemberDetailsIgnoredUser: + let navigationStackCoordinator = NavigationStackCoordinator() + let coordinator = RoomMemberDetailsCoordinator(parameters: .init(roomMemberProxy: RoomMemberProxyMock.mockIgnored, mediaProvider: MockMediaProvider())) + navigationStackCoordinator.setRootCoordinator(coordinator) + return navigationStackCoordinator } }() } diff --git a/ElementX/Sources/UITests/UITestsScreenIdentifier.swift b/ElementX/Sources/UITests/UITestsScreenIdentifier.swift index 2b6de307b..adf9b0ac4 100644 --- a/ElementX/Sources/UITests/UITestsScreenIdentifier.swift +++ b/ElementX/Sources/UITests/UITestsScreenIdentifier.swift @@ -44,6 +44,8 @@ enum UITestsScreenIdentifier: String { case roomDetailsScreenWithRoomAvatar case roomMembersListScreen case roomMemberDetailsAccountOwner + case roomMemberDetails + case roomMemberDetailsIgnoredUser case reportContent case startChat } diff --git a/Tools/Sources/SetupProject.swift b/Tools/Sources/SetupProject.swift index 88caecd59..942ec4c67 100644 --- a/Tools/Sources/SetupProject.swift +++ b/Tools/Sources/SetupProject.swift @@ -15,7 +15,7 @@ struct SetupProject: ParsableCommand { } func brewBundleInstall() throws { - try Utilities.zsh("brew install xcodegen swiftgen swiftlint swiftformat git-lfs sourcery kiliankoe/formulae/swift-outdated") + try Utilities.zsh("brew install xcodegen swiftgen swiftlint swiftformat git-lfs sourcery kiliankoe/formulae/swift-outdated localazy/tools/localazy") } func xcodegen() throws { diff --git a/UITests/Sources/RoomMemberDetailsScreenUITests.swift b/UITests/Sources/RoomMemberDetailsScreenUITests.swift index e41a46257..e0f6a1baf 100644 --- a/UITests/Sources/RoomMemberDetailsScreenUITests.swift +++ b/UITests/Sources/RoomMemberDetailsScreenUITests.swift @@ -20,6 +20,25 @@ import XCTest class RoomMemberDetailsScreenUITests: XCTestCase { func testInitialStateComponentsForAccountOwner() { let app = Application.launch(.roomMemberDetailsAccountOwner) + + XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].exists) + XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].exists) app.assertScreenshot(.roomMemberDetailsAccountOwner) } + + func testInitialStateComponents() { + let app = Application.launch(.roomMemberDetails) + + XCTAssert(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].waitForExistence(timeout: 1)) + XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].exists) + app.assertScreenshot(.roomMemberDetails) + } + + func testInitialStateComponentsForIgnoredUser() { + let app = Application.launch(.roomMemberDetailsIgnoredUser) + + XCTAssertFalse(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.ignore].exists) + XCTAssert(app.buttons[A11yIdentifiers.roomMemberDetailsScreen.unignore].waitForExistence(timeout: 1)) + app.assertScreenshot(.roomMemberDetailsIgnoredUser) + } } diff --git a/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetails.png b/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetails.png new file mode 100644 index 000000000..a3ee2cfce --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetails.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa29d51f482c87a93da7fd8c059215fcc3da9ef6c980a301e9507ed1f7c3c7a5 +size 79947 diff --git a/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetailsIgnoredUser.png b/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetailsIgnoredUser.png new file mode 100644 index 000000000..1d87cf438 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/de-DE-iPad-9th-generation.roomMemberDetailsIgnoredUser.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20e6382f3e6befa47d6a343b63fd5e5094e66e216b50853d35555b1e1b9e86ba +size 81051 diff --git a/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetails.png b/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetails.png new file mode 100644 index 000000000..b1ed803fc --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetails.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9718639645f9d3d1c198a8c3322e7c52c23722d1020a8ee9d1009fc6312d965e +size 92445 diff --git a/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetailsIgnoredUser.png b/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetailsIgnoredUser.png new file mode 100644 index 000000000..1350dbd2a --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/de-DE-iPhone-14.roomMemberDetailsIgnoredUser.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f698182d7eb30b43799b99e49f59422c601387ac4ddc675feecb939ff32e099d +size 94597 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetails.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetails.png new file mode 100644 index 000000000..a3ee2cfce --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetails.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa29d51f482c87a93da7fd8c059215fcc3da9ef6c980a301e9507ed1f7c3c7a5 +size 79947 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetailsIgnoredUser.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetailsIgnoredUser.png new file mode 100644 index 000000000..1d87cf438 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomMemberDetailsIgnoredUser.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20e6382f3e6befa47d6a343b63fd5e5094e66e216b50853d35555b1e1b9e86ba +size 81051 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetails.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetails.png new file mode 100644 index 000000000..b1ed803fc --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetails.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9718639645f9d3d1c198a8c3322e7c52c23722d1020a8ee9d1009fc6312d965e +size 92445 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetailsIgnoredUser.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetailsIgnoredUser.png new file mode 100644 index 000000000..1350dbd2a --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomMemberDetailsIgnoredUser.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f698182d7eb30b43799b99e49f59422c601387ac4ddc675feecb939ff32e099d +size 94597 diff --git a/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift b/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift index b5825e825..c62d7c86e 100644 --- a/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift +++ b/UnitTests/Sources/RoomMemberDetailsViewModelTests.swift @@ -38,6 +38,92 @@ class RoomMemberDetailsViewModelTests: XCTestCase { XCTAssertNil(context.errorAlert) } + func testIgnoreSuccess() async throws { + roomMemberProxyMock = RoomMemberProxyMock.mockAlice + roomMemberProxyMock.ignoreUserClosure = { + try? await Task.sleep(for: .milliseconds(10)) + return .success(()) + } + viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider()) + + context.send(viewAction: .showIgnoreAlert) + await Task.yield() + XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .ignore)) + + context.send(viewAction: .ignoreConfirmed) + await Task.yield() + XCTAssertTrue(context.viewState.isProcessingIgnoreRequest) + XCTAssertFalse(context.viewState.isIgnored) + try await Task.sleep(for: .milliseconds(10)) + XCTAssertFalse(context.viewState.isProcessingIgnoreRequest) + XCTAssertTrue(context.viewState.isIgnored) + } + + func testIgnoreFailure() async throws { + roomMemberProxyMock = RoomMemberProxyMock.mockAlice + roomMemberProxyMock.ignoreUserClosure = { + try? await Task.sleep(for: .milliseconds(10)) + return .failure(.ignoreUserFailed) + } + viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider()) + + context.send(viewAction: .showIgnoreAlert) + await Task.yield() + XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .ignore)) + + context.send(viewAction: .ignoreConfirmed) + await Task.yield() + XCTAssertTrue(context.viewState.isProcessingIgnoreRequest) + XCTAssertFalse(context.viewState.isIgnored) + try await Task.sleep(for: .milliseconds(10)) + XCTAssertFalse(context.viewState.isProcessingIgnoreRequest) + XCTAssertNotNil(context.errorAlert) + XCTAssertFalse(context.viewState.isIgnored) + } + + func testUnignoreSuccess() async throws { + roomMemberProxyMock = RoomMemberProxyMock.mockIgnored + roomMemberProxyMock.unignoreUserClosure = { + try? await Task.sleep(for: .milliseconds(10)) + return .success(()) + } + viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider()) + + context.send(viewAction: .showUnignoreAlert) + await Task.yield() + XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .unignore)) + + context.send(viewAction: .unignoreConfirmed) + await Task.yield() + XCTAssertTrue(context.viewState.isProcessingIgnoreRequest) + XCTAssertTrue(context.viewState.isIgnored) + try await Task.sleep(for: .milliseconds(10)) + XCTAssertFalse(context.viewState.isProcessingIgnoreRequest) + XCTAssertFalse(context.viewState.isIgnored) + } + + func testUnignoreFailure() async throws { + roomMemberProxyMock = RoomMemberProxyMock.mockIgnored + roomMemberProxyMock.unignoreUserClosure = { + try? await Task.sleep(for: .milliseconds(10)) + return .failure(.unignoreUserFailed) + } + viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider()) + + context.send(viewAction: .showUnignoreAlert) + await Task.yield() + XCTAssertEqual(context.ignoreUserAlert, IgnoreUserAlertItem(action: .unignore)) + + context.send(viewAction: .unignoreConfirmed) + await Task.yield() + XCTAssertTrue(context.viewState.isProcessingIgnoreRequest) + XCTAssertTrue(context.viewState.isIgnored) + try await Task.sleep(for: .milliseconds(10)) + XCTAssertFalse(context.viewState.isProcessingIgnoreRequest) + XCTAssertTrue(context.viewState.isIgnored) + XCTAssertNotNil(context.errorAlert) + } + func testInitialStateAccountOwner() async { roomMemberProxyMock = RoomMemberProxyMock.mockMe viewModel = RoomMemberDetailsViewModel(roomMemberProxy: roomMemberProxyMock, mediaProvider: MockMediaProvider()) diff --git a/changelog.d/733.feature b/changelog.d/733.feature new file mode 100644 index 000000000..1459f0678 --- /dev/null +++ b/changelog.d/733.feature @@ -0,0 +1 @@ +Ignore User functionality added in the Room Member Details View. \ No newline at end of file diff --git a/project.yml b/project.yml index 4a6379ccb..2ab38d544 100644 --- a/project.yml +++ b/project.yml @@ -42,7 +42,7 @@ include: packages: MatrixRustSDK: url: https://github.com/matrix-org/matrix-rust-components-swift - exactVersion: 1.0.48-alpha + exactVersion: 1.0.49-alpha # path: ../matrix-rust-sdk DesignKit: path: DesignKit