| Index: ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
|
| diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
|
| index c87b1631ed1e5f2e9755a62e6b91d777c554fcac..71ffec5748bdbff67487ef4a6dfe148b1df8e2f2 100644
|
| --- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
|
| +++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
|
| @@ -4,17 +4,83 @@
|
|
|
| #import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h"
|
|
|
| +#include "base/mac/bind_objc_block.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/optional.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| #include "components/ntp_snippets/category.h"
|
| #include "components/ntp_snippets/content_suggestion.h"
|
| +#import "ios/chrome/browser/content_suggestions/content_suggestions_category_wrapper.h"
|
| #import "ios/chrome/browser/content_suggestions/content_suggestions_service_bridge_observer.h"
|
| #import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h"
|
| #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h"
|
| +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_item.h"
|
| +#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_section_information.h"
|
| +#include "ui/gfx/image/image.h"
|
|
|
| #if !defined(__has_feature) || !__has_feature(objc_arc)
|
| #error "This file requires ARC support."
|
| #endif
|
|
|
| +namespace {
|
| +
|
| +// Returns the Type for this |category|.
|
| +ContentSuggestionType TypeForCategory(ntp_snippets::Category category) {
|
| + // For now, only Article is a relevant type.
|
| + return ContentSuggestionTypeArticle;
|
| +}
|
| +
|
| +// Returns the section ID for this |category|.
|
| +ContentSuggestionsSectionID SectionIDForCategory(
|
| + ntp_snippets::Category category) {
|
| + if (category.IsKnownCategory(ntp_snippets::KnownCategories::BOOKMARKS))
|
| + return ContentSuggestionsSectionBookmarks;
|
| + if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES))
|
| + return ContentSuggestionsSectionArticles;
|
| +
|
| + return ContentSuggestionsSectionUnknown;
|
| +}
|
| +
|
| +// Returns the section layout corresponding to the category |layout|.
|
| +ContentSuggestionsSectionLayout SectionLayoutForLayout(
|
| + ntp_snippets::ContentSuggestionsCardLayout layout) {
|
| + // For now, only cards are relevant.
|
| + return ContentSuggestionsSectionLayoutCard;
|
| +}
|
| +
|
| +// Converts a ntp_snippets::ContentSuggestion to an Objective-C
|
| +// ContentSuggestion.
|
| +ContentSuggestion* ConvertContentSuggestion(
|
| + const ntp_snippets::ContentSuggestion& contentSuggestion) {
|
| + ContentSuggestion* suggestion = [[ContentSuggestion alloc] init];
|
| + suggestion.title = base::SysUTF16ToNSString(contentSuggestion.title());
|
| + suggestion.text = base::SysUTF16ToNSString(contentSuggestion.snippet_text());
|
| + suggestion.url = contentSuggestion.url();
|
| +
|
| + return suggestion;
|
| +}
|
| +
|
| +// Returns a SectionInformation for a |category|, filled with the
|
| +// |categoryInfo|.
|
| +ContentSuggestionsSectionInformation* SectionInformationFromCategoryInfo(
|
| + const base::Optional<ntp_snippets::CategoryInfo>& categoryInfo,
|
| + const ntp_snippets::Category& category) {
|
| + ContentSuggestionsSectionInformation* sectionInfo =
|
| + [[ContentSuggestionsSectionInformation alloc]
|
| + initWithSectionID:SectionIDForCategory(category)];
|
| + if (categoryInfo) {
|
| + sectionInfo.layout = SectionLayoutForLayout(categoryInfo->card_layout());
|
| + if (categoryInfo->show_if_empty()) {
|
| + // TODO(crbug.com/686728): Creates an item to display information when the
|
| + // section is empty.
|
| + }
|
| + sectionInfo.title = base::SysUTF16ToNSString(categoryInfo->title());
|
| + }
|
| + return sectionInfo;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| @interface ContentSuggestionsMediator ()<ContentSuggestionsServiceObserver> {
|
| // Bridge for this class to become an observer of a ContentSuggestionsService.
|
| std::unique_ptr<ContentSuggestionsServiceBridge> _suggestionBridge;
|
| @@ -22,15 +88,19 @@
|
|
|
| @property(nonatomic, assign)
|
| ntp_snippets::ContentSuggestionsService* contentService;
|
| +@property(nonatomic, strong, nonnull)
|
| + NSMutableDictionary<ContentSuggestionsCategoryWrapper*,
|
| + ContentSuggestionsSectionInformation*>*
|
| + sectionInformationByCategory;
|
|
|
| // Converts the data in |category| to ContentSuggestion and adds them to the
|
| // |contentArray|.
|
| - (void)addContentInCategory:(ntp_snippets::Category&)category
|
| toArray:(NSMutableArray<ContentSuggestion*>*)contentArray;
|
|
|
| -// Converts the |contentsuggestion| to a ContentSuggestion.
|
| -- (ContentSuggestion*)convertContentSuggestion:
|
| - (const ntp_snippets::ContentSuggestion&)contentsuggestion;
|
| +// Adds the section information for |category| in
|
| +// self.sectionInformationByCategory.
|
| +- (void)addSectionInformationForCategory:(ntp_snippets::Category)category;
|
|
|
| @end
|
|
|
| @@ -38,6 +108,7 @@
|
|
|
| @synthesize contentService = _contentService;
|
| @synthesize dataSink = _dataSink;
|
| +@synthesize sectionInformationByCategory = _sectionInformationByCategory;
|
|
|
| - (instancetype)initWithContentService:
|
| (ntp_snippets::ContentSuggestionsService*)contentService {
|
| @@ -46,6 +117,7 @@
|
| _suggestionBridge =
|
| base::MakeUnique<ContentSuggestionsServiceBridge>(self, contentService);
|
| _contentService = contentService;
|
| + _sectionInformationByCategory = [[NSMutableDictionary alloc] init];
|
| }
|
| return self;
|
| }
|
| @@ -57,6 +129,14 @@
|
| self.contentService->GetCategories();
|
| NSMutableArray<ContentSuggestion*>* dataHolders = [NSMutableArray array];
|
| for (auto& category : categories) {
|
| + if (self.contentService->GetCategoryStatus(category) !=
|
| + ntp_snippets::CategoryStatus::AVAILABLE) {
|
| + continue;
|
| + }
|
| + if (!self.sectionInformationByCategory[
|
| + [ContentSuggestionsCategoryWrapper wrapperWithCategory:category]]) {
|
| + [self addSectionInformationForCategory:category];
|
| + }
|
| [self addContentInCategory:category toArray:dataHolders];
|
| }
|
| return dataHolders;
|
| @@ -100,14 +180,28 @@
|
| toArray:(NSMutableArray<ContentSuggestion*>*)contentArray {
|
| const std::vector<ntp_snippets::ContentSuggestion>& suggestions =
|
| self.contentService->GetSuggestionsForCategory(category);
|
| + ContentSuggestionsCategoryWrapper* categoryWrapper =
|
| + [[ContentSuggestionsCategoryWrapper alloc] initWithCategory:category];
|
| for (auto& contentSuggestion : suggestions) {
|
| - [contentArray addObject:[self convertContentSuggestion:contentSuggestion]];
|
| + ContentSuggestion* suggestion = ConvertContentSuggestion(contentSuggestion);
|
| + suggestion.type = TypeForCategory(category);
|
| + suggestion.section = self.sectionInformationByCategory[categoryWrapper];
|
| +
|
| + // TODO(crbug.com/686728): fetch the image.
|
| +
|
| + [contentArray addObject:suggestion];
|
| }
|
| }
|
|
|
| -- (ContentSuggestion*)convertContentSuggestion:
|
| - (const ntp_snippets::ContentSuggestion&)contentsuggestion {
|
| - return [[ContentSuggestion alloc] init];
|
| +- (void)addSectionInformationForCategory:(ntp_snippets::Category)category {
|
| + base::Optional<ntp_snippets::CategoryInfo> categoryInfo =
|
| + self.contentService->GetCategoryInfo(category);
|
| +
|
| + ContentSuggestionsSectionInformation* sectionInfo =
|
| + SectionInformationFromCategoryInfo(categoryInfo, category);
|
| +
|
| + self.sectionInformationByCategory[[ContentSuggestionsCategoryWrapper
|
| + wrapperWithCategory:category]] = sectionInfo;
|
| }
|
|
|
| @end
|
|
|