Skip to content

Commit

Permalink
Introduce IPFS promo infobar
Browse files Browse the repository at this point in the history
  • Loading branch information
cypt4 committed Aug 8, 2023
1 parent fd839ac commit d3b30ea
Show file tree
Hide file tree
Showing 18 changed files with 764 additions and 43 deletions.
15 changes: 15 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,21 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
<message name="IDS_BRAVE_IPFS_LEARN_MORE">
Learn more about IPFS and privacy
</message>
<message name="IDS_BRAVE_IPFS_INFOBAR_TEXT" desc="Text that promotes turning on autoredirect to the configured gateway setting">
Would you like to handle content-addressed resources with native IPFS support (ipfs:// and ipns://) built into Brave?
</message>
<message name="IDS_BRAVE_IPFS_INFOBAR_APPROVE" desc="Turns on promoted setting">
Always
</message>
<message name="IDS_BRAVE_IPFS_INFOBAR_APPROVE_ONCE" desc="Redirects to the ipfs:// or ipns:// resource for once">
Only This Time
</message>
<message name="IDS_BRAVE_IPFS_INFOBAR_NEVER" desc="Closed infobar and disables it showing">
No Thanks
</message>
<message name="IDS_BRAVE_IPFS_INFOBAR_LINK" desc="Link redirects to the privacy description article">
Learn how this affects my privacy
</message>

<!-- Brave Wayback Machine -->
<message name="IDS_BRAVE_WAYBACK_MACHINE_INFOBAR_PAGE_MISSING_TEXT" desc="The label for sorry message when page is not available on infobar">
Expand Down
145 changes: 145 additions & 0 deletions browser/infobars/brave_ipfs_infobar_delegate.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/. */

#include "brave/browser/infobars/brave_ipfs_infobar_delegate.h"

#include <algorithm>
#include <utility>

#include "brave/browser/ui/views/infobars/brave_confirm_infobar.h"
#include "brave/components/ipfs/ipfs_constants.h"
#include "brave/components/ipfs/pref_names.h"
#include "brave/components/l10n/common/localization_util.h"
#include "brave/grit/brave_generated_resources.h"
#include "components/infobars/core/infobar.h"
#include "components/prefs/pref_service.h"
#include "ui/views/vector_icons.h"

// BraveIPFSInfoBarDelegateObserver
BraveIPFSInfoBarDelegateObserver::BraveIPFSInfoBarDelegateObserver() {}

BraveIPFSInfoBarDelegateObserver::~BraveIPFSInfoBarDelegateObserver() {}

// BraveIPFSInfoBarDelegate
// static
void BraveIPFSInfoBarDelegate::Create(
infobars::ContentInfoBarManager* infobar_manager,
std::unique_ptr<BraveIPFSInfoBarDelegateObserver> observer,
PrefService* local_state) {
if (!local_state->GetBoolean(kShowIPFSPromoInfobar)) {
return;
}
infobar_manager->AddInfoBar(std::make_unique<BraveConfirmInfoBar>(
std::make_unique<BraveIPFSInfoBarDelegate>(
std::move(observer), local_state)),
true);
}

BraveIPFSInfoBarDelegate::BraveIPFSInfoBarDelegate(
std::unique_ptr<BraveIPFSInfoBarDelegateObserver> observer,
PrefService* local_state)
: observer_(std::move(observer)), local_state_(local_state) {}

BraveIPFSInfoBarDelegate::~BraveIPFSInfoBarDelegate() {}

// BraveConfirmInfoBarDelegate
bool BraveIPFSInfoBarDelegate::HasCheckbox() const {
return false;
}

std::u16string BraveIPFSInfoBarDelegate::GetCheckboxText() const {
NOTREACHED();
return std::u16string();
}

void BraveIPFSInfoBarDelegate::SetCheckboxChecked(bool checked) {
NOTREACHED();
}

bool BraveIPFSInfoBarDelegate::InterceptClosing() {
return false;
}

// ConfirmInfoBarDelegate
infobars::InfoBarDelegate::InfoBarIdentifier
BraveIPFSInfoBarDelegate::GetIdentifier() const {
return BRAVE_IPFS_INFOBAR_DELEGATE;
}

const gfx::VectorIcon& BraveIPFSInfoBarDelegate::GetVectorIcon() const {
return views::kInfoIcon;
}

bool BraveIPFSInfoBarDelegate::ShouldExpire(
const NavigationDetails& details) const {
return details.is_navigation_to_different_page;
}

void BraveIPFSInfoBarDelegate::InfoBarDismissed() {}

std::u16string BraveIPFSInfoBarDelegate::GetMessageText() const {
return brave_l10n::GetLocalizedResourceUTF16String(
IDS_BRAVE_IPFS_INFOBAR_TEXT);
}

int BraveIPFSInfoBarDelegate::GetButtons() const {
return BUTTON_OK | BUTTON_CANCEL | BUTTON_EXTRA;
}

bool BraveIPFSInfoBarDelegate::IsProminent(int id) const {
return id == BUTTON_OK || id == BUTTON_EXTRA;
}

std::u16string BraveIPFSInfoBarDelegate::GetButtonLabel(
InfoBarButton button) const {
switch (button) {
case InfoBarButton::BUTTON_OK:
return brave_l10n::GetLocalizedResourceUTF16String(
IDS_BRAVE_IPFS_INFOBAR_APPROVE);
case InfoBarButton::BUTTON_EXTRA:
return brave_l10n::GetLocalizedResourceUTF16String(
IDS_BRAVE_IPFS_INFOBAR_APPROVE_ONCE);
case InfoBarButton::BUTTON_CANCEL:
return brave_l10n::GetLocalizedResourceUTF16String(
IDS_BRAVE_IPFS_INFOBAR_NEVER);
default:
NOTREACHED();
}
return std::u16string();
}

std::vector<int> BraveIPFSInfoBarDelegate::GetButtonsOrder() const {
return {InfoBarButton::BUTTON_OK, InfoBarButton::BUTTON_EXTRA,
InfoBarButton::BUTTON_CANCEL};
}

std::u16string BraveIPFSInfoBarDelegate::GetLinkText() const {
return brave_l10n::GetLocalizedResourceUTF16String(
IDS_BRAVE_IPFS_INFOBAR_LINK);
}

GURL BraveIPFSInfoBarDelegate::GetLinkURL() const {
return GURL(ipfs::kIPFSLearnMorePrivacyURL);
}

bool BraveIPFSInfoBarDelegate::Accept() {
if (observer_) {
local_state_->SetBoolean(kShowIPFSPromoInfobar, false);
observer_->OnRedirectToIPFS(true);
}
return true;
}

bool BraveIPFSInfoBarDelegate::ExtraButtonPressed() {
if (observer_) {
observer_->OnRedirectToIPFS(false);
}
return true;
}

bool BraveIPFSInfoBarDelegate::Cancel() {
local_state_->SetBoolean(kShowIPFSPromoInfobar, false);
return true;
}
73 changes: 73 additions & 0 deletions browser/infobars/brave_ipfs_infobar_delegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_BROWSER_INFOBARS_BRAVE_IPFS_INFOBAR_DELEGATE_H_
#define BRAVE_BROWSER_INFOBARS_BRAVE_IPFS_INFOBAR_DELEGATE_H_

#include <memory>
#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/raw_ptr.h"
#include "brave/components/infobars/core/brave_confirm_infobar_delegate.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "url/gurl.h"

class PrefService;

namespace infobars {
class ContentInfoBarManager;
} // namespace infobars

class BraveIPFSInfoBarDelegateObserver {
public:
BraveIPFSInfoBarDelegateObserver();
virtual ~BraveIPFSInfoBarDelegateObserver();
virtual void OnRedirectToIPFS(bool remember) = 0;
};

class BraveIPFSInfoBarDelegate : public BraveConfirmInfoBarDelegate {
public:
BraveIPFSInfoBarDelegate(const BraveIPFSInfoBarDelegate&) = delete;
BraveIPFSInfoBarDelegate& operator=(const BraveIPFSInfoBarDelegate&) = delete;

BraveIPFSInfoBarDelegate(
std::unique_ptr<BraveIPFSInfoBarDelegateObserver> observer_,
PrefService* local_state);
~BraveIPFSInfoBarDelegate() override;

static void Create(infobars::ContentInfoBarManager* infobar_manager,
std::unique_ptr<BraveIPFSInfoBarDelegateObserver> observer,
PrefService* local_state);

private:
// BraveConfirmInfoBarDelegate
bool HasCheckbox() const override;
std::u16string GetCheckboxText() const override;
void SetCheckboxChecked(bool checked) override;
bool InterceptClosing() override;

// ConfirmInfoBarDelegate
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
const gfx::VectorIcon& GetVectorIcon() const override;
bool ShouldExpire(const NavigationDetails& details) const override;
void InfoBarDismissed() override;
std::u16string GetMessageText() const override;
int GetButtons() const override;
std::vector<int> GetButtonsOrder() const override;
bool IsProminent(int id) const override;
std::u16string GetButtonLabel(InfoBarButton button) const override;
std::u16string GetLinkText() const override;
GURL GetLinkURL() const override;

bool Accept() override;
bool Cancel() override;
bool ExtraButtonPressed() override;

std::unique_ptr<BraveIPFSInfoBarDelegateObserver> observer_;
raw_ptr<PrefService> local_state_ = nullptr;
};

#endif // BRAVE_BROWSER_INFOBARS_BRAVE_IPFS_INFOBAR_DELEGATE_H_
10 changes: 10 additions & 0 deletions browser/infobars/sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ if (!is_android) {
"//brave/components/ipfs",
"//components/user_prefs",
]
if (!is_android) {
brave_browser_infobar_sources += [
"//brave/browser/infobars/brave_ipfs_infobar_delegate.cc",
"//brave/browser/infobars/brave_ipfs_infobar_delegate.h",
]
brave_browser_infobar_deps += [
"//brave/browser/ui/views/infobars:infobars",
"//brave/components/infobars/core:core",
]
}
}

