mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-29 15:52:40 +00:00
Merge pull request #2482 from vector-im/ReactionsMenuViewModel_update
ReactionsMenuViewModel: Do not perform directly reaction requests
This commit is contained in:
commit
3a2162f46c
6 changed files with 65 additions and 79 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue