session-ios/Signal/src/view controllers/ContactDetailTableViewContr...

345 lines
11 KiB
Objective-C

//
// ContactDetailTableViewController.m
// Signal
//
// Created by Dylan Bourgeois on 30/10/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "ContactDetailTableViewController.h"
#import "ContactDetailCell.h"
#import "ActionContactDetailCell.h"
#import "UIUtil.h"
#import "DJWActionSheet.h"
#import "Environment.h"
#import "PhoneManager.h"
#define kImageRadius 50.0f
#define kMinRows 2
#define kFirstAdaptableCellRow 1
typedef NS_ENUM(NSInteger, CellRow) {
kNameMainNumberCellIndexPath,
kActionCellIndexPath,
kEmailCellIndexPath,
kAnnexPhoneNumberCellIndexPath,
kNotesCellIndexPath,
};
typedef enum {
kNameMainNumberCellHeight = 180,
kNoImageCellHeight = 87,
kActionCellHeight = 60,
kEmailCellHeight = 60,
kAnnexPhoneNumberCellHeight = 60,
kNotesCellHeight = 165,
} kCellHeight;
static NSString* const kNameMainNumberCell = @"NameMainNumberCell";
static NSString* const kActionCell = @"ActionCell";
static NSString* const kEmailCell = @"EmailCell";
static NSString* const kAnnexPhoneNumberCell = @"AnnexPhoneNumberCell";
static NSString *const kNotesCell = @"NotesCell";
static NSString *const kContactDetailSegue = @"DetailSegue";
@interface ContactDetailTableViewController () {
BOOL doesImageExist;
}
@end
@implementation ContactDetailTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
doesImageExist = YES;
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return (NSInteger)[self numberOfRowsForContact:_contact];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
switch (indexPath.row) {
case kNameMainNumberCellIndexPath:
cell = (ContactDetailCell*)[tableView dequeueReusableCellWithIdentifier:kNameMainNumberCell forIndexPath:indexPath];
[self setUpNameMainUserCell:(ContactDetailCell*)cell];
break;
case kActionCellIndexPath:
cell = (ActionContactDetailCell*)[tableView dequeueReusableCellWithIdentifier:kActionCell forIndexPath:indexPath];
[self setUpActionCell:(ActionContactDetailCell*)cell];
break;
default:
cell = [self adaptableCellAtIndexPath:indexPath];
break;
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat cellHeight = 44.0f;
switch (indexPath.row) {
case kNameMainNumberCellIndexPath:
cellHeight = doesImageExist ? kNameMainNumberCellHeight : kNoImageCellHeight;
break;
case kActionCellIndexPath:
cellHeight = kActionCellHeight;
break;
default:
cellHeight = [self heightForAdaptableCellAtIndexPath:indexPath];
break;
}
return cellHeight;
}
#pragma mark - Set Up Cells
-(void)setUpActionCell:(ActionContactDetailCell*)cell
{
Contact * c = self.contact;
UIImage *callImage = [[UIImage imageNamed:@"call_dark"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.contactCallButton setImage:callImage forState:UIControlStateNormal];
UIImage *messageImage = [[UIImage imageNamed:@"signals_tab"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.contactTextButton setImage:messageImage forState:UIControlStateNormal];
UIImage *clearImage = [[UIImage imageNamed:@"delete_history"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.contactShredButton setImage:clearImage forState:UIControlStateNormal];
cell.contactShredButton.tintColor = [UIColor ows_redColor];
if (c.isRedPhoneContact)
{
cell.contactCallButton.tintColor = [UIColor ows_blueColor];
[cell.contactCallButton addTarget:self action:@selector(initiateRedPhoneCall) forControlEvents:UIControlEventTouchUpInside];
} else {
cell.contactCallButton.tintColor = [UIColor ows_darkGrayColor];
cell.contactCallButton.enabled = NO;
}
if (c.isTextSecureContact)
{
cell.contactTextButton.tintColor = [UIColor ows_blueColor];
[cell.contactTextButton addTarget:self action:@selector(openTextSecureConversation) forControlEvents:UIControlEventTouchUpInside];
} else {
cell.contactTextButton.tintColor = [UIColor ows_darkGrayColor];
cell.contactTextButton.enabled = NO;
}
}
- (void)openTextSecureConversation{
NSArray *textSecureIdentifiers = [self.contact textSecureIdentifiers];
if (textSecureIdentifiers.count > 1) {
[DJWActionSheet showInView:self.tabBarController.view
withTitle:@"What number would you like to message?"
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:textSecureIdentifiers
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
DDLogVerbose(@"User Cancelled Call");
} else {
[Environment messageIdentifier:[textSecureIdentifiers objectAtIndex:(NSUInteger)tappedButtonIndex]];
}
}];
} else if (textSecureIdentifiers.count == 1){
[Environment messageIdentifier:[textSecureIdentifiers firstObject]];
} else{
DDLogWarn(@"Tried to intiate a call but contact has no RedPhone identifier");
}
}
- (void)initiateRedPhoneCall{
NSArray *redPhoneIdentifiers = [self.contact redPhoneIdentifiers];
if (redPhoneIdentifiers.count > 1) {
NSMutableArray *e164 = [NSMutableArray array];
for (PhoneNumber *phoneNumber in redPhoneIdentifiers) {
[e164 addObject:phoneNumber.toE164];
}
[DJWActionSheet showInView:self.tabBarController.view
withTitle:@"What number would you like to dial?"
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:e164
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
DDLogVerbose(@"User Cancelled Call");
} else {
[Environment.phoneManager initiateOutgoingCallToContact:self.contact atRemoteNumber:[redPhoneIdentifiers objectAtIndex:(NSUInteger)tappedButtonIndex]];
}
}];
} else if (redPhoneIdentifiers.count == 1){
[Environment.phoneManager initiateOutgoingCallToContact:self.contact atRemoteNumber:[redPhoneIdentifiers firstObject]];
} else{
DDLogWarn(@"Tried to intiate a call but contact has no RedPhone identifier");
}
}
-(void)setUpNameMainUserCell:(ContactDetailCell*)cell
{
Contact* c = self.contact;
cell.contactName.text = [c fullName];
cell.contactPhoneNumber.text = [[c userTextPhoneNumbers] firstObject];
if (c.image) {
cell.contactImageView.image = c.image;
} else {
[cell.contactImageView addConstraint:[NSLayoutConstraint constraintWithItem:cell.contactImageView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:0]];
doesImageExist = NO;
}
[cell.contactImageView.layer setCornerRadius:kImageRadius];
[cell.contactImageView.layer setMasksToBounds:YES];
}
-(void)setUpEmailCell:(ContactDetailCell*)cell forIndexPath:(NSIndexPath*)indexPath
{
cell.contactEmailLabel.text = [_contact.emails objectAtIndex:(NSUInteger)indexPath.row-kMinRows];
}
-(void)setUpAnnexNumberCell:(ContactDetailCell*)cell forIndexPath:(NSIndexPath*)indexPath
{
NSInteger i = indexPath.row - [self emailUpperBound] ;
cell.contactAnnexNumberLabel.text = [_contact.userTextPhoneNumbers objectAtIndex:(NSUInteger)i];
}
-(void)setUpNotesCell:(ContactDetailCell*)cell
{
cell.contactNotesTextView.text = _contact.notes;
}
#pragma mark - Utilities (Adaptable Cells)
-(UITableViewCell*)adaptableCellAtIndexPath:(NSIndexPath*)indexPath
{
ContactDetailCell * cell;
if ([self isEmailIndexPath:indexPath])
{
cell = [self.tableView dequeueReusableCellWithIdentifier:kEmailCell forIndexPath:indexPath];
[self setUpEmailCell:cell forIndexPath:indexPath];
return cell;
}
else if ([self isAnnexNumberIndexPath:indexPath])
{
cell = [self.tableView dequeueReusableCellWithIdentifier:kAnnexPhoneNumberCell forIndexPath:indexPath];
[self setUpAnnexNumberCell:cell forIndexPath:indexPath];
return cell;
}
else if ([self isNotesIndexPath:indexPath])
{
cell = [self.tableView dequeueReusableCellWithIdentifier:kNotesCell forIndexPath:indexPath];
[self setUpNotesCell:cell];
return cell;
}
else
{
return nil;
}
}
-(CGFloat)heightForAdaptableCellAtIndexPath:(NSIndexPath*)indexPath
{
if ([self isEmailIndexPath:indexPath])
{
return kEmailCellHeight;
}
else if ([self isAnnexNumberIndexPath:indexPath])
{
return kAnnexPhoneNumberCellHeight;
}
else if ([self isNotesIndexPath:indexPath])
{
return kNotesCellHeight;
}
else
{
return 44.0f;
}
}
#pragma mark - IndexPaths
-(BOOL)isEmailIndexPath:(NSIndexPath*)indexPath
{
return indexPath.row > kFirstAdaptableCellRow && indexPath.row <= [self emailUpperBound];
}
-(BOOL)isAnnexNumberIndexPath:(NSIndexPath*)indexPath
{
return indexPath.row > [self emailUpperBound] && indexPath.row < [self phoneNumberUpperBound];
}
-(BOOL)isNotesIndexPath:(NSIndexPath*)indexPath
{
return indexPath.row == (NSInteger)[self numberOfRowsForContact:_contact]-1;
}
#pragma mark - Utilities (Bounds)
-(NSInteger)emailUpperBound
{
return (NSInteger)(kFirstAdaptableCellRow+_contact.emails.count);
}
-(NSInteger)phoneNumberUpperBound
{
return [self emailUpperBound] + (NSInteger)_contact.userTextPhoneNumbers.count;
}
-(NSUInteger)numberOfRowsForContact:(Contact*)contact
{
NSUInteger numNotes = contact.notes.length == 0 ? 0 : 1;
NSUInteger numEmails = contact.emails.count;
NSUInteger numPhoneNumbers = contact.userTextPhoneNumbers.count-1;
return kMinRows + numEmails + numPhoneNumbers + numNotes;
}
@end