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

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

Issue 2697843003: Display articles in Content Suggestions (Closed)
Patch Set: Address comments Created 3 years, 10 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/content_suggestions_collectio n_updater.h" 5 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collectio n_updater.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/mac/foundation_util.h" 8 #include "base/mac/foundation_util.h"
9 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" 9 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h"
10 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" 10 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
11 #import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h"
11 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_article_i tem.h" 12 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_article_i tem.h"
12 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink .h" 13 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink .h"
13 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sour ce.h" 14 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sour ce.h"
14 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_expandabl e_item.h" 15 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_expandabl e_item.h"
15 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_i tem.h" 16 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_i tem.h"
16 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_item.h" 17 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_item.h"
18 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_section_i nformation.h"
17 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_stack_ite m.h" 19 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_stack_ite m.h"
18 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_cont roller.h" 20 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_cont roller.h"
19 #include "url/gurl.h" 21 #include "url/gurl.h"
20 22
21 #if !defined(__has_feature) || !__has_feature(objc_arc) 23 #if !defined(__has_feature) || !__has_feature(objc_arc)
22 #error "This file requires ARC support." 24 #error "This file requires ARC support."
23 #endif 25 #endif
24 26
27 namespace {
28
29 // Enum defining the ItemType of this ContentSuggestionsCollectionUpdater.
30 typedef NS_ENUM(NSInteger, ItemType) {
31 ItemTypeText = kItemTypeEnumZero,
32 ItemTypeArticle,
33 ItemTypeExpand,
34 ItemTypeStack,
35 ItemTypeFavicon,
36 };
37
38 typedef NS_ENUM(NSInteger, SectionIdentifier) {
39 SectionIdentifierBookmarks = kSectionIdentifierEnumZero,
40 SectionIdentifierArticles,
41 SectionIdentifierDefault,
42 };
43
44 ItemType ItemTypeForContentSuggestionType(ContentSuggestionType type) {
45 switch (type) {
46 case ContentSuggestionTypeArticle:
47 return ItemTypeArticle;
48 }
49 }
50
51 ContentSuggestionType ContentSuggestionTypeForItemType(NSInteger type) {
52 if (type == ItemTypeArticle)
53 return ContentSuggestionTypeArticle;
54 // Add new type here
55
56 // Default type.
57 return ContentSuggestionTypeArticle;
58 }
59
60 // Returns the section identifier corresponding to the section |info|.
61 SectionIdentifier SectionIdentifierForInfo(
62 ContentSuggestionsSectionInformation* info) {
63 switch (info.ID) {
64 case ContentSuggestionsSectionBookmarks:
65 return SectionIdentifierBookmarks;
66
67 case ContentSuggestionsSectionArticles:
68 return SectionIdentifierArticles;
69
70 case ContentSuggestionsSectionUnknown:
71 return SectionIdentifierDefault;
72 }
73 }
74
75 } // namespace
76
25 @interface ContentSuggestionsCollectionUpdater ()<ContentSuggestionsDataSink> 77 @interface ContentSuggestionsCollectionUpdater ()<ContentSuggestionsDataSink>
26 78
27 @property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource; 79 @property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource;
80 @property(nonatomic, strong)
81 NSMutableDictionary<NSNumber*, ContentSuggestionsSectionInformation*>*
82 sectionInfoBySectionIdentifier;
83
84 // Reloads all the data from the data source, deleting all the current items.
85 - (void)reloadData;
86 // Adds a new section if needed and returns the section identifier.
87 - (NSInteger)addSectionIfNeeded:
88 (ContentSuggestionsSectionInformation*)sectionInformation;
89 // Resets the models and cells.
stkhapugin 2017/02/16 10:33:22 What does "reset cells" mean? I'd prefer a more ve
gambard 2017/02/20 08:01:30 Done.
90 - (void)resetModels;
28 91
29 @end 92 @end
30 93
31 @implementation ContentSuggestionsCollectionUpdater 94 @implementation ContentSuggestionsCollectionUpdater
32 95
33 @synthesize collectionViewController = _collectionViewController; 96 @synthesize collectionViewController = _collectionViewController;
34 @synthesize dataSource = _dataSource; 97 @synthesize dataSource = _dataSource;
98 @synthesize sectionInfoBySectionIdentifier = _sectionInfoBySectionIdentifier;
35 99
36 - (instancetype)initWithDataSource: 100 - (instancetype)initWithDataSource:
37 (id<ContentSuggestionsDataSource>)dataSource { 101 (id<ContentSuggestionsDataSource>)dataSource {
38 self = [super init]; 102 self = [super init];
39 if (self) { 103 if (self) {
40 _dataSource = dataSource; 104 _dataSource = dataSource;
41 _dataSource.dataSink = self; 105 _dataSource.dataSink = self;
42 } 106 }
43 return self; 107 return self;
44 } 108 }
45 109
46 #pragma mark - Properties 110 #pragma mark - Properties
47 111
48 - (void)setCollectionViewController: 112 - (void)setCollectionViewController:
49 (ContentSuggestionsViewController*)collectionViewController { 113 (ContentSuggestionsViewController*)collectionViewController {
50 _collectionViewController = collectionViewController; 114 _collectionViewController = collectionViewController;
51 [collectionViewController loadModel];
52 CollectionViewModel* model = collectionViewController.collectionViewModel;
53 115
54 // TODO(crbug.com/686728): Load the data with the dataSource instead of hard 116 [self reloadData];
55 // coded value.
56
57 NSInteger sectionIdentifier = kSectionIdentifierEnumZero;
58
59 // Stack Item.
60 [model addSectionWithIdentifier:sectionIdentifier];
61 [model addItem:[[ContentSuggestionsStackItem alloc]
62 initWithType:ItemTypeStack
63 title:@"The title"
64 subtitle:@"The subtitle"]
65 toSectionWithIdentifier:sectionIdentifier++];
66
67 // Favicon Item.
68 [model addSectionWithIdentifier:sectionIdentifier];
69 ContentSuggestionsFaviconItem* faviconItem =
70 [[ContentSuggestionsFaviconItem alloc] initWithType:ItemTypeFavicon];
71 for (NSInteger i = 0; i < 6; i++) {
72 [faviconItem addFavicon:[UIImage imageNamed:@"bookmark_gray_star_large"]
73 withTitle:@"Super website! Incredible!"];
74 }
75 faviconItem.delegate = _collectionViewController;
76 [model addItem:faviconItem toSectionWithIdentifier:sectionIdentifier++];
77
78 for (NSInteger i = 0; i < 3; i++) {
79 [model addSectionWithIdentifier:sectionIdentifier];
80
81 // Standard Item.
82 [model addItem:[[ContentSuggestionsItem alloc] initWithType:ItemTypeText
83 title:@"The title"
84 subtitle:@"The subtitle"]
85 toSectionWithIdentifier:sectionIdentifier];
86
87 // Article Item.
88 [model addItem:[[ContentSuggestionsArticleItem alloc]
89 initWithType:ItemTypeArticle
90 title:@"Title of an Article"
91 subtitle:@"This is the subtitle of an article, can "
92 @"spawn on multiple lines"
93 image:[UIImage imageNamed:@"distillation_success"]
94 url:GURL()]
95 toSectionWithIdentifier:sectionIdentifier];
96
97 // Expandable Item.
98 SuggestionsExpandableItem* expandableItem =
99 [[SuggestionsExpandableItem alloc]
100 initWithType:ItemTypeExpand
101 title:@"Title of an Expandable Article"
102 subtitle:@"This Article can be expanded to display "
103 @"additional information or interaction "
104 @"options"
105 image:[UIImage imageNamed:@"distillation_fail"]
106 detailText:@"Details shown only when the article is "
107 @"expanded. It can be displayed on "
108 @"multiple lines."];
109 expandableItem.delegate = _collectionViewController;
110 [model addItem:expandableItem toSectionWithIdentifier:sectionIdentifier];
111 sectionIdentifier++;
112 }
113 } 117 }
114 118
115 #pragma mark - ContentSuggestionsDataSink 119 #pragma mark - ContentSuggestionsDataSink
116 120
117 - (void)dataAvailable { 121 - (void)dataAvailable {
118 // TODO(crbug.com/686728): Get the new data from the DataSource. 122 [self reloadData];
119 } 123 }
120 124
121 #pragma mark - Public methods 125 #pragma mark - Public methods
122 126
123 - (void)addTextItem:(NSString*)title 127 - (void)addTextItem:(NSString*)title
124 subtitle:(NSString*)subtitle 128 subtitle:(NSString*)subtitle
125 toSection:(NSInteger)inputSection { 129 toSection:(NSInteger)inputSection {
126 DCHECK(_collectionViewController); 130 DCHECK(self.collectionViewController);
127 ContentSuggestionsItem* item = 131 ContentSuggestionsItem* item =
128 [[ContentSuggestionsItem alloc] initWithType:ItemTypeText 132 [[ContentSuggestionsItem alloc] initWithType:ItemTypeText
129 title:title 133 title:title
130 subtitle:subtitle]; 134 subtitle:subtitle];
131 NSInteger sectionIdentifier = kSectionIdentifierEnumZero + inputSection; 135 NSInteger sectionIdentifier = kSectionIdentifierEnumZero + inputSection;
132 NSInteger sectionIndex = inputSection; 136 NSInteger sectionIndex = inputSection;
133 CollectionViewModel* model = _collectionViewController.collectionViewModel; 137 CollectionViewModel* model =
138 self.collectionViewController.collectionViewModel;
134 if ([model numberOfSections] <= inputSection) { 139 if ([model numberOfSections] <= inputSection) {
135 sectionIndex = [model numberOfSections]; 140 sectionIndex = [model numberOfSections];
136 sectionIdentifier = kSectionIdentifierEnumZero + sectionIndex; 141 sectionIdentifier = kSectionIdentifierEnumZero + sectionIndex;
137 [_collectionViewController.collectionView performBatchUpdates:^{ 142 [self.collectionViewController.collectionView performBatchUpdates:^{
138 [_collectionViewController.collectionViewModel 143 [self.collectionViewController.collectionViewModel
139 addSectionWithIdentifier:sectionIdentifier]; 144 addSectionWithIdentifier:sectionIdentifier];
140 [_collectionViewController.collectionView 145 [self.collectionViewController.collectionView
141 insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]]; 146 insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
142 } 147 }
143 completion:nil]; 148 completion:nil];
144 } 149 }
145 NSInteger numberOfItemsInSection = 150 NSInteger numberOfItemsInSection =
146 [model numberOfItemsInSection:sectionIndex]; 151 [model numberOfItemsInSection:sectionIndex];
147 [_collectionViewController.collectionViewModel addItem:item 152 [self.collectionViewController.collectionViewModel addItem:item
148 toSectionWithIdentifier:sectionIdentifier]; 153 toSectionWithIdentifier:sectionIdentifier];
149 [_collectionViewController.collectionView performBatchUpdates:^{ 154 [self.collectionViewController.collectionView performBatchUpdates:^{
150 [_collectionViewController.collectionView 155 [self.collectionViewController.collectionView
151 insertItemsAtIndexPaths:@[ [NSIndexPath 156 insertItemsAtIndexPaths:@[ [NSIndexPath
152 indexPathForRow:numberOfItemsInSection 157 indexPathForRow:numberOfItemsInSection
153 inSection:sectionIndex] ]]; 158 inSection:sectionIndex] ]];
154 } 159 }
155 completion:nil]; 160 completion:nil];
156 } 161 }
157 162
158 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section { 163 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section {
159 return section == 0 || section == 1; 164 NSNumber* identifier = @([self.collectionViewController.collectionViewModel
165 sectionIdentifierForSection:section]);
166 ContentSuggestionsSectionInformation* sectionInformation =
167 self.sectionInfoBySectionIdentifier[identifier];
168 return sectionInformation.layout == ContentSuggestionsSectionLayoutCustom;
169 }
170
171 - (ContentSuggestionType)contentSuggestionTypeForItem:
172 (CollectionViewItem*)item {
173 return ContentSuggestionTypeForItemType(item.type);
174 }
175
176 #pragma mark - Private methods
177
178 - (void)reloadData {
179 [self resetModels];
180 CollectionViewModel* model =
181 self.collectionViewController.collectionViewModel;
182
183 NSArray<ContentSuggestion*>* suggestions = [self.dataSource allSuggestions];
184
185 for (ContentSuggestion* suggestion in suggestions) {
186 NSInteger sectionIdentifier = [self addSectionIfNeeded:suggestion.section];
187 ContentSuggestionsArticleItem* articleItem =
188 [[ContentSuggestionsArticleItem alloc]
189 initWithType:ItemTypeForContentSuggestionType(suggestion.type)
190 title:suggestion.title
191 subtitle:suggestion.text
192 image:suggestion.image
193 url:suggestion.url];
194
195 [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier];
196 }
197
198 if ([self.collectionViewController isViewLoaded]) {
199 [self.collectionViewController.collectionView reloadData];
200 }
201 }
202
203 - (NSInteger)addSectionIfNeeded:
204 (ContentSuggestionsSectionInformation*)sectionInformation {
205 NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInformation);
206
207 CollectionViewModel* model =
208 self.collectionViewController.collectionViewModel;
209 if (![model hasSectionForSectionIdentifier:sectionIdentifier]) {
210 [model addSectionWithIdentifier:sectionIdentifier];
211 self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] =
212 sectionInformation;
213 [self.sectionInfoBySectionIdentifier setObject:sectionInformation
214 forKey:@(sectionIdentifier)];
215 }
216 return sectionIdentifier;
217 }
218
219 - (void)resetModels {
220 [self.collectionViewController loadModel];
221 self.sectionInfoBySectionIdentifier = [[NSMutableDictionary alloc] init];
160 } 222 }
161 223
162 @end 224 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698