123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2012-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- #import "AddContactViewController.h"
- #import "ScanIdentityController.h"
- #import "ProtocolDefines.h"
- #import "ContactStore.h"
- #import "Contact.h"
- #import "InviteController.h"
- #import "MBProgressHUD.h"
- #import "NewScannedContactViewController.h"
- #import "AppDelegate.h"
- #import "GatewayAvatarMaker.h"
- #import "UIImage+ColoredImage.h"
- #import "NSString+Hex.h"
- #import "ServerAPIConnector.h"
- #import "ThreemaFramework/ThreemaFramework-swift.h"
- #import "MyIdentityStore.h"
- @interface AddContactViewController ()
- @end
- @implementation AddContactViewController {
- InviteController *inviteController;
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- if (![ScanIdentityController canScan]) {
- self.scanIdentityCell.selectionStyle = UITableViewCellSelectionStyleNone;
- self.scanIdentityCell.imageView.alpha = 0.4;
- self.scanIdentityCell.textLabel.alpha = 0.4;
- }
-
- // Tint icon appropriately
- self.scanIdentityCell.imageView.image = [self.scanIdentityCell.imageView.image imageWithTint:[Colors main]];
-
- [Colors updateKeyboardAppearanceFor:self.identityTextField];
-
- [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationDidEnterBackground:) name: UIApplicationDidEnterBackgroundNotification object: nil];
- }
- - (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
-
- [self.identityTextField becomeFirstResponder];
- }
- - (IBAction)cancelAction:(id)sender {
- [self dismissViewControllerAnimated:YES completion:nil];
- }
- - (IBAction)doneAction:(id)sender {
- [self doAdd];
- }
- - (BOOL)shouldAutorotate {
- return YES;
- }
- -(UIInterfaceOrientationMask)supportedInterfaceOrientations {
- if (SYSTEM_IS_IPAD) {
- return UIInterfaceOrientationMaskAll;
- }
-
- return UIInterfaceOrientationMaskAllButUpsideDown;
- }
- #pragma mark - Text field delegate
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-
- if (indexPath.section == 1 && indexPath.row == 0) {
- /* Scan */
- if ([ScanIdentityController canScan]) {
- ScanIdentityController *scanController = [[ScanIdentityController alloc] init];
- scanController.containingViewController = self.presentingViewController;
-
- [self dismissViewControllerAnimated:YES completion:^{
- [scanController startScan];
-
- /* a good opportunity to sync contacts - maybe we find the contact
- that the user is about to scan */
- [[ContactStore sharedContactStore] synchronizeAddressBookForceFullSync:YES onCompletion:nil onError:nil];
- }];
- }
- } else if (indexPath.section == 1 && indexPath.row == 1) {
- [_identityTextField resignFirstResponder];
-
- /* Invite a friend */
- [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
- inviteController = [[InviteController alloc] init];
- inviteController.parentViewController = self.presentingViewController;
- inviteController.shareViewController = self;
- inviteController.actionSheetViewController = self;
- inviteController.rect = [tableView rectForRowAtIndexPath:indexPath];
- inviteController.delegate = self;
- inviteController.rect = [tableView rectForRowAtIndexPath:indexPath];
- [inviteController invite];
- }
- }
- - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
- // Check if the added string contains lowercase characters.
- // If so, those characters are replaced by uppercase characters.
- // But this has the effect of losing the editing point
- // (only when trying to edit with lowercase characters),
- // because the text of the UITextField is modified.
- // That is why we only replace the text when this is really needed.
- NSRange lowercaseCharRange;
- lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];
-
- if (lowercaseCharRange.location != NSNotFound) {
-
- // Get current cursor position
- UITextRange *selectedTextRangeCurrent = textField.selectedTextRange;
-
- textField.text = [textField.text stringByReplacingCharactersInRange:range
- withString:[string uppercaseString]];
- if (selectedTextRangeCurrent != nil) {
- // Set current cursor position, if cursor position + 1 is valid
- UITextPosition *newPosition = [textField positionFromPosition:selectedTextRangeCurrent.start offset:1];
- if (newPosition != nil) {
- textField.selectedTextRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
- }
- }
- self.navigationItem.rightBarButtonItem.enabled = (textField.text.length == kIdentityLen);
- return NO;
- }
-
- NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
- self.navigationItem.rightBarButtonItem.enabled = (newText.length == kIdentityLen);
-
- return YES;
- }
- - (BOOL)textFieldShouldReturn:(UITextField *)textField {
-
- return [self doAdd];
- }
- - (BOOL)doAdd {
- NSString *myIdentity = MyIdentityStore.sharedMyIdentityStore.identity;
- if (self.identityTextField.text.length != kIdentityLen || [self.identityTextField.text isEqualToString:myIdentity])
- return NO;
-
- [MBProgressHUD showHUDAddedTo:self.view animated:YES];
-
- ServerAPIConnector *conn = [[ServerAPIConnector alloc] init];
- [conn fetchIdentityInfo:self.identityTextField.text onCompletion:^(NSData *publicKey, NSNumber *state, NSNumber *type, NSNumber *featureMask) {
- [MBProgressHUD hideHUDForView:self.view animated:YES];
-
- UIViewController *presentingViewController = self.presentingViewController;
- [self dismissViewControllerAnimated:YES completion:^{
- UIStoryboard *storyboard = [AppDelegate getMainStoryboard];
- UINavigationController *newNavVc = [storyboard instantiateViewControllerWithIdentifier:@"NewScannedContact"];
- NewScannedContactViewController *newVc = [newNavVc.viewControllers objectAtIndex:0];
- newVc.identity = self.identityTextField.text;
- newVc.publicKey = publicKey;
- newVc.verificationLevel = kVerificationLevelUnverified;
- newVc.state = state;
- newVc.type = type;
- newVc.featureMask = featureMask;
-
- [presentingViewController presentViewController:newNavVc animated:YES completion:nil];
- }];
- } onError:^(NSError *error) {
- [MBProgressHUD hideHUDForView:self.view animated:YES];
-
- if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == 404) {
- [UIAlertTemplate showAlertWithOwner:self title:NSLocalizedString(@"identity_not_found_title", nil) message:NSLocalizedString(@"identity_not_found_message", nil) actionOk:nil];
-
- } else {
- [UIAlertTemplate showAlertWithOwner:self title:error.localizedDescription message:error.localizedFailureReason actionOk:nil];
- }
- }];
-
- return YES;
- }
- #pragma mark - Invite controller delegate
- - (BOOL)inviteControllerShouldDeferMailComposer:(InviteController *)_inviteController {
- [self dismissViewControllerAnimated:YES completion:^{
- [inviteController presentMailComposer];
- }];
- return YES;
- }
- - (BOOL)inviteControllerShouldDeferMessageComposer:(InviteController *)_inviteController {
- [self dismissViewControllerAnimated:YES completion:^{
- [inviteController presentMessageComposer];
- }];
- return YES;
- }
- - (void)applicationDidEnterBackground:(UIApplication *)application {
- [_identityTextField resignFirstResponder];
- }
- @end
|