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 import UIKit
final class ReactionsMenuViewModel: ReactionsMenuViewModelType { @objc final class ReactionsMenuViewModel: NSObject, ReactionsMenuViewModelType {
// MARK: - Properties // MARK: - Properties
@ -33,15 +33,17 @@ final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
private(set) var isDislikeButtonSelected: Bool = false private(set) var isDislikeButtonSelected: Bool = false
weak var viewDelegate: ReactionsMenuViewModelDelegate? weak var viewDelegate: ReactionsMenuViewModelDelegate?
weak var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate? @objc weak var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate?
// MARK: - Setup // MARK: - Setup
init(aggregations: MXAggregations, roomId: String, eventId: String) { @objc init(aggregations: MXAggregations, roomId: String, eventId: String) {
self.aggregations = aggregations self.aggregations = aggregations
self.roomId = roomId self.roomId = roomId
self.eventId = eventId self.eventId = eventId
super.init()
self.loadData() self.loadData()
self.listenToDataUpdate() self.listenToDataUpdate()
} }
@ -72,7 +74,7 @@ final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
return return
} }
self.react(withReaction: theReaction, selected: theNewState, delegate: self.coordinatorDelegate) self.react(withReaction: theReaction, selected: theNewState)
} }
// MARK: - Private // MARK: - Private
@ -123,53 +125,20 @@ 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 required, unreact first
if selected { if selected {
self.ensure3StateButtons(withReaction: reaction) self.ensure3StateButtons(withReaction: reaction)
} }
let reactionString = reaction.rawValue
if selected { if selected {
self.aggregations.sendReaction(reaction.rawValue, toEvent: self.eventId, inRoom: self.roomId, success: {[weak self] _ in self.coordinatorDelegate?.reactionsMenuViewModel(self, didAddReaction: reactionString, forEventId: self.eventId)
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)
})
} else { } else {
self.coordinatorDelegate?.reactionsMenuViewModel(self, didRemoveReaction: reactionString, forEventId: self.eventId)
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)
})
} }
delegate?.reactionsMenuViewModel(self, didSendReaction: reaction.rawValue, isAddReaction: !selected)
} }
// We can like, dislike, be indifferent but we cannot like & dislike at the same time // 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) func reactionsMenuViewModelDidUpdate(_ viewModel: ReactionsMenuViewModelType)
} }
protocol ReactionsMenuViewModelCoordinatorDelegate: class { @objc protocol ReactionsMenuViewModelCoordinatorDelegate: class {
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didSendReaction reaction: String, isAddReaction: Bool) func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModel, didAddReaction reaction: String, forEventId eventId: String)
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionComplete reaction: String, isAddReaction: Bool) func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModel, didRemoveReaction reaction: String, forEventId eventId: String)
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, didReactionFailedWithError error: Error, reaction: String, isAddReaction: Bool)
} }

View file

@ -107,9 +107,7 @@ final class RoomContextualMenuPresenter: NSObject {
} }
} }
func showReactionsMenu(forEvent eventId: String, inRoom roomId: String, session: MXSession, func showReactionsMenu(reactionsMenuViewModel: ReactionsMenuViewModel, aroundFrame frame: CGRect) {
aroundFrame frame: CGRect) {
let reactionsMenuViewModel = ReactionsMenuViewModel(aggregations: session.aggregations, roomId: roomId, eventId: eventId)
self.roomContextualMenuViewController?.showReactionsMenu(withViewModel: reactionsMenuViewModel, aroundFrame: frame) 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) { func showReactionsMenu(withViewModel viewModel: ReactionsMenuViewModel, aroundFrame frame: CGRect) {
self.reactionsMenuView.viewModel = viewModel self.reactionsMenuView.viewModel = viewModel
self.reactionsMenuView.viewModel?.coordinatorDelegate = self
self.reactionsMenuView.isHidden = false self.reactionsMenuView.isHidden = false
let menuHeight = self.reactionsMenuViewHeightConstraint.constant 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 // MARK: - UIGestureRecognizerDelegate
extension RoomContextualMenuViewController: UIGestureRecognizerDelegate { extension RoomContextualMenuViewController: UIGestureRecognizerDelegate {

View file

@ -594,19 +594,19 @@
- (void)bubbleReactionsViewModel:(BubbleReactionsViewModel *)viewModel didAddReaction:(MXReactionCount *)reactionCount forEventId:(NSString *)eventId - (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 - (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" #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 // The expanded header
ExpandedRoomTitleView *expandedHeader; ExpandedRoomTitleView *expandedHeader;
@ -216,6 +217,7 @@
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView; @property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
@property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter; @property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter;
@property (nonatomic, strong) MXKErrorAlertPresentation *errorPresenter;
@end @end
@ -409,6 +411,7 @@
} }
self.roomContextualMenuPresenter = [RoomContextualMenuPresenter new]; self.roomContextualMenuPresenter = [RoomContextualMenuPresenter new];
self.errorPresenter = [MXKErrorAlertPresentation new];
// Observe user interface theme change. // Observe user interface theme change.
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
@ -5126,7 +5129,13 @@
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]; [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 @end