| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6fa6ecca8dd36972b912b0aa0e000a28e86e5b01
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
|
| @@ -0,0 +1,223 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h"
|
| +
|
| +#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
|
| +#import "ios/chrome/browser/ui/favicon_view.h"
|
| +#import "ios/chrome/browser/ui/uikit_ui_util.h"
|
| +#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"
|
| +#import "url/gurl.h"
|
| +
|
| +#if !defined(__has_feature) || !__has_feature(objc_arc)
|
| +#error "This file requires ARC support."
|
| +#endif
|
| +
|
| +namespace {
|
| +NSString* kSuccessImageString = @"distillation_success";
|
| +NSString* kFailureImageString = @"distillation_fail";
|
| +
|
| +// Distillation indicator constants.
|
| +const CGFloat kDistillationIndicatorSize = 18;
|
| +} // namespace
|
| +
|
| +#pragma mark - ReadingListCell Private interface
|
| +
|
| +@protocol ReadingListCellDelegate<NSObject>
|
| +
|
| +- (void)readingListCellWillPrepareForReload:(ReadingListCell*)cell;
|
| +
|
| +@end
|
| +
|
| +@interface ReadingListCell ()
|
| +
|
| +@property(nonatomic, weak) id<ReadingListCellDelegate> delegate;
|
| +
|
| +@end
|
| +
|
| +#pragma mark - ReadingListCollectionViewItem
|
| +
|
| +@interface ReadingListCollectionViewItem ()<ReadingListCellDelegate> {
|
| + GURL _url;
|
| + ReadingListEntry::DistillationState _distillationState;
|
| +}
|
| +// Attributes provider used to retrieve favicons.
|
| +@property(nonatomic, strong)
|
| + FaviconAttributesProvider* faviconAttributesProvider;
|
| +// Attributes for favicon. Fetched in init, then retained for future updates.
|
| +@property(nonatomic, strong) FaviconAttributes* attributes;
|
| +// The cell that is displaying this item, if any. Used to reload favicon when
|
| +// the cell is on screen. Backed by WeakNSObject.
|
| +@property(nonatomic, weak) ReadingListCell* displayedCell;
|
| +@end
|
| +
|
| +@implementation ReadingListCollectionViewItem
|
| +@synthesize faviconAttributesProvider = _faviconAttributesProvider;
|
| +@synthesize attributes = _attributes;
|
| +@synthesize text = _text;
|
| +@synthesize detailText = _detailText;
|
| +@synthesize url = _url;
|
| +@synthesize displayedCell = _displayedCell;
|
| +
|
| +- (instancetype)initWithType:(NSInteger)type
|
| + attributesProvider:(FaviconAttributesProvider*)provider
|
| + url:(const GURL&)url
|
| + distillationState:(ReadingListEntry::DistillationState)state {
|
| + self = [super initWithType:type];
|
| + if (!self)
|
| + return nil;
|
| + self.cellClass = [ReadingListCell class];
|
| + _faviconAttributesProvider = provider;
|
| + _url = url;
|
| + _distillationState = state;
|
| + // |self| owns |provider|, |provider| owns the block, so a week self reference
|
| + // is necessary.
|
| + __weak ReadingListCollectionViewItem* weakSelf = self;
|
| + [provider
|
| + fetchFaviconAttributesForURL:url
|
| + completion:^(FaviconAttributes* _Nonnull attributes) {
|
| + ReadingListCollectionViewItem* strongSelf = weakSelf;
|
| + if (!strongSelf) {
|
| + return;
|
| + }
|
| + strongSelf.attributes = attributes;
|
| + [strongSelf.displayedCell.faviconView
|
| + configureWithAttributes:attributes];
|
| + }];
|
| +
|
| + return self;
|
| +}
|
| +
|
| +#pragma mark - CollectionViewTextItem
|
| +
|
| +- (void)configureCell:(ReadingListCell*)cell {
|
| + [super configureCell:cell];
|
| + if (self.attributes) {
|
| + [cell.faviconView configureWithAttributes:self.attributes];
|
| + }
|
| + cell.textLabel.text = self.text;
|
| + cell.detailTextLabel.text = self.detailText;
|
| + self.displayedCell = cell;
|
| + cell.delegate = self;
|
| + cell.distillationState = _distillationState;
|
| +}
|
| +
|
| +#pragma mark - ReadingListCellDelegate
|
| +
|
| +- (void)readingListCellWillPrepareForReload:(ReadingListCell*)cell {
|
| + self.displayedCell = nil;
|
| +}
|
| +
|
| +#pragma mark - NSObject
|
| +
|
| +- (NSString*)description {
|
| + return [NSString stringWithFormat:@"Reading List item \"%@\" for url %@",
|
| + self.text, self.detailText];
|
| +}
|
| +
|
| +@end
|
| +
|
| +#pragma mark - ReadingListCell
|
| +
|
| +@implementation ReadingListCell {
|
| + UIImageView* _downloadIndicator;
|
| +}
|
| +@synthesize faviconView = _faviconView;
|
| +@synthesize textLabel = _textLabel;
|
| +@synthesize detailTextLabel = _detailTextLabel;
|
| +@synthesize distillationState = _distillationState;
|
| +@synthesize delegate = _delegate;
|
| +
|
| +- (instancetype)initWithFrame:(CGRect)frame {
|
| + self = [super initWithFrame:frame];
|
| + if (self) {
|
| + MDFRobotoFontLoader* fontLoader = [MDFRobotoFontLoader sharedInstance];
|
| + CGFloat faviconSize = kFaviconPreferredSize;
|
| + _textLabel = [[UILabel alloc] init];
|
| + _textLabel.font = [fontLoader mediumFontOfSize:16];
|
| + _textLabel.textColor = [[MDCPalette greyPalette] tint900];
|
| +
|
| + _detailTextLabel = [[UILabel alloc] init];
|
| + _detailTextLabel.font = [fontLoader mediumFontOfSize:14];
|
| + _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
|
| +
|
| + _faviconView = [[FaviconViewNew alloc] init];
|
| + CGFloat fontSize = floorf(faviconSize / 2);
|
| + [_faviconView setFont:[fontLoader regularFontOfSize:fontSize]];
|
| +
|
| + _downloadIndicator = [[UIImageView alloc] init];
|
| + [_downloadIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + [_faviconView addSubview:_downloadIndicator];
|
| +
|
| + UIStackView* labelsStack = [[UIStackView alloc]
|
| + initWithArrangedSubviews:@[ _textLabel, _detailTextLabel ]];
|
| + labelsStack.axis = UILayoutConstraintAxisVertical;
|
| +
|
| + UIStackView* stackView = [[UIStackView alloc]
|
| + initWithArrangedSubviews:@[ _faviconView, labelsStack ]];
|
| + [self.contentView addSubview:stackView];
|
| + stackView.layoutMarginsRelativeArrangement = YES;
|
| + stackView.layoutMargins = UIEdgeInsetsMake(16, 16, 16, 16);
|
| + stackView.alignment = UIStackViewAlignmentCenter;
|
| + stackView.spacing = 16;
|
| +
|
| + stackView.translatesAutoresizingMaskIntoConstraints = NO;
|
| + AddSameSizeConstraint(self.contentView, stackView);
|
| + [NSLayoutConstraint activateConstraints:@[
|
| + // Favicons are always the same size.
|
| + [_faviconView.widthAnchor constraintEqualToConstant:faviconSize],
|
| + [_faviconView.heightAnchor constraintEqualToConstant:faviconSize],
|
| + // Place the download indicator in the bottom right corner of the favicon.
|
| + [[_downloadIndicator centerXAnchor]
|
| + constraintEqualToAnchor:_faviconView.trailingAnchor],
|
| + [[_downloadIndicator centerYAnchor]
|
| + constraintEqualToAnchor:_faviconView.bottomAnchor],
|
| + [[_downloadIndicator widthAnchor]
|
| + constraintEqualToConstant:kDistillationIndicatorSize],
|
| + [[_downloadIndicator heightAnchor]
|
| + constraintEqualToConstant:kDistillationIndicatorSize],
|
| + ]];
|
| +
|
| + self.editingSelectorColor = [[MDCPalette cr_bluePalette] tint500];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)setDistillationState:
|
| + (ReadingListEntry::DistillationState)distillationState {
|
| + if (_distillationState == distillationState)
|
| + return;
|
| +
|
| + _distillationState = distillationState;
|
| + switch (distillationState) {
|
| + case ReadingListEntry::ERROR:
|
| + [_downloadIndicator setImage:[UIImage imageNamed:kFailureImageString]];
|
| + break;
|
| +
|
| + case ReadingListEntry::PROCESSED:
|
| + [_downloadIndicator setImage:[UIImage imageNamed:kSuccessImageString]];
|
| + break;
|
| +
|
| + // Same behavior for all pre-download states.
|
| + case ReadingListEntry::WAITING:
|
| + case ReadingListEntry::WILL_RETRY:
|
| + case ReadingListEntry::PROCESSING:
|
| + [_downloadIndicator setImage:nil];
|
| + break;
|
| + }
|
| +}
|
| +
|
| +#pragma mark UICollectionViewCell
|
| +
|
| +- (void)prepareForReuse {
|
| + [self.delegate readingListCellWillPrepareForReload:self];
|
| + self.delegate = nil;
|
| + self.textLabel.text = nil;
|
| + self.detailTextLabel.text = nil;
|
| + self.distillationState = ReadingListEntry::WAITING;
|
| + [super prepareForReuse];
|
| +}
|
| +
|
| +@end
|
|
|