blob: 04277f1d649399746049bd68e58077532317a5dc [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
#include "base/functional/callback.h"
#include "base/strings/escape.h"
#include "base/strings/stringprintf.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/history_clusters/history_clusters_metrics_logger.h"
#include "chrome/browser/history_clusters/history_clusters_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
#include "chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h"
#include "chrome/common/webui_url_constants.h"
#include "components/history_clusters/core/features.h"
#include "components/history_clusters/core/history_clusters_prefs.h"
#include "components/history_clusters/core/history_clusters_service.h"
#include "components/history_clusters/core/url_constants.h"
#include "components/omnibox/browser/actions/history_clusters_action.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
HistoryClustersSidePanelCoordinator::HistoryClustersSidePanelCoordinator(
Browser* browser)
: BrowserUserData<HistoryClustersSidePanelCoordinator>(*browser) {
pref_change_registrar_.Init(browser->profile()->GetPrefs());
base::RepeatingClosure callback(base::BindRepeating(
&HistoryClustersSidePanelCoordinator::OnHistoryClustersPreferenceChanged,
base::Unretained(this)));
pref_change_registrar_.Add(history_clusters::prefs::kVisible, callback);
}
HistoryClustersSidePanelCoordinator::~HistoryClustersSidePanelCoordinator() =
default;
// static
bool HistoryClustersSidePanelCoordinator::IsSupported(Profile* profile) {
auto* history_clusters_service =
HistoryClustersServiceFactory::GetForBrowserContext(profile);
return base::FeatureList::IsEnabled(history_clusters::kSidePanelJourneys) &&
history_clusters_service &&
history_clusters_service->IsJourneysEnabled() &&
!profile->IsIncognitoProfile() && !profile->IsGuestSession();
}
void HistoryClustersSidePanelCoordinator::CreateAndRegisterEntry(
SidePanelRegistry* global_registry) {
global_registry->Register(std::make_unique<SidePanelEntry>(
SidePanelEntry::Id::kHistoryClusters,
l10n_util::GetStringUTF16(IDS_HISTORY_CLUSTERS_JOURNEYS_TAB_LABEL),
ui::ImageModel::FromVectorIcon(kJourneysIcon, ui::kColorIcon,
/*icon_size=*/16),
base::BindRepeating(
&HistoryClustersSidePanelCoordinator::CreateHistoryClustersWebView,
base::Unretained(this)),
base::BindRepeating(
&HistoryClustersSidePanelCoordinator::GetOpenInNewTabURL,
base::Unretained(this))));
}
std::unique_ptr<views::View>
HistoryClustersSidePanelCoordinator::CreateHistoryClustersWebView() {
// Construct our URL including our initial query. Other ways of passing the
// initial query to the WebUI interface are mostly all racy.
std::string query_string = base::StringPrintf(
"initial_query=%s",
base::EscapeQueryParamValue(initial_query_, /*use_plus=*/false).c_str());
// Side Panel WebViews created from the omnibox have a non-empty query, and
// ones created from the toolbar have an empty query.
const auto created_from_omnibox = !initial_query_.empty();
// Clear the initial query, because this is a singleton, and we want to
// "consume" the initial query after we create a side panel with it.
initial_query_.clear();
GURL::Replacements replacements;
replacements.SetQueryStr(query_string);
const GURL url = GURL(chrome::kChromeUIHistoryClustersSidePanelURL)
.ReplaceComponents(replacements);
auto side_panel_ui =
std::make_unique<SidePanelWebUIViewT<HistoryClustersSidePanelUI>>(
base::RepeatingClosure(), base::RepeatingClosure(),
std::make_unique<BubbleContentsWrapperT<HistoryClustersSidePanelUI>>(
url, GetBrowser().profile(),
IDS_HISTORY_CLUSTERS_JOURNEYS_TAB_LABEL,
/*webui_resizes_host=*/false,
/*esc_closes_ui=*/false));
history_clusters_ui_ =
side_panel_ui->contents_wrapper()->GetWebUIController()->GetWeakPtr();
if (history_clusters_ui_) {
history_clusters_ui_->set_metrics_initial_state(
created_from_omnibox ? history_clusters::HistoryClustersInitialState::
kSidePanelFromOmnibox
: history_clusters::HistoryClustersInitialState::
kSidePanelFromToolbarButton);
}
return std::move(side_panel_ui);
}
void HistoryClustersSidePanelCoordinator::OnHistoryClustersPreferenceChanged() {
auto* browser = &GetBrowser();
auto* global_registry = BrowserView::GetBrowserViewForBrowser(browser)
->side_panel_coordinator()
->GetGlobalSidePanelRegistry();
if (browser->profile()->GetPrefs()->GetBoolean(
history_clusters::prefs::kVisible)) {
if (IsSupported(browser->profile())) {
HistoryClustersSidePanelCoordinator::GetOrCreateForBrowser(browser)
->CreateAndRegisterEntry(global_registry);
}
} else {
global_registry->Deregister(
SidePanelEntry::Key(SidePanelEntry::Id::kHistoryClusters));
}
}
bool HistoryClustersSidePanelCoordinator::Show(const std::string& query) {
auto* browser_view = BrowserView::GetBrowserViewForBrowser(&GetBrowser());
if (!browser_view)
return false;
if (history_clusters_ui_) {
history_clusters_ui_->SetQuery(query);
} else {
// If the WebUI hasn't been created yet, store it in a member, so that when
// it is created (by a different callsite) it receives the initial query.
initial_query_ = query;
}
if (auto* side_panel_coordinator = browser_view->side_panel_coordinator()) {
side_panel_coordinator->Show(SidePanelEntry::Id::kHistoryClusters);
}
return true;
}
GURL HistoryClustersSidePanelCoordinator::GetOpenInNewTabURL() const {
std::string query;
if (history_clusters_ui_)
query = history_clusters_ui_->GetLastQueryIssued();
return query.empty() ? GURL(history_clusters::kChromeUIHistoryClustersURL)
: history_clusters::GetFullJourneysUrlForQuery(query);
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(HistoryClustersSidePanelCoordinator);