Merge branch 'charlesmchen/blocking3'

pull/1/head
Matthew Chen 8 years ago
commit d001a5b519

@ -3,7 +3,10 @@
//
#import "AddToBlockListViewController.h"
#import "ContactTableViewCell.h"
#import "CountryCodeViewController.h"
#import "Environment.h"
#import "OWSContactsManager.h"
#import "PhoneNumber.h"
#import "StringUtil.h"
#import "UIFont+OWS.h"
@ -17,10 +20,14 @@ NS_ASSUME_NONNULL_BEGIN
NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockListViewControllerCellIdentifier";
NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseIdentifier";
#pragma mark -
// TODO: Add a list of contacts to make it easier to block contacts.
@interface AddToBlockListViewController () <CountryCodeViewControllerDelegate, UITextFieldDelegate>
@interface AddToBlockListViewController () <CountryCodeViewControllerDelegate,
UITextFieldDelegate,
UITableViewDataSource,
UITableViewDelegate>
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@ -31,20 +38,19 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
@property (nonatomic) UIButton *blockButton;
@property (nonatomic) UITableView *contactsTableView;
@property (nonatomic) NSString *callingCode;
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic) NSArray<Contact *> *contacts;
@end
#pragma mark -
@implementation AddToBlockListViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController.navigationBar setTranslucent:NO];
}
- (void)loadView
{
[super loadView];
@ -52,6 +58,8 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
self.view.backgroundColor = [UIColor whiteColor];
_blockingManager = [OWSBlockingManager sharedManager];
_contactsManager = [Environment getCurrent].contactsManager;
self.contacts = self.contactsManager.signalContacts;
self.title = NSLocalizedString(@"SETTINGS_ADD_TO_BLOCK_LIST_TITLE", @"");
@ -62,12 +70,22 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
[self addNotificationListeners];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController.navigationBar setTranslucent:NO];
}
- (void)addNotificationListeners
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(blockedPhoneNumbersDidChange:)
name:kNSNotificationName_BlockedPhoneNumbersDidChange
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(signalRecipientsDidChange:)
name:OWSContactsManagerSignalRecipientsDidChangeNotification
object:nil];
}
- (void)dealloc
@ -164,6 +182,17 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
[_blockButton autoSetDimension:ALDimensionWidth toSize:160];
[_blockButton autoSetDimension:ALDimensionHeight toSize:40];
_contactsTableView = [UITableView new];
_contactsTableView.dataSource = self;
_contactsTableView.delegate = self;
[_contactsTableView registerClass:[ContactTableViewCell class]
forCellReuseIdentifier:kContactsTable_CellReuseIdentifier];
_contactsTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[self.view addSubview:_contactsTableView];
[_contactsTableView autoPinWidthToSuperview];
[_contactsTableView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:blockButtonRow withOffset:30];
[_contactsTableView autoPinToBottomLayoutGuideOfViewController:self withInset:0];
[self updateBlockButtonEnabling];
}
@ -247,10 +276,11 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
[_blockingManager addBlockedPhoneNumber:[parsedPhoneNumber toE164]];
UIAlertController *controller = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_BLOCKED_ALERT_TITLE",
alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_PHONE_NUMBER_BLOCKED_ALERT_TITLE",
@"The title of the 'phone number blocked' alert in the block view.")
message:[NSString
stringWithFormat:NSLocalizedString(@"BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT",
stringWithFormat:NSLocalizedString(
@"BLOCK_LIST_VIEW_PHONE_NUMBER_BLOCKED_ALERT_MESSAGE_FORMAT",
@"The message format of the 'phone number blocked' alert in "
@"the block view. Embeds {{the blocked phone number}}."),
[parsedPhoneNumber toE164]]
@ -295,6 +325,19 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
// TODO: Once we have a list of contacts, we should update it here.
}
- (void)signalRecipientsDidChange:(NSNotification *)notification
{
[self updateContacts];
}
- (void)updateContacts
{
dispatch_async(dispatch_get_main_queue(), ^{
self.contacts = self.contactsManager.signalContacts;
[self.contactsTableView reloadData];
});
}
#pragma mark - CountryCodeViewControllerDelegate
- (void)countryCodeViewController:(CountryCodeViewController *)vc
@ -332,6 +375,113 @@ NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockList
return NO;
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return (NSInteger)self.contacts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Contact *contact = self.contacts[(NSUInteger)indexPath.item];
ContactTableViewCell *cell = [_contactsTableView cellForRowAtIndexPath:indexPath];
if (!cell) {
cell = [ContactTableViewCell new];
}
[cell configureWithContact:contact contactsManager:self.contactsManager];
return cell;
}
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return NSLocalizedString(
@"BLOCK_LIST_VIEW_CONTACTS_SECTION_TITLE", @"A title for the contacts section of the blocklist view.");
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [ContactTableViewCell rowHeight];
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Contact *contact = self.contacts[(NSUInteger)indexPath.item];
[self showBlockActionSheet:contact];
}
- (void)showBlockActionSheet:(Contact *)contact
{
OWSAssert(contact);
NSString *displayName = contact.fullName;
NSString *title = [NSString stringWithFormat:NSLocalizedString(@"BLOCK_LIST_BLOCK_TITLE_FORMAT",
@"A format for the 'block phone number' action sheet title."),
displayName];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
__weak AddToBlockListViewController *weakSelf = self;
UIAlertAction *unblockAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"BLOCK_LIST_BLOCK_BUTTON", @"Button label for the 'block' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[weakSelf blockContact:contact displayName:displayName];
}];
[actionSheetController addAction:unblockAction];
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
style:UIAlertActionStyleCancel
handler:nil];
[actionSheetController addAction:dismissAction];
[self presentViewController:actionSheetController animated:YES completion:nil];
}
- (void)blockContact:(Contact *)contact displayName:(NSString *)displayName
{
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
if (phoneNumber.toE164.length > 0) {
[_blockingManager addBlockedPhoneNumber:phoneNumber.toE164];
}
}
UIAlertController *controller = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_CONTACT_BLOCKED_ALERT_TITLE",
@"The title of the 'contact blocked' alert in the block view.")
message:[NSString stringWithFormat:NSLocalizedString(
@"BLOCK_LIST_VIEW_CONTACT_BLOCKED_ALERT_MESSAGE_FORMAT",
@"The message format of the 'contact blocked' "
@"alert in the block view. It is populated with the "
@"blocked contact's name."),
displayName]
preferredStyle:UIAlertControllerStyleAlert];
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:controller animated:YES completion:nil];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self.phoneNumberTextField resignFirstResponder];
}
#pragma mark - Logging
+ (NSString *)tag

