Add ipfs page info bubble

This commit is contained in:
sergey
2021-03-30 07:17:40 +03:00
parent 7d31c912f1
commit 0945316ecf
11 changed files with 418 additions and 6 deletions
+1
View File
@@ -12,6 +12,7 @@ aggregate_vector_icons("brave_vector_icons") {
"brave_ads_close_button.icon",
"brave_ads_info.icon",
"download_unlock.icon",
"exclamation.icon",
"open_in_ipfs.icon",
"open_in_tor.icon",
"speedreader.icon",
+41
View File
@@ -0,0 +1,41 @@
CANVAS_DIMENSIONS, 24,
MOVE_TO, 20.48f, 20.49f,
CUBIC_TO, 18.22f, 22.75f, 15.2f, 24, 12, 24,
CUBIC_TO, 8.79f, 24, 5.78f, 22.75f, 3.51f, 20.49f,
CUBIC_TO, -1.17f, 15.81f, -1.17f, 8.19f, 3.51f, 3.52f,
CUBIC_TO, 5.78f, 1.25f, 8.79f, 0, 12, 0,
CUBIC_TO, 15.2f, 0, 18.22f, 1.25f, 20.48f, 3.52f,
CUBIC_TO, 22.75f, 5.78f, 24, 8.8f, 24, 12,
CUBIC_TO, 24, 15.21f, 22.75f, 18.22f, 20.48f, 20.49f,
CLOSE,
MOVE_TO, 19.07f, 4.93f,
CUBIC_TO, 17.18f, 3.04f, 14.67f, 2, 12, 2,
CUBIC_TO, 9.32f, 2, 6.81f, 3.04f, 4.92f, 4.93f,
CUBIC_TO, 1.02f, 8.83f, 1.02f, 15.17f, 4.92f, 19.07f,
CUBIC_TO, 6.81f, 20.96f, 9.32f, 22, 12, 22,
CUBIC_TO, 14.67f, 22, 17.18f, 20.96f, 19.07f, 19.07f,
CUBIC_TO, 20.96f, 17.18f, 22, 14.67f, 22, 12,
CUBIC_TO, 22, 9.33f, 20.96f, 6.82f, 19.07f, 4.93f,
CLOSE,
MOVE_TO, 14, 19,
H_LINE_TO, 10,
CUBIC_TO, 9.44f, 19, 9, 18.55f, 9, 18,
CUBIC_TO, 9, 17.45f, 9.44f, 17, 10, 17,
H_LINE_TO, 11,
V_LINE_TO, 13,
H_LINE_TO, 10,
CUBIC_TO, 9.44f, 13, 9, 12.55f, 9, 12,
CUBIC_TO, 9, 11.45f, 9.44f, 11, 10, 11,
H_LINE_TO, 12,
CUBIC_TO, 12.55f, 11, 13, 11.45f, 13, 12,
V_LINE_TO, 17,
H_LINE_TO, 14,
CUBIC_TO, 14.55f, 17, 15, 17.45f, 15, 18,
CUBIC_TO, 15, 18.55f, 14.55f, 19, 14, 19,
CLOSE,
MOVE_TO, 12, 9,
CUBIC_TO, 10.89f, 9, 10, 8.1f, 10, 7,
CUBIC_TO, 10, 5.9f, 10.89f, 5, 12, 5,
CUBIC_TO, 13.1f, 5, 14, 5.9f, 14, 7,
CUBIC_TO, 14, 8.1f, 13.1f, 9, 12, 9,
CLOSE
+2
View File
@@ -399,6 +399,8 @@ source_set("ui") {
if (ipfs_enabled) {
sources += [
"views/ipfs_page_info/ipfs_page_info_bubble_view.cc",
"views/ipfs_page_info/ipfs_page_info_bubble_view.h",
"views/location_bar/ipfs_location_view.cc",
"views/location_bar/ipfs_location_view.h",
]
@@ -0,0 +1,241 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/browser/ui/views/ipfs_page_info/ipfs_page_info_bubble_view.h"
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/i18n/rtl.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "brave/app/vector_icons/vector_icons.h"
#include "brave/components/ipfs/ipfs_constants.h"
#include "brave/components/ipfs/ipfs_utils.h"
#include "build/build_config.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "components/grit/brave_components_strings.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_manager.h"
#include "ui/views/metadata/metadata_impl_macros.h"
#include "url/gurl.h"
namespace {
const int kExclamationIconSize = 24;
const int kFirstRowHeight = 30;
const int kCommonMargins = 15;
const int kTextColumnWidth = 325;
const int kCornerRadius = 15;
// Bubble background color
const SkColor kBackgroundColor = SK_ColorWHITE;
// Adds a ColumnSet on |layout| with a single View column and padding columns
// on either side of it with |margin| width.
void AddColumnWithSideMargin(views::GridLayout* layout, int margin, int id) {
views::ColumnSet* column_set = layout->AddColumnSet(id);
column_set->AddPaddingColumn(views::GridLayout::kFixedSize, 0);
column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING,
1.0, views::GridLayout::ColumnSize::kUsePreferred, 0,
0);
column_set->AddPaddingColumn(views::GridLayout::kFixedSize, margin);
column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1.0,
views::GridLayout::ColumnSize::kUsePreferred, 0, 0);
column_set->AddPaddingColumn(views::GridLayout::kFixedSize, 0);
}
} // namespace
///////////////////////////////////////////////////////////////////////////////
// IpfsPageInfoBubbleView
////////////////////////////////////////////////////////////////////////////////
IpfsPageInfoBubbleView::IpfsPageInfoBubbleView(
views::View* anchor_view,
const gfx::Rect& anchor_rect,
gfx::NativeView parent_window,
content::WebContents* web_contents,
const GURL& url)
: BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
content::WebContentsObserver(web_contents) {
if (!ipfs::IsIPFSScheme(url)) {
NOTREACHED();
}
set_title_margins(
ChromeLayoutProvider::Get()->GetInsetsMetric(views::INSETS_DIALOG));
set_margins(gfx::Insets(kCommonMargins));
set_close_on_deactivate(true);
set_use_round_corners(true);
SetShowCloseButton(false);
set_color(kBackgroundColor);
SetButtons(ui::DIALOG_BUTTON_NONE);
set_parent_window(parent_window);
views::BubbleDialogDelegateView::CreateBubble(this);
views::GridLayout* layout =
SetLayoutManager(std::make_unique<views::GridLayout>());
const int label_column_status = 1;
AddColumnWithSideMargin(layout, kCommonMargins, label_column_status);
layout->StartRow(views::GridLayout::kFixedSize, label_column_status,
kFirstRowHeight);
AddExclamationIcon(layout);
AddTitleLabel(layout);
layout->StartRow(views::GridLayout::kFixedSize, label_column_status);
FillEmptyCell(layout);
AddBodyText(layout);
GetBubbleFrameView()->SetCornerRadius(kCornerRadius);
SizeToContents();
}
IpfsPageInfoBubbleView::~IpfsPageInfoBubbleView() {}
BEGIN_METADATA(IpfsPageInfoBubbleView, views::BubbleDialogDelegateView)
END_METADATA
void IpfsPageInfoBubbleView::FillEmptyCell(views::GridLayout* layout) {
auto flex = std::make_unique<View>();
flex->SetLayoutManager(std::make_unique<views::FlexLayout>())
->SetOrientation(views::LayoutOrientation::kHorizontal);
layout->AddView(std::move(flex), 1.0, 1.0, views::GridLayout::CENTER,
views::GridLayout::CENTER);
}
void IpfsPageInfoBubbleView::AddExclamationIcon(views::GridLayout* layout) {
gfx::ImageSkia image =
gfx::CreateVectorIcon(kExclamationIcon, kExclamationIconSize,
GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_DefaultIconColor));
std::unique_ptr<views::ImageView> icon_view(new views::ImageView());
icon_view->SetImage(image);
icon_view->SetHorizontalAlignment(views::ImageView::Alignment::kLeading);
layout->AddView(std::move(icon_view), 1.0, 1.0, views::GridLayout::CENTER,
views::GridLayout::CENTER);
}
void IpfsPageInfoBubbleView::AddTitleLabel(views::GridLayout* layout) {
auto title_label = std::make_unique<views::StyledLabel>();
const base::string16 protocol =
l10n_util::GetStringUTF16(IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_IPFS_PROTOCOL);
size_t offset = 0;
const base::string16 text = l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_IPFS_BUBBLE_TITTLE, protocol, &offset);
title_label->SetText(text);
views::StyledLabel::RangeStyleInfo title_style;
gfx::Range title_details(0, offset);
title_label->AddStyleRange(title_details, title_style);
gfx::Range settings_details(offset, text.length());
views::StyledLabel::RangeStyleInfo bold_style;
bold_style.text_style = STYLE_EMPHASIZED_SECONDARY;
title_label->AddStyleRange(settings_details, bold_style);
layout->AddView(std::move(title_label), 2.0, 1.0, views::GridLayout::LEADING,
views::GridLayout::CENTER);
}
void IpfsPageInfoBubbleView::AddBodyText(views::GridLayout* layout) {
std::vector<size_t> offsets;
const base::string16 learn_more_text =
l10n_util::GetStringUTF16(IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_LEARN_MORE);
const base::string16 settings_text =
l10n_util::GetStringUTF16(IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_IPFS_SETTINGS);
const base::string16 explanation_text = l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_IPFS_BUBBLE_TEXT, learn_more_text, settings_text, &offsets);
auto body_text = std::make_unique<views::StyledLabel>();
body_text->SetText(explanation_text);
body_text->AddStyleRange(
gfx::Range(offsets[0], offsets[0] + learn_more_text.size()),
views::StyledLabel::RangeStyleInfo::CreateForLink(base::BindRepeating(
&IpfsPageInfoBubbleView::LearnMoreClicked, base::Unretained(this))));
body_text->AddStyleRange(
gfx::Range(offsets[1], offsets[1] + settings_text.size()),
views::StyledLabel::RangeStyleInfo::CreateForLink(
base::BindRepeating(&IpfsPageInfoBubbleView::SettingsLinkClicked,
base::Unretained(this))));
body_text->SizeToFit(kTextColumnWidth);
layout->AddView(std::move(body_text), 2.0, 1.0, views::GridLayout::LEADING,
views::GridLayout::CENTER);
}
void IpfsPageInfoBubbleView::SettingsLinkClicked(const ui::Event& event) {
web_contents()->OpenURL(content::OpenURLParams(
GURL(ipfs::kIPFSSettingsURL), content::Referrer(),
ui::DispositionFromEventFlags(event.flags(),
WindowOpenDisposition::NEW_FOREGROUND_TAB),
ui::PAGE_TRANSITION_LINK, false));
}
void IpfsPageInfoBubbleView::LearnMoreClicked(const ui::Event& event) {
web_contents()->OpenURL(content::OpenURLParams(
GURL(ipfs::kIPFSLearnMoreURL), content::Referrer(),
ui::DispositionFromEventFlags(event.flags(),
WindowOpenDisposition::NEW_FOREGROUND_TAB),
ui::PAGE_TRANSITION_LINK, false));
}
// static
views::BubbleDialogDelegateView* IpfsPageInfoBubbleView::CreatePageInfoBubble(
views::View* anchor_view,
const gfx::Rect& anchor_rect,
gfx::NativeWindow parent_window,
Profile* profile,
content::WebContents* web_contents,
const GURL& url,
PageInfoClosingCallback closing_callback) {
gfx::NativeView parent_view = platform_util::GetViewForWindow(parent_window);
return new IpfsPageInfoBubbleView(anchor_view, anchor_rect, parent_view,
web_contents, url);
}
// WebContentsObserver:
void IpfsPageInfoBubbleView::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
if (render_frame_host == web_contents()->GetMainFrame()) {
GetWidget()->Close();
}
}
void IpfsPageInfoBubbleView::OnVisibilityChanged(
content::Visibility visibility) {
if (visibility == content::Visibility::HIDDEN)
GetWidget()->Close();
}
void IpfsPageInfoBubbleView::DidStartNavigation(
content::NavigationHandle* handle) {
if (handle->IsInMainFrame())
GetWidget()->Close();
}
void IpfsPageInfoBubbleView::DidChangeVisibleSecurityState() {
// Subclasses may update instead, but this the only safe general option.
GetWidget()->Close();
}
@@ -0,0 +1,84 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_BROWSER_UI_VIEWS_IPFS_PAGE_INFO_IPFS_PAGE_INFO_BUBBLE_VIEW_H_
#define BRAVE_BROWSER_UI_VIEWS_IPFS_PAGE_INFO_IPFS_PAGE_INFO_BUBBLE_VIEW_H_
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/reputation/safety_tip_ui.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/views/bubble_anchor_util_views.h"
#include "chrome/browser/ui/views/hover_button.h"
#include "chrome/browser/ui/views/page_info/chosen_object_view_observer.h"
#include "chrome/browser/ui/views/page_info/page_info_bubble_view_base.h"
#include "chrome/browser/ui/views/page_info/page_info_hover_button.h"
#include "chrome/browser/ui/views/page_info/permission_selector_row.h"
#include "chrome/browser/ui/views/page_info/permission_selector_row_observer.h"
#include "components/page_info/page_info_ui.h"
#include "components/safe_browsing/buildflags.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/widget/widget.h"
class GURL;
class Profile;
namespace content {
class WebContents;
} // namespace content
namespace views {
class View;
class ImageView;
class StyledLabel;
} // namespace views
// The IpfsPageInfoBubbleView shows information about IPFS pages.
class IpfsPageInfoBubbleView : public views::BubbleDialogDelegateView,
public content::WebContentsObserver {
public:
METADATA_HEADER(IpfsPageInfoBubbleView);
// If |anchor_view| is nullptr, or has no Widget, |parent_window| may be
// provided to ensure this bubble is closed when the parent closes.
IpfsPageInfoBubbleView(views::View* anchor_view,
const gfx::Rect& anchor_rect,
gfx::NativeView parent_window,
content::WebContents* web_contents,
const GURL& url);
IpfsPageInfoBubbleView(const IpfsPageInfoBubbleView&) = delete;
IpfsPageInfoBubbleView& operator=(const IpfsPageInfoBubbleView&) = delete;
~IpfsPageInfoBubbleView() override;
// WebContentsObserver:
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void OnVisibilityChanged(content::Visibility visibility) override;
void DidStartNavigation(content::NavigationHandle* handle) override;
void DidChangeVisibleSecurityState() override;
void SettingsLinkClicked(const ui::Event& event);
void LearnMoreClicked(const ui::Event& event);
static views::BubbleDialogDelegateView* CreatePageInfoBubble(
views::View* anchor_view,
const gfx::Rect& anchor_rect,
gfx::NativeWindow parent_window,
Profile* profile,
content::WebContents* web_contents,
const GURL& url,
PageInfoClosingCallback closing_callback);
private:
void FillEmptyCell(views::GridLayout* layout);
void AddTitleLabel(views::GridLayout* layout);
void AddBodyText(views::GridLayout* layout);
void AddExclamationIcon(views::GridLayout* layout);
};
#endif // BRAVE_BROWSER_UI_VIEWS_IPFS_PAGE_INFO_IPFS_PAGE_INFO_BUBBLE_VIEW_H_
@@ -13,8 +13,6 @@
#include "brave/browser/themes/brave_theme_service.h"
#include "brave/browser/ui/views/brave_actions/brave_actions_container.h"
#include "brave/browser/ui/views/toolbar/brave_toolbar_view.h"
#include "brave/components/ipfs/ipfs_constants.h"
#include "brave/components/ipfs/ipfs_utils.h"
#include "brave/grit/brave_theme_resources.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_service_factory.h"
@@ -22,7 +20,6 @@
#include "chrome/browser/ui/omnibox/omnibox_theme.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
#include "chrome/grit/chromium_strings.h"
#include "components/grit/brave_components_strings.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
@@ -37,7 +34,10 @@
#include "brave/browser/ui/views/location_bar/onion_location_view.h"
#endif
#if BUILDFLAG(IPFS_ENABLED)
#include "brave/browser/ui/views/ipfs_page_info/ipfs_page_info_bubble_view.h"
#include "brave/browser/ui/views/location_bar/ipfs_location_view.h"
#include "brave/components/ipfs/ipfs_constants.h"
#include "brave/components/ipfs/ipfs_utils.h"
#endif
namespace {
@@ -106,12 +106,39 @@ void BraveLocationBarView::Init() {
}
bool BraveLocationBarView::ShouldShowIPFSLocationView() const {
#if BUILDFLAG(IPFS_ENABLED)
const GURL& url = GetLocationBarModel()->GetURL();
if (!ipfs::IsIPFSScheme(url) || !ipfs::IsIpfsEnabled(profile_) ||
!ipfs::IsLocalGatewayConfigured(profile_))
return false;
return true;
#else
return false;
#endif
}
bool BraveLocationBarView::ShowPageInfoDialog() {
if (!ShouldShowIPFSLocationView())
return LocationBarView::ShowPageInfoDialog();
content::WebContents* contents = GetWebContents();
if (!contents)
return false;
content::NavigationEntry* entry = contents->GetController().GetVisibleEntry();
if (!entry)
return false;
DCHECK(GetWidget());
views::BubbleDialogDelegateView* bubble =
IpfsPageInfoBubbleView::CreatePageInfoBubble(
this, gfx::Rect(), GetWidget()->GetNativeWindow(), profile_, contents,
entry->GetVirtualURL(),
base::BindOnce(&LocationBarView::OnPageInfoBubbleClosed,
weak_factory_.GetWeakPtr()));
bubble->SetHighlightedButton(location_icon_view_);
bubble->GetWidget()->Show();
return true;
}
void BraveLocationBarView::Update(content::WebContents* contents) {
@@ -43,7 +43,7 @@ class BraveLocationBarView : public LocationBarView {
#endif
// LocationBarView:
std::vector<views::View*> GetTrailingViews() override;
bool ShowPageInfoDialog() override;
ui::ImageModel GetLocationIcon(LocationIconView::Delegate::IconFetchedCallback
on_icon_fetched) const override;
+1
View File
@@ -16,6 +16,7 @@ const char kIPFSScheme[] = "ipfs";
const char kIPNSScheme[] = "ipns";
const char kDefaultIPFSGateway[] = "https://dweb.link";
const char kDefaultIPFSLocalGateway[] = "http://localhost";
const char kIPFSSettingsURL[] = "brave://settings/ipfs";
const char kIPFSLearnMoreURL[] =
"https://support.brave.com/hc/en-us/sections/"
"360010974932-InterPlanetary-File-System-IPFS-";
+1
View File
@@ -18,6 +18,7 @@ extern const char kIPNSScheme[];
extern const char kDefaultIPFSGateway[];
extern const char kDefaultIPFSLocalGateway[];
extern const char kIPFSLearnMoreURL[];
extern const char kIPFSSettingsURL[];
extern const char kRepoStatsPath[];
extern const char kRepoStatsHumanReadableParamName[];
extern const char kRepoStatsHumanReadableParamValue[];
+1 -2
View File
@@ -32,7 +32,6 @@ namespace {
const char kResponseScript[] =
"window.postMessage({command: 'ipfs', value: {value}, text: '{text}'}, "
"'*')";
const char kBraveSettingsURL[] = "brave://settings/ipfs";
constexpr int kOnboardingIsolatedWorldId =
content::ISOLATED_WORLD_ID_CONTENT_END + 1;
@@ -204,7 +203,7 @@ void IPFSOnboardingPage::CommandReceived(const std::string& command) {
controller()->OpenUrlInNewForegroundTab(GURL(kIPFSLearnMoreURL));
break;
case IPFSOnboardingCommandId::OPEN_SETTINGS:
controller()->OpenUrlInNewForegroundTab(GURL(kBraveSettingsURL));
controller()->OpenUrlInNewForegroundTab(GURL(ipfs::kIPFSSettingsURL));
break;
default:
NOTREACHED() << "Unsupported command: " << command;
+15
View File
@@ -114,5 +114,20 @@
<message name="IDS_IPFS_ONBOARDING_INSTALLATION_ERROR" desc="Error message about installation error for IPFS interstitial page.">
Error ocurred during an update.
</message>
<message name="IDS_PAGE_INFO_IPFS_BUBBLE_TITTLE" desc="The title for ips page info bubble.">
This content was loaded over the <ph name="IPFS_SETTINGS">$1<ex>IPFS protocol</ex></ph>
</message>
<message name="IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_IPFS_PROTOCOL" desc="The IPFS Protocol text for ips page info bubble.">
IPFS protocol
</message>
<message name="IDS_PAGE_INFO_IPFS_BUBBLE_TEXT" desc="The text for ips page info bubble.">
InterPlanetary File System (IPFS) is a public network for peer-to-peer data storage and delivery. You can <ph name="LEARN_MORE">$1<ex>learn more</ex></ph> about Brave's integration or configure your <ph name="IPFS_SETTINGS">$2<ex>IPFS settings</ex></ph> at any time.
</message>
<message name="IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_LEARN_MORE" desc="The learn more text for ips page info bubble.">
learn more
</message>
<message name="IDS_PAGE_INFO_IPFS_BUBBLE_TEXT_IPFS_SETTINGS" desc="The IPFS Settings text for ips page info bubble.">
IPFS settings
</message>
</if>
</grit-part>