From 9c9060203e2bbef5fe625a7e36c8ff4c6121fca3 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 4 Apr 2017 15:38:00 -0400 Subject: [PATCH] Block actions in message view for blocked group conversations. * Add block status indicator view. // FREEBIE --- .../ViewControllers/MessagesViewController.m | 95 ++++++++++++++++++- .../translations/en.lproj/Localizable.strings | 15 +-- 2 files changed, 103 insertions(+), 7 deletions(-) diff --git a/Signal/src/ViewControllers/MessagesViewController.m b/Signal/src/ViewControllers/MessagesViewController.m index 573a9acb1..1dec6edda 100644 --- a/Signal/src/ViewControllers/MessagesViewController.m +++ b/Signal/src/ViewControllers/MessagesViewController.m @@ -7,6 +7,7 @@ #import "AttachmentSharing.h" #import "BlockListUIUtils.h" #import "DebugUITableViewController.h" +#import "BlockListViewController.h" #import "Environment.h" #import "FingerprintViewController.h" #import "FullImageViewController.h" @@ -200,7 +201,7 @@ typedef enum : NSUInteger { @property (nonatomic) UILabel *navigationBarTitleLabel; @property (nonatomic) UILabel *navigationBarSubtitleLabel; @property (nonatomic) UIButton *attachButton; -@property (nonatomic) UIButton *blockStateIndicator; +@property (nonatomic) UIView *blockStateIndicator; @property (nonatomic) CGFloat previousCollectionViewFrameWidth; @@ -530,10 +531,86 @@ typedef enum : NSUInteger { - (void)ensureBlockStateIndicator { + // This method should be called rarely, so it's simplest to discard and + // rebuild the indicator view every time. [self.blockStateIndicator removeFromSuperview]; self.blockStateIndicator = nil; + + NSString *blockStateMessage = nil; + if ([self isBlockedContactConversation]) { + blockStateMessage = NSLocalizedString(@"MESSAGES_VIEW_CONTACT_BLOCKED", + @"Indicates that this 1:1 conversation has been blocked."); + } else { + int blockedGroupMemberCount = [self blockedGroupMemberCount]; + if (blockedGroupMemberCount == 1) { + blockStateMessage = [NSString stringWithFormat:NSLocalizedString(@"MESSAGES_VIEW_GROUP_1_MEMBER_BLOCKED_FORMAT", + @"Indicates that a single member of this group has been blocked."), + blockedGroupMemberCount]; + } else if (blockedGroupMemberCount > 1) { + blockStateMessage = [NSString stringWithFormat:NSLocalizedString(@"MESSAGES_VIEW_GROUP_N_MEMBERS_BLOCKED_FORMAT", + @"Indicates that some members of this group has been blocked. Embeds " + @"{{the number of blocked user in this group}}."), + blockedGroupMemberCount]; + } + } + + if (blockStateMessage) { + UILabel *label = [UILabel new]; + label.font = [UIFont ows_mediumFontWithSize:14.f]; + label.text = blockStateMessage; + label.textColor = [UIColor whiteColor]; + + UIView * blockStateIndicator = [UIView new]; + blockStateIndicator.backgroundColor = [UIColor ows_signalBrandBlueColor]; + blockStateIndicator.layer.cornerRadius = 2.5f; + + // Use a shadow to "pop" the indicator above the other views. + blockStateIndicator.layer.shadowColor = [UIColor blackColor].CGColor; + blockStateIndicator.layer.shadowOffset = CGSizeMake(2, 3); + blockStateIndicator.layer.shadowRadius = 2.f; + blockStateIndicator.layer.shadowOpacity = 0.35f; + + [blockStateIndicator addSubview:label]; + [label autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:5]; + [label autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:5]; + [label autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:15]; + [label autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:15]; + + [blockStateIndicator addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(blockStateIndicatorWasTapped:)]]; + + [self.view addSubview:blockStateIndicator]; + [blockStateIndicator autoHCenterInSuperview]; + [blockStateIndicator autoPinToTopLayoutGuideOfViewController:self withInset:10]; + [self.view layoutSubviews]; + + self.blockStateIndicator = blockStateIndicator; + } } + +- (void)blockStateIndicatorWasTapped:(UIGestureRecognizer *)sender { + if (sender.state != UIGestureRecognizerStateRecognized) { + return; + } + if ([self isBlockedContactConversation]) { + // If this a blocked 1:1 conversation, offer to unblock the user. + NSString *contactIdentifier = ((TSContactThread *)self.thread).contactIdentifier; + [BlockListUIUtils showUnblockPhoneNumberActionSheet:contactIdentifier + fromViewController:self + blockingManager:_blockingManager + contactsManager:_contactsManager + completionBlock:nil]; + } else { + // If this a group conversation with at least one blocked member, + // Show the block list view. + int blockedGroupMemberCount = [self blockedGroupMemberCount]; + if (blockedGroupMemberCount > 0) { + BlockListViewController *vc = [[BlockListViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; + } + } +} - (BOOL)isBlockedContactConversation { @@ -544,6 +621,22 @@ typedef enum : NSUInteger { return [[_blockingManager blockedPhoneNumbers] containsObject:contactIdentifier]; } +- (int)blockedGroupMemberCount +{ + if (![self.thread isKindOfClass:[TSGroupThread class]]) { + return 0; + } + TSGroupThread *groupThread = (TSGroupThread *)self.thread; + int blockedMemberCount = 0; + NSArray *blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers]; + for (NSString *contactIdentifier in groupThread.groupModel.groupMemberIds) { + if ([blockedPhoneNumbers containsObject:contactIdentifier]) { + blockedMemberCount++; + } + } + return blockedMemberCount; +} + - (void)startReadTimer { self.readTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index b3ddf3077..4fe8c68a8 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -346,9 +346,6 @@ /* No comment provided by engineer. */ "ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY" = "Safety number changed. Tap to verify."; -/* No comment provided by engineer. */ -"ERROR_WAS_DETECTED_TITLE" = "Bummer!"; - /* during registration */ "EXISTING_USER_REGISTRATION_ALERT_BODY" = "At this time Signal can only be active on one mobile device per phone number."; @@ -529,6 +526,15 @@ /* message footer while attachment is uploading */ "MESSAGE_STATUS_UPLOADING" = "Uploading..."; +/* Indicates that this 1:1 conversation has been blocked. */ +"MESSAGES_VIEW_CONTACT_BLOCKED" = "This user is blocked"; + +/* Indicates that some members of this group has been blocked. Embeds {{the number of blocked user in this group}}. */ +"MESSAGES_VIEW_GROUP_1_MEMBER_BLOCKED_FORMAT" = "1 Blocked Member of this Group"; + +/* Indicates that some members of this group has been blocked. Embeds {{the number of blocked user in this group}}. */ +"MESSAGES_VIEW_GROUP_N_MEMBERS_BLOCKED_FORMAT" = "%d Blocked Members of this Group"; + /* The subtitle for the messages view title indicates that the title can be tapped to access settings for this conversation. */ "MESSAGES_VIEW_TITLE_SUBTITLE" = "Tap here for settings"; @@ -970,9 +976,6 @@ /* No comment provided by engineer. */ "SUCCESSFUL_VERIFICATION_TITLE" = "Safety Number Verified!"; -/* No comment provided by engineer. */ -"TIMEOUT_CONTACTS_DETAIL" = "We couldn't fetch an updated contact list from the server. Please try again later."; - /* No comment provided by engineer. */ "TXT_CANCEL_TITLE" = "Cancel";