@ -3,19 +3,24 @@
//
#import "BlockListViewController.h"
#import "UIFont+OWS.h"
#import "PhoneNumber.h"
#import "AddToBlockListViewController.h"
#import "Environment.h"
#import "OWSContactsManager.h"
#import "PhoneNumber.h"
#import "UIFont+OWS.h"
#import <SignalServiceKit/OWSBlockingManager.h>
NS_ASSUME_NONNULL_BEGIN
// TODO: We should label phone numbers with contact names where possible.
@interface BlockListViewController ()
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic) NSArray<Contact *> *contacts;
@property (nonatomic) NSDictionary<NSString *, Contact *> *contactMap;
@end
#pragma mark -
@ -39,6 +44,8 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
_blockingManager = [OWSBlockingManager sharedManager];
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
_contactsManager = [Environment getCurrent].contactsManager;
self.contacts = self.contactsManager.signalContacts;
self.title
= NSLocalizedString(@"SETTINGS_BLOCK_LIST_TITLE", @"Label for the block list section of the settings view");
@ -52,6 +59,10 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
selector:@selector(blockedPhoneNumbersDidChange:)
name:kNSNotificationName_BlockedPhoneNumbersDidChange
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(signalRecipientsDidChange:)
name:OWSContactsManagerSignalRecipientsDidChangeNotification
object:nil];
}
- (void)dealloc
@ -105,20 +116,13 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
case BlockListViewControllerSection_Add:
cell.textLabel.text = NSLocalizedString(
@"SETTINGS_BLOCK_LIST_ADD_BUTTON", @"A label for the 'add phone number' button in the block list table.");
cell.textLabel.font = [UIFont ows_mediumFontWithSize:18.f];
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case BlockListViewControllerSection_BlockList: {
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger) indexPath.item];
PhoneNumber *parsedPhoneNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber];
// Try to parse and present the phone number in E164.
// It should already be in E164, so this should always work.
// If an invalid or unparsable phone number is already in the block list,
// present it as-is.
cell.textLabel.text = (parsedPhoneNumber
? parsedPhoneNumber.toE164
: phoneNumber);
cell.textLabel.font = [UIFont ows_mediumFontWithSize:18.f];
NSString *displayName = [self displayNameForIndexPath:indexPath];
cell.textLabel.text = displayName;
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
break;
}
@ -130,6 +134,24 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
return cell;
}
- (NSString *)displayNameForIndexPath:(NSIndexPath *)indexPath
{
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
PhoneNumber *parsedPhoneNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber];
// Try to parse and present the phone number in E164.
// It should already be in E164, so this should always work.
// If an invalid or unparsable phone number is already in the block list,
// present it as-is.
NSString *displayName = (parsedPhoneNumber ? parsedPhoneNumber.toE164 : phoneNumber);
Contact *contact = self.contactMap[displayName];
if (contact && [contact fullName].length > 0) {
displayName = [contact fullName];
}
return displayName;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
@ -145,7 +167,8 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
}
case BlockListViewControllerSection_BlockList: {
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
[self showUnblockActionSheet:phoneNumber];
NSString *displayName = [self displayNameForIndexPath:indexPath];
[self showUnblockActionSheet:phoneNumber displayName:displayName];
break;
}
default:
@ -153,16 +176,14 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
}
}
- (void)showUnblockActionSheet:(NSString *)phoneNumber
- (void)showUnblockActionSheet:(NSString *)phoneNumber displayName:(NSString *)displayName
{
OWSAssert(phoneNumber.length > 0);
PhoneNumber *parsedPhoneNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber];
NSString *displayPhoneNumber = (parsedPhoneNumber ? parsedPhoneNumber.toE164 : phoneNumber);
OWSAssert(displayName.length > 0);
NSString *title = [NSString stringWithFormat:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_TITLE_FORMAT",
@"A format for the 'unblock phone number' action sheet title."),
displayPhoneNumber];
displayName];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
@ -172,7 +193,7 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON", @"Button label for the 'unblock' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[weakSelf unblockPhoneNumber:phoneNumber displayPhoneNumber:displayPhoneNumber];
[weakSelf unblockPhoneNumber:phoneNumber displayName:displayName];
}];
[actionSheetController addAction:unblockAction];
@ -184,7 +205,7 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
[self presentViewController:actionSheetController animated:YES completion:nil];
}
- (void)unblockPhoneNumber:(NSString *)phoneNumber displayPhoneNumber:(NSString *)displayPhoneNumber
- (void)unblockPhoneNumber:(NSString *)phoneNumber displayName:(NSString *)displayName
{
[_blockingManager removeBlockedPhoneNumber:phoneNumber];
@ -196,7 +217,7 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
@"The message format of the 'phone number unblocked' "
@"alert in the block view. It is populated with the "
@"blocked phone number."),
displayPhoneNumber]
displayName]
preferredStyle:UIAlertControllerStyleAlert];
[controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
@ -214,6 +235,35 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
[self.tableView reloadData];
}
- (void)signalRecipientsDidChange:(NSNotification *)notification
{
[self updateContacts];
}
- (void)updateContacts
{
dispatch_async(dispatch_get_main_queue(), ^{
self.contacts = self.contactsManager.signalContacts;
[self.tableView reloadData];
});
}
- (void)setContacts:(NSArray<Contact *> *)contacts
{
_contacts = contacts;
NSMutableDictionary<NSString *, Contact *> *contactMap = [NSMutableDictionary new];
for (Contact *contact in contacts) {
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
NSString *phoneNumberE164 = phoneNumber.toE164;
if (phoneNumberE164.length > 0) {
contactMap[phoneNumberE164] = contact;
}
}
}
self.contactMap = contactMap;
}
#pragma mark - Logging
+ (NSString *)tag

