@@ -12,21 +12,51 @@ class CardView: UIView {
13 var post: WallPost? {
13 var post: WallPost? {
15− print(post?.owner)
15+// print(post?.owner)
19+ var minWidth: CGFloat = 300 {
24+ var height: CGFloat = 400 {
20 override init(frame: CGRect) {
30 override init(frame: CGRect) {
21 super.init(frame: frame)
31 super.init(frame: frame)
22 layer.masksToBounds = true
32 layer.masksToBounds = true
23 layer.cornerRadius = 20
33 layer.cornerRadius = 20
34+ gradient.colors = [#colorLiteral(red: 0.9841352105, green: 0.9841352105, blue: 0.9841352105, alpha: 1).cgColor, #colorLiteral(red: 0.9456828237, green: 0.9456828237, blue: 0.9456828237, alpha: 1).cgColor]
35+ gradient.startPoint = CGPoint(x: 0.5, y: 0)
36+ gradient.endPoint = CGPoint(x: 0.5, y: 1)
37+ layer.addSublayer(gradient)
24− backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
38+// backgroundColor = #colorLiteral(red: 0.9638966278, green: 0.9734401588, blue: 0.9734401588, alpha: 1)
27 required init?(coder aDecoder: NSCoder) {
41 required init?(coder aDecoder: NSCoder) {
28 fatalError("init(coder:) has not been implemented")
42 fatalError("init(coder:) has not been implemented")
45+ private let gradient = CAGradientLayer()
48+ private let padding = CGPoint(x: 32, y: 32)
49+ private let vPadding1: CGFloat = 16
50+ private let vPadding2: CGFloat = 16
51+ private var minTextHeight: CGFloat {
52+ return CGFloat(height * 0.2)
54+ private let gradientRatio: CGFloat = 0.2
55+ private let minGradientAmount: CGFloat = 70
56+ private let hiddenByGradient: CGFloat = 10
57+ private var maxAttachmentDim: CGFloat {
58+ return minWidth / 2.3
31// private let avatar = UIImage()
61// private let avatar = UIImage()
32// private let name = UIImage()
62// private let name = UIImage()
@@ -35,14 +65,13 @@ class CardView: UIView {
35 subviews.map {$0.removeFromSuperview()}
65 subviews.map {$0.removeFromSuperview()}
37 let largeStack = StackView(axis: .vertical, alignment: .left)
67 let largeStack = StackView(axis: .vertical, alignment: .left)
38− largeStack.padding = CGPoint(x: 32, y: 32)
68+ largeStack.padding = padding
39 addSubview(largeStack)
69 addSubview(largeStack)
41 let userView = StackView(axis: .horizontal, alignment: .center)
71 let userView = StackView(axis: .horizontal, alignment: .center)
42−// userView.backgroundColor = #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
45− let avatarDim: CGFloat = 50
74+ let avatarDim: CGFloat = 64
46 let avatar = UIImageView()
75 let avatar = UIImageView()
47 post?.owner?.avatar?.load(into: avatar)
76 post?.owner?.avatar?.load(into: avatar)
48 avatar.layer.cornerRadius = avatarDim/2
77 avatar.layer.cornerRadius = avatarDim/2
@@ -52,30 +81,116 @@ class CardView: UIView {
52 avatar.frame.size = CGSize(width: avatarDim, height: avatarDim)
81 avatar.frame.size = CGSize(width: avatarDim, height: avatarDim)
53 userView.addArrangedSubview(.view(avatar))
82 userView.addArrangedSubview(.view(avatar))
55− userView.addArrangedSubview(.spacer(8))
84+ userView.addArrangedSubview(.spacer(16))
57 let userName = UILabel()
86 let userName = UILabel()
58 let firstName = post?.owner?.firstName ?? ""
87 let firstName = post?.owner?.firstName ?? ""
59 let lastName = post?.owner?.lastName ?? ""
88 let lastName = post?.owner?.lastName ?? ""
60 userName.text = "\(firstName) \(lastName)"
89 userName.text = "\(firstName) \(lastName)"
61 userName.font = UIFont.systemFont(ofSize: 28, weight: UIFontWeightHeavy)
90 userName.font = UIFont.systemFont(ofSize: 28, weight: UIFontWeightHeavy)
91+ userName.textColor = UIColor.darkText
62 userName.sizeToFit()
92 userName.sizeToFit()
63 userView.addArrangedSubview(.view(userName))
93 userView.addArrangedSubview(.view(userName))
64− userView.frame.origin = CGPoint(x: 16, y: 16)
94+
95+ userView.layoutIfNeeded()
66 largeStack.addArrangedSubview(.view(userView))
97 largeStack.addArrangedSubview(.view(userView))
68− largeStack.addArrangedSubview(.spacer(16))
99+ largeStack.addArrangedSubview(.spacer(vPadding1))
102+ let width = max(minWidth - 2 * padding.x, userView.frame.width)
105+ let photoView = CollectionView()
106+ photoView.alignment = .top
107+ photoView.horizontalPadding = 8
108+ photoView.verticalPadding = 8
109+ photoView.padding = CGPoint.zero
110+ photoView.maxWidth = width
111+ var maxPhotoDim: CGFloat = maxAttachmentDim
112+ if let attachments = post?.attachments {
113+ for attachment in attachments {
114+ if let v = attachment.value {
116+ case .photo(let photo):
117+ if var pWidth = photo.width.value >>> {CGFloat($0)},
118+ var pHeight = photo.height.value >>> {CGFloat($0)} {
119+ let photoV = UIImageView()
120+ photoV.layer.minificationFilter = kCAFilterTrilinear
121+ photoV.contentMode = .scaleAspectFill
122+ photo.image?.load(into: photoV)
124+ if pWidth > pHeight {
125+ k = CGFloat(pWidth) / maxPhotoDim
127+ k = CGFloat(pHeight) / maxPhotoDim
131+ photoV.frame.size = CGSize(width: pWidth, height: pHeight)
132+ photoView.addArrangedSubview(photoV)
136+ break // TODO: Handle other data types
141+ photoView.layoutIfNeeded()
143+ var textHeight = height
144+ textHeight -= padding.y * 2 + vPadding1 + userView.frame.height
145+ if let count = post?.attachments.count{
147+ textHeight -= vPadding2 + photoView.frame.height
151+ textHeight = max(textHeight, minTextHeight)
70 let body = UILabel()
154 let body = UILabel()
71 body.numberOfLines = 0
155 body.numberOfLines = 0
72− let bodyWidth: Double = 300
156+ let bodyWidth: Double = Double(width)
73 body.font = UIFont.systemFont(ofSize: 22, weight: UIFontWeightSemibold)
157 body.font = UIFont.systemFont(ofSize: 22, weight: UIFontWeightSemibold)
74− body.text = post?.body ?? "Spicy jalapeno flank landjaeger sausage tongue tail fatback frankfurter. Meatball tongue tail short ribs pastrami. Short ribs chicken pig tenderloin sausage pork. Corned beef t-bone pancetta jerky chuck picanha venison, turducken tenderloin shoulder boudin drumstick hamburger. Pork meatball meatloaf prosciutto pig andouille. Sirloin bacon hamburger short ribs pork cupim shank biltong turducken bresaola kevin prosciutto shoulder meatball. Strip steak frankfurter pork chop biltong jowl beef rump venison pancetta turkey tongue."
158+ body.text = post?.body
159+ body.textColor = UIColor.darkText
75 let size = body.textRect(forBounds: CGRect(x: 0, y: 0, width: bodyWidth, height: Double.infinity), limitedToNumberOfLines: 0).size
160 let size = body.textRect(forBounds: CGRect(x: 0, y: 0, width: bodyWidth, height: Double.infinity), limitedToNumberOfLines: 0).size
76− body.frame.size = size
161+ body.frame.size.width = size.width
162+ if size.height > textHeight {
163+ body.frame.size.height = textHeight
164+ let maskView = UIView()
165+ let maskLayer = CAGradientLayer()
166+ maskLayer.colors = [UIColor.black.cgColor, UIColor.clear.cgColor]
167+ maskLayer.endPoint = CGPoint(x: 0.5, y: 1 - (hiddenByGradient/textHeight))
168+ let minPoint = minGradientAmount / textHeight
169+ maskLayer.startPoint = CGPoint(x: 0.5, y: 1 - max(minPoint, gradientRatio))
170+ print(maskLayer.startPoint)
171+ maskLayer.frame = body.bounds
172+ maskView.frame = body.bounds
173+ maskView.layer.addSublayer(maskLayer)
174+ body.mask = maskView
176+ body.frame.size.height = size.height
78 largeStack.addArrangedSubview(.view(body))
179 largeStack.addArrangedSubview(.view(body))
181+ if let count = post?.attachments.count{
183+ largeStack.addArrangedSubview(.spacer(vPadding2))
184+ largeStack.addArrangedSubview(.view(photoView))
188+ largeStack.layoutIfNeeded()
190+ frame.size = CGSize(width: width + padding.x * 2, height: min(height, largeStack.frame.height))
192+ gradient.frame = self.bounds
193+ gradient.endPoint = CGPoint(x: 0.5, y: bounds.height / height)