Merge pull request #2482 from vector-im/ReactionsMenuViewModel_update

ReactionsMenuViewModel: Do not perform directly reaction requests
This commit is contained in:
SBiOSoftWhare 2019-06-11 17:51:28 +02:00 committed by GitHub
commit 3a2162f46c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 79 deletions

View file

@ -16,7 +16,7 @@
import UIKit
final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
@objc final class ReactionsMenuViewModel: NSObject, ReactionsMenuViewModelType {
// MARK: - Properties
@ -33,14 +33,16 @@ final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
private(set) var isDislikeButtonSelected: Bool = false
weak var viewDelegate: ReactionsMenuViewModelDelegate?
weak var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate?
@objc weak var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate?
// MARK: - Setup
init(aggregations: MXAggregations, roomId: String, eventId: String) {
@objc init(aggregations: MXAggregations, roomId: String, eventId: String) {
self.aggregations = aggregations
self.roomId = roomId
self.eventId = eventId
super.init()
self.loadData()
self.listenToDataUpdate()
@ -72,7 +74,7 @@ final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
return
}
self.react(withReaction: theReaction, selected: theNewState, delegate: self.coordinatorDelegate)
self.react(withReaction: theReaction, selected: theNewState)
}
// MARK: - Private
@ -122,54 +124,21 @@ final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
}
}
}
private func react(withReaction reaction: ReactionsMenuReaction, selected: Bool, delegate: ReactionsMenuViewModelCoordinatorDelegate? = nil) {
private func react(withReaction reaction: ReactionsMenuReaction, selected: Bool) {
// If required, unreact first
if selected {
self.ensure3StateButtons(withReaction: reaction)
}
let reactionString = reaction.rawValue
if selected {
self.aggregations.sendReaction(reaction.rawValue, toEvent: self.eventId, inRoom: self.roomId, success: {[weak self] _ in
guard let sself = self else {
return
}
delegate?.reactionsMenuViewModel(sself, didReactionComplete: reaction.rawValue, isAddReaction: true)
}, failure: {[weak self] (error) in
print("[ReactionsMenuViewModel] react: Error: \(error)")
guard let sself = self else {
return
}
delegate?.reactionsMenuViewModel(sself, didReactionFailedWithError: error, reaction: reaction.rawValue, isAddReaction: true)
})
self.coordinatorDelegate?.reactionsMenuViewModel(self, didAddReaction: reactionString, forEventId: self.eventId)
} else {
self.aggregations.unReact(onReaction: reaction.rawValue, toEvent: self.eventId, inRoom: self.roomId, success: {[weak self] in
guard let sself = self else {
return
}
delegate?.reactionsMenuViewModel(sself, didReactionComplete: reaction.rawValue, isAddReaction: false)
}, failure: {[weak self] (error) in
print("[ReactionsMenuViewModel] react: Error: \(error)")
guard let sself = self else {
return
}
delegate?.reactionsMenuViewModel(sself, didReactionFailedWithError: error, reaction: reaction.rawValue, isAddReaction: false)
})
self.coordinatorDelegate?.reactionsMenuViewModel(self, didRemoveReaction: reactionString, forEventId: self.eventId)
}
delegate?.reactionsMenuViewModel(self, didSendReaction: reaction.rawValue, isAddReaction: !selected)
}
// We can like, dislike, be indifferent but we cannot like & dislike at the same time

View file

@ -20,10 +20,9 @@ protocol ReactionsMenuViewModelDelegate: class {
func reactionsMenuViewModelDidUpdate(_ viewModel: ReactionsMenuViewModelType)
}
protocol ReactionsMenuViewModelCoordinatorDelegate: class {
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didSendReaction reaction: String, isAddReaction: Bool)
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionComplete reaction: String, isAddReaction: Bool)
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionFailedWithError error: Error, reaction: String, isAddReaction: Bool)
@objc protocol ReactionsMenuViewModelCoordinatorDelegate: class {
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModel, didAddReaction reaction: String, forEventId eventId: String)
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModel, didRemoveReaction reaction: String, forEventId eventId: String)
}

View file

@ -106,10 +106,8 @@ final class RoomContextualMenuPresenter: NSObject {
animationCompletionInstructions()
}
}
func showReactionsMenu(forEvent eventId: String, inRoom roomId: String, session: MXSession,
aroundFrame frame: CGRect) {
let reactionsMenuViewModel = ReactionsMenuViewModel(aggregations: session.aggregations, roomId: roomId, eventId: eventId)
func showReactionsMenu(reactionsMenuViewModel: ReactionsMenuViewModel, aroundFrame frame: CGRect) {
self.roomContextualMenuViewController?.showReactionsMenu(withViewModel: reactionsMenuViewModel, aroundFrame: frame)
}
}

View file

