// // 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 BlockedUsersScreen: View { @Bindable var context: BlockedUsersScreenViewModel.Context var body: some View { content .compoundList() .navigationBarTitleDisplayMode(.inline) .navigationTitle(L10n.commonBlockedUsers) .alert(item: $context.alertInfo) .disabled(context.viewState.processingUserID != nil) } // MARK: - Private @ViewBuilder private var content: some View { if context.viewState.blockedUsers.isEmpty { Text(L10n.screenBlockedUsersEmpty) .font(.compound.bodyMD) .foregroundColor(.compound.textSecondary) .frame(maxWidth: .infinity, maxHeight: .infinity) } else { Form { ForEach(context.viewState.blockedUsers, id: \.self) { user in ListRow(label: .avatar(title: user.displayName ?? user.id, description: user.displayName != nil ? user.id : nil, icon: avatar(for: user)), details: .isWaiting(context.viewState.processingUserID == user.id), kind: .button { context.send(viewAction: .unblockUser(user)) }) } } } } private func avatar(for user: UserProfile) -> some View { LoadableAvatarImage(url: user.avatarURL, name: user.displayName, contentID: user.id, avatarSize: .user(on: .blockedUsers), mediaProvider: context.mediaProvider) .accessibilityHidden(true) } } // MARK: - Previews struct BlockedUsersScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = BlockedUsersScreenViewModel(hideProfiles: true, userSession: UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: RoomMemberProxyMock.mockMe.userID)))), userIndicatorController: UserIndicatorControllerMock()) static var previews: some View { ElementNavigationStack { BlockedUsersScreen(context: viewModel.context) } } }