Commit e42c6371 authored by Matthew Jones's avatar Matthew Jones Committed by Commit Bot

Show contextual suggestions on reverse-scroll when available

This patch changes the behavior of EoC. When suggestions become
available, the content is not shown until the user scrolls down
the page and reverse scrolls back up. This means that it is possible
the user never sees the bottom sheet even when suggestions are
available.

Bug: 822948
Change-Id: I2f9f16b41469347163295d3d79e5a322d3666cfe
Reviewed-on: https://chromium-review.googlesource.com/982494
Commit-Queue: Matthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#546895}
parent 107e3067
......@@ -49,8 +49,8 @@ public class ContextualSuggestionsCoordinator {
mProfile = Profile.getLastUsedProfile().getOriginalProfile();
mModel = new ContextualSuggestionsModel();
mMediator = new ContextualSuggestionsMediator(
mActivity, mProfile, tabModelSelector, this, mModel);
mMediator = new ContextualSuggestionsMediator(mActivity, mProfile, tabModelSelector,
activity.getFullscreenManager(), this, mModel);
SuggestionsSource suggestionsSource = mMediator.getSuggestionsSource();
SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegateImpl(
......@@ -71,9 +71,10 @@ public class ContextualSuggestionsCoordinator {
}
/**
* Displays contextual suggestions in the {@link BottomSheet}.
* Preload the contextual suggestions in the {@link BottomSheet}; content won't actually be
* shown until {@link #showSuggestions()} is called.
*/
void displaySuggestions() {
void preloadSuggestionsInSheet() {
// TODO(twellington): Introduce another method that creates bottom sheet content with only
// a toolbar view when suggestions are fist available, and use this method to construct the
// content view when the sheet is opened.
......@@ -84,7 +85,21 @@ public class ContextualSuggestionsCoordinator {
mActivity.getWindowAndroid(), mActivity::closeContextMenu);
mBottomSheetContent = new ContextualSuggestionsBottomSheetContent(
mContentCoordinator, mToolbarCoordinator);
mBottomSheetController.requestShowContent(mBottomSheetContent, true);
// TODO(twellington): Handle the case where preload returns false.
mBottomSheetController.requestContentPreload(mBottomSheetContent);
}
/**
* Show the contextual suggestions in the {@link BottomSheet}.
* {@link #preloadSuggestionsInSheet()} must be called prior to calling this method.
*/
void showSuggestions() {
// #preloadSuggestionsInSheet will always be called before this method, regardless of
// whether content was actually put in the sheet (meaning mBottomSheetContent should never
// be null). If content is not successfully preloaded
// BottomSheetController#requestContentPreload will return false.
assert mBottomSheetContent != null;
mBottomSheetController.requestShowContent(mBottomSheetContent, false);
}
/** Removes contextual suggestions from the {@link BottomSheet}. */
......
......@@ -10,11 +10,14 @@ import android.text.TextUtils;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge;
import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.util.MathUtils;
import org.chromium.ui.widget.Toast;
import java.util.ArrayList;
......@@ -32,6 +35,9 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
private final ContextualSuggestionsModel mModel;
private final SnippetsBridge mBridge;
private final FetchHelper mFetchHelper;
private final ChromeFullscreenManager mFullscreenManager;
private boolean mDidSuggestionsShowForTab;
@Nullable
private String mCurrentRequestUrl;
......@@ -41,18 +47,45 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
* @param context The {@link Context} used to retrieve resources.
* @param profile The regular {@link Profile}.
* @param tabModelSelector The {@link TabModelSelector} for the containing activity.
* @param fullscreenManager The {@link ChromeFullscreenManager} to listen for browser controls
* events.
* @param coordinator The {@link ContextualSuggestionsCoordinator} for the component.
* @param model The {@link ContextualSuggestionsModel} for the component.
*/
ContextualSuggestionsMediator(Context context, Profile profile,
TabModelSelector tabModelSelector, ContextualSuggestionsCoordinator coordinator,
ContextualSuggestionsModel model) {
TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager,
ContextualSuggestionsCoordinator coordinator, ContextualSuggestionsModel model) {
mContext = context;
mCoordinator = coordinator;
mModel = model;
mFullscreenManager = fullscreenManager;
mBridge = new SnippetsBridge(Profile.getLastUsedProfile());
mFetchHelper = new FetchHelper(this, tabModelSelector);
fullscreenManager.addListener(new FullscreenListener() {
@Override
public void onContentOffsetChanged(float offset) {}
@Override
public void onControlsOffsetChanged(
float topOffset, float bottomOffset, boolean needsAnimate) {
// When the controls scroll completely off-screen, the suggestions are "shown" but
// remain hidden since their offset from the bottom of the screen is determined by
// the top controls.
if (!mDidSuggestionsShowForTab && mModel.hasSuggestions()
&& areBrowserControlsHidden()) {
mDidSuggestionsShowForTab = true;
mCoordinator.showSuggestions();
}
}
@Override
public void onToggleOverlayVideoMode(boolean enabled) {}
@Override
public void onBottomControlsHeightChanged(int bottomControlsHeight) {}
});
}
/**
......@@ -70,10 +103,17 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
mFetchHelper.destroy();
}
/**
* @return Whether the browser controls are currently completely hidden.
*/
private boolean areBrowserControlsHidden() {
return MathUtils.areFloatsEqual(-mFullscreenManager.getTopControlOffset(),
mFullscreenManager.getTopControlsHeight());
}
@Override
public void requestSuggestions(String url) {
mCurrentRequestUrl = url;
mBridge.fetchContextualSuggestions(url, (suggestions) -> {
// Avoiding double fetches causing suggestions for incorrect context.
if (!TextUtils.equals(url, mCurrentRequestUrl)) return;
......@@ -83,7 +123,10 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
.show();
if (suggestions.size() > 0) {
displaySuggestions(generateClusterList(suggestions), suggestions.get(0).mTitle);
preloadSuggestions(generateClusterList(suggestions), suggestions.get(0).mTitle);
// If the controls are already off-screen, show the suggestions immediately so they
// are available on reverse scroll.
if (areBrowserControlsHidden()) mCoordinator.showSuggestions();
}
});
}
......@@ -95,6 +138,7 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
private void clearSuggestions() {
// TODO(twellington): Does this signal need to go back to FetchHelper?
mDidSuggestionsShowForTab = false;
mModel.setClusterList(new ClusterList(Collections.emptyList()));
mModel.setCloseButtonOnClickListener(null);
mModel.setTitle(null);
......@@ -102,11 +146,11 @@ class ContextualSuggestionsMediator implements FetchHelper.Delegate {
mCurrentRequestUrl = "";
}
private void displaySuggestions(ClusterList clusters, String title) {
private void preloadSuggestions(ClusterList clusters, String title) {
mModel.setClusterList(clusters);
mModel.setCloseButtonOnClickListener(view -> { clearSuggestions(); });
mModel.setTitle(mContext.getString(R.string.contextual_suggestions_toolbar_title, title));
mCoordinator.displaySuggestions();
mCoordinator.preloadSuggestionsInSheet();
}
// TODO(twellington): Remove after clusters are returned from the backend.
......
......@@ -68,4 +68,11 @@ class ContextualSuggestionsModel extends PropertyObservable<PropertyKey> {
String getTitle() {
return mTitle;
}
/**
* @return Whether there are any suggestions to be shown.
*/
boolean hasSuggestions() {
return getClusterList().getItemCount() > 0;
}
}
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