| Index: components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
|
| diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..25b18e3d3421b0e69f400cddd2a8ce0afc1c93f4
|
| --- /dev/null
|
| +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
|
| @@ -0,0 +1,167 @@
|
| +// Copyright 2016 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.
|
| +
|
| +#include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h"
|
| +
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "components/bookmarks/browser/bookmark_model.h"
|
| +#include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h"
|
| +#include "components/ntp_snippets/content_suggestion.h"
|
| +
|
| +using bookmarks::BookmarkModel;
|
| +using bookmarks::BookmarkNode;
|
| +
|
| +namespace {
|
| +const int kMaxBookmarks = 10;
|
| +const int kMaxBookmarkAgeInDays = 42;
|
| +
|
| +base::Time GetThresholdTime() {
|
| + return base::Time::Now() - base::TimeDelta::FromDays(kMaxBookmarkAgeInDays);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace ntp_snippets {
|
| +
|
| +BookmarkSuggestionsProvider::BookmarkSuggestionsProvider(
|
| + bookmarks::BookmarkModel* bookmark_model)
|
| + : ContentSuggestionsProvider({ContentSuggestionsCategory::BOOKMARKS}),
|
| + category_status_(ContentSuggestionsCategoryStatus::AVAILABLE_LOADING),
|
| + observer_(nullptr),
|
| + bookmark_model_(bookmark_model),
|
| + fetch_requested_(false),
|
| + end_of_list_last_visit_date_(GetThresholdTime()) {
|
| + bookmark_model_->AddObserver(this);
|
| +}
|
| +
|
| +BookmarkSuggestionsProvider::~BookmarkSuggestionsProvider() {}
|
| +
|
| +// Inherited from KeyedService.
|
| +void BookmarkSuggestionsProvider::Shutdown() {
|
| + bookmark_model_->RemoveObserver(this);
|
| + category_status_ = ContentSuggestionsCategoryStatus::NOT_PROVIDED;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// Private methods
|
| +
|
| +void BookmarkSuggestionsProvider::SetObserver(
|
| + ContentSuggestionsProvider::Observer* observer) {
|
| + observer_ = observer;
|
| + if (observer)
|
| + FetchBookmarks();
|
| +}
|
| +
|
| +ContentSuggestionsCategoryStatus BookmarkSuggestionsProvider::GetCategoryStatus(
|
| + ContentSuggestionsCategory category) {
|
| + return category_status_;
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::DismissSuggestion(
|
| + const std::string& suggestion_id) {
|
| + // TODO(jkrcal): Implement blacklisting bookmarks until they are next visited.
|
| + // Then also implement ClearDismissedSuggestionsForDebugging.
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::FetchSuggestionImage(
|
| + const std::string& suggestion_id,
|
| + const ImageFetchedCallback& callback) {
|
| + callback.Run(suggestion_id, gfx::Image());
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::ClearCachedSuggestionsForDebugging() {
|
| + // Ignored.
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::ClearDismissedSuggestionsForDebugging() {
|
| + // TODO(jkrcal): Implement when discarded suggestions are supported.
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::BookmarkModelLoaded(
|
| + bookmarks::BookmarkModel* model,
|
| + bool ids_reassigned) {
|
| + DCHECK_EQ(bookmark_model_, model);
|
| + if (fetch_requested_) {
|
| + fetch_requested_ = false;
|
| + FetchBookmarksInternal();
|
| + }
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::OnWillChangeBookmarkMetaInfo(
|
| + BookmarkModel* model,
|
| + const BookmarkNode* node) {
|
| + // Store the last visit date of the node that is about to change.
|
| + node_to_change_last_visit_date_ = GetLastVisitDateForBookmark(node);
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::BookmarkMetaInfoChanged(
|
| + BookmarkModel* model,
|
| + const BookmarkNode* node) {
|
| + base::Time time = GetLastVisitDateForBookmark(node);
|
| + if (time == node_to_change_last_visit_date_ ||
|
| + time < end_of_list_last_visit_date_)
|
| + return;
|
| +
|
| + // Last visit date of a node has changed (and is relevant for the list), we
|
| + // should update the suggestions.
|
| + FetchBookmarks();
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::FetchBookmarksInternal() {
|
| + DCHECK(bookmark_model_->loaded());
|
| +
|
| + NotifyStatusChanged(ContentSuggestionsCategoryStatus::AVAILABLE);
|
| + if (!observer_)
|
| + return;
|
| +
|
| + std::vector<const BookmarkNode*> bookmarks = GetRecentlyVisitedBookmarks(
|
| + bookmark_model_, kMaxBookmarks, GetThresholdTime());
|
| +
|
| + std::vector<ContentSuggestion> suggestions;
|
| + for (const BookmarkNode* bookmark : bookmarks) {
|
| + ContentSuggestion suggestion(
|
| + MakeUniqueID(ContentSuggestionsCategory::BOOKMARKS,
|
| + bookmark->url().spec()),
|
| + bookmark->url());
|
| +
|
| + // TODO(jkrcal): keep it in UTF16 when ContentSuggestion title adapts to it.
|
| + suggestion.set_title(base::UTF16ToUTF8(bookmark->GetTitle()));
|
| + suggestion.set_snippet_text(std::string());
|
| + suggestion.set_publish_date(GetLastVisitDateForBookmark(bookmark));
|
| + suggestion.set_publisher_name(bookmark->url().host());
|
| + suggestions.emplace_back(std::move(suggestion));
|
| + }
|
| +
|
| + if (suggestions.empty())
|
| + end_of_list_last_visit_date_ = GetThresholdTime();
|
| + else
|
| + end_of_list_last_visit_date_ = suggestions.back().publish_date();
|
| +
|
| + observer_->OnNewSuggestions(ContentSuggestionsCategory::BOOKMARKS,
|
| + std::move(suggestions));
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::FetchBookmarks() {
|
| + if (bookmark_model_->loaded())
|
| + FetchBookmarksInternal();
|
| + else
|
| + fetch_requested_ = true;
|
| +}
|
| +
|
| +void BookmarkSuggestionsProvider::NotifyStatusChanged(
|
| + ContentSuggestionsCategoryStatus new_status) {
|
| + if (category_status_ == new_status)
|
| + return;
|
| + category_status_ = new_status;
|
| +
|
| + if (!observer_)
|
| + return;
|
| + observer_->OnCategoryStatusChanged(ContentSuggestionsCategory::BOOKMARKS,
|
| + new_status);
|
| +}
|
| +
|
| +} // namespace ntp_snippets
|
|
|