| OLD | NEW |
| 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 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" | 10 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 80 |
| 81 @interface ContentSuggestionsCollectionUpdater ()< | 81 @interface ContentSuggestionsCollectionUpdater ()< |
| 82 ContentSuggestionsArticleItemDelegate, | 82 ContentSuggestionsArticleItemDelegate, |
| 83 ContentSuggestionsDataSink> | 83 ContentSuggestionsDataSink> |
| 84 | 84 |
| 85 @property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource; | 85 @property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource; |
| 86 @property(nonatomic, strong) | 86 @property(nonatomic, strong) |
| 87 NSMutableDictionary<NSNumber*, ContentSuggestionsSectionInformation*>* | 87 NSMutableDictionary<NSNumber*, ContentSuggestionsSectionInformation*>* |
| 88 sectionInfoBySectionIdentifier; | 88 sectionInfoBySectionIdentifier; |
| 89 | 89 |
| 90 // Adds a new section if needed and returns the section identifier. | |
| 91 - (NSInteger)addSectionIfNeeded: | |
| 92 (ContentSuggestionsSectionInformation*)sectionInformation; | |
| 93 // Resets the models, removing the current CollectionViewItem and the | 90 // Resets the models, removing the current CollectionViewItem and the |
| 94 // SectionInfo. | 91 // SectionInfo. |
| 95 - (void)resetModels; | 92 - (void)resetModels; |
| 96 | 93 |
| 97 @end | 94 @end |
| 98 | 95 |
| 99 @implementation ContentSuggestionsCollectionUpdater | 96 @implementation ContentSuggestionsCollectionUpdater |
| 100 | 97 |
| 101 @synthesize collectionViewController = _collectionViewController; | 98 @synthesize collectionViewController = _collectionViewController; |
| 102 @synthesize dataSource = _dataSource; | 99 @synthesize dataSource = _dataSource; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 128 SectionIdentifier sectionIdentifier = SectionIdentifierForInfo(sectionInfo); | 125 SectionIdentifier sectionIdentifier = SectionIdentifierForInfo(sectionInfo); |
| 129 | 126 |
| 130 CollectionViewModel* model = | 127 CollectionViewModel* model = |
| 131 self.collectionViewController.collectionViewModel; | 128 self.collectionViewController.collectionViewModel; |
| 132 if ([model hasSectionForSectionIdentifier:sectionIdentifier] && | 129 if ([model hasSectionForSectionIdentifier:sectionIdentifier] && |
| 133 [model itemsInSectionWithIdentifier:sectionIdentifier].count > 0) { | 130 [model itemsInSectionWithIdentifier:sectionIdentifier].count > 0) { |
| 134 // Do not dismiss the presented items. | 131 // Do not dismiss the presented items. |
| 135 return; | 132 return; |
| 136 } | 133 } |
| 137 | 134 |
| 138 [self addSuggestions:[self.dataSource suggestionsForSection:sectionInfo]]; | 135 [self.collectionViewController |
| 136 addSuggestions:[self.dataSource suggestionsForSection:sectionInfo]]; |
| 139 } | 137 } |
| 140 | 138 |
| 141 - (void)clearSuggestion:(ContentSuggestionIdentifier*)suggestionIdentifier { | 139 - (void)clearSuggestion:(ContentSuggestionIdentifier*)suggestionIdentifier { |
| 142 SectionIdentifier sectionIdentifier = | 140 SectionIdentifier sectionIdentifier = |
| 143 SectionIdentifierForInfo(suggestionIdentifier.sectionInfo); | 141 SectionIdentifierForInfo(suggestionIdentifier.sectionInfo); |
| 144 if (![self.collectionViewController.collectionViewModel | 142 if (![self.collectionViewController.collectionViewModel |
| 145 hasSectionForSectionIdentifier:sectionIdentifier]) { | 143 hasSectionForSectionIdentifier:sectionIdentifier]) { |
| 146 return; | 144 return; |
| 147 } | 145 } |
| 148 | 146 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 163 return; | 161 return; |
| 164 | 162 |
| 165 NSIndexPath* indexPath = [self.collectionViewController.collectionViewModel | 163 NSIndexPath* indexPath = [self.collectionViewController.collectionViewModel |
| 166 indexPathForItem:correspondingItem | 164 indexPathForItem:correspondingItem |
| 167 inSectionWithIdentifier:sectionIdentifier]; | 165 inSectionWithIdentifier:sectionIdentifier]; |
| 168 [self.collectionViewController dismissEntryAtIndexPath:indexPath]; | 166 [self.collectionViewController dismissEntryAtIndexPath:indexPath]; |
| 169 } | 167 } |
| 170 | 168 |
| 171 - (void)reloadAllData { | 169 - (void)reloadAllData { |
| 172 [self resetModels]; | 170 [self resetModels]; |
| 173 [self addSuggestions:[self.dataSource allSuggestions]]; | 171 [self.collectionViewController |
| 172 addSuggestions:[self.dataSource allSuggestions]]; |
| 174 } | 173 } |
| 175 | 174 |
| 176 - (void)clearSection:(ContentSuggestionsSectionInformation*)sectionInfo { | 175 - (void)clearSection:(ContentSuggestionsSectionInformation*)sectionInfo { |
| 177 SectionIdentifier sectionIdentifier = SectionIdentifierForInfo(sectionInfo); | 176 SectionIdentifier sectionIdentifier = SectionIdentifierForInfo(sectionInfo); |
| 178 NSInteger section = [self.collectionViewController.collectionViewModel | 177 NSInteger section = [self.collectionViewController.collectionViewModel |
| 179 sectionIdentifierForSection:sectionIdentifier]; | 178 sectionIdentifierForSection:sectionIdentifier]; |
| 180 | 179 |
| 181 [self.collectionViewController dismissSection:section]; | 180 [self.collectionViewController dismissSection:section]; |
| 182 } | 181 } |
| 183 | 182 |
| 184 #pragma mark - Public methods | 183 #pragma mark - Public methods |
| 185 | 184 |
| 186 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section { | 185 - (BOOL)shouldUseCustomStyleForSection:(NSInteger)section { |
| 187 NSNumber* identifier = @([self.collectionViewController.collectionViewModel | 186 NSNumber* identifier = @([self.collectionViewController.collectionViewModel |
| 188 sectionIdentifierForSection:section]); | 187 sectionIdentifierForSection:section]); |
| 189 ContentSuggestionsSectionInformation* sectionInformation = | 188 ContentSuggestionsSectionInformation* sectionInformation = |
| 190 self.sectionInfoBySectionIdentifier[identifier]; | 189 self.sectionInfoBySectionIdentifier[identifier]; |
| 191 return sectionInformation.layout == ContentSuggestionsSectionLayoutCustom; | 190 return sectionInformation.layout == ContentSuggestionsSectionLayoutCustom; |
| 192 } | 191 } |
| 193 | 192 |
| 194 - (ContentSuggestionType)contentSuggestionTypeForItem: | 193 - (ContentSuggestionType)contentSuggestionTypeForItem: |
| 195 (CollectionViewItem*)item { | 194 (CollectionViewItem*)item { |
| 196 return ContentSuggestionTypeForItemType(item.type); | 195 return ContentSuggestionTypeForItemType(item.type); |
| 197 } | 196 } |
| 198 | 197 |
| 199 #pragma mark - ContentSuggestionsArticleItemDelegate | 198 - (NSArray<NSIndexPath*>*)addSuggestionsToModel: |
| 200 | 199 (NSArray<ContentSuggestion*>*)suggestions { |
| 201 - (void)loadImageForArticleItem:(ContentSuggestionsArticleItem*)articleItem { | |
| 202 NSInteger sectionIdentifier = | |
| 203 SectionIdentifierForInfo(articleItem.suggestionIdentifier.sectionInfo); | |
| 204 | |
| 205 __weak ContentSuggestionsCollectionUpdater* weakSelf = self; | |
| 206 __weak ContentSuggestionsArticleItem* weakArticle = articleItem; | |
| 207 void (^imageFetchedCallback)(const gfx::Image&) = ^(const gfx::Image& image) { | |
| 208 if (image.IsEmpty()) { | |
| 209 return; | |
| 210 } | |
| 211 | |
| 212 ContentSuggestionsCollectionUpdater* strongSelf = weakSelf; | |
| 213 ContentSuggestionsArticleItem* strongArticle = weakArticle; | |
| 214 if (!strongSelf || !strongArticle) { | |
| 215 return; | |
| 216 } | |
| 217 | |
| 218 strongArticle.image = image.CopyUIImage(); | |
| 219 [strongSelf.collectionViewController | |
| 220 reconfigureCellsForItems:@[ strongArticle ] | |
| 221 inSectionWithIdentifier:sectionIdentifier]; | |
| 222 }; | |
| 223 | |
| 224 [self.dataSource.imageFetcher | |
| 225 fetchImageForSuggestion:articleItem.suggestionIdentifier | |
| 226 callback:imageFetchedCallback]; | |
| 227 } | |
| 228 | |
| 229 #pragma mark - Private methods | |
| 230 | |
| 231 // Add the |suggestions| to the model and reload the data. | |
| 232 - (void)addSuggestions:(NSArray<ContentSuggestion*>*)suggestions { | |
| 233 if (suggestions.count == 0) { | 200 if (suggestions.count == 0) { |
| 234 return; | 201 return [NSArray array]; |
| 235 } | 202 } |
| 236 | 203 |
| 237 CollectionViewModel* model = | 204 CollectionViewModel* model = |
| 238 self.collectionViewController.collectionViewModel; | 205 self.collectionViewController.collectionViewModel; |
| 239 | 206 |
| 207 NSMutableArray<NSIndexPath*>* indexPaths = [NSMutableArray array]; |
| 240 for (ContentSuggestion* suggestion in suggestions) { | 208 for (ContentSuggestion* suggestion in suggestions) { |
| 241 NSInteger sectionIdentifier = | 209 NSInteger sectionIdentifier = |
| 242 [self addSectionIfNeeded:suggestion.suggestionIdentifier.sectionInfo]; | 210 SectionIdentifierForInfo(suggestion.suggestionIdentifier.sectionInfo); |
| 211 |
| 243 ContentSuggestionsArticleItem* articleItem = | 212 ContentSuggestionsArticleItem* articleItem = |
| 244 [[ContentSuggestionsArticleItem alloc] | 213 [[ContentSuggestionsArticleItem alloc] |
| 245 initWithType:ItemTypeForContentSuggestionType(suggestion.type) | 214 initWithType:ItemTypeForContentSuggestionType(suggestion.type) |
| 246 title:suggestion.title | 215 title:suggestion.title |
| 247 subtitle:suggestion.text | 216 subtitle:suggestion.text |
| 248 delegate:self | 217 delegate:self |
| 249 url:suggestion.url]; | 218 url:suggestion.url]; |
| 250 | 219 |
| 251 articleItem.publisher = suggestion.publisher; | 220 articleItem.publisher = suggestion.publisher; |
| 252 articleItem.publishDate = suggestion.publishDate; | 221 articleItem.publishDate = suggestion.publishDate; |
| 253 | 222 |
| 254 articleItem.suggestionIdentifier = suggestion.suggestionIdentifier; | 223 articleItem.suggestionIdentifier = suggestion.suggestionIdentifier; |
| 255 | 224 |
| 225 NSInteger section = [model sectionForSectionIdentifier:sectionIdentifier]; |
| 226 NSInteger itemNumber = [model numberOfItemsInSection:section]; |
| 256 [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier]; | 227 [model addItem:articleItem toSectionWithIdentifier:sectionIdentifier]; |
| 228 |
| 229 [indexPaths |
| 230 addObject:[NSIndexPath indexPathForItem:itemNumber inSection:section]]; |
| 257 } | 231 } |
| 258 | 232 |
| 259 if ([self.collectionViewController isViewLoaded]) { | 233 return indexPaths; |
| 260 [self.collectionViewController.collectionView reloadData]; | |
| 261 } | |
| 262 } | 234 } |
| 263 | 235 |
| 264 - (NSInteger)addSectionIfNeeded: | 236 - (NSIndexSet*)addSectionsForSuggestionsToModel: |
| 265 (ContentSuggestionsSectionInformation*)sectionInformation { | 237 (NSArray<ContentSuggestion*>*)suggestions { |
| 266 NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInformation); | 238 NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet]; |
| 267 | 239 |
| 268 CollectionViewModel* model = | 240 CollectionViewModel* model = |
| 269 self.collectionViewController.collectionViewModel; | 241 self.collectionViewController.collectionViewModel; |
| 270 if (![model hasSectionForSectionIdentifier:sectionIdentifier]) { | 242 for (ContentSuggestion* suggestion in suggestions) { |
| 271 [model addSectionWithIdentifier:sectionIdentifier]; | 243 ContentSuggestionsSectionInformation* sectionInfo = |
| 272 self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] = | 244 suggestion.suggestionIdentifier.sectionInfo; |
| 273 sectionInformation; | 245 NSInteger sectionIdentifier = SectionIdentifierForInfo(sectionInfo); |
| 274 [self.sectionInfoBySectionIdentifier setObject:sectionInformation | 246 |
| 275 forKey:@(sectionIdentifier)]; | 247 if (![model hasSectionForSectionIdentifier:sectionIdentifier]) { |
| 248 [model addSectionWithIdentifier:sectionIdentifier]; |
| 249 self.sectionInfoBySectionIdentifier[@(sectionIdentifier)] = sectionInfo; |
| 250 [indexSet addIndex:[model sectionForSectionIdentifier:sectionIdentifier]]; |
| 251 } |
| 276 } | 252 } |
| 277 return sectionIdentifier; | 253 return indexSet; |
| 278 } | 254 } |
| 279 | 255 |
| 256 #pragma mark - ContentSuggestionsArticleItemDelegate |
| 257 |
| 258 - (void)loadImageForArticleItem:(ContentSuggestionsArticleItem*)articleItem { |
| 259 NSInteger sectionIdentifier = |
| 260 SectionIdentifierForInfo(articleItem.suggestionIdentifier.sectionInfo); |
| 261 |
| 262 __weak ContentSuggestionsCollectionUpdater* weakSelf = self; |
| 263 __weak ContentSuggestionsArticleItem* weakArticle = articleItem; |
| 264 void (^imageFetchedCallback)(const gfx::Image&) = ^(const gfx::Image& image) { |
| 265 if (image.IsEmpty()) { |
| 266 return; |
| 267 } |
| 268 |
| 269 ContentSuggestionsCollectionUpdater* strongSelf = weakSelf; |
| 270 ContentSuggestionsArticleItem* strongArticle = weakArticle; |
| 271 if (!strongSelf || !strongArticle) { |
| 272 return; |
| 273 } |
| 274 |
| 275 strongArticle.image = image.CopyUIImage(); |
| 276 [strongSelf.collectionViewController |
| 277 reconfigureCellsForItems:@[ strongArticle ] |
| 278 inSectionWithIdentifier:sectionIdentifier]; |
| 279 }; |
| 280 |
| 281 [self.dataSource.imageFetcher |
| 282 fetchImageForSuggestion:articleItem.suggestionIdentifier |
| 283 callback:imageFetchedCallback]; |
| 284 } |
| 285 |
| 286 #pragma mark - Private methods |
| 287 |
| 280 - (void)resetModels { | 288 - (void)resetModels { |
| 281 [self.collectionViewController loadModel]; | 289 [self.collectionViewController loadModel]; |
| 282 self.sectionInfoBySectionIdentifier = [[NSMutableDictionary alloc] init]; | 290 self.sectionInfoBySectionIdentifier = [[NSMutableDictionary alloc] init]; |
| 283 } | 291 } |
| 284 | 292 |
| 285 @end | 293 @end |
| OLD | NEW |