Files
letro-ios/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectorySearchScreen.swift
Mauro 56eec826df Fix A11y tests (#5104)
* replace NavigationStack with ElementNavigationStack to allow the content to be rendered without a NavigationStack in a11y tests

* fix a11y tests

* update xcodeproject

* swiftformat fix

* use iOS 26.1 for CI

* use a wrapper to solve the issue for a11y tests

* ElementNavigationStack only uses the trick in DEBUG mode, and added a swiftlint rule to prevent the usage of NavigationStack
2026-02-13 16:45:58 +01:00

103 lines
4.6 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct RoomDirectorySearchScreen: View {
@ObservedObject var context: RoomDirectorySearchScreenViewModel.Context
var body: some View {
ElementNavigationStack {
List {
Section {
ForEach(context.viewState.rooms) { room in
RoomDirectorySearchCell(result: room, mediaProvider: context.mediaProvider) {
context.send(viewAction: .select(room: room))
}
}
} footer: {
VStack(spacing: 0) {
if context.viewState.isLoading {
ProgressView()
.frame(maxWidth: .infinity)
} else if context.viewState.rooms.isEmpty {
Text(L10n.commonNoResults)
.font(.compound.bodyLG)
.foregroundColor(.compound.textSecondary)
.frame(maxWidth: .infinity)
.accessibilityIdentifier(A11yIdentifiers.startChatScreen.searchNoResults)
}
emptyRectangle
.onAppear {
context.send(viewAction: .reachedBottom)
}
}
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
.environment(\.defaultMinListRowHeight, 48)
.scrollContentBackground(.hidden)
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.isSearching($context.isSearching)
.searchable(text: $context.searchString, placement: .navigationBarDrawer(displayMode: .always))
.navigationTitle(L10n.screenRoomDirectorySearchTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(L10n.actionCancel) {
context.send(viewAction: .dismiss)
}
}
}
}
}
/// The greedy size of Rectangle can create an issue with the navigation bar when the search is highlighted, so is best to use a fixed frame instead of hidden() or EmptyView()
private var emptyRectangle: some View {
Rectangle()
.frame(width: 0, height: 0)
}
}
// MARK: - Previews
struct RoomDirectorySearchScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel: RoomDirectorySearchScreenViewModel = {
let results = [RoomDirectorySearchResult(id: "test_1",
alias: "#test_1:example.com",
name: "Test 1",
topic: "Test description 1",
avatar: .room(id: "test_1",
name: "Test 1",
avatarURL: nil),
canBeJoined: true),
RoomDirectorySearchResult(id: "test_2",
alias: "#test_2:example.com",
name: "Test 2",
topic: nil,
avatar: .room(id: "test_2",
name: "Test 2",
avatarURL: .mockMXCAvatar),
canBeJoined: false)]
let roomDirectorySearchProxy = RoomDirectorySearchProxyMock(configuration: .init(results: results))
let clientProxy = ClientProxyMock(.init(roomDirectorySearchProxy: roomDirectorySearchProxy))
return RoomDirectorySearchScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
userIndicatorController: UserIndicatorControllerMock())
}()
static var previews: some View {
RoomDirectorySearchScreen(context: viewModel.context)
}
}