From 178797a17872ca2f6866443c386d2a34e3bec256 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Fri, 10 May 2024 21:38:11 +0100 Subject: [PATCH] Fix macOS timeline context menu missing the Remove item. (#2830) The necessary permissions were only being checked when presenting the long press menu. --- ElementX/Sources/Mocks/RoomProxyMock.swift | 1 + .../RoomScreenInteractionHandler.swift | 29 ++++++++++++------- .../RoomScreen/RoomScreenViewModel.swift | 4 +-- .../TimelineItems/RoomTimelineItemView.swift | 8 ++--- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/ElementX/Sources/Mocks/RoomProxyMock.swift b/ElementX/Sources/Mocks/RoomProxyMock.swift index dd78d7b6ac..d66297de09 100644 --- a/ElementX/Sources/Mocks/RoomProxyMock.swift +++ b/ElementX/Sources/Mocks/RoomProxyMock.swift @@ -115,6 +115,7 @@ extension RoomProxyMock { } canUserInviteUserIDReturnValue = .success(configuration.canUserInvite) canUserRedactOtherUserIDReturnValue = .success(false) + canUserRedactOwnUserIDReturnValue = .success(false) canUserKickUserIDClosure = { [weak self] userID in .success(self?.membersPublisher.value.first { $0.userID == userID }?.role ?? .user != .user) } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift index 3e89036cd6..deaaca4b3d 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenInteractionHandler.swift @@ -84,23 +84,16 @@ class RoomScreenInteractionHandler { self.appSettings = appSettings self.analyticsService = analyticsService pollInteractionHandler = PollInteractionHandler(analyticsService: analyticsService, roomProxy: roomProxy) + + // Set initial values for redacting from the macOS context menu. + Task { await updatePermissions() } } // MARK: Timeline Item Action Menu func displayTimelineItemActionMenu(for itemID: TimelineItemIdentifier) { Task { - if case let .success(value) = await roomProxy.canUserRedactOther(userID: roomProxy.ownUserID) { - canCurrentUserRedactOthers = value - } else { - canCurrentUserRedactOthers = false - } - - if case let .success(value) = await roomProxy.canUserRedactOwn(userID: roomProxy.ownUserID) { - canCurrentUserRedactSelf = value - } else { - canCurrentUserRedactSelf = false - } + await updatePermissions() guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID), let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else { @@ -607,6 +600,20 @@ class RoomScreenInteractionHandler { // MARK: - Private + private func updatePermissions() async { + if case let .success(value) = await roomProxy.canUserRedactOther(userID: roomProxy.ownUserID) { + canCurrentUserRedactOthers = value + } else { + canCurrentUserRedactOthers = false + } + + if case let .success(value) = await roomProxy.canUserRedactOwn(userID: roomProxy.ownUserID) { + canCurrentUserRedactSelf = value + } else { + canCurrentUserRedactSelf = false + } + } + private func canRedactItem(_ item: EventBasedTimelineItemProtocol) -> Bool { item.isOutgoing ? canCurrentUserRedactSelf : canCurrentUserRedactOthers && !roomProxy.isDirect } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index aa281fecaf..926fc645a7 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -814,7 +814,7 @@ extension RoomScreenViewModel { } private struct RoomContextKey: EnvironmentKey { - @MainActor static let defaultValue = RoomScreenViewModel.mock.context + @MainActor static let defaultValue: RoomScreenViewModel.Context? = nil } private struct FocussedEventID: EnvironmentKey { @@ -823,7 +823,7 @@ private struct FocussedEventID: EnvironmentKey { extension EnvironmentValues { /// Used to access and inject the room context without observing it - var roomContext: RoomScreenViewModel.Context { + var roomContext: RoomScreenViewModel.Context? { get { self[RoomContextKey.self] } set { self[RoomContextKey.self] = newValue } } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemView.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemView.swift index 98b0391da7..32ba1125c5 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemView.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemView.swift @@ -16,7 +16,7 @@ import SwiftUI struct RoomTimelineItemView: View { - @Environment(\.roomContext) var context: RoomScreenViewModel.Context + @Environment(\.roomContext) var context @ObservedObject var viewState: RoomTimelineItemViewState var body: some View { @@ -25,10 +25,10 @@ struct RoomTimelineItemView: View { .animation(.elementDefault, value: viewState.type) .environment(\.timelineGroupStyle, viewState.groupStyle) .onAppear { - context.send(viewAction: .itemAppeared(itemID: viewState.identifier)) + context?.send(viewAction: .itemAppeared(itemID: viewState.identifier)) } .onDisappear { - context.send(viewAction: .itemDisappeared(itemID: viewState.identifier)) + context?.send(viewAction: .itemDisappeared(itemID: viewState.identifier)) } } @@ -73,7 +73,7 @@ struct RoomTimelineItemView: View { case .poll(let item): PollRoomTimelineView(timelineItem: item) case .voice(let item): - VoiceMessageRoomTimelineView(timelineItem: item, playerState: context.viewState.audioPlayerStateProvider?(item.id) ?? AudioPlayerState(id: .timelineItemIdentifier(item.id), duration: 0)) + VoiceMessageRoomTimelineView(timelineItem: item, playerState: context?.viewState.audioPlayerStateProvider?(item.id) ?? AudioPlayerState(id: .timelineItemIdentifier(item.id), duration: 0)) case .callInvite(let item): CallInviteRoomTimelineView(timelineItem: item) }