Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java |
index 8d33e3b076fac139eeea632f8cad57df8380ebf1..e28af52ddfbb3bf0a9630bb957537f837ef394a3 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java |
@@ -60,6 +60,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
private final List<ItemGroup> mGroups = new ArrayList<>(); |
private final AboveTheFoldItem mAboveTheFold = new AboveTheFoldItem(); |
private final SigninPromoItem mSigninPromo = new SigninPromoItem(); |
+ private final AllDismissedItem mAllDismissed = new AllDismissedItem(); |
private final Footer mFooter = new Footer(); |
private final SpacingItem mBottomSpacer = new SpacingItem(); |
@@ -136,14 +137,14 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
mAboveTheFoldView = aboveTheFoldView; |
mUiConfig = uiConfig; |
mSigninPromo.setObserver(this); |
- resetSections(); |
+ resetSections(/*alwaysAllowEmptySections=*/false); |
mNewTabPageManager.getSuggestionsSource().setObserver(this); |
mNewTabPageManager.registerSignInStateObserver(new SignInStateObserver() { |
@Override |
public void onSignedIn() { |
mSigninPromo.hide(); |
- resetSections(); |
+ resetSections(/*alwaysAllowEmptySections=*/false); |
} |
@Override |
@@ -153,12 +154,15 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
}); |
} |
- /** Resets the sections, reloading the whole new tab page content. */ |
- private void resetSections() { |
+ /** |
+ * Resets the sections, reloading the whole new tab page content. |
+ * @param alwaysAllowEmptySections Whether sections are always allowed to be displayed when |
+ * they are empty, even when they are normally not. |
+ */ |
+ public void resetSections(boolean alwaysAllowEmptySections) { |
mSections.clear(); |
SuggestionsSource suggestionsSource = mNewTabPageManager.getSuggestionsSource(); |
- |
int[] categories = suggestionsSource.getCategories(); |
int[] suggestionsPerCategory = new int[categories.length]; |
int i = 0; |
@@ -169,7 +173,8 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
|| categoryStatus == CategoryStatus.CATEGORY_EXPLICITLY_DISABLED) |
continue; |
- suggestionsPerCategory[i++] = resetSection(category, categoryStatus); |
+ suggestionsPerCategory[i++] = |
+ resetSection(category, categoryStatus, alwaysAllowEmptySections); |
} |
mNewTabPageManager.trackSnippetsPageImpression(categories, suggestionsPerCategory); |
@@ -177,17 +182,29 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
updateGroups(); |
} |
- private int resetSection(@CategoryInt int category, @CategoryStatusEnum int categoryStatus) { |
+ /** |
+ * Resets the section for {@code category}. Removes the section if there are no suggestions for |
+ * it and it is not allowed to be empty. Otherwise, creates the section if it is not present |
+ * yet. Sets the available suggestions on the section. |
+ * @param category The category for which the section must be reset. |
+ * @param categoryStatus The category status. |
+ * @param alwaysAllowEmptySections Whether sections are always allowed to be displayed when |
+ * they are empty, even when they are normally not. |
+ * @return The number of suggestions for the section. |
+ */ |
+ private int resetSection(@CategoryInt int category, @CategoryStatusEnum int categoryStatus, |
+ boolean alwaysAllowEmptySections) { |
SuggestionsSource suggestionsSource = mNewTabPageManager.getSuggestionsSource(); |
List<SnippetArticle> suggestions = suggestionsSource.getSuggestionsForCategory(category); |
- |
- // Create the new section. |
SuggestionsCategoryInfo info = suggestionsSource.getCategoryInfo(category); |
- if (suggestions.isEmpty() && !info.showIfEmpty()) { |
+ |
+ // Do not show an empty section if not allowed. |
+ if (suggestions.isEmpty() && !info.showIfEmpty() && !alwaysAllowEmptySections) { |
mSections.remove(category); |
return 0; |
} |
+ // Create the section if needed. |
SuggestionsSection section = mSections.get(category); |
if (section == null) { |
section = new SuggestionsSection(info, this); |
@@ -256,7 +273,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
return; |
case CategoryStatus.SIGNED_OUT: |
- resetSection(category, status); |
+ resetSection(category, status, /*alwaysAllowEmptySections=*/false); |
return; |
default: |
@@ -317,6 +334,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
return new Footer.ViewHolder(mRecyclerView, mNewTabPageManager); |
} |
+ if (viewType == NewTabPageItem.VIEW_TYPE_ALL_DISMISSED) { |
+ return new AllDismissedItem.ViewHolder(mRecyclerView, mNewTabPageManager, this); |
+ } |
+ |
return null; |
} |
@@ -349,7 +370,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
return RecyclerView.NO_POSITION; |
} |
- public int getLastContentItemPosition() { |
+ public int getFooterPosition() { |
return getGroupPositionOffset(mFooter); |
} |
@@ -392,11 +413,11 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
mGroups.add(mAboveTheFold); |
mGroups.addAll(mSections.values()); |
mGroups.add(mSigninPromo); |
- if (hasVisibleBelowTheFoldItems()) { |
- mGroups.add(mFooter); |
- mGroups.add(mBottomSpacer); |
- } |
+ mGroups.add(hasAllBeenDismissed() ? mAllDismissed : mFooter); |
+ mGroups.add(mBottomSpacer); |
+ // TODO(mvanouwerkerk): Notify about the subset of changed items. At least |mAboveTheFold| |
+ // has not changed when refreshing from the all dismissed state. |
notifyDataSetChanged(); |
} |
@@ -404,17 +425,15 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
mSections.remove(section.getCategory()); |
int startPos = getGroupPositionOffset(section); |
mGroups.remove(section); |
- int removedItems = section.getItems().size(); |
- |
- notifyItemRangeRemoved(startPos, removedItems); |
+ notifyItemRangeRemoved(startPos, section.getItems().size()); |
- if (!hasVisibleBelowTheFoldItems()) { |
- mGroups.remove(mFooter); |
- mGroups.remove(mBottomSpacer); |
- notifyItemRangeRemoved(startPos + removedItems, 2); |
- } else { |
- notifyItemChanged(getItems().size() - 1); // Refresh the spacer too. |
+ if (hasAllBeenDismissed()) { |
+ int footerPosition = getFooterPosition(); |
+ mGroups.set(mGroups.indexOf(mFooter), mAllDismissed); |
+ notifyItemChanged(footerPosition); |
} |
+ |
+ notifyItemChanged(getBottomSpacerPosition()); |
} |
@Override |
@@ -518,11 +537,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
// TODO(dgn): accessibility announcement. |
mSigninPromo.dismiss(); |
- if (!hasVisibleBelowTheFoldItems()) { |
- int footerPosition = getLastContentItemPosition(); |
- mGroups.remove(mFooter); |
- mGroups.remove(mBottomSpacer); |
- notifyItemRangeRemoved(footerPosition, 2); |
+ if (hasAllBeenDismissed()) { |
+ int footerPosition = getFooterPosition(); |
+ mGroups.set(mGroups.indexOf(mFooter), mAllDismissed); |
+ notifyItemChanged(footerPosition); |
} |
} |
@@ -553,8 +571,8 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> |
return mRecyclerView.findViewHolderForAdapterPosition(siblingPosDelta + swipePos); |
} |
- private boolean hasVisibleBelowTheFoldItems() { |
- return !mSections.isEmpty() || mSigninPromo.isShown(); |
+ private boolean hasAllBeenDismissed() { |
+ return mSections.isEmpty() && !mSigninPromo.isShown(); |
} |
@VisibleForTesting |