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