From 19ecf906e33d8597ad7b0cb3f68247709649652d Mon Sep 17 00:00:00 2001 From: Mauro <34335419+Velin92@users.noreply.github.com> Date: Tue, 18 Jul 2023 15:51:27 +0200 Subject: [PATCH] Redacting is now displayed for moderators in groups (#1324) * basic implementation * sdk update * format * changelog --- .../Mocks/Generated/GeneratedMocks.swift | 26 +++++++++++++++++++ .../RoomScreen/RoomScreenViewModel.swift | 21 ++++++++++++--- .../Sources/Services/Room/RoomProxy.swift | 13 ++++++++++ .../Services/Room/RoomProxyProtocol.swift | 4 +++ changelog.d/1321.bugfix | 1 + 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 changelog.d/1321.bugfix diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 2ceb98d20..a026d0117 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -718,6 +718,11 @@ class RoomProxyMock: RoomProxyProtocol { set(value) { underlyingHasUnreadNotifications = value } } var underlyingHasUnreadNotifications: Bool! + var ownUserID: String { + get { return underlyingOwnUserID } + set(value) { underlyingOwnUserID = value } + } + var underlyingOwnUserID: String! var name: String? var displayName: String? var topic: String? @@ -1360,6 +1365,27 @@ class RoomProxyMock: RoomProxyProtocol { return uploadAvatarMediaReturnValue } } + //MARK: - canUserRedact + + var canUserRedactUserIDCallsCount = 0 + var canUserRedactUserIDCalled: Bool { + return canUserRedactUserIDCallsCount > 0 + } + var canUserRedactUserIDReceivedUserID: String? + var canUserRedactUserIDReceivedInvocations: [String] = [] + var canUserRedactUserIDReturnValue: Result! + var canUserRedactUserIDClosure: ((String) async -> Result)? + + func canUserRedact(userID: String) async -> Result { + canUserRedactUserIDCallsCount += 1 + canUserRedactUserIDReceivedUserID = userID + canUserRedactUserIDReceivedInvocations.append(userID) + if let canUserRedactUserIDClosure = canUserRedactUserIDClosure { + return await canUserRedactUserIDClosure(userID) + } else { + return canUserRedactUserIDReturnValue + } + } } class RoomTimelineProviderMock: RoomTimelineProviderProtocol { var updatePublisher: AnyPublisher { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 820eb6173..7f02b9e77 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -34,6 +34,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol private let analytics: AnalyticsService private unowned let userIndicatorController: UserIndicatorControllerProtocol private let notificationCenterProtocol: NotificationCenterProtocol + + private var canCurrentUserRedact = false init(timelineController: RoomTimelineControllerProtocol, mediaProvider: MediaProviderProtocol, @@ -104,7 +106,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol case .markRoomAsRead: Task { await markRoomAsRead() } case .timelineItemMenu(let itemID): - showTimelineItemActionMenu(for: itemID) + Task { + if case let .success(value) = await roomProxy.canUserRedact(userID: roomProxy.ownUserID) { + canCurrentUserRedact = value + } else { + canCurrentUserRedact = false + } + showTimelineItemActionMenu(for: itemID) + } case .timelineItemMenuAction(let itemID, let action): processTimelineItemMenuAction(action, itemID: itemID) case .displayCameraPicker: @@ -408,9 +417,11 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol actions.append(.copyPermalink) - if item.isOutgoing { + if canRedactItem(item) { actions.append(.redact) - } else { + } + + if !item.isOutgoing { actions.append(.report) } @@ -424,6 +435,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol return .init(actions: actions, debugActions: debugActions) } + + private func canRedactItem(_ item: EventBasedTimelineItemProtocol) -> Bool { + item.isOutgoing || (canCurrentUserRedact && !roomProxy.isDirect) + } // swiftlint:disable:next cyclomatic_complexity function_body_length private func processTimelineItemMenuAction(_ action: TimelineItemMenuAction, itemID: TimelineItemIdentifier) { diff --git a/ElementX/Sources/Services/Room/RoomProxy.swift b/ElementX/Sources/Services/Room/RoomProxy.swift index 88f3810b9..32abf141c 100644 --- a/ElementX/Sources/Services/Room/RoomProxy.swift +++ b/ElementX/Sources/Services/Room/RoomProxy.swift @@ -55,6 +55,10 @@ class RoomProxy: RoomProxyProtocol { innerTimelineProvider } + var ownUserID: String { + room.ownUserId() + } + deinit { roomTimelineObservationToken?.cancel() backPaginationStateObservationToken?.cancel() @@ -647,6 +651,15 @@ class RoomProxy: RoomProxyProtocol { } } + func canUserRedact(userID: String) async -> Result { + do { + return try await .success(room.canUserRedact(userId: userID)) + } catch { + MXLog.error("Failed checking if the user can redact with error: \(error)") + return .failure(.failedCheckingPermission) + } + } + // MARK: - Private /// Force the timeline to load member details so it can populate sender profiles whenever we add a timeline listener diff --git a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift index b33dbab6a..2aa2d524c 100644 --- a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -41,6 +41,7 @@ enum RoomProxyError: Error, Equatable { case failedSettingRoomTopic case failedRemovingAvatar case failedUploadingAvatar + case failedCheckingPermission } // sourcery: AutoMockable @@ -54,6 +55,7 @@ protocol RoomProxyProtocol { var canonicalAlias: String? { get } var alternativeAliases: [String] { get } var hasUnreadNotifications: Bool { get } + var ownUserID: String { get } var name: String? { get } var displayName: String? { get } @@ -159,6 +161,8 @@ protocol RoomProxyProtocol { func removeAvatar() async -> Result func uploadAvatar(media: MediaInfo) async -> Result + + func canUserRedact(userID: String) async -> Result } extension RoomProxyProtocol { diff --git a/changelog.d/1321.bugfix b/changelog.d/1321.bugfix new file mode 100644 index 000000000..38a5de183 --- /dev/null +++ b/changelog.d/1321.bugfix @@ -0,0 +1 @@ +Moderators can now remove other people messages if they have permission in non direct rooms. \ No newline at end of file