if (enable_brave_wayback_machine) {
Expand Down
45 changes: 45 additions & 0 deletions browser/ipfs/ipfs_tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "brave/components/ipfs/ipfs_constants.h"
#include "brave/components/ipfs/ipfs_utils.h"
#include "brave/components/ipfs/pref_names.h"
#include "build/buildflag.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/channel_info.h"
Expand All @@ -28,6 +29,10 @@
#include "net/http/http_status_code.h"
#include "url/origin.h"

#if !BUILDFLAG(IS_ANDROID)
#include "brave/browser/infobars/brave_ipfs_infobar_delegate.h"
#endif

namespace {

// We have to check both domain and _dnslink.domain
Expand Down Expand Up @@ -62,6 +67,32 @@ void SetupIPFSProtocolHandler(const std::string& protocol) {

namespace ipfs {

#if !BUILDFLAG(IS_ANDROID)
class BraveIPFSInfoBarDelegateObserverImpl
: public BraveIPFSInfoBarDelegateObserver {
public:
BraveIPFSInfoBarDelegateObserverImpl(
base::WeakPtr<IPFSTabHelper> ipfs_tab_helper)
: ipfs_tab_helper_(ipfs_tab_helper) {}

void OnRedirectToIPFS(bool enable_gateway_autoredirect) override {
if (ipfs_tab_helper_.get() &&
ipfs_tab_helper_->ipfs_resolved_url_.is_valid()) {
if (enable_gateway_autoredirect) {
ipfs_tab_helper_->pref_service_->SetBoolean(
kIPFSAutoRedirectToConfiguredGateway, true);
}
ipfs_tab_helper_->LoadUrl(ipfs_tab_helper_->ipfs_resolved_url_);
}
}

~BraveIPFSInfoBarDelegateObserverImpl() override {}

private:
base::WeakPtr<IPFSTabHelper> ipfs_tab_helper_;
};
#endif // !BUILDFLAG(IS_ANDROID)

IPFSTabHelper::~IPFSTabHelper() = default;

IPFSTabHelper::IPFSTabHelper(content::WebContents* web_contents)
Expand Down Expand Up @@ -143,6 +174,20 @@ void IPFSTabHelper::LoadUrl(const GURL& gurl) {
}

void IPFSTabHelper::UpdateLocationBar() {
#if !BUILDFLAG(IS_ANDROID)
auto* content_infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(web_contents());
// Check whether content_infobar_manager is present for unit tests
if (content_infobar_manager && ipfs_resolved_url_.is_valid() &&
!pref_service_->GetBoolean(kIPFSAutoRedirectToConfiguredGateway)) {
BraveIPFSInfoBarDelegate::Create(
content_infobar_manager,
std::make_unique<BraveIPFSInfoBarDelegateObserverImpl>(
weak_ptr_factory_.GetWeakPtr()),
pref_service_);
}
#endif

if (web_contents()->GetDelegate())
web_contents()->GetDelegate()->NavigationStateChanged(
web_contents(), content::INVALIDATE_TYPE_URL);
Expand Down
1 change: 1 addition & 0 deletions browser/ipfs/ipfs_tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class IPFSTabHelper : public content::WebContentsObserver,
FRIEND_TEST_ALL_PREFIXES(IpfsTabHelperUnitTest,
GatewayIPNS_No_Redirect_WhenNoDnsLink);
friend class content::WebContentsUserData<IPFSTabHelper>;
friend class BraveIPFSInfoBarDelegateObserverImpl;
explicit IPFSTabHelper(content::WebContents* web_contents);

GURL GetCurrentPageURL() const;
Expand Down
Loading

0 comments on commit d3b30ea

Please sign in to comment.