|  |  |  | // | 
					
						
							|  |  |  | //  Copyright (c) 2018 Open Whisper Systems. All rights reserved. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import Foundation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public class ContactFieldView: UIView { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @available(*, unavailable, message: "use other constructor instead.") | 
					
						
							|  |  |  |     public required init?(coder aDecoder: NSCoder) { | 
					
						
							|  |  |  |         fatalError("Unimplemented") | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public required init(rows: [UIView], hMargin: CGFloat) { | 
					
						
							|  |  |  |         super.init(frame: CGRect.zero) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.layoutMargins = .zero | 
					
						
							|  |  |  |         self.preservesSuperviewLayoutMargins = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         addRows(rows: rows, hMargin: hMargin) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private func addRows(rows: [UIView], hMargin: CGFloat) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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) | 
					
						
							|  |  |  |             self.addSubview(row) | 
					
						
							|  |  |  |             row.autoSetDimension(.height, toSize: 1) | 
					
						
							|  |  |  |             row.autoPinLeadingToSuperviewMargin(withInset: hMargin) | 
					
						
							|  |  |  |             row.autoPinTrailingToSuperviewMargin() | 
					
						
							|  |  |  |             row.autoPinEdge(.top, to: .bottom, of: prevRow, withOffset: 0) | 
					
						
							|  |  |  |             lastRow = row | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let addRow: ((UIView) -> Void) = { (row) in | 
					
						
							|  |  |  |             if lastRow != nil { | 
					
						
							|  |  |  |                 addSpacerRow() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             self.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 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for row in rows { | 
					
						
							|  |  |  |             addRow(row) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         lastRow?.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public class func contactFieldView(forAvatarImage avatarImage: UIImage, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView { | 
					
						
							|  |  |  |         var stackView: UIStackView | 
					
						
							|  |  |  |         if let actionBlock = actionBlock { | 
					
						
							|  |  |  |             stackView = TappableStackView(actionBlock: actionBlock) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             stackView = UIStackView() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         stackView.axis = .vertical | 
					
						
							|  |  |  |         stackView.alignment = .leading | 
					
						
							|  |  |  |         stackView.spacing = 3 | 
					
						
							|  |  |  |         stackView.layoutMargins = layoutMargins | 
					
						
							|  |  |  |         stackView.isLayoutMarginsRelativeArrangement = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let avatarView = AvatarImageView() | 
					
						
							|  |  |  |         avatarView.image = avatarImage | 
					
						
							|  |  |  |         let avatarSize = CGFloat(50) | 
					
						
							|  |  |  |         avatarView.autoSetDimension(.width, toSize: avatarSize) | 
					
						
							|  |  |  |         avatarView.autoSetDimension(.height, toSize: avatarSize) | 
					
						
							|  |  |  |         avatarView.setCompressionResistanceHigh() | 
					
						
							|  |  |  |         avatarView.setContentHuggingHigh() | 
					
						
							|  |  |  |         stackView.addArrangedSubview(avatarView) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return stackView | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public class func contactFieldView(forOrganizationName organizationName: String, layoutMargins: UIEdgeInsets) -> UIView { | 
					
						
							|  |  |  |         return simpleFieldView(name: NSLocalizedString("CONTACT_FIELD_ORGANIZATION", | 
					
						
							|  |  |  |                                                        comment: "Label for the 'organization' field of a contact."), | 
					
						
							|  |  |  |                                value: organizationName, | 
					
						
							|  |  |  |                                layoutMargins: layoutMargins, actionBlock: nil) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public class func contactFieldView(forPhoneNumber phoneNumber: OWSContactPhoneNumber, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView { | 
					
						
							|  |  |  |         let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: phoneNumber.phoneNumber) | 
					
						
							|  |  |  |         return simpleFieldView(name: phoneNumber.localizedLabel(), value: formattedPhoneNumber, layoutMargins: layoutMargins, actionBlock: actionBlock) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public class func contactFieldView(forEmail email: OWSContactEmail, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView { | 
					
						
							|  |  |  |         return simpleFieldView(name: email.localizedLabel(), value: email.email, layoutMargins: layoutMargins, actionBlock: actionBlock) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private class func simpleFieldView(name: String, value: String?, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView { | 
					
						
							|  |  |  |         var stackView: UIStackView | 
					
						
							|  |  |  |         if let actionBlock = actionBlock { | 
					
						
							|  |  |  |             stackView = TappableStackView(actionBlock: actionBlock) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             stackView = UIStackView() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         stackView.axis = .vertical | 
					
						
							|  |  |  |         stackView.alignment = .leading | 
					
						
							|  |  |  |         stackView.spacing = 3 | 
					
						
							|  |  |  |         stackView.layoutMargins = layoutMargins | 
					
						
							|  |  |  |         stackView.isLayoutMarginsRelativeArrangement = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let nameLabel = UILabel() | 
					
						
							|  |  |  |         nameLabel.text = name.lowercased() | 
					
						
							|  |  |  |         nameLabel.font = UIFont.ows_dynamicTypeSubheadline | 
					
						
							|  |  |  |         nameLabel.textColor = UIColor.black | 
					
						
							|  |  |  |         nameLabel.lineBreakMode = .byTruncatingTail | 
					
						
							|  |  |  |         stackView.addArrangedSubview(nameLabel) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let valueLabel = UILabel() | 
					
						
							|  |  |  |         valueLabel.text = value | 
					
						
							|  |  |  |         valueLabel.font = UIFont.ows_dynamicTypeBody | 
					
						
							|  |  |  |         valueLabel.textColor = UIColor.ows_materialBlue | 
					
						
							|  |  |  |         valueLabel.lineBreakMode = .byTruncatingTail | 
					
						
							|  |  |  |         stackView.addArrangedSubview(valueLabel) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return stackView | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public class func contactFieldView(forAddress address: OWSContactAddress, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView { | 
					
						
							|  |  |  |         var stackView: UIStackView | 
					
						
							|  |  |  |         if let actionBlock = actionBlock { | 
					
						
							|  |  |  |              stackView = TappableStackView(actionBlock: actionBlock) | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             stackView = UIStackView() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         stackView.axis = .vertical | 
					
						
							|  |  |  |         stackView.alignment = .leading | 
					
						
							|  |  |  |         stackView.spacing = 3 | 
					
						
							|  |  |  |         stackView.layoutMargins = layoutMargins | 
					
						
							|  |  |  |         stackView.isLayoutMarginsRelativeArrangement = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let nameLabel = UILabel() | 
					
						
							|  |  |  |         nameLabel.text = address.localizedLabel() | 
					
						
							|  |  |  |         nameLabel.font = UIFont.ows_dynamicTypeSubheadline | 
					
						
							|  |  |  |         nameLabel.textColor = UIColor.black | 
					
						
							|  |  |  |         nameLabel.lineBreakMode = .byTruncatingTail | 
					
						
							|  |  |  |         stackView.addArrangedSubview(nameLabel) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let tryToAddNameValue: ((String, String?) -> Void) = { (propertyName, propertyValue) in | 
					
						
							|  |  |  |             guard let propertyValue = propertyValue else { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             guard propertyValue.count > 0 else { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let row = UIStackView() | 
					
						
							|  |  |  |             row.axis = .horizontal | 
					
						
							|  |  |  |             row.alignment = .leading | 
					
						
							|  |  |  |             row.spacing = 10 | 
					
						
							|  |  |  |             row.layoutMargins = .zero | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let nameLabel = UILabel() | 
					
						
							|  |  |  |             nameLabel.text = propertyName | 
					
						
							|  |  |  |             nameLabel.font = UIFont.ows_dynamicTypeBody | 
					
						
							|  |  |  |             nameLabel.textColor = UIColor.black | 
					
						
							|  |  |  |             nameLabel.lineBreakMode = .byTruncatingTail | 
					
						
							|  |  |  |             row.addArrangedSubview(nameLabel) | 
					
						
							|  |  |  |             nameLabel.setContentHuggingHigh() | 
					
						
							|  |  |  |             nameLabel.setCompressionResistanceHigh() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let valueLabel = UILabel() | 
					
						
							|  |  |  |             valueLabel.text = propertyValue | 
					
						
							|  |  |  |             valueLabel.font = UIFont.ows_dynamicTypeBody | 
					
						
							|  |  |  |             valueLabel.textColor = UIColor.ows_materialBlue | 
					
						
							|  |  |  |             valueLabel.lineBreakMode = .byTruncatingTail | 
					
						
							|  |  |  |             row.addArrangedSubview(valueLabel) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             stackView.addArrangedSubview(row) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_STREET", comment: "Label for the 'street' field of a contact's address."), | 
					
						
							|  |  |  |                           address.street) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POBOX", comment: "Label for the 'pobox' field of a contact's address."), | 
					
						
							|  |  |  |                           address.pobox) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_NEIGHBORHOOD", comment: "Label for the 'neighborhood' field of a contact's address."), | 
					
						
							|  |  |  |                           address.neighborhood) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_CITY", comment: "Label for the 'city' field of a contact's address."), | 
					
						
							|  |  |  |                           address.city) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_REGION", comment: "Label for the 'region' field of a contact's address."), | 
					
						
							|  |  |  |                           address.region) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POSTCODE", comment: "Label for the 'postcode' field of a contact's address."), | 
					
						
							|  |  |  |                           address.postcode) | 
					
						
							|  |  |  |         tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_COUNTRY", comment: "Label for the 'country' field of a contact's address."), | 
					
						
							|  |  |  |                           address.country) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return stackView | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |