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

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.sectionID) {
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, removing the current CollectionViewItem and the
90 // SectionInfo.
91 - (void)resetModels;
28 92
29 @end 93 @end
30 94
31 @implementation ContentSuggestionsCollectionUpdater 95 @implementation ContentSuggestionsCollectionUpdater
32 96
33 @synthesize collectionViewController = _collectionViewController; 97 @synthesize collectionViewController = _collectionViewController;
34 @synthesize dataSource = _dataSource; 98 @synthesize dataSource = _dataSource;
99 @synthesize sectionInfoBySectionIdentifier = _sectionInfoBySectionIdentifier;
35 100
36 - (instancetype)initWithDataSource: 101 - (instancetype)initWithDataSource:
37 (id<ContentSuggestionsDataSource>)dataSource { 102 (id<ContentSuggestionsDataSource>)dataSource {
38 self = [super init]; 103 self = [super init];
39 if (self) { 104 if (self) {
40 _dataSource = dataSource; 105 _dataSource = dataSource;
41 _dataSource.dataSink = self; 106 _dataSource.dataSink = self;
42 } 107 }
43 return self; 108 return self;
44 } 109 }
45 110
46 #pragma mark - Properties 111 #pragma mark - Properties
47 112
48 - (void)setCollectionViewController: 113 - (void)setCollectionViewController:
49 (ContentSuggestionsViewController*)collectionViewController { 114 (ContentSuggestionsViewController*)collectionViewController {
50 _collectionViewController = collectionViewController; 115 _collectionViewController = collectionViewController;
51 [collectionViewController loadModel];
52 CollectionViewModel* model = collectionViewController.collectionViewModel;
53 116
54 // TODO(crbug.com/686728): Load the data with the dataSource instead of hard 117 [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 } 118 }
114 119
115 #pragma mark - ContentSuggestionsDataSink 120 #pragma mark - ContentSuggestionsDataSink
116 121
117 - (void)dataAvailable { 122 - (void)dataAvailable {
118 // TODO(crbug.com/686728): Get the new data from the DataSource. 123 [self reloadData];
119 } 124 }
120 125
121 #pragma mark - Public methods 126 #pragma mark - Public methods
122 127
123 - (void)addTextItem:(NSString*)title 128 - (void)addTextItem:(NSString*)title
124 subtitle:(NSString*)subtitle 129 subtitle:(NSString*)subtitle
125 toSection:(NSInteger)inputSection { 130 toSection:(NSInteger)inputSection {
126 DCHECK(_collectionViewController); 131 DCHECK(self.collectionViewController);
127 ContentSuggestionsItem* item = 132 ContentSuggestionsItem* item =
128 [[ContentSuggestionsItem alloc] initWithType:ItemTypeText 133 [[ContentSuggestionsItem alloc] initWithType:ItemTypeText
129 title:title 134 title:title
130 subtitle:subtitle]; 135 subtitle:subtitle];
131 NSInteger sectionIdentifier = kSectionIdentifierEnumZero + inputSection; 136 NSInteger sectionIdentifier = kSectionIdentifierEnumZero + inputSection;
132 NSInteger sectionIndex = inputSection; 137 NSInteger sectionIndex = inputSection;
133 CollectionViewModel* model = _collectionViewController.collectionViewModel; 138 CollectionViewModel* model =
139 self.collectionViewController.collectionViewModel;
134 if ([model numberOfSections] <= inputSection) { 140 if ([model numberOfSections] <= inputSection) {
135 sectionIndex = [model numberOfSections]; 141 sectionIndex = [model numberOfSections];
136 sectionIdentifier = kSectionIdentifierEnumZero + sectionIndex; 142 sectionIdentifier = kSectionIdentifierEnumZero + sectionIndex;
137 [_collectionViewController.collectionView performBatchUpdates:^{ 143 [self.collectionViewController.collectionView performBatchUpdates:^{
138 [_collectionViewController.collectionViewModel 144 [self.collectionViewController.collectionViewModel
139 addSectionWithIdentifier:sectionIdentifier]; 145 addSectionWithIdentifier:sectionIdentifier];
140 [_collectionViewController.collectionView 146 [self.collectionViewController.collectionView
141 insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]]; 147 insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
142 } 148 }
143 completion:nil]; 149 completion:nil];
144 } 150 }
145 NSInteger numberOfItemsInSection = 151 NSInteger numberOfItemsInSection =
146 [model numberOfItemsInSection:sectionIndex]; 152 [model numberOfItemsInSection:sectionIndex];
147 [_collectionViewController.collectionViewModel addItem:item 153 [self.collectionViewController.collectionViewModel addItem:item
148 toSectionWithIdentifier:sectionIdentifier]; 154 toSectionWithIdentifier:sectionIdentifier];
149 [_collectionViewController.collectionView performBatchUpdates:^{ 155 [self.collectionViewController.collectionView performBatchUpdates:^{
150 [_collectionViewController.collectionView 156 [self.collectionViewController.collectionView
151 insertItemsAtIndexPaths:@[ [NSIndexPath 157 insertItemsAtIndexPaths:@[ [NSIndexPath
152 indexPathForRow:numberOfItemsInSection 158 indexPathForRow:numberOfItemsInSection
153 inSection:sectionIndex] ]]; 159 inSection:sectionIndex] ]];
154 } 160 }
155 completion:nil]; 161 completion:nil];
156 } 162 }
157 163
158 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section { 164 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section {
159 return section == 0 || section == 1; 165 NSNumber* identifier = @([self.collectionViewController.collectionViewModel
166 sectionIdentifierForSection:section]);
167 ContentSuggestionsSectionInformation* sectionInformation =
168 self.sectionInfoBySectionIdentifier[identifier];
169 return sectionInformation.layout == ContentSuggestionsSectionLayoutCustom;
170 }
171
172 - (ContentSuggestionType)contentSuggestionTypeForItem:
173 (CollectionViewItem*)item {
174 return ContentSuggestionTypeForItemType(item.type);
175 }
176
177 #pragma mark - Private methods
178
179 - (void)reloadData {
180 [self resetModels];
181 CollectionViewModel* model =
182 self.collectionViewController.collectionViewModel;
183
184 NSArray<ContentSuggestion*>* suggestions = [self.dataSource allSuggestions];
185
186 for (ContentSuggestion* suggestion in suggestions) {
187 NSInteger sectionIdentifier = [self addSectionIfNeeded:suggestion.section];
188 ContentSuggestionsArticleItem* articleItem =
189 [[ContentSuggestionsArticleItem alloc]
190 initWithType:ItemTypeForContentSuggestionType(suggestion.type)
191 title:suggestion.title
192 subtitle:suggestion.text
193 image:suggestion.image
194 url:suggestion.url];
195
196 [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier];
197 }
198
199 if ([self.collectionViewController isViewLoaded]) {
200 [self.collectionViewController.collectionView reloadData];
201 }
202 }
203
204 - (NSInteger)addSectionIfNeeded:
205 (ContentSuggestionsSectionInformation*)sectionInformation {
206 NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInformation);
207
208 CollectionViewModel* model =
209 self.collectionViewController.collectionViewModel;
210 if (![model hasSectionForSectionIdentifier:sectionIdentifier]) {
211 [model addSectionWithIdentifier:sectionIdentifier];
212 self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] =
213 sectionInformation;
214 [self.sectionInfoBySectionIdentifier setObject:sectionInformation
215 forKey:@(sectionIdentifier)];
216 }
217 return sectionIdentifier;
218 }
219
220 - (void)resetModels {
221 [self.collectionViewController loadModel];
222 self.sectionInfoBySectionIdentifier = [[NSMutableDictionary alloc] init];
160 } 223 }
161 224
162 @end 225 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698