From ccb0fc7de04abc2c53cb91a73fcead5f8c000595 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 18 Jun 2025 17:02:49 +0300 Subject: [PATCH] Fixes #4222 - Hide timeline item actions that the user's power level does not allow --- .../FilePreviewScreen/TimelineMediaPreviewViewModel.swift | 1 + ElementX/Sources/Screens/Timeline/TimelineModels.swift | 1 + ElementX/Sources/Screens/Timeline/TimelineViewModel.swift | 6 ++++++ .../Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift | 1 + .../View/ItemMenu/TimelineItemMenuActionProvider.swift | 5 +++-- .../Timeline/View/Style/TimelineItemBubbledStylerView.swift | 1 + ElementX/Sources/Screens/Timeline/View/TimelineView.swift | 1 + 7 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift index 3b36e2d84..9e85b0b5d 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift @@ -140,6 +140,7 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType { state.currentItemActions = switch state.currentItem { case .media(let mediaItem): TimelineItemMenuActionProvider(timelineItem: mediaItem.timelineItem, + canCurrentUserSendMessage: timelineContext.viewState.canCurrentUserSendMessage, canCurrentUserRedactSelf: timelineContext.viewState.canCurrentUserRedactSelf, canCurrentUserRedactOthers: timelineContext.viewState.canCurrentUserRedactOthers, canCurrentUserPin: timelineContext.viewState.canCurrentUserPin, diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index df8a414e0..ae2c00895 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -101,6 +101,7 @@ struct TimelineViewState: BindableState { var timelineState: TimelineState // check the doc before changing this var ownUserID: String + var canCurrentUserSendMessage = false var canCurrentUserRedactOthers = false var canCurrentUserRedactSelf = false var canCurrentUserPin = false diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index dd4f34c95..719e2c1af 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -404,6 +404,12 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { } private func updatePermissions() async { + if case let .success(value) = await roomProxy.canUser(userID: roomProxy.ownUserID, sendMessage: .roomMessage) { + state.canCurrentUserSendMessage = value + } else { + state.canCurrentUserSendMessage = false + } + if case let .success(value) = await roomProxy.canUserRedactOther(userID: roomProxy.ownUserID) { state.canCurrentUserRedactOthers = value } else { diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift index 6dcacad0b..c1972c9a5 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenu.swift @@ -342,6 +342,7 @@ struct TimelineItemMenu_Previews: PreviewProvider, TestablePreview { deliveryStatus: TimelineItemDeliveryStatus? = nil) -> (EventBasedTimelineItemProtocol, TimelineItemMenuActions)! { guard var item = makeItem(itemType: itemType) else { return nil } let provider = TimelineItemMenuActionProvider(timelineItem: item, + canCurrentUserSendMessage: true, canCurrentUserRedactSelf: true, canCurrentUserRedactOthers: false, canCurrentUserPin: true, diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift index f6c5ad7a3..352985034 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuActionProvider.swift @@ -10,6 +10,7 @@ import Foundation @MainActor struct TimelineItemMenuActionProvider { let timelineItem: RoomTimelineItemProtocol + let canCurrentUserSendMessage: Bool let canCurrentUserRedactSelf: Bool let canCurrentUserRedactOthers: Bool let canCurrentUserPin: Bool @@ -47,7 +48,7 @@ struct TimelineItemMenuActionProvider { actions.append(.endPoll(pollStartID: eventID)) } - if item.canBeRepliedTo { + if item.canBeRepliedTo, canCurrentUserSendMessage { if let messageItem = item as? EventBasedMessageTimelineItemProtocol { actions.append(.reply(isThread: messageItem.properties.isThreaded)) } else { @@ -63,7 +64,7 @@ struct TimelineItemMenuActionProvider { actions.append(.forward(itemID: item.id)) } - if item.isEditable { + if item.isEditable, canCurrentUserSendMessage { if item.supportsMediaCaption { if item.hasMediaCaption { actions.append(.editCaption) diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift index 74120560b..5375152b6 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift @@ -150,6 +150,7 @@ struct TimelineItemBubbledStylerView: View { } .contextMenu { let provider = TimelineItemMenuActionProvider(timelineItem: timelineItem, + canCurrentUserSendMessage: context.viewState.canCurrentUserSendMessage, canCurrentUserRedactSelf: context.viewState.canCurrentUserRedactSelf, canCurrentUserRedactOthers: context.viewState.canCurrentUserRedactOthers, canCurrentUserPin: context.viewState.canCurrentUserPin, diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineView.swift index 753d4ef8c..fcf50f2f4 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineView.swift @@ -27,6 +27,7 @@ struct TimelineView: View { .sheet(item: $timelineContext.debugInfo) { TimelineItemDebugView(info: $0) } .sheet(item: $timelineContext.actionMenuInfo) { info in let actions = TimelineItemMenuActionProvider(timelineItem: info.item, + canCurrentUserSendMessage: timelineContext.viewState.canCurrentUserSendMessage, canCurrentUserRedactSelf: timelineContext.viewState.canCurrentUserRedactSelf, canCurrentUserRedactOthers: timelineContext.viewState.canCurrentUserRedactOthers, canCurrentUserPin: timelineContext.viewState.canCurrentUserPin,