session-ios/Signal/src/view controllers/DialerViewController.m

195 lines
6.1 KiB
Objective-C

#import "DialerViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
#import "ContactsManager.h"
#import "Environment.h"
#import "InCallViewController.h"
#import "InviteContactModal.h"
#import "LocalizableText.h"
#import "PhoneManager.h"
#import "PhoneNumberDirectoryFilter.h"
#import "PhoneNumberUtil.h"
#import "RecentCallManager.h"
#define INITIAL_BACKSPACE_TIMER_DURATION 0.5f
#define BACKSPACE_TIME_DECREASE_AMMOUNT 0.1f
#define FOUND_CONTACT_ANIMATION_DURATION 0.25f
#define E164_PREFIX @"+"
@interface DialerViewController () {
NSMutableString *_currentNumberMutable;
Contact *_contact;
NSTimer *_backspaceTimer;
float _backspaceDuration;
InviteContactModal* inviteModal;
}
@end
@implementation DialerViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupPasteBehaviour];
self.title = KEYPAD_NAV_BAR_TITLE;
_currentNumberMutable = [NSMutableString string];
[self updateNumberLabel];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[_callButton setTitle:CALL_BUTTON_TITLE forState:UIControlStateNormal];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (_phoneNumber) {
_currentNumberMutable = [[_phoneNumber toE164] mutableCopy];
[self updateNumberLabel];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
_phoneNumber = nil;
}
- (void)setupPasteBehaviour {
[self.numberLabel onPaste:^(id sender) {
[UIPasteboard generalPasteboard];
if([[UIPasteboard generalPasteboard] containsPasteboardTypes:UIPasteboardTypeListString]){
[_currentNumberMutable setString:[self sanitizePhoneNumberFromUnknownSource:[[UIPasteboard generalPasteboard] string]]];
[self updateNumberLabel];
}
}];
}
-(NSString*) sanitizePhoneNumberFromUnknownSource:(NSString*) dirtyNumber {
NSString* cleanNumber = [PhoneNumberUtil normalizePhoneNumber:dirtyNumber];
if ([dirtyNumber hasPrefix:E164_PREFIX]) {
cleanNumber = [NSString stringWithFormat:@"%@%@",E164_PREFIX,cleanNumber];
}
return cleanNumber;
}
#pragma mark - DialerButtonViewDelegate
- (void)dialerButtonViewDidSelect:(DialerButtonView *)view {
[_currentNumberMutable appendString:view.buttonInput];
[self updateNumberLabel];
}
#pragma mark - Actions
- (void)backspaceButtonTouchDown {
_backspaceDuration = INITIAL_BACKSPACE_TIMER_DURATION;
[self removeLastDigit];
}
- (void)backspaceButtonTouchUp {
[_backspaceTimer invalidate];
_backspaceTimer = nil;
}
- (void)removeLastDigit {
NSUInteger n = _currentNumberMutable.length;
if (n > 0) {
[_currentNumberMutable deleteCharactersInRange:NSMakeRange(n - 1, 1)];
}
[self updateNumberLabel];
_backspaceDuration -= BACKSPACE_TIME_DECREASE_AMMOUNT;
_backspaceTimer = [NSTimer scheduledTimerWithTimeInterval:_backspaceDuration
target:self
selector:@selector(removeLastDigit)
userInfo:nil
repeats:NO];
}
- (void)callButtonTapped {
PhoneNumber *phoneNumber = [self phoneNumberForCurrentInput];
BOOL shouldTryCall = [[[[Environment getCurrent] phoneDirectoryManager] getCurrentFilter] containsPhoneNumber:phoneNumber] || [[Environment getCurrent].recentCallManager isPhoneNumberPresentInRecentCalls:phoneNumber];
if( shouldTryCall){
[self initiateCallToPhoneNumber:phoneNumber];
}else if([phoneNumber isValid]){
[self promptToInvitePhoneNumber:phoneNumber];
}
}
-(void) initiateCallToPhoneNumber:(PhoneNumber*) phoneNumber {
if (_contact) {
[[Environment phoneManager] initiateOutgoingCallToContact:_contact
atRemoteNumber:phoneNumber];
} else {
[[Environment phoneManager] initiateOutgoingCallToRemoteNumber:phoneNumber];
}
}
- (PhoneNumber *)phoneNumberForCurrentInput {
NSString *numberText = [_currentNumberMutable copy];
if (numberText.length> 0 && [[numberText substringToIndex:1] isEqualToString:COUNTRY_CODE_PREFIX]) {
return [PhoneNumber tryParsePhoneNumberFromE164:numberText];
} else {
return [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:numberText];
}
}
- (void)updateNumberLabel {
NSString* numberText = [_currentNumberMutable copy];
_numberLabel.text = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:numberText];
PhoneNumber* number = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:numberText];
[self tryUpdateContactForNumber:number];
}
- (void)tryUpdateContactForNumber:(PhoneNumber *)number {
if (number) {
_contact = [[[Environment getCurrent] contactsManager] latestContactForPhoneNumber:number];
} else {
_contact = nil;
}
if (_contact) {
if (_contact.image) {
_matchedContactImageView.alpha = 0.0f;
_matchedContactImageView.image = _contact.image;
[UIUtil applyRoundedBorderToImageView:&_matchedContactImageView];
[UIView animateWithDuration:FOUND_CONTACT_ANIMATION_DURATION animations:^{
_matchedContactImageView.alpha = 1.0f;
}];
} else {
[self removeContactImage];
}
[_addContactButton setTitle:[_contact fullName] forState:UIControlStateNormal];
} else {
[_addContactButton setTitle:@"" forState:UIControlStateNormal];
[self removeContactImage];
}
}
- (void)removeContactImage {
[UIView animateWithDuration:FOUND_CONTACT_ANIMATION_DURATION animations:^{
_matchedContactImageView.alpha = 0.0f;
} completion:^(BOOL finished) {
[UIUtil removeRoundedBorderToImageView:&_matchedContactImageView];
_matchedContactImageView.image = nil;
}];
}
-(void) promptToInvitePhoneNumber:(PhoneNumber*) phoneNumber {
inviteModal = [InviteContactModal inviteContactModelWithPhoneNumber:phoneNumber andParentViewController:self];
[inviteModal presentModalView];
}
@end