| Index: ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
|
| diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
|
| index f8cbd839705dbaee7004df37b8d40a645956f2c5..7370638f60f22d787ef9fe6224c6d6bdd7d92d02 100644
|
| --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
|
| +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
|
| @@ -13,6 +13,7 @@
|
| #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
|
| #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/l10n/time_format.h"
|
| #import "url/gurl.h"
|
|
|
| #if !defined(__has_feature) || !__has_feature(objc_arc)
|
| @@ -28,6 +29,9 @@ const CGFloat kDistillationIndicatorSize = 18;
|
|
|
| // Margin for the elements displayed in the cell.
|
| const CGFloat kMargin = 16;
|
| +
|
| +// Transparency of the distillation size and date.
|
| +const CGFloat kInfoTextTransparency = 0.38;
|
| } // namespace
|
|
|
| #pragma mark - ReadingListCollectionViewItem
|
| @@ -43,11 +47,13 @@ const CGFloat kMargin = 16;
|
|
|
| @implementation ReadingListCollectionViewItem
|
| @synthesize attributes = _attributes;
|
| -@synthesize text = _text;
|
| -@synthesize detailText = _detailText;
|
| +@synthesize title = _title;
|
| +@synthesize subtitle = _subtitle;
|
| @synthesize url = _url;
|
| @synthesize faviconPageURL = _faviconPageURL;
|
| @synthesize distillationState = _distillationState;
|
| +@synthesize distillationDate = _distillationDate;
|
| +@synthesize distillationSize = _distillationSize;
|
| @synthesize accessibilityDelegate = _accessibilityDelegate;
|
|
|
| - (instancetype)initWithType:(NSInteger)type
|
| @@ -69,9 +75,11 @@ const CGFloat kMargin = 16;
|
| if (self.attributes) {
|
| [cell.faviconView configureWithAttributes:self.attributes];
|
| }
|
| - cell.textLabel.text = self.text;
|
| - cell.detailTextLabel.text = self.detailText;
|
| + cell.titleLabel.text = self.title;
|
| + cell.subtitleLabel.text = self.subtitle;
|
| cell.distillationState = _distillationState;
|
| + cell.distillationSize = _distillationSize;
|
| + cell.distillationDate = _distillationDate;
|
| cell.isAccessibilityElement = YES;
|
| cell.accessibilityLabel = [self accessibilityLabel];
|
| cell.accessibilityCustomActions = [self customActions];
|
| @@ -90,9 +98,9 @@ const CGFloat kMargin = 16;
|
| }
|
|
|
| return l10n_util::GetNSStringF(IDS_IOS_READING_LIST_ENTRY_ACCESSIBILITY_LABEL,
|
| - base::SysNSStringToUTF16(self.text),
|
| + base::SysNSStringToUTF16(self.title),
|
| base::SysNSStringToUTF16(accessibilityState),
|
| - base::SysNSStringToUTF16(self.detailText));
|
| + base::SysNSStringToUTF16(self.subtitle));
|
| }
|
|
|
| #pragma mark - AccessibilityCustomAction
|
| @@ -195,7 +203,7 @@ const CGFloat kMargin = 16;
|
|
|
| - (NSString*)description {
|
| return [NSString stringWithFormat:@"Reading List item \"%@\" for url %@",
|
| - self.text, self.detailText];
|
| + self.title, self.subtitle];
|
| }
|
|
|
| - (BOOL)isEqual:(id)other {
|
| @@ -205,9 +213,11 @@ const CGFloat kMargin = 16;
|
| return NO;
|
| ReadingListCollectionViewItem* otherItem =
|
| static_cast<ReadingListCollectionViewItem*>(other);
|
| - return [self.text isEqualToString:otherItem.text] &&
|
| - [self.detailText isEqualToString:otherItem.detailText] &&
|
| - self.distillationState == otherItem.distillationState;
|
| + return [self.title isEqualToString:otherItem.title] &&
|
| + [self.subtitle isEqualToString:otherItem.subtitle] &&
|
| + self.distillationState == otherItem.distillationState &&
|
| + self.distillationSize == otherItem.distillationSize &&
|
| + self.distillationDate == otherItem.distillationDate;
|
| }
|
|
|
| @end
|
| @@ -216,10 +226,22 @@ const CGFloat kMargin = 16;
|
|
|
| @implementation ReadingListCell {
|
| UIImageView* _downloadIndicator;
|
| + UILayoutGuide* _textGuide;
|
| +
|
| + UILabel* _distillationSizeLabel;
|
| + UILabel* _distillationDateLabel;
|
| +
|
| + // View containing |_distillationSizeLabel| and |_distillationDateLabel|.
|
| + UIView* _infoView;
|
| +
|
| + // Whether |_infoView| is visible.
|
| + BOOL _showInfo;
|
| }
|
| @synthesize faviconView = _faviconView;
|
| -@synthesize textLabel = _textLabel;
|
| -@synthesize detailTextLabel = _detailTextLabel;
|
| +@synthesize titleLabel = _titleLabel;
|
| +@synthesize subtitleLabel = _subtitleLabel;
|
| +@synthesize distillationDate = _distillationDate;
|
| +@synthesize distillationSize = _distillationSize;
|
| @synthesize distillationState = _distillationState;
|
|
|
| - (instancetype)initWithFrame:(CGRect)frame {
|
| @@ -227,15 +249,33 @@ const CGFloat kMargin = 16;
|
| if (self) {
|
| MDFRobotoFontLoader* fontLoader = [MDFRobotoFontLoader sharedInstance];
|
| CGFloat faviconSize = kFaviconPreferredSize;
|
| - _textLabel = [[UILabel alloc] init];
|
| - _textLabel.font = [fontLoader mediumFontOfSize:16];
|
| - _textLabel.textColor = [[MDCPalette greyPalette] tint900];
|
| - _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
| -
|
| - _detailTextLabel = [[UILabel alloc] init];
|
| - _detailTextLabel.font = [fontLoader mediumFontOfSize:14];
|
| - _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
|
| - _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
| + _titleLabel = [[UILabel alloc] init];
|
| + _titleLabel.font = [fontLoader mediumFontOfSize:16];
|
| + _titleLabel.textColor = [[MDCPalette greyPalette] tint900];
|
| + _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
| +
|
| + _subtitleLabel = [[UILabel alloc] init];
|
| + _subtitleLabel.font = [fontLoader mediumFontOfSize:14];
|
| + _subtitleLabel.textColor = [[MDCPalette greyPalette] tint500];
|
| + _subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
| +
|
| + _distillationDateLabel = [[UILabel alloc] init];
|
| + _distillationDateLabel.font = [fontLoader mediumFontOfSize:12];
|
| + [_distillationDateLabel
|
| + setContentHuggingPriority:UILayoutPriorityDefaultHigh
|
| + forAxis:UILayoutConstraintAxisHorizontal];
|
| + _distillationDateLabel.textColor =
|
| + [UIColor colorWithWhite:0 alpha:kInfoTextTransparency];
|
| + _distillationDateLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
| +
|
| + _distillationSizeLabel = [[UILabel alloc] init];
|
| + _distillationSizeLabel.font = [fontLoader mediumFontOfSize:12];
|
| + [_distillationSizeLabel
|
| + setContentHuggingPriority:UILayoutPriorityDefaultHigh
|
| + forAxis:UILayoutConstraintAxisHorizontal];
|
| + _distillationSizeLabel.textColor =
|
| + [UIColor colorWithWhite:0 alpha:kInfoTextTransparency];
|
| + _distillationSizeLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
|
| _faviconView = [[FaviconViewNew alloc] init];
|
| CGFloat fontSize = floorf(faviconSize / 2);
|
| @@ -246,29 +286,58 @@ const CGFloat kMargin = 16;
|
| [_downloadIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| [_faviconView addSubview:_downloadIndicator];
|
|
|
| - [self.contentView addSubview:_textLabel];
|
| - [self.contentView addSubview:_detailTextLabel];
|
| [self.contentView addSubview:_faviconView];
|
| + [self.contentView addSubview:_titleLabel];
|
| + [self.contentView addSubview:_subtitleLabel];
|
| +
|
| + _infoView = [[UIView alloc] initWithFrame:CGRectZero];
|
| + [_infoView addSubview:_distillationDateLabel];
|
| + [_infoView addSubview:_distillationSizeLabel];
|
| + _infoView.translatesAutoresizingMaskIntoConstraints = NO;
|
| +
|
| + _textGuide = [[UILayoutGuide alloc] init];
|
| + [self.contentView addLayoutGuide:_textGuide];
|
|
|
| ApplyVisualConstraintsWithMetrics(
|
| @[
|
| - @"V:|-(margin)-[title][text]-(margin)-|",
|
| + @"H:|[date]-(>=margin)-[size]|",
|
| + @"V:[title][subtitle]",
|
| @"H:|-(margin)-[favicon]-(margin)-[title]-(>=margin)-|",
|
| - @"H:[favicon]-(margin)-[text]-(>=margin)-|"
|
| + @"H:[favicon]-(margin)-[subtitle]-(>=margin)-|",
|
| + @"V:|[date]|",
|
| + @"V:|[size]|",
|
| ],
|
| @{
|
| - @"title" : _textLabel,
|
| - @"text" : _detailTextLabel,
|
| - @"favicon" : _faviconView
|
| + @"favicon" : _faviconView,
|
| + @"title" : _titleLabel,
|
| + @"subtitle" : _subtitleLabel,
|
| + @"date" : _distillationDateLabel,
|
| + @"size" : _distillationSizeLabel,
|
| },
|
| - @{ @"margin" : @(kMargin) });
|
| + @{
|
| + @"margin" : @(kMargin),
|
| + });
|
| +
|
| + // Sets the bottom of the text. Lower the priority so we can add the details
|
| + // later.
|
| + NSLayoutConstraint* bottomTextConstraint = [_textGuide.bottomAnchor
|
| + constraintEqualToAnchor:_subtitleLabel.bottomAnchor];
|
| + bottomTextConstraint.priority = UILayoutPriorityDefaultHigh;
|
| + NSLayoutConstraint* topTextConstraint =
|
| + [_textGuide.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor];
|
|
|
| [NSLayoutConstraint activateConstraints:@[
|
| + topTextConstraint,
|
| + bottomTextConstraint,
|
| // Favicons are always the same size.
|
| [_faviconView.widthAnchor constraintEqualToConstant:faviconSize],
|
| [_faviconView.heightAnchor constraintEqualToConstant:faviconSize],
|
| + // Center the content (favicon and text) vertically.
|
| [_faviconView.centerYAnchor
|
| constraintEqualToAnchor:self.contentView.centerYAnchor],
|
| + [_textGuide.centerYAnchor
|
| + constraintEqualToAnchor:self.contentView.centerYAnchor],
|
| +
|
| // Place the download indicator in the bottom right corner of the favicon.
|
| [[_downloadIndicator centerXAnchor]
|
| constraintEqualToAnchor:_faviconView.trailingAnchor],
|
| @@ -309,12 +378,72 @@ const CGFloat kMargin = 16;
|
| }
|
| }
|
|
|
| +- (void)setShowInfo:(BOOL)show {
|
| + if (_showInfo == show) {
|
| + return;
|
| + }
|
| + _showInfo = show;
|
| + if (!show) {
|
| + [_infoView removeFromSuperview];
|
| + return;
|
| + }
|
| + [self.contentView addSubview:_infoView];
|
| + ApplyVisualConstraintsWithMetrics(
|
| + @[
|
| + @"H:|-(margin)-[favicon]-(margin)-[detail]-(margin)-|",
|
| + ],
|
| + @{
|
| + @"favicon" : _faviconView,
|
| + @"detail" : _infoView,
|
| + },
|
| + @{
|
| + @"margin" : @(kMargin),
|
| + });
|
| + [NSLayoutConstraint activateConstraints:@[
|
| + [_infoView.topAnchor constraintEqualToAnchor:_subtitleLabel.bottomAnchor],
|
| + [_infoView.bottomAnchor constraintEqualToAnchor:_textGuide.bottomAnchor],
|
| + ]];
|
| +}
|
| +
|
| +- (void)setDistillationSize:(int64_t)distillationSize {
|
| + [_distillationSizeLabel
|
| + setText:[NSByteCountFormatter
|
| + stringFromByteCount:distillationSize
|
| + countStyle:NSByteCountFormatterCountStyleFile]];
|
| + _distillationSize = distillationSize;
|
| + BOOL showInfo = _distillationSize != 0 && _distillationDate != 0;
|
| + [self setShowInfo:showInfo];
|
| +}
|
| +
|
| +- (void)setDistillationDate:(int64_t)distillationDate {
|
| + int64_t now = (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
|
| + int64_t elapsed = now - distillationDate;
|
| + NSString* text;
|
| + if (elapsed < base::Time::kMicrosecondsPerMinute) {
|
| + // This will also catch items added in the future. In that case, show the
|
| + // "just now" string.
|
| + text = l10n_util::GetNSString(IDS_IOS_READING_LIST_JUST_NOW);
|
| + } else {
|
| + text = base::SysUTF16ToNSString(ui::TimeFormat::Simple(
|
| + ui::TimeFormat::FORMAT_ELAPSED, ui::TimeFormat::LENGTH_LONG,
|
| + base::TimeDelta::FromMicroseconds(elapsed)));
|
| + }
|
| +
|
| + [_distillationDateLabel setText:text];
|
| + _distillationDate = distillationDate;
|
| + BOOL showInfo = _distillationSize != 0 && _distillationDate != 0;
|
| + [self setShowInfo:showInfo];
|
| +}
|
| +
|
| #pragma mark - UICollectionViewCell
|
|
|
| - (void)prepareForReuse {
|
| - self.textLabel.text = nil;
|
| - self.detailTextLabel.text = nil;
|
| + self.titleLabel.text = nil;
|
| + self.subtitleLabel.text = nil;
|
| self.distillationState = ReadingListEntry::WAITING;
|
| + self.distillationDate = 0;
|
| + self.distillationSize = 0;
|
| + [self setShowInfo:NO];
|
| self.accessibilityCustomActions = nil;
|
| [super prepareForReuse];
|
| }
|
|
|