@ -1,3 +1,7 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "OWSContactsManager.h"
@ -13,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface ContactTableViewCell : UITableViewCell
+ (CGFloat)rowHeight;
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager;
@end

@ -6,7 +6,9 @@
#import "Environment.h"
#import "OWSContactAvatarBuilder.h"
#import "OWSContactsManager.h"
#import "UIFont+OWS.h"
#import "UIUtil.h"
#import "UIView+OWS.h"
NS_ASSUME_NONNULL_BEGIN
@ -19,11 +21,51 @@ NS_ASSUME_NONNULL_BEGIN
@implementation ContactTableViewCell
- (instancetype)init
{
if (self = [super init]) {
[self configureProgrammatically];
}
return self;
}
- (nullable NSString *)reuseIdentifier
{
return NSStringFromClass(self.class);
}
+ (CGFloat)rowHeight
{
return 59.f;
}
- (void)configureProgrammatically
{
_avatarView = [UIImageView new];
_avatarView.contentMode = UIViewContentModeScaleToFill;
_avatarView.image = [UIImage imageNamed:@"empty-group-avatar"];
[self.contentView addSubview:_avatarView];
_nameLabel = [UILabel new];
_nameLabel.contentMode = UIViewContentModeLeft;
_nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_nameLabel.font = [UIFont ows_dynamicTypeBodyFont];
[self.contentView addSubview:_nameLabel];
[_avatarView autoVCenterInSuperview];
[_avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:8.f];
[_avatarView autoSetDimension:ALDimensionWidth toSize:40.f];
[_avatarView autoSetDimension:ALDimensionHeight toSize:40.f];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeRight];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[_nameLabel autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:_avatarView withOffset:12.f];
// Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews];
}
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager
{
self.nameLabel.attributedText = [contactsManager formattedFullNameForContact:contact font:self.nameLabel.font];

@ -97,6 +97,12 @@
/* No comment provided by engineer. */
"ATTACHMENT_QUEUED" = "New attachment queued for retrieval.";
/* Button label for the 'block' button */
"BLOCK_LIST_BLOCK_BUTTON" = "Block";
/* A format for the 'block phone number' action sheet title. */
"BLOCK_LIST_BLOCK_TITLE_FORMAT" = "Block %@?";
/* Button label for the 'unblock' button */
"BLOCK_LIST_UNBLOCK_BUTTON" = "Unblock";
@ -106,11 +112,20 @@
/* A label for the block button in the block list view */
"BLOCK_LIST_VIEW_BLOCK_BUTTON" = "Block";
/* The message format of the 'contact blocked' alert in the block view. It is populated with the blocked contact's name. */
"BLOCK_LIST_VIEW_CONTACT_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been blocked";
/* The title of the 'contact blocked' alert in the block view. */
"BLOCK_LIST_VIEW_CONTACT_BLOCKED_ALERT_TITLE" = "Contact Blocked";
/* A title for the contacts section of the blocklist view. */
"BLOCK_LIST_VIEW_CONTACTS_SECTION_TITLE" = "Contacts";
/* The message format of the 'phone number blocked' alert in the block view. It is populated with the blocked phone number. */
"BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been blocked.";
"BLOCK_LIST_VIEW_PHONE_NUMBER_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been blocked";
/* The title of the 'phone number blocked' alert in the block view. */
"BLOCK_LIST_VIEW_BLOCKED_ALERT_TITLE" = "Phone Number Blocked";
"BLOCK_LIST_VIEW_PHONE_NUMBER_BLOCKED_ALERT_TITLE" = "Phone Number Blocked";
/* The message format of the 'phone number unblocked' alert in the block view. It is populated with the blocked phone number. */
"BLOCK_LIST_VIEW_UNBLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been unblocked.";

Loading…
Cancel
Save