mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 15:45:11 +00:00
Add a flag to disable hidden profiles for ignored users. (#2892)
This commit is contained in:
@@ -18,7 +18,9 @@ import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct BlockedUsersScreenCoordinatorParameters {
|
||||
let hideProfiles: Bool
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
@@ -26,7 +28,9 @@ final class BlockedUsersScreenCoordinator: CoordinatorProtocol {
|
||||
private let viewModel: BlockedUsersScreenViewModelProtocol
|
||||
|
||||
init(parameters: BlockedUsersScreenCoordinatorParameters) {
|
||||
viewModel = BlockedUsersScreenViewModel(clientProxy: parameters.clientProxy,
|
||||
viewModel = BlockedUsersScreenViewModel(hideProfiles: parameters.hideProfiles,
|
||||
clientProxy: parameters.clientProxy,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import Foundation
|
||||
|
||||
struct BlockedUsersScreenViewState: BindableState {
|
||||
var blockedUsers: [String]
|
||||
var blockedUsers: [UserProfileProxy]
|
||||
var processingUserID: String?
|
||||
|
||||
var bindings = BlockedUsersScreenViewStateBindings()
|
||||
@@ -28,7 +28,7 @@ struct BlockedUsersScreenViewStateBindings {
|
||||
}
|
||||
|
||||
enum BlockedUsersScreenViewAction {
|
||||
case unblockUser(userID: String)
|
||||
case unblockUser(UserProfileProxy)
|
||||
}
|
||||
|
||||
enum BlockedUsersScreenViewStateAlertType: Hashable {
|
||||
|
||||
@@ -20,27 +20,30 @@ import SwiftUI
|
||||
typealias BlockedUsersScreenViewModelType = StateStoreViewModel<BlockedUsersScreenViewState, BlockedUsersScreenViewAction>
|
||||
|
||||
class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsersScreenViewModelProtocol {
|
||||
let hideProfiles: Bool
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
init(clientProxy: ClientProxyProtocol,
|
||||
init(hideProfiles: Bool,
|
||||
clientProxy: ClientProxyProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.hideProfiles = hideProfiles
|
||||
self.clientProxy = clientProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: BlockedUsersScreenViewState(blockedUsers: clientProxy.ignoredUsersPublisher.value ?? []))
|
||||
let ignoredUsers = clientProxy.ignoredUsersPublisher.value?.map { UserProfileProxy(userID: $0) }
|
||||
|
||||
super.init(initialViewState: BlockedUsersScreenViewState(blockedUsers: ignoredUsers ?? []),
|
||||
imageProvider: mediaProvider)
|
||||
|
||||
showLoadingIndicator()
|
||||
|
||||
clientProxy.ignoredUsersPublisher
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] blockedUsers in
|
||||
guard let self else { return }
|
||||
|
||||
if let blockedUsers {
|
||||
hideLoadingIndicator()
|
||||
state.blockedUsers = blockedUsers
|
||||
}
|
||||
guard let blockedUsers else { return }
|
||||
Task { await self?.updateUsers(blockedUsers) }
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
@@ -49,12 +52,12 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
||||
|
||||
override func process(viewAction: BlockedUsersScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .unblockUser(let userID):
|
||||
case .unblockUser(let user):
|
||||
state.bindings.alertInfo = .init(id: .unblock,
|
||||
title: L10n.screenBlockedUsersUnblockAlertTitle,
|
||||
message: L10n.screenBlockedUsersUnblockAlertDescription,
|
||||
primaryButton: .init(title: L10n.screenBlockedUsersUnblockAlertAction, role: .destructive) { [weak self] in
|
||||
self?.unblockUser(userID)
|
||||
self?.unblockUser(user)
|
||||
},
|
||||
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||
}
|
||||
@@ -66,12 +69,35 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func unblockUser(_ userID: String) {
|
||||
private func updateUsers(_ blockedUsers: [String]) async {
|
||||
defer { hideLoadingIndicator() }
|
||||
|
||||
if hideProfiles {
|
||||
state.blockedUsers = blockedUsers.map { UserProfileProxy(userID: $0) }
|
||||
} else {
|
||||
state.blockedUsers = await withTaskGroup(of: UserProfileProxy.self) { group in
|
||||
for userID in blockedUsers {
|
||||
group.addTask {
|
||||
switch await self.clientProxy.profile(for: userID) {
|
||||
case .success(let profile): profile
|
||||
case .failure: UserProfileProxy(userID: userID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await group.reduce(into: []) { partialResult, profile in
|
||||
partialResult.append(profile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func unblockUser(_ user: UserProfileProxy) {
|
||||
showLoadingIndicator()
|
||||
state.processingUserID = userID
|
||||
state.processingUserID = user.userID
|
||||
|
||||
Task {
|
||||
if case .failure = await clientProxy.unignoreUser(userID) {
|
||||
if case .failure = await clientProxy.unignoreUser(user.userID) {
|
||||
state.bindings.alertInfo = .init(id: .error)
|
||||
}
|
||||
|
||||
|
||||
@@ -40,21 +40,21 @@ struct BlockedUsersScreen: View {
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
} else {
|
||||
Form {
|
||||
ForEach(context.viewState.blockedUsers, id: \.self) { userID in
|
||||
ListRow(label: .avatar(title: userID, icon: avatar(for: userID)),
|
||||
details: .isWaiting(context.viewState.processingUserID == userID),
|
||||
kind: .button(action: { context.send(viewAction: .unblockUser(userID: userID)) }))
|
||||
ForEach(context.viewState.blockedUsers, id: \.self) { user in
|
||||
ListRow(label: .avatar(title: user.displayName ?? user.userID, icon: avatar(for: user)),
|
||||
details: .isWaiting(context.viewState.processingUserID == user.userID),
|
||||
kind: .button(action: { context.send(viewAction: .unblockUser(user)) }))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func avatar(for userID: String) -> some View {
|
||||
LoadableAvatarImage(url: nil,
|
||||
name: String(userID.dropFirst()),
|
||||
contentID: userID,
|
||||
private func avatar(for user: UserProfileProxy) -> some View {
|
||||
LoadableAvatarImage(url: user.avatarURL,
|
||||
name: user.displayName,
|
||||
contentID: user.userID,
|
||||
avatarSize: .user(on: .blockedUsers),
|
||||
imageProvider: nil)
|
||||
imageProvider: context.imageProvider)
|
||||
.accessibilityHidden(true)
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,9 @@ struct BlockedUsersScreen: View {
|
||||
// MARK: - Previews
|
||||
|
||||
struct BlockedUsersScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = BlockedUsersScreenViewModel(clientProxy: ClientProxyMock(.init(userID: RoomMemberProxyMock.mockMe.userID)),
|
||||
static let viewModel = BlockedUsersScreenViewModel(hideProfiles: true,
|
||||
clientProxy: ClientProxyMock(.init(userID: RoomMemberProxyMock.mockMe.userID)),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
Reference in New Issue
Block a user