Always open manage member sheet (#4110)

* always open manage member sheet

* Update ElementX/Sources/Screens/ManageRoomMemberSheet/ManageRoomMemberSheetModels.swift

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* Update ElementX/Sources/Screens/ManageRoomMemberSheet/ManageRoomMemberSheetModels.swift

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* pr suggestions and handled the buttons actions correctly

* Update ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* fixed some compilation errors

* added some documentation

* using a struct instead of a protocol

* using arguments instead of a struct

---------

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
Mauro
2025-05-19 16:17:57 +02:00
committed by GitHub
parent 4f4b4b236d
commit 9a8819ac26
25 changed files with 334 additions and 170 deletions
@@ -55,7 +55,7 @@ enum TimelineViewAction {
case displayTimelineItemMenu(itemID: TimelineItemIdentifier)
case handleTimelineItemMenuAction(itemID: TimelineItemIdentifier, action: TimelineItemMenuAction)
case tappedOnSenderDetails(userID: String)
case tappedOnSenderDetails(sender: TimelineItemSender)
case displayReactionSummary(itemID: TimelineItemIdentifier, key: String)
case displayEmojiPicker(itemID: TimelineItemIdentifier)
case displayReadReceipts(itemID: TimelineItemIdentifier)
@@ -183,8 +183,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
timelineInteractionHandler.displayTimelineItemActionMenu(for: itemID)
case .handleTimelineItemMenuAction(let itemID, let action):
timelineInteractionHandler.handleTimelineItemMenuAction(action, itemID: itemID)
case .tappedOnSenderDetails(let userID):
handleTappedOnSenderDetails(userID: userID)
case .tappedOnSenderDetails(let sender):
handleTappedOnSenderDetails(sender: sender)
case .displayEmojiPicker(let itemID):
timelineInteractionHandler.displayEmojiPicker(for: itemID)
case .displayReactionSummary(let itemID, let key):
@@ -271,39 +271,34 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
// MARK: - Private
private func handleTappedOnSenderDetails(userID: String) {
// We also need to make sure the user is in the joined state, otherwise we just show the details.
guard let memberProxy = roomProxy.membersPublisher.value.first(where: { $0.userID == userID && $0.membership == .join }),
let currentUserProxy,
currentUserProxy.powerLevel > memberProxy.powerLevel else {
actionsSubject.send(.displaySenderDetails(userID: userID))
return
private func handleTappedOnSenderDetails(sender: TimelineItemSender) {
let memberDetails: ManageRoomMemberDetails = if let memberProxy = roomProxy.membersPublisher.value.first(where: { $0.userID == sender.id }) {
.memberDetails(roomMember: .init(withProxy: memberProxy))
} else {
.loadingMemberDetails(sender: sender)
}
if state.canCurrentUserBan || state.canCurrentUserKick {
let member = RoomMemberDetails(withProxy: memberProxy)
let manageMemeberViewModel = ManageRoomMemberSheetViewModel(member: member,
canKick: state.canCurrentUserKick,
canBan: state.canCurrentUserBan,
roomProxy: roomProxy,
userIndicatorController: userIndicatorController,
analyticsService: analyticsService,
mediaProvider: mediaProvider)
manageMemeberViewModel.actions.sink { [weak self] action in
guard let self else { return }
switch action {
case .dismiss(let shouldShowDetails):
state.bindings.manageMemberViewModel = nil
if shouldShowDetails {
actionsSubject.send(.displaySenderDetails(userID: userID))
}
let viewModel = ManageRoomMemberSheetViewModel(memberDetails: memberDetails,
permissions: .init(canKick: state.canCurrentUserKick,
canBan: state.canCurrentUserBan,
ownPowerLevel: currentUserProxy?.powerLevel ?? 0),
roomProxy: roomProxy,
userIndicatorController: userIndicatorController,
analyticsService: analyticsService,
mediaProvider: mediaProvider)
viewModel.actions.sink { [weak self] action in
guard let self else { return }
switch action {
case .dismiss(let shouldShowDetails):
state.bindings.manageMemberViewModel = nil
if shouldShowDetails {
actionsSubject.send(.displaySenderDetails(userID: sender.id))
}
}
.store(in: &cancellables)
state.bindings.manageMemberViewModel = manageMemeberViewModel
} else {
actionsSubject.send(.displaySenderDetails(userID: userID))
}
.store(in: &cancellables)
state.bindings.manageMemberViewModel = viewModel
}
private func focusLive() {
@@ -95,7 +95,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
// sender info are read inside the `TimelineAccessibilityModifier`
.accessibilityHidden(true)
.onTapGesture {
context.send(viewAction: .tappedOnSenderDetails(userID: timelineItem.sender.id))
context.send(viewAction: .tappedOnSenderDetails(sender: timelineItem.sender))
}
.padding(.top, 8)
}