mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
13 KiB
Objective-C
382 lines
13 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 3
|
|
#define kFirstAdaptableCellRow 2
|
|
|
|
|
|
typedef NS_ENUM(NSInteger, CellRow) {
|
|
kNameMainNumberCellIndexPath,
|
|
kActionCellIndexPath,
|
|
kShareCellIndexPath,
|
|
kEmailCellIndexPath,
|
|
kAnnexPhoneNumberCellIndexPath,
|
|
kNotesCellIndexPath,
|
|
};
|
|
|
|
typedef enum {
|
|
kNameMainNumberCellHeight = 180,
|
|
kNoImageCellHeight = 87,
|
|
kActionCellHeight = 60,
|
|
kShareCellHeight = 60,
|
|
kEmailCellHeight = 60,
|
|
kAnnexPhoneNumberCellHeight = 60,
|
|
kNotesCellHeight = 165,
|
|
} kCellHeight;
|
|
|
|
static NSString* const kNameMainNumberCell = @"NameMainNumberCell";
|
|
static NSString* const kActionCell = @"ActionCell";
|
|
static NSString* const kShareCell = @"ShareCell";
|
|
static NSString* const kEmailCell = @"EmailCell";
|
|
static NSString* const kAnnexPhoneNumberCell = @"AnnexPhoneNumberCell";
|
|
static NSString *const kNotesCell = @"NotesCell";
|
|
|
|
|
|
static NSString *const kContactDetailSegue = @"DetailSegue";
|
|
|
|
|
|
@interface ContactDetailTableViewController () {
|
|
BOOL doesImageExist;
|
|
NSInteger numberOfRows;
|
|
}
|
|
@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;
|
|
case kShareCellIndexPath:
|
|
cell = [tableView dequeueReusableCellWithIdentifier:kShareCell forIndexPath:indexPath];
|
|
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;
|
|
case kShareCellIndexPath:
|
|
cellHeight = kShareCellHeight;
|
|
break;
|
|
default:
|
|
cellHeight = [self heightForAdaptableCellAtIndexPath:indexPath];
|
|
break;
|
|
}
|
|
return cellHeight;
|
|
}
|
|
|
|
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
switch (indexPath.row) {
|
|
case kShareCellIndexPath:
|
|
[DJWActionSheet showInView:self.tabBarController.view
|
|
withTitle:nil
|
|
cancelButtonTitle:@"Cancel"
|
|
destructiveButtonTitle:nil
|
|
otherButtonTitles:@[@"Mail", @"Message", @"Airdrop", @"Other"]
|
|
tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
|
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
|
if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
|
|
NSLog(@"User Cancelled");
|
|
|
|
} else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
|
|
NSLog(@"Destructive button tapped");
|
|
}else {
|
|
NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex);
|
|
}
|
|
}];
|
|
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#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
|