diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index b1cc323eb..e8a428a91 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -16,6 +16,7 @@ #import "MediaDetailViewController.h" #import "NotificationSettingsViewController.h" #import "NotificationsManager.h" +#import "OWSAddToContactViewController.h" #import "OWSAnyTouchGestureRecognizer.h" #import "OWSAudioPlayer.h" #import "OWSBackup.h" diff --git a/Signal/src/ViewControllers/ContactViewController.swift b/Signal/src/ViewControllers/ContactViewController.swift index 605220570..3ba1e5738 100644 --- a/Signal/src/ViewControllers/ContactViewController.swift +++ b/Signal/src/ViewControllers/ContactViewController.swift @@ -6,27 +6,52 @@ import Foundation import SignalServiceKit import SignalMessaging import Reachability +import ContactsUI -class ContactViewController: OWSViewController { +class TappableView: UIView { + let actionBlock : (() -> Void) + + // MARK: - Initializers + + @available(*, unavailable, message: "use init(call:) constructor instead.") + required init?(coder aDecoder: NSCoder) { + fatalError("Unimplemented") + } + + required init(actionBlock : @escaping () -> Void) { + self.actionBlock = actionBlock + super.init(frame: CGRect.zero) + + self.isUserInteractionEnabled = true + self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped))) + } + + func wasTapped(sender: UIGestureRecognizer) { + Logger.info("\(self.logTag) \(#function)") + + guard sender.state == .recognized else { + return + } + actionBlock() + } +} + +// MARK: - + +class ContactViewController: OWSViewController, CNContactViewControllerDelegate +//, ContactsViewHelperDelegate +{ let TAG = "[ContactView]" enum ContactViewMode { case systemContactWithSignal, systemContactWithoutSignal, - nonSystemContactWithSignal, - nonSystemContactWithoutSignal, + nonSystemContact, noPhoneNumber, unknown } - enum ContactLookupMode { - case notLookingUp, - lookingUp, - lookedUpNoAccount, - lookedUpHasAccount - } - private var hasLoadedView = false private var viewMode = ContactViewMode.unknown { @@ -39,16 +64,6 @@ class ContactViewController: OWSViewController { } } - private var lookupMode = ContactLookupMode.notLookingUp { - didSet { - SwiftAssertIsOnMainThread(#function) - - if oldValue != lookupMode && hasLoadedView { - updateContent() - } - } - } - let contactsManager: OWSContactsManager var reachability: Reachability? @@ -59,6 +74,8 @@ class ContactViewController: OWSViewController { private let contact: OWSContact +// private var contactsViewHelper : ContactsViewHelper! + // MARK: - Initializers @available(*, unavailable, message: "use init(call:) constructor instead.") @@ -69,9 +86,12 @@ class ContactViewController: OWSViewController { required init(contact: OWSContact) { contactsManager = Environment.current().contactsManager self.contact = contact + self.scrollView = UIScrollView() super.init(nibName: nil, bundle: nil) +// contactsViewHelper = ContactsViewHelper(delegate:self) + tryToDetermineMode() NotificationCenter.default.addObserver(forName: .OWSContactsManagerSignalAccountsDidChange, object: nil, queue: nil) { [weak self] _ in @@ -96,6 +116,8 @@ class ContactViewController: OWSViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + UIUtil.applySignalAppearence() + self.becomeFirstResponder() contactsManager.requestSystemContactsOnce(completion: { [weak self] _ in @@ -107,11 +129,28 @@ class ContactViewController: OWSViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + UIUtil.applySignalAppearence() + self.becomeFirstResponder() } + private var scrollView: UIScrollView + override func loadView() { +// scrollView.dir +// self.view = scrollView +// let rootView = UIView() super.loadView() +// self.view.layoutMargins = .zero + +// self.scrollView = scrollView +// scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + self.view.addSubview(scrollView) + scrollView.layoutMargins = .zero + scrollView.autoPinWidthToSuperview() + scrollView.autoPin(toTopLayoutGuideOf: self, withInset: 0) + scrollView.autoPin(toBottomLayoutGuideOf: self, withInset: 0) + self.view.backgroundColor = UIColor.white updateContent() @@ -138,41 +177,7 @@ class ContactViewController: OWSViewController { return } - switch lookupMode { - case .notLookingUp: - lookupMode = .lookingUp - viewMode = .unknown - ContactsUpdater.shared().lookupIdentifiers([firstPhoneNumber.phoneNumber], success: { [weak self] (signalRecipients) in - guard let strongSelf = self else { return } - - let hasSignalAccount = signalRecipients.filter({ (signalRecipient) -> Bool in - return signalRecipient.recipientId() == firstPhoneNumber.phoneNumber - }).count > 0 - - if hasSignalAccount { - strongSelf.lookupMode = .lookedUpHasAccount - strongSelf.tryToDetermineMode() - } else { - strongSelf.lookupMode = .lookedUpNoAccount - strongSelf.tryToDetermineMode() - } - }) { [weak self] (error) in - guard let strongSelf = self else { return } - Logger.error("\(strongSelf.logTag) error looking up contact: \(error)") - strongSelf.lookupMode = .notLookingUp - strongSelf.tryToDetermineModeRetry() - } - return - case .lookingUp: - viewMode = .unknown - return - case .lookedUpNoAccount: - viewMode = .nonSystemContactWithoutSignal - return - case .lookedUpHasAccount: - viewMode = .nonSystemContactWithSignal - return - } + viewMode = .nonSystemContact } private func tryToDetermineModeRetry() { @@ -186,7 +191,9 @@ class ContactViewController: OWSViewController { private func updateContent() { SwiftAssertIsOnMainThread(#function) - for subview in self.view.subviews { + let rootView = self.scrollView + + for subview in rootView.subviews { subview.removeFromSuperview() } @@ -194,9 +201,10 @@ class ContactViewController: OWSViewController { let topView = UIView.container() topView.backgroundColor = UIColor(rgbHex: 0xefeff4) topView.preservesSuperviewLayoutMargins = true - self.view.addSubview(topView) + rootView.addSubview(topView) topView.autoPinEdge(toSuperviewEdge: .top) - topView.autoPinWidthToSuperview() + topView.autoPinEdge(.left, to: .left, of: self.view, withOffset: 0) + topView.autoPinEdge(.right, to: .right, of: self.view, withOffset: 0) // TODO: Use actual avatar. let avatarSize = CGFloat(100) @@ -204,14 +212,14 @@ class ContactViewController: OWSViewController { avatarView.backgroundColor = UIColor.ows_materialBlue avatarView.layer.cornerRadius = avatarSize * 0.5 topView.addSubview(avatarView) - avatarView.autoPin(toTopLayoutGuideOf: self, withInset: 0) + avatarView.autoPin(toTopLayoutGuideOf: self, withInset: 10) avatarView.autoHCenterInSuperview() avatarView.autoSetDimension(.width, toSize: avatarSize) avatarView.autoSetDimension(.height, toSize: avatarSize) let nameLabel = UILabel() nameLabel.text = contact.displayName - nameLabel.font = UIFont.ows_dynamicTypeTitle3 + nameLabel.font = UIFont.ows_dynamicTypeTitle1 nameLabel.textColor = UIColor.black nameLabel.lineBreakMode = .byTruncatingTail nameLabel.textAlignment = .center @@ -225,12 +233,12 @@ class ContactViewController: OWSViewController { if let firstPhoneNumber = contact.phoneNumbers?.first { let phoneNumberLabel = UILabel() phoneNumberLabel.text = firstPhoneNumber.phoneNumber - phoneNumberLabel.font = UIFont.ows_dynamicTypeCaption1 + phoneNumberLabel.font = UIFont.ows_dynamicTypeCaption2 phoneNumberLabel.textColor = UIColor.black phoneNumberLabel.lineBreakMode = .byTruncatingTail phoneNumberLabel.textAlignment = .center topView.addSubview(phoneNumberLabel) - phoneNumberLabel.autoPinEdge(.top, to: .bottom, of: lastView, withOffset: 10) + phoneNumberLabel.autoPinEdge(.top, to: .bottom, of: lastView, withOffset: 5) phoneNumberLabel.autoPinLeadingToSuperviewMargin() phoneNumberLabel.autoPinTrailingToSuperviewMargin() lastView = phoneNumberLabel @@ -238,14 +246,16 @@ class ContactViewController: OWSViewController { switch viewMode { case .systemContactWithSignal: + // Show actions buttons for system contacts with a Signal account. break case .systemContactWithoutSignal: + // Show invite button for system contacts without a Signal account. break - case .nonSystemContactWithSignal: - break - case .nonSystemContactWithoutSignal: + case .nonSystemContact: + // Show no action buttons for contacts not in user's device contacts. break case .noPhoneNumber: + // Show no action buttons for contacts without a phone number. break case .unknown: let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) @@ -256,7 +266,149 @@ class ContactViewController: OWSViewController { break } - lastView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 10) + lastView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 15) + + let bottomView = UIView.container() + bottomView.backgroundColor = UIColor.white + bottomView.layoutMargins = .zero + bottomView.preservesSuperviewLayoutMargins = false + rootView.addSubview(bottomView) + bottomView.autoPinEdge(.top, to: .bottom, of: topView, withOffset: 0) + bottomView.autoPinEdge(toSuperviewEdge: .bottom) + bottomView.autoPinEdge(.left, to: .left, of: self.view, withOffset: 0) + bottomView.autoPinEdge(.right, to: .right, of: self.view, withOffset: 0) + bottomView.setContentHuggingVerticalLow() + + var lastRow: UIView? + + let addSpacerRow = { + guard let prevRow = lastRow else { + owsFail("\(self.logTag) missing last row") + return + } + let row = UIView() + row.backgroundColor = UIColor(rgbHex: 0xdedee1) + bottomView.addSubview(row) + row.autoSetDimension(.height, toSize: 1) + row.autoPinLeadingToSuperviewMargin(withInset: self.hMargin) + row.autoPinTrailingToSuperviewMargin() + row.autoPinEdge(.top, to: .bottom, of: prevRow, withOffset: 0) + lastRow = row + } + + let addRow: ((UIView) -> Void) = { (row) in + if lastRow != nil { + addSpacerRow() + } + bottomView.addSubview(row) + row.autoPinLeadingToSuperviewMargin() + row.autoPinTrailingToSuperviewMargin() + if let lastRow = lastRow { + row.autoPinEdge(.top, to: .bottom, of: lastRow, withOffset: 0) + } else { + row.autoPinEdge(toSuperviewEdge: .top, withInset: 0) + } + lastRow = row + } + + if viewMode == .nonSystemContact { + addRow(createActionRow(labelText: NSLocalizedString("CONVERSATION_SETTINGS_NEW_CONTACT", + comment: "Label for 'new contact' button in conversation settings view."), + action: #selector(didPressCreateNewContact))) + + addRow(createActionRow(labelText: NSLocalizedString("CONVERSATION_SETTINGS_ADD_TO_EXISTING_CONTACT", + comment: "Label for 'new contact' button in conversation settings view."), + action: #selector(didPressAddToExistingContact))) + } + + // TODO: Not designed yet. +// if viewMode == .systemContactWithSignal || +// viewMode == .systemContactWithoutSignal { +// addRow(createActionRow(labelText:NSLocalizedString("ACTION_SHARE_CONTACT", +// comment:"Label for 'share contact' button."), +// action:#selector(didPressShareContact))) +// } + + if let phoneNumbers = contact.phoneNumbers { + for phoneNumber in phoneNumbers { + // TODO: Try to format the phone number nicely. + addRow(createNameValueRow(name: phoneNumber.labelString(), + value: phoneNumber.phoneNumber, + actionBlock: { + guard let url = NSURL(string: "tel:\(phoneNumber.phoneNumber)") else { + owsFail("\(ContactViewController.logTag) could not open phone number.") + return + } + UIApplication.shared.openURL(url as URL) + })) + } + } + + if let emails = contact.emails { + for email in emails { + addRow(createNameValueRow(name: email.labelString(), + value: email.email, + actionBlock: { + guard let url = NSURL(string: "mailto:\(email.email)") else { + owsFail("\(ContactViewController.logTag) could not open email.") + return + } + UIApplication.shared.openURL(url as URL) + })) + } + } + + // TODO: Should we present addresses here too? How? + + lastRow?.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0) + } + + private let hMargin = CGFloat(10) + + private func createActionRow(labelText: String, action: Selector) -> UIView { + let row = UIView() + row.isUserInteractionEnabled = true + row.addGestureRecognizer(UITapGestureRecognizer(target: self, action: action)) + let label = UILabel() + label.text = labelText + label.font = UIFont.ows_dynamicTypeBody + label.textColor = UIColor.ows_materialBlue + label.lineBreakMode = .byTruncatingTail + row.addSubview(label) + label.autoPinTopToSuperviewMargin() + label.autoPinBottomToSuperviewMargin() + label.autoPinLeadingToSuperviewMargin(withInset: hMargin) + label.autoPinTrailingToSuperviewMargin(withInset: hMargin) + return row + } + + private func createNameValueRow(name: String, value: String, actionBlock : @escaping () -> Void) -> UIView { + let row = TappableView(actionBlock: actionBlock) + + let nameLabel = UILabel() + nameLabel.text = name + nameLabel.font = UIFont.ows_dynamicTypeCaption1 + nameLabel.textColor = UIColor.black + nameLabel.lineBreakMode = .byTruncatingTail + row.addSubview(nameLabel) + nameLabel.autoPinTopToSuperviewMargin() + nameLabel.autoPinLeadingToSuperviewMargin(withInset: hMargin) + nameLabel.autoPinTrailingToSuperviewMargin(withInset: hMargin) + + let valueLabel = UILabel() + valueLabel.text = value + valueLabel.font = UIFont.ows_dynamicTypeCaption1 + valueLabel.textColor = UIColor.ows_materialBlue + valueLabel.lineBreakMode = .byTruncatingTail + row.addSubview(valueLabel) + valueLabel.autoPinEdge(.top, to: .bottom, of: nameLabel, withOffset: 3) + valueLabel.autoPinBottomToSuperviewMargin() + valueLabel.autoPinLeadingToSuperviewMargin(withInset: hMargin) + valueLabel.autoPinTrailingToSuperviewMargin(withInset: hMargin) + + // TODO: Should there be a disclosure icon here? + + return row } // acceptIncomingButton = createButton(image: #imageLiteral(resourceName: "call-active-wide"), @@ -299,5 +451,127 @@ class ContactViewController: OWSViewController { // self.dismiss(animated: true, completion: completion) // } // } + + func didPressCreateNewContact(sender: UIGestureRecognizer) { + Logger.info("\(self.TAG) \(#function)") + + guard sender.state == .recognized else { + return + } + presentNewContactView() + } + + func didPressAddToExistingContact(sender: UIGestureRecognizer) { + Logger.info("\(self.TAG) \(#function)") + + guard sender.state == .recognized else { + return + } + presentSelectAddToExistingContactView() + } + + func didPressShareContact(sender: UIGestureRecognizer) { + Logger.info("\(self.TAG) \(#function)") + + guard sender.state == .recognized else { + return + } + // TODO: + } + + // MARK: - ContactsViewHelperDelegate + +// @objc +// public func contactsViewHelperDidUpdateContacts() { +// Logger.info("\(self.TAG) \(#function)") // +// // Do nothing +// } + + // MARK: - + + private func presentNewContactView() { + guard contactsManager.supportsContactEditing else { + owsFail("\(self.logTag) Contact editing not supported") + return + } + // contactsViewHelper.presentContactViewController + // let contactsViewHelper = ContactsViewHelper(delegate:self) + // + // TSContactThread *contactThread = (TSContactThread *)self.thread; + // [self.contactsViewHelper presentContactViewControllerForRecipientId:contactThread.contactIdentifier + // fromViewController:self + // editImmediately:YES]; + + guard let systemContact = OWSContacts.systemContact(for: contact) else { + owsFail("\(self.logTag) Could not derive system contact.") + return + } + + guard contactsManager.isSystemContactsAuthorized else { + ContactsViewHelper.presentMissingContactAccessAlertController(from: self) + return + } + + let contactViewController = CNContactViewController(forNewContact: systemContact) + contactViewController.delegate = self + contactViewController.allowsActions = false + contactViewController.allowsEditing = true + contactViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: CommonStrings.cancelButton, style: .plain, target: self, action: #selector(didFinishEditingContact)) + contactViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: CommonStrings.cancelButton, + style: .plain, + target: self, + action: #selector(didFinishEditingContact)) + + self.navigationController?.pushViewController(contactViewController, animated: true) + + // HACK otherwise CNContactViewController Navbar is shown as black. + // RADAR rdar://28433898 http://www.openradar.me/28433898 + // CNContactViewController incompatible with opaque navigation bar + UIUtil.applyDefaultSystemAppearence() + } + + private func presentSelectAddToExistingContactView() { + guard contactsManager.supportsContactEditing else { + owsFail("\(self.logTag) Contact editing not supported") + return + } + + guard let systemContact = OWSContacts.systemContact(for: contact) else { + owsFail("\(self.logTag) Could not derive system contact.") + return + } + + guard contactsManager.isSystemContactsAuthorized else { + ContactsViewHelper.presentMissingContactAccessAlertController(from: self) + return + } + + guard let firstPhoneNumber = contact.phoneNumbers?.first else { + owsFail("\(self.logTag) Missing phone number.") + return + } + + let viewController = OWSAddToContactViewController() + viewController.configure(withRecipientId: firstPhoneNumber.phoneNumber) + self.navigationController?.pushViewController(viewController, animated: true) + } + + // MARK: - CNContactViewControllerDelegate + + @objc public func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) { + Logger.info("\(self.TAG) \(#function)") + + self.navigationController?.popToViewController(self, animated: true) + + updateContent() + } + + @objc public func didFinishEditingContact() { + Logger.info("\(self.TAG) \(#function)") + + self.navigationController?.popToViewController(self, animated: true) + + updateContent() + } } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 181c97cca..108e8e9a0 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -2976,11 +2976,11 @@ typedef OWSContact * (^OWSContactBlock)(void); OWSContactPhoneNumber *phoneNumber1 = [OWSContactPhoneNumber new]; phoneNumber1.phoneType = OWSContactPhoneType_Home; - phoneNumber1.phoneNumber = @"+13213214321"; + phoneNumber1.phoneNumber = @"+13213215555"; OWSContactPhoneNumber *phoneNumber2 = [OWSContactPhoneNumber new]; phoneNumber2.phoneType = OWSContactPhoneType_Custom; phoneNumber2.label = @"Carphone"; - phoneNumber2.phoneNumber = @"+13332221111"; + phoneNumber2.phoneNumber = @"+13332226666"; contact.phoneNumbers = @[ phoneNumber1, phoneNumber2, @@ -2988,11 +2988,11 @@ typedef OWSContact * (^OWSContactBlock)(void); OWSContactEmail *email1 = [OWSContactEmail new]; email1.emailType = OWSContactEmailType_Home; - email1.email = @"a@b.com"; + email1.email = @"a1@b.com"; OWSContactEmail *email2 = [OWSContactEmail new]; email2.emailType = OWSContactEmailType_Custom; email2.label = @"customer support"; - email2.email = @"a@b.com"; + email2.email = @"a2@b.com"; contact.emails = @[ email1, email2, diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 08d1adffa..efd90e5c1 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -286,6 +286,10 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations } [self updateBarButtonItems]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + }); } - (void)applyDefaultBackButton diff --git a/SignalMessaging/Views/ContactsViewHelper.h b/SignalMessaging/Views/ContactsViewHelper.h index e963ba687..e48b1675a 100644 --- a/SignalMessaging/Views/ContactsViewHelper.h +++ b/SignalMessaging/Views/ContactsViewHelper.h @@ -1,12 +1,13 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN -@class ContactsViewHelper; @class Contact; +@class ContactsViewHelper; @class SignalAccount; + @protocol CNContactViewControllerDelegate; @protocol ContactsViewHelperDelegate @@ -27,9 +28,9 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - -@class OWSContactsManager; -@class OWSBlockingManager; @class CNContact; +@class OWSBlockingManager; +@class OWSContactsManager; @interface ContactsViewHelper : NSObject @@ -81,6 +82,8 @@ NS_ASSUME_NONNULL_BEGIN editImmediately:(BOOL)shouldEditImmediately addToExistingCnContact:(CNContact *_Nullable)cnContact; ++ (void)presentMissingContactAccessAlertControllerFromViewController:(UIViewController *)viewController; + @end NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/Views/ContactsViewHelper.m b/SignalMessaging/Views/ContactsViewHelper.m index af2ae1829..17c38ef4d 100644 --- a/SignalMessaging/Views/ContactsViewHelper.m +++ b/SignalMessaging/Views/ContactsViewHelper.m @@ -264,6 +264,11 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Editing - (void)presentMissingContactAccessAlertControllerFromViewController:(UIViewController *)viewController +{ + [ContactsViewHelper presentMissingContactAccessAlertControllerFromViewController:viewController]; +} + ++ (void)presentMissingContactAccessAlertControllerFromViewController:(UIViewController *)viewController { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_TITLE", comment diff --git a/SignalServiceKit/src/Messages/Interactions/OWSContact.h b/SignalServiceKit/src/Messages/Interactions/OWSContact.h index 8f3f5c07f..bd83eff04 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSContact.h +++ b/SignalServiceKit/src/Messages/Interactions/OWSContact.h @@ -30,6 +30,8 @@ typedef NS_ENUM(NSUInteger, OWSContactPhoneType) { - (BOOL)ows_isValid; +- (NSString *)labelString; + @end #pragma mark - @@ -51,6 +53,8 @@ typedef NS_ENUM(NSUInteger, OWSContactEmailType) { - (BOOL)ows_isValid; +- (NSString *)labelString; + @end #pragma mark - @@ -77,6 +81,8 @@ typedef NS_ENUM(NSUInteger, OWSContactAddressType) { - (BOOL)ows_isValid; +- (NSString *)labelString; + @end #pragma mark - diff --git a/SignalServiceKit/src/Messages/Interactions/OWSContact.m b/SignalServiceKit/src/Messages/Interactions/OWSContact.m index aa15b985e..f97cb6473 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSContact.m +++ b/SignalServiceKit/src/Messages/Interactions/OWSContact.m @@ -42,6 +42,20 @@ NS_ASSUME_NONNULL_BEGIN } } +- (NSString *)labelString +{ + switch (self.phoneType) { + case OWSContactPhoneType_Home: + return [CNLabeledValue localizedStringForLabel:CNLabelHome]; + case OWSContactPhoneType_Mobile: + return [CNLabeledValue localizedStringForLabel:CNLabelPhoneNumberMobile]; + case OWSContactPhoneType_Work: + return [CNLabeledValue localizedStringForLabel:CNLabelWork]; + default: + return self.label; + } +} + @end #pragma mark - @@ -74,6 +88,20 @@ NS_ASSUME_NONNULL_BEGIN } } +- (NSString *)labelString +{ + switch (self.emailType) { + case OWSContactEmailType_Home: + return [CNLabeledValue localizedStringForLabel:CNLabelHome]; + case OWSContactEmailType_Mobile: + return [CNLabeledValue localizedStringForLabel:CNLabelPhoneNumberMobile]; + case OWSContactEmailType_Work: + return [CNLabeledValue localizedStringForLabel:CNLabelWork]; + default: + return self.label; + } +} + @end #pragma mark - @@ -114,6 +142,18 @@ NS_ASSUME_NONNULL_BEGIN } } +- (NSString *)labelString +{ + switch (self.addressType) { + case OWSContactAddressType_Home: + return [CNLabeledValue localizedStringForLabel:CNLabelHome]; + case OWSContactAddressType_Work: + return [CNLabeledValue localizedStringForLabel:CNLabelWork]; + default: + return self.label; + } +} + @end #pragma mark -