@ -99,7 +99,6 @@ final class RoomContextualMenuViewController: UIViewController, Themable {
func showReactionsMenu(withViewModel viewModel: ReactionsMenuViewModel, aroundFrame frame: CGRect) {
self.reactionsMenuView.viewModel = viewModel
self.reactionsMenuView.viewModel?.coordinatorDelegate = self
self.reactionsMenuView.isHidden = false
let menuHeight = self.reactionsMenuViewHeightConstraint.constant
@ -151,22 +150,6 @@ final class RoomContextualMenuViewController: UIViewController, Themable {
}
}
// MARK: - ReactionsMenuViewModelCoordinatorDelegate
extension RoomContextualMenuViewController: ReactionsMenuViewModelCoordinatorDelegate {
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didSendReaction reaction: String, isAddReaction: Bool) {
self.delegate?.roomContextualMenuViewControllerDidReaction(self)
}
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionComplete reaction: String, isAddReaction: Bool) {
}
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionFailedWithError error: Error, reaction: String, isAddReaction: Bool) {
self.errorPresenter?.presentError(from: self, forError: error, animated: true) {
}
}
}
// MARK: - UIGestureRecognizerDelegate
extension RoomContextualMenuViewController: UIGestureRecognizerDelegate {

View file

@ -594,19 +594,19 @@
- (void)bubbleReactionsViewModel:(BubbleReactionsViewModel *)viewModel didAddReaction:(MXReactionCount *)reactionCount forEventId:(NSString *)eventId
{
[self.mxSession.aggregations sendReaction:reactionCount.reaction toEvent:eventId inRoom:self.roomId success:^(NSString * _Nonnull eventId) {
[self addReaction:reactionCount.reaction forEventId:eventId success:^(NSString *eventId) {
} failure:^(NSError *error) {
} failure:^(NSError * _Nonnull error) {
NSLog(@"[MXKRoomDataSource] Fail to send reaction on eventId: %@", eventId);
}];
}
- (void)bubbleReactionsViewModel:(BubbleReactionsViewModel *)viewModel didRemoveReaction:(MXReactionCount * _Nonnull)reactionCount forEventId:(NSString * _Nonnull)eventId
{
[self.mxSession.aggregations unReactOnReaction:reactionCount.reaction toEvent:eventId inRoom:self.roomId success:^{
[self removeReaction:reactionCount.reaction forEventId:eventId success:^{
} failure:^(NSError *error) {
} failure:^(NSError * _Nonnull error) {
NSLog(@"[MXKRoomDataSource] Fail to unreact on eventId: %@", eventId);
}];
}

View file

@ -123,7 +123,8 @@
#import "Riot-Swift.h"
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate>
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
ReactionsMenuViewModelCoordinatorDelegate>
{
// The expanded header
ExpandedRoomTitleView *expandedHeader;
@ -216,6 +217,7 @@
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
@property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter;
@property (nonatomic, strong) MXKErrorAlertPresentation *errorPresenter;
@end
@ -409,6 +411,7 @@
}
self.roomContextualMenuPresenter = [RoomContextualMenuPresenter new];
self.errorPresenter = [MXKErrorAlertPresentation new];
// Observe user interface theme change.
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
@ -5124,9 +5127,15 @@
bubbleComponentFrame = roomBubbleTableViewCell.frame;
}
CGRect bubbleComponentFrameInOverlayView = [self.bubblesTableView convertRect:bubbleComponentFrame toView:self.overlayContainerView];
CGRect bubbleComponentFrameInOverlayView = [self.bubblesTableView convertRect:bubbleComponentFrame toView:self.overlayContainerView];
[self.roomContextualMenuPresenter showReactionsMenuForEvent:event.eventId inRoom:event.roomId session:self.mainSession aroundFrame:bubbleComponentFrameInOverlayView];
NSString *roomId = self.roomDataSource.roomId;
MXAggregations *aggregations = self.mainSession.aggregations;
ReactionsMenuViewModel *reactionsMenuViewModel = [[ReactionsMenuViewModel alloc] initWithAggregations:aggregations roomId:roomId eventId:event.eventId];
reactionsMenuViewModel.coordinatorDelegate = self;
[self.roomContextualMenuPresenter showReactionsMenuWithReactionsMenuViewModel:reactionsMenuViewModel aroundFrame:bubbleComponentFrameInOverlayView];
}
}
@ -5181,5 +5190,33 @@
[self hideContextualMenuAnimated:YES];
}
#pragma mark - ReactionsMenuViewModelCoordinatorDelegate
- (void)reactionsMenuViewModel:(ReactionsMenuViewModel *)viewModel didAddReaction:(NSString *)reaction forEventId:(NSString *)eventId
{
MXWeakify(self);
[self.roomDataSource addReaction:reaction forEventId:eventId success:^(NSString *eventId) {
} failure:^(NSError *error) {
MXStrongifyAndReturnIfNil(self);
[self.errorPresenter presentErrorFromViewController:self forError:error animated:YES handler:nil];
}];
}
- (void)reactionsMenuViewModel:(ReactionsMenuViewModel *)viewModel didRemoveReaction:(NSString *)reaction forEventId:(NSString *)eventId
{
MXWeakify(self);
[self.roomDataSource removeReaction:reaction forEventId:eventId success:^{
} failure:^(NSError *error) {
MXStrongifyAndReturnIfNil(self);
[self.errorPresenter presentErrorFromViewController:self forError:error animated:YES handler:nil];
}];
}
@end