| 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 package org.chromium.chrome.browser.ntp.cards; | 5 package org.chromium.chrome.browser.ntp.cards; |
| 6 | 6 |
| 7 import org.chromium.base.Callback; | 7 import org.chromium.base.Callback; |
| 8 import org.chromium.base.Log; | 8 import org.chromium.base.Log; |
| 9 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
| 10 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver; | 10 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver; |
| 11 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; | 11 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; |
| 12 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; | 12 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; |
| 13 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnu
m; | 13 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnu
m; |
| 14 import org.chromium.chrome.browser.ntp.snippets.SectionHeader; | 14 import org.chromium.chrome.browser.ntp.snippets.SectionHeader; |
| 15 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; | 15 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; |
| 16 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; | 16 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; |
| 17 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; | 17 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; |
| 18 import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; | 18 import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; |
| 19 import org.chromium.chrome.browser.offlinepages.ClientId; | 19 import org.chromium.chrome.browser.offlinepages.ClientId; |
| 20 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; | 20 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; |
| 21 import org.chromium.chrome.browser.offlinepages.OfflinePageItem; | 21 import org.chromium.chrome.browser.offlinepages.OfflinePageItem; |
| 22 import org.chromium.chrome.browser.suggestions.SuggestionsRanker; |
| 22 | 23 |
| 23 import java.util.ArrayList; | 24 import java.util.ArrayList; |
| 24 import java.util.Iterator; | 25 import java.util.Iterator; |
| 25 import java.util.List; | 26 import java.util.List; |
| 26 | 27 |
| 27 /** | 28 /** |
| 28 * A group of suggestions, with a header, a status card, and a progress indicato
r. This is | 29 * A group of suggestions, with a header, a status card, and a progress indicato
r. This is |
| 29 * responsible for tracking whether its suggestions have been saved offline. | 30 * responsible for tracking whether its suggestions have been saved offline. |
| 30 */ | 31 */ |
| 31 public class SuggestionsSection extends InnerNode { | 32 public class SuggestionsSection extends InnerNode { |
| 32 private static final String TAG = "NtpCards"; | 33 private static final String TAG = "NtpCards"; |
| 33 | 34 |
| 34 private final Delegate mDelegate; | 35 private final Delegate mDelegate; |
| 35 private final SuggestionsCategoryInfo mCategoryInfo; | 36 private final SuggestionsCategoryInfo mCategoryInfo; |
| 36 private final OfflinePageBridge mOfflinePageBridge; | 37 private final OfflinePageBridge mOfflinePageBridge; |
| 38 private final SuggestionsRanker mSuggestionsRanker; |
| 37 | 39 |
| 38 // Children | 40 // Children |
| 39 private final SectionHeader mHeader; | 41 private final SectionHeader mHeader; |
| 40 private final SuggestionsList mSuggestionsList; | 42 private final SuggestionsList mSuggestionsList; |
| 41 private final StatusItem mStatus; | 43 private final StatusItem mStatus; |
| 42 private final ActionItem mMoreButton; | 44 private final ActionItem mMoreButton; |
| 43 private final ProgressItem mProgressIndicator; | 45 private final ProgressItem mProgressIndicator; |
| 44 | 46 |
| 45 private boolean mIsNtpDestroyed; | 47 private boolean mIsNtpDestroyed; |
| 46 | 48 |
| 47 // Keep track of impressions of the suggestions so that we replace only sugg
estions that | 49 // Keep track of impressions of the suggestions so that we replace only sugg
estions that |
| 48 // have not been impressed, yet. We keep track of the first suggestion separ
ately as the | 50 // have not been impressed, yet. We keep track of the first suggestion separ
ately as the |
| 49 // first is often impressed in the form of a peeking card and we still want
to be able to | 51 // first is often impressed in the form of a peeking card and we still want
to be able to |
| 50 // replace something in this case. | 52 // replace something in this case. |
| 51 private boolean mFirstSuggestionSeen; | 53 private boolean mFirstSuggestionSeen; |
| 52 private boolean mSubsequentSuggestionsSeen; | 54 private boolean mSubsequentSuggestionsSeen; |
| 53 | 55 |
| 54 /** | 56 /** |
| 55 * Delegate interface that allows dismissing this section without introducin
g | 57 * Delegate interface that allows dismissing this section without introducin
g |
| 56 * a circular dependency. | 58 * a circular dependency. |
| 57 */ | 59 */ |
| 58 public interface Delegate { | 60 public interface Delegate { |
| 59 void dismissSection(SuggestionsSection section); | 61 void dismissSection(SuggestionsSection section); |
| 60 } | 62 } |
| 61 | 63 |
| 62 public SuggestionsSection(Delegate delegate, NewTabPageManager manager, | 64 public SuggestionsSection(Delegate delegate, NewTabPageManager manager, |
| 63 OfflinePageBridge offlinePageBridge, SuggestionsCategoryInfo info) { | 65 SuggestionsRanker ranker, OfflinePageBridge offlinePageBridge, |
| 66 SuggestionsCategoryInfo info) { |
| 64 mDelegate = delegate; | 67 mDelegate = delegate; |
| 65 mCategoryInfo = info; | 68 mCategoryInfo = info; |
| 66 mOfflinePageBridge = offlinePageBridge; | 69 mOfflinePageBridge = offlinePageBridge; |
| 70 mSuggestionsRanker = ranker; |
| 67 | 71 |
| 68 mHeader = new SectionHeader(info.getTitle()); | 72 mHeader = new SectionHeader(info.getTitle()); |
| 69 mSuggestionsList = new SuggestionsList(manager, info); | 73 mSuggestionsList = new SuggestionsList(manager, info); |
| 70 mStatus = StatusItem.createNoSuggestionsItem(info); | 74 mStatus = StatusItem.createNoSuggestionsItem(info); |
| 71 mMoreButton = new ActionItem(this); | 75 mMoreButton = new ActionItem(this, ranker); |
| 72 mProgressIndicator = new ProgressItem(); | 76 mProgressIndicator = new ProgressItem(); |
| 73 addChildren(mHeader, mSuggestionsList, mStatus, mMoreButton, mProgressIn
dicator); | 77 addChildren(mHeader, mSuggestionsList, mStatus, mMoreButton, mProgressIn
dicator); |
| 74 | 78 |
| 75 setupOfflinePageBridgeObserver(manager); | 79 setupOfflinePageBridgeObserver(manager); |
| 76 refreshChildrenVisibility(); | 80 refreshChildrenVisibility(); |
| 77 } | 81 } |
| 78 | 82 |
| 79 private static class SuggestionsList extends ChildNode implements Iterable<S
nippetArticle> { | 83 private static class SuggestionsList extends ChildNode implements Iterable<S
nippetArticle> { |
| 80 private final List<SnippetArticle> mSuggestions = new ArrayList<>(); | 84 private final List<SnippetArticle> mSuggestions = new ArrayList<>(); |
| 81 private final NewTabPageManager mNewTabPageManager; | 85 private final NewTabPageManager mNewTabPageManager; |
| 82 private final SuggestionsCategoryInfo mCategoryInfo; | 86 private final SuggestionsCategoryInfo mCategoryInfo; |
| 83 private int mCategoryIndex; | |
| 84 | 87 |
| 85 public SuggestionsList(NewTabPageManager newTabPageManager, | 88 public SuggestionsList(NewTabPageManager newTabPageManager, |
| 86 SuggestionsCategoryInfo categoryInfo) { | 89 SuggestionsCategoryInfo categoryInfo) { |
| 87 mNewTabPageManager = newTabPageManager; | 90 mNewTabPageManager = newTabPageManager; |
| 88 mCategoryInfo = categoryInfo; | 91 mCategoryInfo = categoryInfo; |
| 89 } | 92 } |
| 90 | 93 |
| 91 public void setCategoryIndex(int categoryIndex) { | |
| 92 mCategoryIndex = categoryIndex; | |
| 93 } | |
| 94 | |
| 95 public int getCategoryIndex() { | |
| 96 return mCategoryIndex; | |
| 97 } | |
| 98 | |
| 99 @Override | 94 @Override |
| 100 public int getItemCount() { | 95 public int getItemCount() { |
| 101 return mSuggestions.size(); | 96 return mSuggestions.size(); |
| 102 } | 97 } |
| 103 | 98 |
| 104 @Override | 99 @Override |
| 105 @ItemViewType | 100 @ItemViewType |
| 106 public int getItemViewType(int position) { | 101 public int getItemViewType(int position) { |
| 107 checkIndex(position); | 102 checkIndex(position); |
| 108 return ItemViewType.SNIPPET; | 103 return ItemViewType.SNIPPET; |
| 109 } | 104 } |
| 110 | 105 |
| 111 @Override | 106 @Override |
| 112 public void onBindViewHolder( | 107 public void onBindViewHolder( |
| 113 NewTabPageViewHolder holder, int position, List<Object> payloads
) { | 108 NewTabPageViewHolder holder, int position, List<Object> payloads
) { |
| 114 checkIndex(position); | 109 checkIndex(position); |
| 115 assert holder instanceof SnippetArticleViewHolder; | 110 assert holder instanceof SnippetArticleViewHolder; |
| 116 ((SnippetArticleViewHolder) holder) | 111 ((SnippetArticleViewHolder) holder) |
| 117 .onBindViewHolder( | 112 .onBindViewHolder(getSuggestionAt(position), mCategoryInfo,
payloads); |
| 118 getSuggestionAt(position), mCategoryInfo, payloads,
mCategoryIndex); | |
| 119 } | 113 } |
| 120 | 114 |
| 121 @Override | 115 @Override |
| 122 public SnippetArticle getSuggestionAt(int position) { | 116 public SnippetArticle getSuggestionAt(int position) { |
| 123 return mSuggestions.get(position); | 117 return mSuggestions.get(position); |
| 124 } | 118 } |
| 125 | 119 |
| 126 @Override | 120 @Override |
| 127 public int getDismissSiblingPosDelta(int position) { | 121 public int getDismissSiblingPosDelta(int position) { |
| 128 checkIndex(position); | 122 checkIndex(position); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 Log.d(TAG, "setSuggestions: removing all suggestions"); | 346 Log.d(TAG, "setSuggestions: removing all suggestions"); |
| 353 mSuggestionsList.clear(); | 347 mSuggestionsList.clear(); |
| 354 } | 348 } |
| 355 } | 349 } |
| 356 | 350 |
| 357 mProgressIndicator.setVisible(SnippetsBridge.isCategoryLoading(status)); | 351 mProgressIndicator.setVisible(SnippetsBridge.isCategoryLoading(status)); |
| 358 | 352 |
| 359 mSuggestionsList.addAll(suggestions); | 353 mSuggestionsList.addAll(suggestions); |
| 360 | 354 |
| 361 for (SnippetArticle article : suggestions) { | 355 for (SnippetArticle article : suggestions) { |
| 356 mSuggestionsRanker.rankSuggestion(article); |
| 362 if (!article.requiresExactOfflinePage()) { | 357 if (!article.requiresExactOfflinePage()) { |
| 363 updateSnippetOfflineAvailability(article); | 358 updateSnippetOfflineAvailability(article); |
| 364 } | 359 } |
| 365 } | 360 } |
| 366 | 361 |
| 367 refreshChildrenVisibility(); | 362 refreshChildrenVisibility(); |
| 368 } | 363 } |
| 369 | 364 |
| 370 private void updateSnippetOfflineAvailability(final SnippetArticle article)
{ | 365 private void updateSnippetOfflineAvailability(final SnippetArticle article)
{ |
| 371 // This method is not applicable to articles for which the exact offline
id must specified. | 366 // This method is not applicable to articles for which the exact offline
id must specified. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 // The sibling of the status card is the more button when it exists, sho
uld be right below. | 424 // The sibling of the status card is the more button when it exists, sho
uld be right below. |
| 430 if (child == mStatus) return 1; | 425 if (child == mStatus) return 1; |
| 431 | 426 |
| 432 return 0; | 427 return 0; |
| 433 } | 428 } |
| 434 | 429 |
| 435 public SuggestionsCategoryInfo getCategoryInfo() { | 430 public SuggestionsCategoryInfo getCategoryInfo() { |
| 436 return mCategoryInfo; | 431 return mCategoryInfo; |
| 437 } | 432 } |
| 438 | 433 |
| 439 public int getCategoryIndex() { | |
| 440 return mSuggestionsList.getCategoryIndex(); | |
| 441 } | |
| 442 | |
| 443 public void setCategoryIndex(int categoryIndex) { | |
| 444 mSuggestionsList.setCategoryIndex(categoryIndex); | |
| 445 } | |
| 446 | |
| 447 public String getHeaderText() { | 434 public String getHeaderText() { |
| 448 return mHeader.getHeaderText(); | 435 return mHeader.getHeaderText(); |
| 449 } | 436 } |
| 450 | 437 |
| 451 /** | 438 /** |
| 452 * @return The progress indicator. | 439 * @return The progress indicator. |
| 453 */ | 440 */ |
| 454 @VisibleForTesting | 441 @VisibleForTesting |
| 455 ProgressItem getProgressItemForTesting() { | 442 ProgressItem getProgressItemForTesting() { |
| 456 return mProgressIndicator; | 443 return mProgressIndicator; |
| 457 } | 444 } |
| 458 | 445 |
| 459 @VisibleForTesting | 446 @VisibleForTesting |
| 460 ActionItem getActionItem() { | 447 ActionItem getActionItem() { |
| 461 return mMoreButton; | 448 return mMoreButton; |
| 462 } | 449 } |
| 463 | 450 |
| 464 @VisibleForTesting | 451 @VisibleForTesting |
| 465 StatusItem getStatusItem() { | 452 StatusItem getStatusItem() { |
| 466 return mStatus; | 453 return mStatus; |
| 467 } | 454 } |
| 468 } | 455 } |
| OLD | NEW |