diff --git a/Riot/Modules/Room/ReactionHistory/ReactionHistoryBridgeCoordinatorPresenter.swift b/Riot/Modules/Room/ReactionHistory/ReactionHistoryBridgeCoordinatorPresenter.swift new file mode 100644 index 000000000..9804af4e8 --- /dev/null +++ b/Riot/Modules/Room/ReactionHistory/ReactionHistoryBridgeCoordinatorPresenter.swift @@ -0,0 +1,89 @@ +/* + Copyright 2019 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import Foundation + +@objc protocol ReactionHistoryCoordinatorBridgePresenterDelegate { + func reactionHistoryCoordinatorBridgePresenterDelegateDidClose(_ coordinatorBridgePresenter: ReactionHistoryCoordinatorBridgePresenter) +} + +/// ReactionHistoryCoordinatorBridgePresenter enables to start ReactionHistoryCoordinator from a view controller. +/// This bridge is used while waiting for global usage of coordinator pattern. +@objcMembers +final class ReactionHistoryCoordinatorBridgePresenter: NSObject { + + // MARK: - Properties + + // MARK: Private + + private let session: MXSession + private let roomId: String + private let eventId: String + private var coordinator: ReactionHistoryCoordinator? + + // MARK: Public + + var isPresenting: Bool { + return self.coordinator != nil + } + + weak var delegate: ReactionHistoryCoordinatorBridgePresenterDelegate? + + // MARK: - Setup + + init(session: MXSession, roomId: String, eventId: String) { + self.session = session + self.roomId = roomId + self.eventId = eventId + super.init() + } + + // MARK: - Public + + func present(from viewController: UIViewController, animated: Bool) { + + let reactionHistoryCoordinator = ReactionHistoryCoordinator(session: self.session, roomId: self.roomId, eventId: self.eventId) + reactionHistoryCoordinator.delegate = self + + let coordinatorPresentable = reactionHistoryCoordinator.toPresentable() + coordinatorPresentable.modalPresentationStyle = .formSheet + viewController.present(coordinatorPresentable, animated: animated, completion: nil) + + reactionHistoryCoordinator.start() + + self.coordinator = reactionHistoryCoordinator + } + + func dismiss(animated: Bool, completion: (() -> Void)?) { + guard let coordinator = self.coordinator else { + return + } + coordinator.toPresentable().dismiss(animated: animated) { + self.coordinator = nil + + if let completion = completion { + completion() + } + } + } +} + +// MARK: - ReactionHistoryCoordinatorDelegate +extension ReactionHistoryCoordinatorBridgePresenter: ReactionHistoryCoordinatorDelegate { + func reactionHistoryCoordinatorDidClose(_ coordinator: ReactionHistoryCoordinatorType) { + self.delegate?.reactionHistoryCoordinatorBridgePresenterDelegateDidClose(self) + } +} diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index e40e31cd7..50eba1739 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -124,7 +124,8 @@ #import "Riot-Swift.h" @interface RoomViewController () + ReactionsMenuViewModelCoordinatorDelegate, EditHistoryCoordinatorBridgePresenterDelegate, MXKDocumentPickerPresenterDelegate, EmojiPickerCoordinatorBridgePresenterDelegate, + ReactionHistoryCoordinatorBridgePresenterDelegate> { // The expanded header ExpandedRoomTitleView *expandedHeader; @@ -224,6 +225,7 @@ @property (nonatomic, strong) EditHistoryCoordinatorBridgePresenter *editHistoryPresenter; @property (nonatomic, strong) MXKDocumentPickerPresenter *documentPickerPresenter; @property (nonatomic, strong) EmojiPickerCoordinatorBridgePresenter *emojiPickerCoordinatorBridgePresenter; +@property (nonatomic, strong) ReactionHistoryCoordinatorBridgePresenter *reactionHistoryCoordinatorBridgePresenter; @end @@ -1531,6 +1533,21 @@ } } +- (void)showReactionHistoryForEventId:(NSString*)eventId animated:(BOOL)animated +{ + if (self.reactionHistoryCoordinatorBridgePresenter.isPresenting) + { + return; + } + + ReactionHistoryCoordinatorBridgePresenter *presenter = [[ReactionHistoryCoordinatorBridgePresenter alloc] initWithSession:self.mainSession roomId:self.roomDataSource.roomId eventId:eventId]; + presenter.delegate = self; + + [presenter presentFrom:self animated:animated]; + + self.reactionHistoryCoordinatorBridgePresenter = presenter; +} + #pragma mark - Hide/Show expanded header - (void)showExpandedHeader:(BOOL)isVisible @@ -2173,6 +2190,14 @@ [self handleLongPressFromCell:cell withTappedEvent:tappedEvent]; } } + else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellLongPressOnReactionView]) + { + NSString *tappedEventId = userInfo[kMXKRoomBubbleCellEventIdKey]; + if (tappedEventId) + { + [self showReactionHistoryForEventId:tappedEventId animated:YES]; + } + } else { // Keep default implementation for other actions @@ -2533,6 +2558,20 @@ }]]; + // Add reaction history if event contains reactions + if (roomBubbleTableViewCell.bubbleData.reactions[selectedEvent.eventId].aggregatedReactionsWithNonZeroCount) + { + [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_reaction_history", @"Vector", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + + [self cancelEventSelection]; + + // Show reaction history + [self showReactionHistoryForEventId:selectedEvent.eventId animated:YES]; + }]]; + } + [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_source", @"Vector", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -5456,5 +5495,14 @@ self.emojiPickerCoordinatorBridgePresenter = nil; } +#pragma mark - ReactionHistoryCoordinatorBridgePresenterDelegate + +- (void)reactionHistoryCoordinatorBridgePresenterDelegateDidClose:(ReactionHistoryCoordinatorBridgePresenter *)coordinatorBridgePresenter +{ + [coordinatorBridgePresenter dismissWithAnimated:YES completion:^{ + self.reactionHistoryCoordinatorBridgePresenter = nil; + }]; +} + @end