Commit 38b64b14 authored by adamta's avatar adamta Committed by Commit Bot

[iOS] Trigger infinite feed for Discover feed

When a user scrolls near the bottom of the NTP (with a variable offset),
the Discover provider function for loading the next feed's page is
called.

Bug: 1085419
Change-Id: I26c493bc588905e0018902261eb3d050291a83ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2237717
Commit-Queue: Adam Trudeau-Arcaro <adamta@google.com>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795335}
parent 4807bfab
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
source_set("content_suggestions") { source_set("content_suggestions") {
sources = [ sources = [
"content_suggestions_action_handler.h",
"content_suggestions_alert_factory.h", "content_suggestions_alert_factory.h",
"content_suggestions_alert_factory.mm", "content_suggestions_alert_factory.mm",
"content_suggestions_category_wrapper.h", "content_suggestions_category_wrapper.h",
"content_suggestions_category_wrapper.mm", "content_suggestions_category_wrapper.mm",
"content_suggestions_consumer.h",
"content_suggestions_coordinator.h", "content_suggestions_coordinator.h",
"content_suggestions_coordinator.mm", "content_suggestions_coordinator.mm",
"content_suggestions_favicon_mediator.h", "content_suggestions_favicon_mediator.h",
...@@ -105,11 +107,13 @@ source_set("constants") { ...@@ -105,11 +107,13 @@ source_set("constants") {
source_set("content_suggestions_ui") { source_set("content_suggestions_ui") {
sources = [ sources = [
"content_suggestions_action_handler.h",
"content_suggestions_collection_controlling.h", "content_suggestions_collection_controlling.h",
"content_suggestions_collection_synchronizing.h", "content_suggestions_collection_synchronizing.h",
"content_suggestions_collection_updater.h", "content_suggestions_collection_updater.h",
"content_suggestions_collection_updater.mm", "content_suggestions_collection_updater.mm",
"content_suggestions_commands.h", "content_suggestions_commands.h",
"content_suggestions_consumer.h",
"content_suggestions_data_sink.h", "content_suggestions_data_sink.h",
"content_suggestions_data_source.h", "content_suggestions_data_source.h",
"content_suggestions_header_controlling.h", "content_suggestions_header_controlling.h",
...@@ -143,6 +147,7 @@ source_set("content_suggestions_ui") { ...@@ -143,6 +147,7 @@ source_set("content_suggestions_ui") {
"resources:ntp_search_icon", "resources:ntp_search_icon",
"//base", "//base",
"//components/strings", "//components/strings",
"//ios/chrome/browser",
"//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/collection_view", "//ios/chrome/browser/ui/collection_view",
"//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/commands",
...@@ -162,6 +167,8 @@ source_set("content_suggestions_ui") { ...@@ -162,6 +167,8 @@ source_set("content_suggestions_ui") {
"//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/favicon", "//ios/chrome/common/ui/favicon",
"//ios/chrome/common/ui/util", "//ios/chrome/common/ui/util",
"//ios/public/provider/chrome/browser",
"//ios/public/provider/chrome/browser/discover_feed",
"//ios/web/common", "//ios/web/common",
"//ui/base", "//ui/base",
] ]
......
...@@ -53,6 +53,10 @@ ...@@ -53,6 +53,10 @@
@implementation ContentSuggestionsDiscoverCell @implementation ContentSuggestionsDiscoverCell
- (void)setDiscoverFeedView:(UIViewController*)discoverFeed { - (void)setDiscoverFeedView:(UIViewController*)discoverFeed {
if (_discoverFeed == discoverFeed) {
return;
}
[_discoverFeed.view removeFromSuperview];
_discoverFeed = discoverFeed; _discoverFeed = discoverFeed;
if (discoverFeed) { if (discoverFeed) {
UIView* discoverView = discoverFeed.view; UIView* discoverView = discoverFeed.view;
...@@ -76,7 +80,8 @@ ...@@ -76,7 +80,8 @@
if (!self.discoverFeed) { if (!self.discoverFeed) {
return 0; return 0;
} }
// TODO(crbug.com/1092900): Make this more robust. Will require
// the provider to expose the feed as a UICollectionViewController.
for (UIView* view in self.discoverFeed.view.subviews) { for (UIView* view in self.discoverFeed.view.subviews) {
if ([view isKindOfClass:[UICollectionView class]]) { if ([view isKindOfClass:[UICollectionView class]]) {
feedView = static_cast<UICollectionView*>(view); feedView = static_cast<UICollectionView*>(view);
......
// Copyright 2020 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.
#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ACTION_HANDLER_H_
#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ACTION_HANDLER_H_
// Action handler protocol for the content suggestions view controller.
@protocol ContentSuggestionsActionHandler
// Paginates the Discover feed by appending a set of articles to
// the bottom of it.
- (void)loadMoreFeedArticles;
@end
#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_ACTION_HANDLER_H_
// Copyright 2020 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.
#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_CONSUMER_H_
// Consumer protocol for the content suggestions view controller.
@protocol ContentSuggestionsConsumer
// Notifies the consumer to set the content suggestions enabled
// based on the user setting.
- (void)setContentSuggestionsEnabled:(BOOL)enabled;
@end
#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_CONSUMER_H_
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_action_handler.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.h"
...@@ -70,6 +71,7 @@ ...@@ -70,6 +71,7 @@
#endif #endif
@interface ContentSuggestionsCoordinator () < @interface ContentSuggestionsCoordinator () <
ContentSuggestionsActionHandler,
ContentSuggestionsMenuProvider, ContentSuggestionsMenuProvider,
ContentSuggestionsViewControllerAudience, ContentSuggestionsViewControllerAudience,
DiscoverFeedDelegate, DiscoverFeedDelegate,
...@@ -99,6 +101,7 @@ ...@@ -99,6 +101,7 @@
// Delegate for handling Discover feed header UI changes. // Delegate for handling Discover feed header UI changes.
@property(nonatomic, weak) id<DiscoverFeedHeaderChanging> @property(nonatomic, weak) id<DiscoverFeedHeaderChanging>
discoverFeedHeaderDelegate; discoverFeedHeaderDelegate;
@property(nonatomic) CGFloat discoverFeedHeight;
@end @end
...@@ -215,12 +218,16 @@ ...@@ -215,12 +218,16 @@
self.browser->GetCommandDispatcher(), SnackbarCommands); self.browser->GetCommandDispatcher(), SnackbarCommands);
self.suggestionsViewController.dispatcher = dispatcher; self.suggestionsViewController.dispatcher = dispatcher;
self.suggestionsViewController.discoverFeedMenuHandler = self; self.suggestionsViewController.discoverFeedMenuHandler = self;
self.discoverFeedHeaderDelegate = self.discoverFeedHeaderDelegate =
self.suggestionsViewController.discoverFeedHeaderDelegate; self.suggestionsViewController.discoverFeedHeaderDelegate;
[self.discoverFeedHeaderDelegate [self.discoverFeedHeaderDelegate
changeDiscoverFeedHeaderVisibility:[self.contentSuggestionsVisible changeDiscoverFeedHeaderVisibility:[self.contentSuggestionsVisible
value]]; value]];
self.suggestionsViewController.contentSuggestionsEnabled =
prefs->FindPreference(prefs::kArticlesForYouEnabled);
self.suggestionsViewController.handler = self;
self.contentSuggestionsMediator.consumer = self.suggestionsViewController;
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
self.suggestionsViewController.menuProvider = self; self.suggestionsViewController.menuProvider = self;
...@@ -431,6 +438,26 @@ ...@@ -431,6 +438,26 @@
self.discoverFeedViewController; self.discoverFeedViewController;
} }
#pragma mark - ContentSuggestionsActionHandler
- (void)loadMoreFeedArticles {
CGFloat currentHeight = 0;
for (UIView* view in self.discoverFeedViewController.view.subviews) {
if ([view isKindOfClass:[UICollectionView class]]) {
UICollectionView* feedView = static_cast<UICollectionView*>(view);
currentHeight = feedView.contentSize.height;
}
}
// TODO(crbug.com/1085419): Track number of cards from protocol instead of
// height to determine whether or not we should fetch more cards.
if (currentHeight > self.discoverFeedHeight) {
ios::GetChromeBrowserProvider()
->GetDiscoverFeedProvider()
->LoadMoreFeedArticles();
self.discoverFeedHeight = currentHeight;
}
}
#pragma mark - Public methods #pragma mark - Public methods
- (UIView*)view { - (UIView*)view {
......
...@@ -28,6 +28,7 @@ class MostVisitedSites; ...@@ -28,6 +28,7 @@ class MostVisitedSites;
} }
@protocol ContentSuggestionsCommands; @protocol ContentSuggestionsCommands;
@protocol ContentSuggestionsConsumer;
@protocol ContentSuggestionsGestureCommands; @protocol ContentSuggestionsGestureCommands;
@protocol ContentSuggestionsHeaderProvider; @protocol ContentSuggestionsHeaderProvider;
@class ContentSuggestionIdentifier; @class ContentSuggestionIdentifier;
...@@ -79,6 +80,9 @@ class ReadingListModel; ...@@ -79,6 +80,9 @@ class ReadingListModel;
// Delegate used to communicate to communicate events to the DiscoverFeed. // Delegate used to communicate to communicate events to the DiscoverFeed.
@property(nonatomic, weak) id<DiscoverFeedDelegate> discoverFeedDelegate; @property(nonatomic, weak) id<DiscoverFeedDelegate> discoverFeedDelegate;
// The consumer for this mediator.
@property(nonatomic, weak) id<ContentSuggestionsConsumer> consumer;
// Disconnects the mediator. // Disconnects the mediator.
- (void)disconnect; - (void)disconnect;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h" #import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_category_wrapper.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_category_wrapper.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
...@@ -85,8 +86,8 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -85,8 +86,8 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
// Whether the contents section should be hidden completely. // Whether the contents section should be hidden completely.
// Don't use PrefBackedBoolean or PrefMember as this value needs to be checked // Don't use PrefBackedBoolean or PrefMember as this value needs to be checked
// when the Preference is updated. // when the Preference is updated.
@property(nullable, nonatomic, assign) @property(nonatomic, assign)
const PrefService::Preference* contentArticlesEnabled; const PrefService::Preference* contentSuggestionsEnabled;
// Most visited items from the MostVisitedSites service currently displayed. // Most visited items from the MostVisitedSites service currently displayed.
@property(nonatomic, strong) @property(nonatomic, strong)
NSMutableArray<ContentSuggestionsMostVisitedItem*>* mostVisitedItems; NSMutableArray<ContentSuggestionsMostVisitedItem*>* mostVisitedItems;
...@@ -155,7 +156,7 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -155,7 +156,7 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
discoverFeed:(UIViewController*)discoverFeed { discoverFeed:(UIViewController*)discoverFeed {
self = [super init]; self = [super init];
if (self) { if (self) {
_contentArticlesEnabled = _contentSuggestionsEnabled =
prefService->FindPreference(prefs::kArticlesForYouEnabled); prefService->FindPreference(prefs::kArticlesForYouEnabled);
_suggestionBridge = _suggestionBridge =
std::make_unique<ContentSuggestionsServiceBridge>(self, contentService); std::make_unique<ContentSuggestionsServiceBridge>(self, contentService);
...@@ -216,6 +217,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -216,6 +217,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
[self.dataSink reloadAllData]; [self.dataSink reloadAllData];
} }
- (void)setConsumer:(id<ContentSuggestionsConsumer>)consumer {
_consumer = consumer;
[self.consumer
setContentSuggestionsEnabled:self.contentSuggestionsEnabled->GetValue()
->GetBool()];
}
- (void)blockMostVisitedURL:(GURL)URL { - (void)blockMostVisitedURL:(GURL)URL {
_mostVisitedSites->AddOrRemoveBlacklistedUrl(URL, true); _mostVisitedSites->AddOrRemoveBlacklistedUrl(URL, true);
[self useFreshMostVisited]; [self useFreshMostVisited];
...@@ -275,7 +283,7 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -275,7 +283,7 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
// TODO(crbug.com/1105624): Observe the kArticlesForYouEnabled Pref in order // TODO(crbug.com/1105624): Observe the kArticlesForYouEnabled Pref in order
// to hide the DiscoverFeed section if the finch flag is enabled. // to hide the DiscoverFeed section if the finch flag is enabled.
if (IsDiscoverFeedEnabled() && if (IsDiscoverFeedEnabled() &&
self.contentArticlesEnabled->GetValue()->GetBool()) { self.contentSuggestionsEnabled->GetValue()->GetBool()) {
[sectionsInfo addObject:self.discoverSectionInfo]; [sectionsInfo addObject:self.discoverSectionInfo];
} }
...@@ -473,6 +481,9 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -473,6 +481,9 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
[self.dataSink section:sectionInfo isLoading:NO]; [self.dataSink section:sectionInfo isLoading:NO];
} }
} }
[self.consumer
setContentSuggestionsEnabled:self.contentSuggestionsEnabled->GetValue()
->GetBool()];
} }
- (void)contentSuggestionsService: - (void)contentSuggestionsService:
...@@ -687,13 +698,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -687,13 +698,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
// ntp_snippets doesn't differentiate between disabled vs collapsed, so if // ntp_snippets doesn't differentiate between disabled vs collapsed, so if
// the status is |CATEGORY_EXPLICITLY_DISABLED|, check the value of // the status is |CATEGORY_EXPLICITLY_DISABLED|, check the value of
// |contentArticlesEnabled|. // |contentSuggestionsEnabled|.
- (BOOL)isCategoryInitOrAvailable:(ntp_snippets::Category)category { - (BOOL)isCategoryInitOrAvailable:(ntp_snippets::Category)category {
ntp_snippets::CategoryStatus status = ntp_snippets::CategoryStatus status =
self.contentService->GetCategoryStatus(category); self.contentService->GetCategoryStatus(category);
if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) &&
status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED) status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED)
return self.contentArticlesEnabled->GetValue()->GetBool(); return self.contentSuggestionsEnabled->GetValue()->GetBool();
else else
return IsCategoryStatusInitOrAvailable( return IsCategoryStatusInitOrAvailable(
self.contentService->GetCategoryStatus(category)); self.contentService->GetCategoryStatus(category));
...@@ -701,13 +712,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4; ...@@ -701,13 +712,13 @@ const NSInteger kMaxNumMostVisitedTiles = 4;
// ntp_snippets doesn't differentiate between disabled vs collapsed, so if // ntp_snippets doesn't differentiate between disabled vs collapsed, so if
// the status is |CATEGORY_EXPLICITLY_DISABLED|, check the value of // the status is |CATEGORY_EXPLICITLY_DISABLED|, check the value of
// |contentArticlesEnabled|. // |contentSuggestionsEnabled|.
- (BOOL)isCategoryAvailable:(ntp_snippets::Category)category { - (BOOL)isCategoryAvailable:(ntp_snippets::Category)category {
ntp_snippets::CategoryStatus status = ntp_snippets::CategoryStatus status =
self.contentService->GetCategoryStatus(category); self.contentService->GetCategoryStatus(category);
if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) && if (category.IsKnownCategory(ntp_snippets::KnownCategories::ARTICLES) &&
status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED) { status == ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED) {
return self.contentArticlesEnabled->GetValue()->GetBool(); return self.contentSuggestionsEnabled->GetValue()->GetBool();
} else { } else {
return IsCategoryStatusAvailable( return IsCategoryStatusAvailable(
self.contentService->GetCategoryStatus(category)); self.contentService->GetCategoryStatus(category));
......
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
#import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_controlling.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_controlling.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h"
@class ContentSuggestionsSectionInformation; @class ContentSuggestionsSectionInformation;
@protocol ContentSuggestionsActionHandler;
@protocol ContentSuggestionsCommands; @protocol ContentSuggestionsCommands;
@protocol ContentSuggestionsDataSource; @protocol ContentSuggestionsDataSource;
@protocol ContentSuggestionsHeaderSynchronizing; @protocol ContentSuggestionsHeaderSynchronizing;
...@@ -29,7 +31,8 @@ extern NSString* const ...@@ -29,7 +31,8 @@ extern NSString* const
// CollectionViewController to display the suggestions items. // CollectionViewController to display the suggestions items.
@interface ContentSuggestionsViewController @interface ContentSuggestionsViewController
: CollectionViewController <ContentSuggestionsCollectionControlling> : CollectionViewController <ContentSuggestionsCollectionControlling,
ContentSuggestionsConsumer>
- (instancetype)initWithStyle:(CollectionViewControllerStyle)style - (instancetype)initWithStyle:(CollectionViewControllerStyle)style
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
...@@ -57,7 +60,10 @@ extern NSString* const ...@@ -57,7 +60,10 @@ extern NSString* const
discoverFeedHeaderDelegate; discoverFeedHeaderDelegate;
@property(nonatomic, weak) id<ContentSuggestionsMetricsRecording> @property(nonatomic, weak) id<ContentSuggestionsMetricsRecording>
metricsRecorder; metricsRecorder;
// Whether or not the contents section should be hidden completely.
@property(nonatomic, assign) BOOL contentSuggestionsEnabled;
// Delegate for handling actions relating to content suggestions.
@property(nonatomic, weak) id<ContentSuggestionsActionHandler> handler;
// Provider of menu configurations for the contentSuggestions component. // Provider of menu configurations for the contentSuggestions component.
@property(nonatomic, weak) id<ContentSuggestionsMenuProvider> menuProvider @property(nonatomic, weak) id<ContentSuggestionsMenuProvider> menuProvider
API_AVAILABLE(ios(13.0)); API_AVAILABLE(ios(13.0));
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h" #import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_action_handler.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizing.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizing.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_menu_provider.h"
...@@ -49,6 +51,8 @@ using CSCollectionViewItem = CollectionViewItem<SuggestedContent>; ...@@ -49,6 +51,8 @@ using CSCollectionViewItem = CollectionViewItem<SuggestedContent>;
const CGFloat kMostVisitedBottomMargin = 13; const CGFloat kMostVisitedBottomMargin = 13;
const CGFloat kCardBorderRadius = 11; const CGFloat kCardBorderRadius = 11;
const CGFloat kDiscoverFeedContentWith = 430; const CGFloat kDiscoverFeedContentWith = 430;
// Value representing offset from bottom of the page to trigger pagination.
const CGFloat kPaginationOffset = 100;
} }
NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix = NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix =
...@@ -643,6 +647,14 @@ NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix = ...@@ -643,6 +647,14 @@ NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix =
[self.headerSynchronizer updateFakeOmniboxOnCollectionScroll]; [self.headerSynchronizer updateFakeOmniboxOnCollectionScroll];
self.scrolledToTop = self.scrolledToTop =
scrollView.contentOffset.y >= [self.headerSynchronizer pinnedOffsetY]; scrollView.contentOffset.y >= [self.headerSynchronizer pinnedOffsetY];
if (IsDiscoverFeedEnabled() && self.contentSuggestionsEnabled) {
float scrollPosition =
scrollView.contentOffset.y + scrollView.frame.size.height;
if (scrollPosition >= scrollView.contentSize.height - kPaginationOffset) {
[self.handler loadMoreFeedArticles];
}
}
} }
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView*)scrollView { - (BOOL)scrollViewShouldScrollToTop:(UIScrollView*)scrollView {
...@@ -807,4 +819,10 @@ NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix = ...@@ -807,4 +819,10 @@ NSString* const kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix =
[self.discoverFeedMenuHandler openDiscoverFeedMenu:menuButton]; [self.discoverFeedMenuHandler openDiscoverFeedMenu:menuButton];
} }
#pragma mark - ContentSuggestionsConsumer
- (void)setContentSuggestionsEnabled:(BOOL)enabled {
_contentSuggestionsEnabled = enabled;
}
@end @end
...@@ -47,6 +47,8 @@ class DiscoverFeedProvider { ...@@ -47,6 +47,8 @@ class DiscoverFeedProvider {
// Methods to register or remove observers. // Methods to register or remove observers.
virtual void AddObserver(Observer* observer); virtual void AddObserver(Observer* observer);
virtual void RemoveObserver(Observer* observer); virtual void RemoveObserver(Observer* observer);
// Loads and appends the next set of articles in the feed.
virtual void LoadMoreFeedArticles();
}; };
#endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_DISCOVER_FEED_DISCOVER_FEED_PROVIDER_H_ #endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_DISCOVER_FEED_DISCOVER_FEED_PROVIDER_H_
...@@ -24,3 +24,4 @@ void DiscoverFeedProvider::RefreshFeedWithCompletion( ...@@ -24,3 +24,4 @@ void DiscoverFeedProvider::RefreshFeedWithCompletion(
void DiscoverFeedProvider::AddObserver(Observer* observer) {} void DiscoverFeedProvider::AddObserver(Observer* observer) {}
void DiscoverFeedProvider::RemoveObserver(Observer* observer) {} void DiscoverFeedProvider::RemoveObserver(Observer* observer) {}
void DiscoverFeedProvider::LoadMoreFeedArticles() {}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment