pEpForiOS/UI/EmailDisplay/EmailHeaderView.swift
author Dirk Zimmermann <dirk@pep-project.org>
Mon, 19 Dec 2016 17:00:48 +0100
changeset 1348 47fb980d20d4
parent 1011 9f1b63f73169
child 1927 80bb88fbb017
permissions -rw-r--r--
IOS-358 SendLayerDelegate -> MessageFolderDelegate
     1 //
     2 //  EmailHeaderView.swift
     3 //  pEpForiOS
     4 //
     5 //  Created by Dirk Zimmermann on 20/06/16.
     6 //  Copyright © 2016 p≡p Security S.A. All rights reserved.
     7 //
     8 
     9 import UIKit
    10 
    11 import MessageModel
    12 
    13 class EmailHeaderView: UIView {
    14     /**
    15      Where to start laying out labels from the left.
    16      */
    17     let insetsX: CGFloat = 5
    18 
    19     /**
    20      Some extra padding from the left when we have to break apart labels that belong together.
    21      */
    22     let insetsNewlineX: CGFloat = 5
    23 
    24     /**
    25      Where to start laying out labels from the top.
    26      */
    27     let insetsY: CGFloat = 5
    28 
    29     /** Horizontal gap between labels that belong in one row.
    30      */
    31     let labelGapX: CGFloat = 5
    32 
    33     /**
    34      Vertical gap between lines of labels.
    35      */
    36     let labelGapY: CGFloat = 5
    37 
    38     /**
    39      Vertical gap between different sections.
    40      */
    41     let biggerLabelGapY: CGFloat = 10
    42 
    43     /**
    44      The size we need to layout all labels, dependent on the input width.
    45      */
    46     var preferredSize: CGSize = CGSize.zero
    47 
    48     /**
    49      The last label we layed out on the left side.
    50      */
    51     var lastLeftLabel: UILabel? = nil
    52 
    53     var message: Message!
    54 
    55     let dateFormatter = UIHelper.dateFormatterEmailDetails()
    56 
    57     /**
    58      Layout the message header contents.
    59 
    60      - Parameter width: The maximum width the layout should use. Very important for
    61      determining line breaks.
    62      */
    63     func update(_ width: CGFloat) {
    64         while subviews.count > 0 {
    65             subviews.first?.removeFromSuperview()
    66         }
    67 
    68         var pos = CGPoint(x: insetsX, y: insetsY)
    69         pos = addFromAtPosition(pos, width: width)
    70 
    71 //        if message.to.count > 0 {
    72 //            pos = addRecipients(message.to,
    73 //                                title: NSLocalizedString("To",
    74 //                                    comment: "Header label for email display"),
    75 //                                position: pos, width: width)
    76 //        }
    77 //        if message.cc.count > 0 {
    78 //            pos = addRecipients(message.cc,
    79 //                                title: NSLocalizedString("Cc",
    80 //                                    comment: "Header label for email display"),
    81 //                                position: pos, width: width)
    82 //        }
    83 //        if message.bcc.count > 0 {
    84 //            pos = addRecipients(message.bcc,
    85 //                                title: NSLocalizedString("Bcc",
    86 //                                    comment: "Header label for email display"),
    87 //                                position: pos, width: width)
    88 //        }
    89 //
    90 //        if let date = message.received {
    91 //            pos = biggerNewline(pos)
    92 //            let dateLabel = headerBaseLabelWithText(dateFormatter.string(from: date as Date),
    93 //                                                    maxWidth: width)
    94 //            dateLabel.frame.origin = pos
    95 //            addSubview(dateLabel)
    96 //            pos.x = labelGapX
    97 //            pos.y += dateLabel.bounds.height
    98 //            lastLeftLabel = dateLabel
    99 //        }
   100 //
   101 //        if let subject = message.shortMessage {
   102 //            pos = biggerNewline(pos)
   103 //            let subjectLabel = headerBaseLabelWithText(subject, maxWidth: width)
   104 //            subjectLabel.frame.origin = pos
   105 //            addSubview(subjectLabel)
   106 //            pos.x = labelGapX
   107 //            pos.y += subjectLabel.bounds.height
   108 //            lastLeftLabel = subjectLabel
   109 //        }
   110 //
   111 //        preferredSize = CGSize(width: width, height: pos.y)
   112     }
   113 
   114     func addRecipients(_ recipients: [Identity], title: String, position: CGPoint,
   115                        width: CGFloat) -> CGPoint {
   116         var pos = newline(position)
   117 
   118         let titleString = "\(title):"
   119         let titleLabel = headerBaseLabelWithText(titleString)
   120         titleLabel.frame.origin = pos
   121         addSubview(titleLabel)
   122         lastLeftLabel = titleLabel
   123         var lastUsedLabel = titleLabel
   124 
   125         let session = PEPSession.init()
   126         for rec in recipients {
   127             let recLabel = recipientBaseLabelWithText(rec.displayString)
   128             let privacyColor = PEPUtil.pEpColor(identity: rec, session: session)
   129             UIHelper.setBackgroundColor(
   130                 privacyColor, forLabel: recLabel, defaultColor: recLabel.backgroundColor)
   131             pos = putAdjacentLeftLabel(lastUsedLabel, rightLabel: recLabel, atLeftPos: pos,
   132                                        width: width)
   133             lastUsedLabel = recLabel
   134             addSubview(recLabel)
   135         }
   136 
   137         return pos
   138     }
   139 
   140     func addFromAtPosition(_ position: CGPoint, width: CGFloat) -> CGPoint {
   141         let pos = position
   142         let fromTitleLabel = headerBaseLabelWithText(
   143             NSLocalizedString("From:",
   144                 comment: "Header label for email display"))
   145         fromTitleLabel.frame.origin = pos
   146         lastLeftLabel = fromTitleLabel
   147 
   148 //        if let fromContact = message.from {
   149 //            let fromLabel = recipientBaseLabelWithText(fromContact.displayString)
   150 //            let privacyColor = PEPUtil.pEpColor(identity: fromContact)
   151 //            UIHelper.setBackgroundColor(
   152 //                privacyColor, forLabel: fromLabel, defaultColor: fromLabel.backgroundColor)
   153 //
   154 //            pos = putAdjacentLeftLabel(fromTitleLabel, rightLabel: fromLabel, atLeftPos: pos,
   155 //            width: width)
   156 //
   157 //            addSubview(fromTitleLabel)
   158 //            addSubview(fromLabel)
   159 //        }
   160 
   161         return pos
   162     }
   163 
   164     func putAdjacentLeftLabel(_ leftLabel: UILabel, rightLabel: UILabel,
   165                               atLeftPos: CGPoint, width: CGFloat) -> CGPoint {
   166         var pos = atLeftPos
   167 
   168         let leftSize = leftLabel.intrinsicContentSize
   169         let rightSize = rightLabel.intrinsicContentSize
   170 
   171         if rightSize.width + leftLabel.frame.origin.x + leftSize.width + labelGapX
   172             + insetsX < width {
   173             // They fit adjacent
   174             rightLabel.frame.origin = pos
   175             rightLabel.frame.origin.x = pos.x + leftSize.width + labelGapX
   176             pos = rightLabel.frame.origin
   177         } else {
   178             // do a newline
   179             pos.x = insetsX + insetsNewlineX
   180             pos.y = pos.y + leftLabel.bounds.height + labelGapY
   181             rightLabel.frame.origin = pos
   182             lastLeftLabel = rightLabel
   183         }
   184 
   185         return pos
   186     }
   187 
   188     func newline(_ pos: CGPoint) -> CGPoint {
   189         return newline(pos, gap: labelGapY)
   190     }
   191 
   192     func biggerNewline(_ pos: CGPoint) -> CGPoint {
   193         return newline(pos, gap: biggerLabelGapY)
   194     }
   195 
   196     func newline(_ pos: CGPoint, gap: CGFloat) -> CGPoint {
   197         if let last = lastLeftLabel {
   198             return CGPoint(x: insetsX, y: last.frame.origin.y + last.frame.size.height + gap)
   199         } else {
   200             return CGPoint(x: insetsX, y: pos.y + gap)
   201         }
   202     }
   203 
   204     func labelWithFont(_ font: UIFont, text: String?, maxWidth: CGFloat? = nil) -> UILabel {
   205         let label = UILabel.init()
   206         label.font = font
   207 
   208         if let t = text {
   209             label.text = t
   210         }
   211 
   212         if let max = maxWidth {
   213             label.preferredMaxLayoutWidth = max
   214             label.lineBreakMode = .byWordWrapping
   215             label.numberOfLines = 0
   216             var size = label.sizeThatFits(CGSize(width: max, height: 0))
   217             size.width = max
   218             label.frame.size = size
   219         } else {
   220             label.sizeToFit()
   221         }
   222 
   223         return label
   224     }
   225 
   226     func headerBaseLabelWithText(_ text: String?, maxWidth: CGFloat? = nil) -> UILabel {
   227         return labelWithFont(UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline),
   228                              text: text, maxWidth: maxWidth)
   229     }
   230 
   231     func recipientBaseLabelWithText(_ text: String?, maxWidth: CGFloat? = nil) -> UILabel {
   232         return labelWithFont(UIFont.preferredFont(forTextStyle: UIFontTextStyle.body),
   233                              text: text, maxWidth: maxWidth)
   234     }
   235 }