From 3754b6f264ee0b921369241de3f72452d028d351 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 9 May 2017 17:55:18 -0400 Subject: [PATCH 1/5] Edit 1:1 contact details // FREEBIE --- .../src/ViewControllers/ContactsViewHelper.h | 13 +++ .../src/ViewControllers/ContactsViewHelper.m | 93 ++++++++++++++++++- ...SConversationSettingsTableViewController.m | 64 ++++++++++++- .../ShowGroupMembersViewController.m | 87 +++-------------- .../translations/en.lproj/Localizable.strings | 3 + 5 files changed, 182 insertions(+), 78 deletions(-) diff --git a/Signal/src/ViewControllers/ContactsViewHelper.h b/Signal/src/ViewControllers/ContactsViewHelper.h index 263675d75..bc9e1088d 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.h +++ b/Signal/src/ViewControllers/ContactsViewHelper.h @@ -7,15 +7,24 @@ NS_ASSUME_NONNULL_BEGIN @class ContactsViewHelper; @class Contact; @class SignalAccount; +@protocol CNContactViewControllerDelegate; @protocol ContactsViewHelperDelegate - (void)contactsViewHelperDidUpdateContacts; +@optional + - (BOOL)shouldHideLocalNumber; @end +@protocol ContactEditingDelegate + +- (void)didFinishEditingContact; + +@end + #pragma mark - @class OWSContactsManager; @@ -46,6 +55,10 @@ NS_ASSUME_NONNULL_BEGIN - (NSArray *)nonSignalContactsMatchingSearchString:(NSString *)searchText; +- (void)presentContactViewControllerForRecipientId:(NSString *)recipientId + fromViewController:(UIViewController *)fromViewController + editImmediately:(BOOL)shouldEditImmediately; + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/ContactsViewHelper.m b/Signal/src/ViewControllers/ContactsViewHelper.m index 1f0e9c787..5990e1ae1 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.m +++ b/Signal/src/ViewControllers/ContactsViewHelper.m @@ -5,12 +5,15 @@ #import "ContactsViewHelper.h" #import "ContactTableViewCell.h" #import "Environment.h" +#import "Signal-Swift.h" #import #import #import #import #import +@import ContactsUI; + NS_ASSUME_NONNULL_BEGIN @interface ContactsViewHelper () @@ -95,7 +98,10 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert([NSThread isMainThread]); - if ([self.delegate shouldHideLocalNumber] && [self isCurrentUser:signalAccount]) { + + if ([self.delegate respondsToSelector:@selector(shouldHideLocalNumber)] && [self.delegate shouldHideLocalNumber] && + [self isCurrentUser:signalAccount]) { + return YES; } @@ -277,6 +283,91 @@ NS_ASSUME_NONNULL_BEGIN return _nonSignalContacts; } +#pragma mark - Editing + +- (void)presentContactViewControllerForRecipientId:(NSString *)recipientId + fromViewController:(UIViewController *)fromViewController + editImmediately:(BOOL)shouldEditImmediately +{ + SignalAccount *signalAccount = [self signalAccountForRecipientId:recipientId]; + + if (!self.contactsManager.isSystemContactsAuthorized) { + UIAlertController *alertController = [UIAlertController + alertControllerWithTitle:NSLocalizedString(@"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_TITLE", comment + : @"Alert title for when the user has just tried to edit a " + @"contacts after declining to give Signal contacts " + @"permissions") + message:NSLocalizedString(@"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_BODY", comment + : @"Alert body for when the user has just tried to edit a " + @"contacts after declining to give Signal contacts " + @"permissions") + preferredStyle:UIAlertControllerStyleAlert]; + + [alertController + addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"AB_PERMISSION_MISSING_ACTION_NOT_NOW", + @"Button text to dismiss missing contacts permission alert") + style:UIAlertActionStyleCancel + handler:nil]]; + + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OPEN_SETTINGS_BUTTON", + @"Button text which opens the settings app") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *_Nonnull action) { + [[UIApplication sharedApplication] openSystemSettings]; + }]]; + + [fromViewController presentViewController:alertController animated:YES completion:nil]; + return; + } + + CNContactViewController *_Nullable contactViewController; + if (signalAccount) { + CNContact *_Nullable cnContact = signalAccount.contact.cnContact; + if (cnContact) { + if (shouldEditImmediately) { + // Not acutally a "new" contact, but this brings up the edit form rather than the "Read" form + // saving our users a tap in some cases when we already know they want to edit. + contactViewController = [CNContactViewController viewControllerForNewContact:cnContact]; + } else { + contactViewController = [CNContactViewController viewControllerForContact:cnContact]; + } + } + } + + if (!contactViewController) { + CNMutableContact *newContact = [CNMutableContact new]; + CNPhoneNumber *phoneNumber = [CNPhoneNumber phoneNumberWithStringValue:recipientId]; + CNLabeledValue *labeledPhoneNumber = + [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMain value:phoneNumber]; + newContact.phoneNumbers = @[ labeledPhoneNumber ]; + + contactViewController = [CNContactViewController viewControllerForNewContact:newContact]; + } + + contactViewController.delegate = fromViewController; + contactViewController.allowsActions = NO; + contactViewController.allowsEditing = YES; + contactViewController.navigationItem.leftBarButtonItem = + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil) + style:UIBarButtonItemStylePlain + target:fromViewController + action:@selector(didFinishEditingContact)]; + + UINavigationController *navigationController = + [[UINavigationController alloc] initWithRootViewController:contactViewController]; + + // We want the presentation to imply a "replacement" in this case. + if (shouldEditImmediately) { + navigationController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + } + [fromViewController presentViewController:navigationController animated:YES completion:nil]; + + // HACK otherwise CNContactViewController Navbar is shown as black. + // RADAR rdar://28433898 http://www.openradar.me/28433898 + // CNContactViewController incompatible with opaque navigation bar + [UIUtil applyDefaultSystemAppearence]; +} + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m index e64b503a6..1554207c0 100644 --- a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m +++ b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m @@ -4,6 +4,7 @@ #import "OWSConversationSettingsTableViewController.h" #import "BlockListUIUtils.h" +#import "ContactsViewHelper.h" #import "Environment.h" #import "FingerprintViewController.h" #import "OWSAvatarBuilder.h" @@ -29,9 +30,11 @@ #import #import +@import ContactsUI; + NS_ASSUME_NONNULL_BEGIN -@interface OWSConversationSettingsTableViewController () +@interface OWSConversationSettingsTableViewController () @property (nonatomic) TSThread *thread; @@ -42,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSMessageSender *messageSender; @property (nonatomic, readonly) OWSBlockingManager *blockingManager; - +@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper; @property (nonatomic, readonly) UIImageView *avatarView; @property (nonatomic, readonly) UILabel *disappearingMessagesDurationLabel; @@ -93,6 +96,8 @@ NS_ASSUME_NONNULL_BEGIN _contactsManager = [Environment getCurrent].contactsManager; _messageSender = [Environment getCurrent].messageSender; _blockingManager = [OWSBlockingManager sharedManager]; + _contactsViewHelper = [ContactsViewHelper new]; + _contactsViewHelper.delegate = self; } - (NSString *)threadName @@ -115,6 +120,58 @@ NS_ASSUME_NONNULL_BEGIN - (void)configureWithThread:(TSThread *)thread { self.thread = thread; + [self updateEditButton]; +} + +- (void)updateEditButton +{ + OWSAssert(self.thread); + + if ([self.thread isKindOfClass:[TSContactThread class]]) { + self.navigationItem.rightBarButtonItem = + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"EDIT_TXT", nil) + style:UIBarButtonItemStylePlain + target:self + action:@selector(didTapEditButton)]; + } +} + +- (void)didTapEditButton +{ + if (![self.thread isKindOfClass:[TSContactThread class]]) { + DDLogError(@"%@ unexpected thread: %@ in %s", self.tag, self.thread, __PRETTY_FUNCTION__); + OWSAssert(NO); + return; + } + + TSContactThread *contactThread = (TSContactThread *)self.thread; + [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier + fromViewController:self + editImmediately:YES]; +} + +#pragma mark - ContactEditingDelegate + +- (void)didFinishEditingContact +{ + DDLogDebug(@"%@ %s", self.tag, __PRETTY_FUNCTION__); + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - CNContactViewControllerDelegate + +- (void)contactViewController:(CNContactViewController *)viewController + didCompleteWithContact:(nullable CNContact *)contact +{ + DDLogDebug(@"%@ done editing contact.", self.tag); + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - ContactsViewHelperDelegate + +- (void)contactsViewHelperDidUpdateContacts +{ + [self updateTableContents]; } #pragma mark - View Lifecycle @@ -568,6 +625,9 @@ NS_ASSUME_NONNULL_BEGIN { [super viewWillAppear:animated]; + // In case we're dismissing a CNContactViewController which requires default system appearance + [UIUtil applySignalAppearence]; + // HACK to unselect rows when swiping back // http://stackoverflow.com/questions/19379510/uitableviewcell-doesnt-get-deselected-when-swiping-back-quickly [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated]; diff --git a/Signal/src/ViewControllers/ShowGroupMembersViewController.m b/Signal/src/ViewControllers/ShowGroupMembersViewController.m index 382cbb312..536bee6a5 100644 --- a/Signal/src/ViewControllers/ShowGroupMembersViewController.m +++ b/Signal/src/ViewControllers/ShowGroupMembersViewController.m @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface ShowGroupMembersViewController () +@interface ShowGroupMembersViewController () @property (nonatomic, readonly) TSGroupThread *thread; @property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper; @@ -265,74 +265,9 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(recipientId.length > 0); - ContactsViewHelper *helper = self.contactsViewHelper; - SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId]; - - if (!helper.contactsManager.isSystemContactsAuthorized) { - UIAlertController *alertController = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_TITLE", comment - : @"Alert title for when the user has just tried to edit a " - @"contacts after declining to give Signal contacts " - @"permissions") - message:NSLocalizedString(@"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_BODY", comment - : @"Alert body for when the user has just tried to edit a " - @"contacts after declining to give Signal contacts " - @"permissions") - preferredStyle:UIAlertControllerStyleAlert]; - - [alertController - addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"AB_PERMISSION_MISSING_ACTION_NOT_NOW", - @"Button text to dismiss missing contacts permission alert") - style:UIAlertActionStyleCancel - handler:nil]]; - - [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OPEN_SETTINGS_BUTTON", - @"Button text which opens the settings app") - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *_Nonnull action) { - [[UIApplication sharedApplication] openSystemSettings]; - }]]; - - [self presentViewController:alertController animated:YES completion:nil]; - return; - } - - CNContactViewController *_Nullable contactViewController; - if (signalAccount) { - CNContact *_Nullable cnContact = signalAccount.contact.cnContact; - if (cnContact) { - contactViewController = [CNContactViewController viewControllerForContact:cnContact]; - } - } - - if (!contactViewController) { - CNMutableContact *newContact = [CNMutableContact new]; - CNPhoneNumber *phoneNumber = [CNPhoneNumber phoneNumberWithStringValue:recipientId]; - CNLabeledValue *labeledPhoneNumber = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMain - value:phoneNumber]; - newContact.phoneNumbers = @[labeledPhoneNumber]; - - contactViewController = [CNContactViewController viewControllerForNewContact:newContact]; - } - - contactViewController.delegate = self; - contactViewController.allowsActions = NO; - contactViewController.allowsEditing = YES; - contactViewController.navigationItem.leftBarButtonItem = - [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil) - style:UIBarButtonItemStylePlain - target:self - action:@selector(dismissPressed)]; - - UINavigationController *navigationController = - [[UINavigationController alloc] initWithRootViewController:contactViewController]; - [self presentViewController:navigationController animated:YES completion:nil]; - - - // HACK otherwise CNContactViewController Navbar is shown as black. - // RADAR rdar://28433898 http://www.openradar.me/28433898 - // CNContactViewController incompatible with opaque navigation bar - [UIUtil applyDefaultSystemAppearence]; + [self.contactsViewHelper presentContactViewControllerForRecipientId:recipientId + fromViewController:self + editImmediately:NO]; } - (void)showConversationViewForRecipientId:(NSString *)recipientId @@ -347,12 +282,6 @@ NS_ASSUME_NONNULL_BEGIN [Environment callUserWithIdentifier:recipientId]; } -- (void)dismissPressed -{ - DDLogDebug(@"%@ %s", self.tag, __PRETTY_FUNCTION__); - [self dismissViewControllerAnimated:YES completion:nil]; -} - #pragma mark - ContactsViewHelperDelegate - (void)contactsViewHelperDidUpdateContacts @@ -365,6 +294,14 @@ NS_ASSUME_NONNULL_BEGIN return YES; } +#pragma mark - ContactEditingDelegate + +- (void)didFinishEditingContact +{ + DDLogDebug(@"%@ %s", self.tag, __PRETTY_FUNCTION__); + [self dismissViewControllerAnimated:YES completion:nil]; +} + #pragma mark - CNContactViewControllerDelegate - (void)contactViewController:(CNContactViewController *)viewController diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index acd93a650..f7342b6cb 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -364,6 +364,9 @@ /* Short name for edit menu item to share contents of media message. */ "EDIT_ITEM_SHARE_ACTION" = "Share"; +/* No comment provided by engineer. */ +"EDIT_TXT" = "Edit"; + /* body of email sent to contacts when inviting to install Signal. Embeds {{link to install Signal}} and {{link to WhisperSystems home page}} */ "EMAIL_INVITE_BODY" = "Hey,\n\nLately I've been using Signal to keep the conversations on my iPhone private. I'd like you to install it too, so we can be confident that only you and I can read our messages or hear our calls.\n\nSignal is available for iPhones and Android. Get it here: %@\n\nSignal works like your existing messaging app. We can send pictures and video, make calls, and start group chats. The best part is, no one else can see any of it, not even the people who make Signal!\n\nYou can read more about Open Whisper Systems, the people who make Signal, here: %@"; From 9dc9813deaee34ab4aa6dbe85bcab57cabdbf7d8 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 9 May 2017 18:05:53 -0400 Subject: [PATCH 2/5] fix layout for long named contacts // FREEBIE --- .../ViewControllers/OWSConversationSettingsTableViewController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m index 1554207c0..e4c658134 100644 --- a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m +++ b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m @@ -565,6 +565,7 @@ NS_ASSUME_NONNULL_BEGIN [threadNameView addSubview:threadTitleLabel]; [threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeTop]; [threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft]; + [threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeRight]; if (![self isGroupThread] && ![self.thread.name isEqualToString:self.thread.contactIdentifier]) { NSString *subtitle = From aabd56b23de38271dce2c7d012c8bccbadaf337c Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 10 May 2017 10:56:57 -0400 Subject: [PATCH 3/5] Clean up comments per CR // FREEBIE --- Signal/src/ViewControllers/ContactsViewHelper.h | 4 ++++ Signal/src/ViewControllers/ContactsViewHelper.m | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Signal/src/ViewControllers/ContactsViewHelper.h b/Signal/src/ViewControllers/ContactsViewHelper.h index bc9e1088d..79fc60bef 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.h +++ b/Signal/src/ViewControllers/ContactsViewHelper.h @@ -55,6 +55,10 @@ NS_ASSUME_NONNULL_BEGIN - (NSArray *)nonSignalContactsMatchingSearchString:(NSString *)searchText; +/** + * NOTE: This method calls `[UIUtil applyDefaultSystemAppearence]`. + * When using this method, you must call `[UIUtil applySignalAppearence]` once contact editing is finished; + */ - (void)presentContactViewControllerForRecipientId:(NSString *)recipientId fromViewController:(UIViewController *)fromViewController editImmediately:(BOOL)shouldEditImmediately; diff --git a/Signal/src/ViewControllers/ContactsViewHelper.m b/Signal/src/ViewControllers/ContactsViewHelper.m index 5990e1ae1..f65800c88 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.m +++ b/Signal/src/ViewControllers/ContactsViewHelper.m @@ -325,7 +325,7 @@ NS_ASSUME_NONNULL_BEGIN CNContact *_Nullable cnContact = signalAccount.contact.cnContact; if (cnContact) { if (shouldEditImmediately) { - // Not acutally a "new" contact, but this brings up the edit form rather than the "Read" form + // Not actually a "new" contact, but this brings up the edit form rather than the "Read" form // saving our users a tap in some cases when we already know they want to edit. contactViewController = [CNContactViewController viewControllerForNewContact:cnContact]; } else { From bd343f6971a2d918ce7fd4962a0e701e3c4e4750 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 10 May 2017 12:02:14 -0400 Subject: [PATCH 4/5] clean up some animations // FREEBIE --- Signal/src/ViewControllers/ContactsViewHelper.m | 4 ++++ .../OWSConversationSettingsTableViewController.m | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Signal/src/ViewControllers/ContactsViewHelper.m b/Signal/src/ViewControllers/ContactsViewHelper.m index f65800c88..f3a3032f5 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.m +++ b/Signal/src/ViewControllers/ContactsViewHelper.m @@ -328,6 +328,10 @@ NS_ASSUME_NONNULL_BEGIN // Not actually a "new" contact, but this brings up the edit form rather than the "Read" form // saving our users a tap in some cases when we already know they want to edit. contactViewController = [CNContactViewController viewControllerForNewContact:cnContact]; + + // Default title is "New Contact". We could give a more descriptive title, but anything + // seems redundant - the context is sufficiently clear. + contactViewController.title = @""; } else { contactViewController = [CNContactViewController viewControllerForContact:cnContact]; } diff --git a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m index e4c658134..df591c212 100644 --- a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m +++ b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m @@ -155,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)didFinishEditingContact { DDLogDebug(@"%@ %s", self.tag, __PRETTY_FUNCTION__); - [self dismissViewControllerAnimated:YES completion:nil]; + [self dismissViewControllerAnimated:NO completion:nil]; } #pragma mark - CNContactViewControllerDelegate @@ -163,8 +163,16 @@ NS_ASSUME_NONNULL_BEGIN - (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(nullable CNContact *)contact { - DDLogDebug(@"%@ done editing contact.", self.tag); - [self dismissViewControllerAnimated:YES completion:nil]; + if (contact) { + // Saving normally returns you to the "Show Contact" view + // which we're not interested in, so we skip it here. There is + // an unfortunate blip of the "Show Contact" view on slower devices. + DDLogDebug(@"%@ completed editing contact.", self.tag); + [self dismissViewControllerAnimated:NO completion:nil]; + } else { + DDLogDebug(@"%@ canceled editing contact.", self.tag); + [self dismissViewControllerAnimated:YES completion:nil]; + } } #pragma mark - ContactsViewHelperDelegate From 737a5932c03fa2165cc7f35b787316b8843e3701 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 10 May 2017 12:07:14 -0400 Subject: [PATCH 5/5] tapping contact label shows contact edit view // FREEBIE --- ...SConversationSettingsTableViewController.m | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m index df591c212..8e1789439 100644 --- a/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m +++ b/Signal/src/ViewControllers/OWSConversationSettingsTableViewController.m @@ -136,20 +136,6 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)didTapEditButton -{ - if (![self.thread isKindOfClass:[TSContactThread class]]) { - DDLogError(@"%@ unexpected thread: %@ in %s", self.tag, self.thread, __PRETTY_FUNCTION__); - OWSAssert(NO); - return; - } - - TSContactThread *contactThread = (TSContactThread *)self.thread; - [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier - fromViewController:self - editImmediately:YES]; -} - #pragma mark - ContactEditingDelegate - (void)didFinishEditingContact @@ -612,7 +598,7 @@ NS_ASSUME_NONNULL_BEGIN [self showUpdateGroupView:UpdateGroupMode_EditGroupName]; } } else { - // TODO: Edit 1:1 contact. + [self presentContactViewController]; } } } @@ -683,6 +669,25 @@ NS_ASSUME_NONNULL_BEGIN [self presentViewController:navigationController animated:YES completion:nil]; } +- (void)presentContactViewController +{ + if (![self.thread isKindOfClass:[TSContactThread class]]) { + DDLogError(@"%@ unexpected thread: %@ in %s", self.tag, self.thread, __PRETTY_FUNCTION__); + OWSAssert(NO); + return; + } + + TSContactThread *contactThread = (TSContactThread *)self.thread; + [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier + fromViewController:self + editImmediately:YES]; +} + +- (void)didTapEditButton +{ + [self presentContactViewController]; +} + - (void)didTapLeaveGroup { UIAlertController *alertController =