Merge pull request #2534 from vector-im/context_menu_UX_improvements

Room: Improve context menu UX
This commit is contained in:
SBiOSoftWhare
2019-06-27 16:36:17 +02:00
committed by GitHub
5 changed files with 441 additions and 479 deletions
+359 -380
View File
@@ -216,6 +216,8 @@
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
@property (nonatomic, strong) RoomContextualMenuViewController *roomContextualMenuViewController;
@property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter;
@property (nonatomic, strong) MXKErrorAlertPresentation *errorPresenter;
@property (nonatomic, strong) NSString *textMessageBeforeEditing;
@@ -1521,7 +1523,7 @@
{
if (event && !customizedRoomDataSource.selectedEventId)
{
[self showContextualMenuForEvent:event cell:cell animated:YES];
[self showContextualMenuForEvent:event fromSingleTapGesture:NO cell:cell animated:YES];
}
}
@@ -2085,7 +2087,7 @@
}
else
{
[self showContextualMenuForEvent:tappedEvent cell:cell animated:YES];
[self showContextualMenuForEvent:tappedEvent fromSingleTapGesture:YES cell:cell animated:YES];
}
}
}
@@ -2103,7 +2105,7 @@
if (selectedEvent)
{
[self showEditButtonAlertMenuForEvent:selectedEvent inCell:cell level:0];
[self showContextualMenuForEvent:selectedEvent fromSingleTapGesture:YES cell:cell animated:YES];
}
}
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnAttachmentView])
@@ -2180,8 +2182,8 @@
}
}
// Display the edit menu on 2 pages/levels.
- (void)showEditButtonAlertMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXKCellRendering>)cell level:(NSUInteger)level;
// Display the additiontal event actions menu
- (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXKCellRendering>)cell animated:(BOOL)animated
{
MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = (MXKRoomBubbleTableViewCell *)cell;
MXKAttachment *attachment = roomBubbleTableViewCell.bubbleData.attachment;
@@ -2195,42 +2197,39 @@
__weak __typeof(self) weakSelf = self;
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
if (level == 0)
// Add actions for a failed event
if (selectedEvent.sentState == MXEventSentStateFailed)
{
// Add actions for a failed event
if (selectedEvent.sentState == MXEventSentStateFailed)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_resend", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_resend", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Let the datasource resend. It will manage local echo, etc.
[self.roomDataSource resendEventWithEventId:selectedEvent.eventId success:nil failure:nil];
}
[self cancelEventSelection];
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_delete", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// Let the datasource resend. It will manage local echo, etc.
[self.roomDataSource resendEventWithEventId:selectedEvent.eventId success:nil failure:nil];
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_delete", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
}
[self cancelEventSelection];
}]];
}
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
}
}]];
}
// Add actions for text message
@@ -2248,171 +2247,160 @@
selectedComponent = nil;
}
if (level == 0)
// Check status of the selected event
if (selectedEvent.sentState == MXEventSentStatePreparing ||
selectedEvent.sentState == MXEventSentStateEncrypting ||
selectedEvent.sentState == MXEventSentStateSending)
{
// Check status of the selected event
if (selectedEvent.sentState == MXEventSentStatePreparing ||
selectedEvent.sentState == MXEventSentStateEncrypting ||
selectedEvent.sentState == MXEventSentStateSending)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Cancel and remove the outgoing message
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
[self cancelEventSelection];
}
}]];
}
}
if (level == 0)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_quote", @"Vector", nil)
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Quote the message a la Markdown into the input toolbar composer
self.inputToolbarView.textMessage = [NSString stringWithFormat:@"%@\n>%@\n\n", self.inputToolbarView.textMessage, selectedComponent.textMessage];
// And display the keyboard
[self.inputToolbarView becomeFirstResponder];
}
}]];
handler:^(UIAlertAction * action)
{
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Cancel and remove the outgoing message
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
[self cancelEventSelection];
}
}]];
}
if (level == 1)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_share", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_quote", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
if (weakSelf)
[self cancelEventSelection];
// Quote the message a la Markdown into the input toolbar composer
self.inputToolbarView.textMessage = [NSString stringWithFormat:@"%@\n>%@\n\n", self.inputToolbarView.textMessage, selectedComponent.textMessage];
// And display the keyboard
[self.inputToolbarView becomeFirstResponder];
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_share", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
NSArray *activityItems = @[selectedComponent.textMessage];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
if (activityViewController)
{
typeof(self) self = weakSelf;
activityViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
activityViewController.popoverPresentationController.sourceView = roomBubbleTableViewCell;
activityViewController.popoverPresentationController.sourceRect = roomBubbleTableViewCell.bounds;
[self cancelEventSelection];
NSArray *activityItems = @[selectedComponent.textMessage];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
if (activityViewController)
{
activityViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
activityViewController.popoverPresentationController.sourceView = roomBubbleTableViewCell;
activityViewController.popoverPresentationController.sourceRect = roomBubbleTableViewCell.bounds;
[self presentViewController:activityViewController animated:YES completion:nil];
}
[self presentViewController:activityViewController animated:YES completion:nil];
}
}]];
}
}
}]];
}
else // Add action for attachment
{
if (level == 0)
if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo)
{
if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo)
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_save", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
[self startActivityIndicator];
[attachment save:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
// Start animation in case of download during attachment preparing
[roomBubbleTableViewCell startProgressUI];
}
}]];
}
// Check status of the selected event
if (selectedEvent.sentState == MXEventSentStatePreparing ||
selectedEvent.sentState == MXEventSentStateEncrypting ||
selectedEvent.sentState == MXEventSentStateUploading ||
selectedEvent.sentState == MXEventSentStateSending)
{
// Upload id is stored in attachment url (nasty trick)
NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.contentURL;
if ([MXMediaManager existingUploaderWithId:uploadId])
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_save", @"Vector", nil)
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// Get again the loader
MXMediaLoader *loader = [MXMediaManager existingUploaderWithId:uploadId];
if (loader)
{
[loader cancel];
}
// Hide the progress animation
roomBubbleTableViewCell.progressView.hidden = YES;
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Remove the outgoing message and its related cached file.
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheFilePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.thumbnailCachePath error:nil];
// Cancel and remove the outgoing message
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
[self cancelEventSelection];
[self startActivityIndicator];
[attachment save:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
// Start animation in case of download during attachment preparing
[roomBubbleTableViewCell startProgressUI];
}
}]];
}
// Check status of the selected event
if (selectedEvent.sentState == MXEventSentStatePreparing ||
selectedEvent.sentState == MXEventSentStateEncrypting ||
selectedEvent.sentState == MXEventSentStateUploading ||
selectedEvent.sentState == MXEventSentStateSending)
{
// Upload id is stored in attachment url (nasty trick)
NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.contentURL;
if ([MXMediaManager existingUploaderWithId:uploadId])
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// Get again the loader
MXMediaLoader *loader = [MXMediaManager existingUploaderWithId:uploadId];
if (loader)
{
[loader cancel];
}
// Hide the progress animation
roomBubbleTableViewCell.progressView.hidden = YES;
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Remove the outgoing message and its related cached file.
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheFilePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.thumbnailCachePath error:nil];
// Cancel and remove the outgoing message
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
[self cancelEventSelection];
}
}]];
}
}
}
if (level == 1 && (attachment.type != MXKAttachmentTypeSticker))
if (attachment.type != MXKAttachmentTypeSticker)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_share", @"Vector", nil)
style:UIAlertActionStyleDefault
@@ -2457,7 +2445,7 @@
if (selectedEvent.sentState == MXEventSentStateSent)
{
// Check whether download is in progress
if (level == 0 && selectedEvent.isMediaAttachment)
if (selectedEvent.isMediaAttachment)
{
NSString *downloadId = roomBubbleTableViewCell.bubbleData.attachment.downloadId;
if ([MXMediaManager existingDownloaderWithIdentifier:downloadId])
@@ -2486,48 +2474,11 @@
}
}
if (level == 0)
// Do not allow to redact the event that enabled encryption (m.room.encryption)
// because it breaks everything
if (selectedEvent.eventType != MXEventTypeRoomEncryption)
{
// Do not allow to redact the event that enabled encryption (m.room.encryption)
// because it breaks everything
if (selectedEvent.eventType != MXEventTypeRoomEncryption)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_redact", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
[self startActivityIndicator];
[self.roomDataSource.room redactEvent:selectedEvent.eventId reason:nil success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Redact event (%@) failed", selectedEvent.eventId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
}
}
if (level == 1)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_permalink", @"Vector", nil)
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_redact", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
@@ -2537,37 +2488,65 @@
[self cancelEventSelection];
// Create a matrix.to permalink that is common to all matrix clients
NSString *permalink = [MXTools permalinkToEvent:selectedEvent.eventId inRoom:selectedEvent.roomId];
[self startActivityIndicator];
// Create a room matrix.to permalink
[[UIPasteboard generalPasteboard] setString:permalink];
}
}]];
}
if (level == 1)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_source", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Display event details
[self showEventDetails:selectedEvent];
[self.roomDataSource.room redactEvent:selectedEvent.eventId reason:nil success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Redact event (%@) failed", selectedEvent.eventId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
}
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_permalink", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Create a matrix.to permalink that is common to all matrix clients
NSString *permalink = [MXTools permalinkToEvent:selectedEvent.eventId inRoom:selectedEvent.roomId];
// Create a room matrix.to permalink
[[UIPasteboard generalPasteboard] setString:permalink];
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_source", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Display event details
[self showEventDetails:selectedEvent];
}
}]];
// Add "View Decrypted Source" for e2ee event we can decrypt
if (level == 1 && selectedEvent.isEncrypted && selectedEvent.clearEvent)
if (selectedEvent.isEncrypted && selectedEvent.clearEvent)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_decrypted_source", @"Vector", nil)
style:UIAlertActionStyleDefault
@@ -2586,117 +2565,115 @@
}]];
}
if (level == 1)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_report", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_report", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
if (weakSelf)
{
typeof(self) self = weakSelf;
[self cancelEventSelection];
// Prompt user to enter a description of the problem content.
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_reason", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.secureTextEntry = NO;
textField.placeholder = nil;
textField.keyboardType = UIKeyboardTypeDefault;
}];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
NSString *text = [self->currentAlert textFields].firstObject.text;
self->currentAlert = nil;
[self startActivityIndicator];
[self.roomDataSource.room reportEvent:selectedEvent.eventId score:-100 reason:text success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
// Prompt user to ignore content from this user
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_ignore_user", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self startActivityIndicator];
// Add the user to the blacklist: ignored users
[self.mainSession ignoreUsers:@[selectedEvent.sender] success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Ignore user (%@) failed", selectedEvent.sender);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[self presentViewController:self->currentAlert animated:YES completion:nil];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Report event (%@) failed", selectedEvent.eventId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[self presentViewController:self->currentAlert animated:YES completion:nil];
}
[self cancelEventSelection];
}]];
}
if (level == 1 && self.roomDataSource.room.summary.isEncrypted)
// Prompt user to enter a description of the problem content.
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_reason", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.secureTextEntry = NO;
textField.placeholder = nil;
textField.keyboardType = UIKeyboardTypeDefault;
}];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
NSString *text = [self->currentAlert textFields].firstObject.text;
self->currentAlert = nil;
[self startActivityIndicator];
[self.roomDataSource.room reportEvent:selectedEvent.eventId score:-100 reason:text success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
// Prompt user to ignore content from this user
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_ignore_user", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self startActivityIndicator];
// Add the user to the blacklist: ignored users
[self.mainSession ignoreUsers:@[selectedEvent.sender] success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Ignore user (%@) failed", selectedEvent.sender);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[self presentViewController:self->currentAlert animated:YES completion:nil];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomVC] Report event (%@) failed", selectedEvent.eventId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[self presentViewController:self->currentAlert animated:YES completion:nil];
}
}]];
if (self.roomDataSource.room.summary.isEncrypted)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_encryption", @"Vector", nil)
style:UIAlertActionStyleDefault
@@ -2713,25 +2690,6 @@
}]];
}
if (level == 0)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_more", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Show the next level of options
[self showEditButtonAlertMenuForEvent:selectedEvent inCell:cell level:1];
}
}]];
}
}
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"cancel", @"Vector", nil)
@@ -2749,10 +2707,24 @@
// Do not display empty action sheet
if (currentAlert.actions.count > 1)
{
NSArray *components = roomBubbleTableViewCell.bubbleData.bubbleComponents;
NSInteger index = 0;
for (MXKRoomBubbleComponent *component in components)
{
if ([component.event.eventId isEqualToString:selectedEvent.eventId])
{
break;
}
index++;
}
CGRect sourceRect = [roomBubbleTableViewCell componentFrameInContentViewForIndex:index];
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCEventMenuAlert"];
[currentAlert popoverPresentationController].sourceView = roomBubbleTableViewCell;
[currentAlert popoverPresentationController].sourceRect = roomBubbleTableViewCell.bounds;
[self presentViewController:currentAlert animated:YES completion:nil];
[currentAlert popoverPresentationController].sourceRect = sourceRect;
[self presentViewController:currentAlert animated:animated completion:nil];
}
else
{
@@ -5150,7 +5122,8 @@
RoomContextualMenuItem *moreMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionMore];
moreMenuItem.action = ^{
MXStrongifyAndReturnIfNil(self);
[self showEditButtonAlertMenuForEvent:event inCell:cell level:0];
[self hideContextualMenuAnimated:YES completion:nil];
[self showAdditionalActionsMenuForEvent:event inCell:cell animated:YES];
};
// Actions list
@@ -5165,7 +5138,7 @@
return actionItems;
}
- (void)showContextualMenuForEvent:(MXEvent*)event cell:(id<MXKCellRendering>)cell animated:(BOOL)animated
- (void)showContextualMenuForEvent:(MXEvent*)event fromSingleTapGesture:(BOOL)usedSingleTapGesture cell:(id<MXKCellRendering>)cell animated:(BOOL)animated
{
if (self.roomContextualMenuPresenter.isPresenting)
{
@@ -5174,8 +5147,6 @@
NSString *selectedEventId = event.eventId;
[self selectEventWithId:selectedEventId];
NSArray<RoomContextualMenuItem*>* contextualMenuItems = [self contextualMenuItemsForEvent:event andCell:cell];
ReactionsMenuViewModel *reactionsMenuViewModel;
CGRect bubbleComponentFrameInOverlayView = CGRectNull;
@@ -5217,18 +5188,26 @@
reactionsMenuViewModel.coordinatorDelegate = self;
}
RoomContextualMenuViewController *roomContextualMenuViewController = [RoomContextualMenuViewController instantiateWith:contextualMenuItems reactionsMenuViewModel:reactionsMenuViewModel];
roomContextualMenuViewController.delegate = self;
if (!self.roomContextualMenuViewController)
{
self.roomContextualMenuViewController = [RoomContextualMenuViewController instantiate];
self.roomContextualMenuViewController.delegate = self;
}
[self.roomContextualMenuViewController updateWithContextualMenuItems:contextualMenuItems reactionsMenuViewModel:reactionsMenuViewModel];
[self enableOverlayContainerUserInteractions:YES];
[self.roomContextualMenuPresenter presentWithRoomContextualMenuViewController:roomContextualMenuViewController
[self.roomContextualMenuPresenter presentWithRoomContextualMenuViewController:self.roomContextualMenuViewController
from:self
on:self.overlayContainerView
contentToReactFrame:bubbleComponentFrameInOverlayView
animated:YES
fromSingleTapGesture:usedSingleTapGesture
animated:animated
completion:^{
}];
[self selectEventWithId:selectedEventId];
}
- (void)hideContextualMenuAnimated:(BOOL)animated