Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(693)

Side by Side Diff: ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.mm

Issue 2779843006: Add favicon view to ContentSuggestionsArticle (Closed)
Patch Set: Rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_art icle_item.h" 5 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_art icle_item.h"
6 6
7 #include "base/time/time.h" 7 #include "base/time/time.h"
8 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" 8 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
9 #import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
10 #import "ios/chrome/browser/ui/favicon/favicon_view.h"
9 #import "ios/chrome/browser/ui/uikit_ui_util.h" 11 #import "ios/chrome/browser/ui/uikit_ui_util.h"
10 #import "ios/chrome/browser/ui/util/i18n_string.h" 12 #import "ios/chrome/browser/ui/util/i18n_string.h"
11 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat erialPalettes.h" 13 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat erialPalettes.h"
12 #import "ios/third_party/material_components_ios/src/components/Typography/src/M aterialTypography.h" 14 #import "ios/third_party/material_components_ios/src/components/Typography/src/M aterialTypography.h"
13 #include "url/gurl.h" 15 #include "url/gurl.h"
14 16
15 #if !defined(__has_feature) || !__has_feature(objc_arc) 17 #if !defined(__has_feature) || !__has_feature(objc_arc)
16 #error "This file requires ARC support." 18 #error "This file requires ARC support."
17 #endif 19 #endif
18 20
19 namespace { 21 namespace {
20 const CGFloat kImageSize = 72; 22 const CGFloat kImageSize = 72;
21 // When updating this, make sure to update |layoutSubviews|.
22 const CGFloat kStandardSpacing = 16; 23 const CGFloat kStandardSpacing = 16;
24 const CGFloat kSmallSpacing = 8;
25
26 // Size of the favicon view.
27 const CGFloat kFaviconSize = 16;
23 // Size of the icon displayed when there is not image. 28 // Size of the icon displayed when there is not image.
24 const CGFloat kIconSize = 24; 29 const CGFloat kIconSize = 24;
25 // Name of the icon displayed when there is not image. 30 // Name of the icon displayed when there is not image.
26 NSString* const kNoImageIconName = @"content_suggestions_no_image"; 31 NSString* const kNoImageIconName = @"content_suggestions_no_image";
27 // No image icon percentage of white. 32 // No image icon percentage of white.
28 const CGFloat kNoImageIconWhite = 0.38; 33 const CGFloat kNoImageIconWhite = 0.38;
29 // No image background percentage of white. 34 // No image background percentage of white.
30 const CGFloat kNoImageBackgroundWhite = 0.95; 35 const CGFloat kNoImageBackgroundWhite = 0.95;
31 // Duration of the animation to display the image for the article. 36 // Duration of the animation to display the image for the article.
32 const CGFloat kAnimationDuration = 0.3; 37 const CGFloat kAnimationDuration = 0.3;
(...skipping 15 matching lines...) Expand all
48 53
49 @synthesize title = _title; 54 @synthesize title = _title;
50 @synthesize subtitle = _subtitle; 55 @synthesize subtitle = _subtitle;
51 @synthesize image = _image; 56 @synthesize image = _image;
52 @synthesize articleURL = _articleURL; 57 @synthesize articleURL = _articleURL;
53 @synthesize publisher = _publisher; 58 @synthesize publisher = _publisher;
54 @synthesize publishDate = _publishDate; 59 @synthesize publishDate = _publishDate;
55 @synthesize suggestionIdentifier = _suggestionIdentifier; 60 @synthesize suggestionIdentifier = _suggestionIdentifier;
56 @synthesize delegate = _delegate; 61 @synthesize delegate = _delegate;
57 @synthesize imageFetched = _imageFetched; 62 @synthesize imageFetched = _imageFetched;
63 @synthesize attributes = _attributes;
58 64
59 - (instancetype)initWithType:(NSInteger)type 65 - (instancetype)initWithType:(NSInteger)type
60 title:(NSString*)title 66 title:(NSString*)title
61 subtitle:(NSString*)subtitle 67 subtitle:(NSString*)subtitle
62 delegate:(id<ContentSuggestionsArticleItemDelegate>)delegate 68 delegate:(id<ContentSuggestionsArticleItemDelegate>)delegate
63 url:(const GURL&)url { 69 url:(const GURL&)url {
64 self = [super initWithType:type]; 70 self = [super initWithType:type];
65 if (self) { 71 if (self) {
66 self.cellClass = [ContentSuggestionsArticleCell class]; 72 self.cellClass = [ContentSuggestionsArticleCell class];
67 _title = [title copy]; 73 _title = [title copy];
68 _subtitle = [subtitle copy]; 74 _subtitle = [subtitle copy];
69 _articleURL = url; 75 _articleURL = url;
70 _delegate = delegate; 76 _delegate = delegate;
71 } 77 }
72 return self; 78 return self;
73 } 79 }
74 80
75 - (void)configureCell:(ContentSuggestionsArticleCell*)cell { 81 - (void)configureCell:(ContentSuggestionsArticleCell*)cell {
76 [super configureCell:cell]; 82 [super configureCell:cell];
77 if (!self.imageFetched) { 83 if (!self.imageFetched) {
78 self.imageFetched = YES; 84 self.imageFetched = YES;
79 // Fetch the image. During the fetch the cell's image should still be set. 85 // Fetch the image. During the fetch the cell's image should still be set.
80 [self.delegate loadImageForArticleItem:self]; 86 [self.delegate loadImageForArticleItem:self];
81 } 87 }
88 if (self.attributes)
89 [cell.faviconView configureWithAttributes:self.attributes];
82 cell.titleLabel.text = self.title; 90 cell.titleLabel.text = self.title;
83 cell.subtitleLabel.text = self.subtitle; 91 cell.subtitleLabel.text = self.subtitle;
84 [cell setContentImage:self.image]; 92 [cell setContentImage:self.image];
85 [cell setPublisherName:self.publisher date:self.publishDate]; 93 [cell setPublisherName:self.publisher date:self.publishDate];
86 } 94 }
87 95
88 @end 96 @end
89 97
90 #pragma mark - ContentSuggestionsArticleCell 98 #pragma mark - ContentSuggestionsArticleCell
91 99
(...skipping 15 matching lines...) Expand all
107 @end 115 @end
108 116
109 @implementation ContentSuggestionsArticleCell 117 @implementation ContentSuggestionsArticleCell
110 118
111 @synthesize titleLabel = _titleLabel; 119 @synthesize titleLabel = _titleLabel;
112 @synthesize subtitleLabel = _subtitleLabel; 120 @synthesize subtitleLabel = _subtitleLabel;
113 @synthesize imageContainer = _imageContainer; 121 @synthesize imageContainer = _imageContainer;
114 @synthesize noImageIcon = _noImageIcon; 122 @synthesize noImageIcon = _noImageIcon;
115 @synthesize publisherLabel = _publisherLabel; 123 @synthesize publisherLabel = _publisherLabel;
116 @synthesize contentImageView = _contentImageView; 124 @synthesize contentImageView = _contentImageView;
125 @synthesize faviconView = _faviconView;
117 126
118 - (instancetype)initWithFrame:(CGRect)frame { 127 - (instancetype)initWithFrame:(CGRect)frame {
119 self = [super initWithFrame:frame]; 128 self = [super initWithFrame:frame];
120 if (self) { 129 if (self) {
121 _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 130 _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
122 _subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 131 _subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
123 _imageContainer = [[UIView alloc] initWithFrame:CGRectZero]; 132 _imageContainer = [[UIView alloc] initWithFrame:CGRectZero];
124 _noImageIcon = [[UIImageView alloc] initWithFrame:CGRectZero]; 133 _noImageIcon = [[UIImageView alloc] initWithFrame:CGRectZero];
125 _publisherLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 134 _publisherLabel = [[UILabel alloc] initWithFrame:CGRectZero];
126 _contentImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 135 _contentImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
136 _faviconView = [[FaviconViewNew alloc] init];
127 137
128 _titleLabel.numberOfLines = 2; 138 _titleLabel.numberOfLines = 2;
129 _subtitleLabel.numberOfLines = 2; 139 _subtitleLabel.numberOfLines = 2;
130 [_subtitleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh 140 [_subtitleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh
131 forAxis:UILayoutConstraintAxisVertical]; 141 forAxis:UILayoutConstraintAxisVertical];
132 [_titleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh 142 [_titleLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh
133 forAxis:UILayoutConstraintAxisVertical]; 143 forAxis:UILayoutConstraintAxisVertical];
134 144
135 _contentImageView.contentMode = UIViewContentModeScaleAspectFill; 145 _contentImageView.contentMode = UIViewContentModeScaleAspectFill;
136 _contentImageView.clipsToBounds = YES; 146 _contentImageView.clipsToBounds = YES;
137 _contentImageView.hidden = YES; 147 _contentImageView.hidden = YES;
138 148
139 _imageContainer.translatesAutoresizingMaskIntoConstraints = NO; 149 _imageContainer.translatesAutoresizingMaskIntoConstraints = NO;
140 _noImageIcon.translatesAutoresizingMaskIntoConstraints = NO; 150 _noImageIcon.translatesAutoresizingMaskIntoConstraints = NO;
141 _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; 151 _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
142 _subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO; 152 _subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
143 _publisherLabel.translatesAutoresizingMaskIntoConstraints = NO; 153 _publisherLabel.translatesAutoresizingMaskIntoConstraints = NO;
144 _contentImageView.translatesAutoresizingMaskIntoConstraints = NO; 154 _contentImageView.translatesAutoresizingMaskIntoConstraints = NO;
155 _faviconView.translatesAutoresizingMaskIntoConstraints = NO;
145 156
146 [self.contentView addSubview:_imageContainer]; 157 [self.contentView addSubview:_imageContainer];
147 [self.contentView addSubview:_titleLabel]; 158 [self.contentView addSubview:_titleLabel];
148 [self.contentView addSubview:_subtitleLabel]; 159 [self.contentView addSubview:_subtitleLabel];
149 [self.contentView addSubview:_publisherLabel]; 160 [self.contentView addSubview:_publisherLabel];
161 [self.contentView addSubview:_faviconView];
150 162
151 [_imageContainer addSubview:_noImageIcon]; 163 [_imageContainer addSubview:_noImageIcon];
152 [_imageContainer addSubview:_contentImageView]; 164 [_imageContainer addSubview:_contentImageView];
153 165
154 _imageContainer.backgroundColor = 166 _imageContainer.backgroundColor =
155 [UIColor colorWithWhite:kNoImageBackgroundWhite alpha:1]; 167 [UIColor colorWithWhite:kNoImageBackgroundWhite alpha:1];
156 _noImageIcon.image = [[UIImage imageNamed:kNoImageIconName] 168 _noImageIcon.image = [[UIImage imageNamed:kNoImageIconName]
157 imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 169 imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
158 [_noImageIcon 170 [_noImageIcon
159 setTintColor:[UIColor colorWithWhite:kNoImageIconWhite alpha:1]]; 171 setTintColor:[UIColor colorWithWhite:kNoImageIconWhite alpha:1]];
160 172
161 _titleLabel.font = [MDCTypography subheadFont]; 173 _titleLabel.font = [MDCTypography subheadFont];
162 _subtitleLabel.font = [MDCTypography body1Font]; 174 _subtitleLabel.font = [MDCTypography body1Font];
163 _publisherLabel.font = [MDCTypography captionFont]; 175 _publisherLabel.font = [MDCTypography captionFont];
176 _faviconView.font =
177 [[MDCTypography fontLoader] regularFontOfSize:kFaviconSize / 2];
164 178
165 _subtitleLabel.textColor = [[MDCPalette greyPalette] tint700]; 179 _subtitleLabel.textColor = [[MDCPalette greyPalette] tint700];
166 _publisherLabel.textColor = [[MDCPalette greyPalette] tint700]; 180 _publisherLabel.textColor = [[MDCPalette greyPalette] tint700];
167 181
168 [self applyConstraints]; 182 [self applyConstraints];
169 } 183 }
170 return self; 184 return self;
171 } 185 }
172 186
173 - (void)setContentImage:(UIImage*)image { 187 - (void)setContentImage:(UIImage*)image {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 [super layoutSubviews]; 224 [super layoutSubviews];
211 225
212 // Adjust the text label preferredMaxLayoutWidth when the parent's width 226 // Adjust the text label preferredMaxLayoutWidth when the parent's width
213 // changes, for instance on screen rotation. 227 // changes, for instance on screen rotation.
214 CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds); 228 CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
215 229
216 self.titleLabel.preferredMaxLayoutWidth = 230 self.titleLabel.preferredMaxLayoutWidth =
217 parentWidth - kImageSize - 3 * kStandardSpacing; 231 parentWidth - kImageSize - 3 * kStandardSpacing;
218 self.subtitleLabel.preferredMaxLayoutWidth = 232 self.subtitleLabel.preferredMaxLayoutWidth =
219 parentWidth - kImageSize - 3 * kStandardSpacing; 233 parentWidth - kImageSize - 3 * kStandardSpacing;
234 self.publisherLabel.preferredMaxLayoutWidth =
235 parentWidth - kFaviconSize - kSmallSpacing - 2 * kStandardSpacing;
220 236
221 // Re-layout with the new preferred width to allow the label to adjust its 237 // Re-layout with the new preferred width to allow the label to adjust its
222 // height. 238 // height.
223 [super layoutSubviews]; 239 [super layoutSubviews];
224 } 240 }
225 241
226 #pragma mark - Private 242 #pragma mark - Private
227 243
228 - (void)applyConstraints { 244 - (void)applyConstraints {
229 [NSLayoutConstraint activateConstraints:@[ 245 [NSLayoutConstraint activateConstraints:@[
230 [_imageContainer.widthAnchor constraintEqualToConstant:kImageSize], 246 [_imageContainer.widthAnchor constraintEqualToConstant:kImageSize],
231 [_imageContainer.heightAnchor 247 [_imageContainer.heightAnchor
232 constraintEqualToAnchor:_imageContainer.widthAnchor], 248 constraintEqualToAnchor:_imageContainer.widthAnchor],
233 [_imageContainer.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor], 249 [_imageContainer.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor],
250
251 // Publisher.
234 [_publisherLabel.topAnchor 252 [_publisherLabel.topAnchor
235 constraintGreaterThanOrEqualToAnchor:_imageContainer.bottomAnchor 253 constraintGreaterThanOrEqualToAnchor:_imageContainer.bottomAnchor
236 constant:kStandardSpacing], 254 constant:kStandardSpacing],
237 [_publisherLabel.topAnchor 255 [_publisherLabel.topAnchor
238 constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor 256 constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor
239 constant:kStandardSpacing], 257 constant:kStandardSpacing],
258 [_publisherLabel.bottomAnchor
259 constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor
260 constant:-kStandardSpacing],
261
262 // Favicon.
263 [_faviconView.topAnchor
264 constraintGreaterThanOrEqualToAnchor:_imageContainer.bottomAnchor
265 constant:kStandardSpacing],
266 [_faviconView.topAnchor
267 constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor
268 constant:kStandardSpacing],
269 [_faviconView.centerYAnchor
270 constraintEqualToAnchor:_publisherLabel.centerYAnchor],
271 [_faviconView.bottomAnchor
272 constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor
273 constant:-kStandardSpacing],
274 [_faviconView.heightAnchor constraintEqualToConstant:kFaviconSize],
275 [_faviconView.widthAnchor
276 constraintEqualToAnchor:_faviconView.heightAnchor],
240 277
241 // No image icon. 278 // No image icon.
242 [_noImageIcon.centerXAnchor 279 [_noImageIcon.centerXAnchor
243 constraintEqualToAnchor:_imageContainer.centerXAnchor], 280 constraintEqualToAnchor:_imageContainer.centerXAnchor],
244 [_noImageIcon.centerYAnchor 281 [_noImageIcon.centerYAnchor
245 constraintEqualToAnchor:_imageContainer.centerYAnchor], 282 constraintEqualToAnchor:_imageContainer.centerYAnchor],
246 [_noImageIcon.widthAnchor constraintEqualToConstant:kIconSize], 283 [_noImageIcon.widthAnchor constraintEqualToConstant:kIconSize],
247 [_noImageIcon.heightAnchor constraintEqualToAnchor:_noImageIcon.widthAnchor] 284 [_noImageIcon.heightAnchor constraintEqualToAnchor:_noImageIcon.widthAnchor]
248 ]]; 285 ]];
249 286
250 AddSameSizeConstraint(_contentImageView, _imageContainer); 287 AddSameSizeConstraint(_contentImageView, _imageContainer);
251 288
252 ApplyVisualConstraintsWithMetrics( 289 ApplyVisualConstraintsWithMetrics(
253 @[ 290 @[
254 @"H:|-(space)-[title]-(space)-[image]-(space)-|", 291 @"H:|-(space)-[title]-(space)-[image]-(space)-|",
255 @"H:|-(space)-[text]-(space)-[image]", 292 @"H:|-(space)-[text]-(space)-[image]",
256 @"V:|-(space)-[title]-[text]", 293 @"V:|-(space)-[title]-[text]",
257 @"H:|-(space)-[publish]-(space)-|", 294 @"H:|-(space)-[favicon]-(small)-[publish]-(space)-|",
258 @"V:[publish]-|",
259 ], 295 ],
260 @{ 296 @{
261 @"image" : _imageContainer, 297 @"image" : _imageContainer,
262 @"title" : _titleLabel, 298 @"title" : _titleLabel,
263 @"text" : _subtitleLabel, 299 @"text" : _subtitleLabel,
264 @"publish" : _publisherLabel, 300 @"publish" : _publisherLabel,
301 @"favicon" : _faviconView,
265 }, 302 },
266 @{ @"space" : @(kStandardSpacing) }); 303 @{ @"space" : @(kStandardSpacing),
304 @"small" : @(kSmallSpacing) });
267 } 305 }
268 306
269 @end 307 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698