@@ -16,6 +16,15 @@ class GoalCollectionViewCell: UICollectionViewCell {
1616 let todaytaLabel : BSLabel = BSLabel ( )
1717 let thumbnailImageView = GoalImageView ( isThumbnail: true )
1818 let safesumLabel : BSLabel = BSLabel ( )
19+
20+ lazy var dueByDeltasLabel : BSLabel = {
21+ let label = BSLabel ( )
22+ label. textAlignment = NSTextAlignment . center
23+ label. font = UIFont . beeminder. defaultBoldFont. withSize ( 13 )
24+ label. numberOfLines = 0
25+ return label
26+ } ( )
27+
1928 let margin = 8
2029
2130 override init ( frame: CGRect ) {
@@ -26,6 +35,7 @@ class GoalCollectionViewCell: UICollectionViewCell {
2635 self . contentView. addSubview ( self . todaytaLabel)
2736 self . contentView. addSubview ( self . thumbnailImageView)
2837 self . contentView. addSubview ( self . safesumLabel)
38+ self . contentView. addSubview ( self . dueByDeltasLabel)
2939 self . contentView. backgroundColor = . systemBackground
3040
3141 self . slugLabel. font = UIFont . beeminder. defaultFontHeavy
@@ -69,6 +79,12 @@ class GoalCollectionViewCell: UICollectionViewCell {
6979 make. centerY. equalTo ( self . thumbnailImageView. snp. centerY)
7080 make. right. equalTo ( - self . margin)
7181 }
82+
83+ self . dueByDeltasLabel. snp. makeConstraints { ( make) -> Void in
84+ make. left. equalTo ( self . thumbnailImageView. snp. right) . offset ( 5 )
85+ make. top. equalTo ( self . safesumLabel. snp. bottom) . offset ( 6 )
86+ make. right. equalTo ( - self . margin)
87+ }
7288 }
7389
7490 required init ? ( coder aDecoder: NSCoder ) {
@@ -89,5 +105,47 @@ class GoalCollectionViewCell: UICollectionViewCell {
89105 self . todaytaLabel. text = goal? . todayta == true ? " ✓ " : " "
90106 self . safesumLabel. text = goal? . capitalSafesum ( )
91107 self . safesumLabel. textColor = goal? . countdownColor ?? UIColor . Beeminder. gray
108+ self . dueByDeltasLabel. attributedText = goal? . dueByTableAttributedString
109+ self . dueByDeltasLabel. isHidden = goal == nil || goal? . dueByContainsSpecificAmounts == false
110+ }
111+ }
112+
113+
114+ private extension Goal {
115+ var dueByContainsSpecificAmounts : Bool {
116+ dueByTable. entries
117+ . compactMap { $0. value. formatted_delta_for_beedroid }
118+ . joined ( separator: " " )
119+ . contains ( where: { $0. isNumber } )
120+ }
121+
122+ var dueByTableAttributedString : NSAttributedString {
123+ let textAndColor : [ ( text: String , color: UIColor ) ] = dueByTable. entries
124+ . sorted ( using: SortDescriptor ( \. key) )
125+ . compactMap { $0. value. formatted_delta_for_beedroid }
126+ . map { $0 == " ✔ " ? " ✓ " : $0 }
127+ . enumerated ( )
128+ . map { offset, element in
129+ var color : UIColor {
130+ switch offset {
131+ case 0 : return UIColor . Beeminder. SafetyBuffer. orange
132+ case 1 : return UIColor . Beeminder. SafetyBuffer. blue
133+ case 2 : return UIColor . Beeminder. SafetyBuffer. green
134+ default : return . label. withAlphaComponent ( 0.8 )
135+ }
136+ }
137+ return ( text: element, color: color)
138+ }
139+
140+ let attrStr = NSMutableAttributedString ( )
141+
142+ textAndColor
143+ . map { ( text: String , color: UIColor ) in
144+ NSAttributedString ( string: text + " " , attributes: [ . foregroundColor: color] )
145+ }
146+ . forEach { attrStr. append ( $0) }
147+
148+ return attrStr
92149 }
93150}
151+
0 commit comments