diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index 030710c688fc..97198356df44 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -78,6 +78,7 @@ source_set("extensions") { if (brave_rewards_enabled) { deps += [ + "//brave/components/brave_rewards/browser", "//brave/components/brave_rewards/resources/extension:extension_generated_resources", "//brave/components/brave_rewards/resources/extension:static_resources", ] diff --git a/browser/extensions/brave_component_loader.cc b/browser/extensions/brave_component_loader.cc index c9af80bcd7d3..8a1155631874 100644 --- a/browser/extensions/brave_component_loader.cc +++ b/browser/extensions/brave_component_loader.cc @@ -7,6 +7,7 @@ #include +#include "base/bind.h" #include "base/command_line.h" #include "brave/browser/brave_browser_process_impl.h" #include "brave/browser/component_updater/brave_component_installer.h" @@ -15,6 +16,7 @@ #include "brave/common/pref_names.h" #include "brave/components/brave_extension/grit/brave_extension.h" #include "brave/components/brave_rewards/browser/buildflags/buildflags.h" +#include "brave/components/brave_rewards/common/pref_names.h" #include "brave/components/brave_rewards/resources/extension/grit/brave_rewards_extension_resources.h" #include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources.h" #include "chrome/browser/extensions/extension_service.h" @@ -22,6 +24,8 @@ #include "chrome/browser/ui/webui/components_ui.h" #include "chrome/common/pref_names.h" #include "components/grit/brave_components_resources.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" @@ -33,7 +37,14 @@ BraveComponentLoader::BraveComponentLoader( Profile* profile) : ComponentLoader(extension_service, profile), profile_(profile), - profile_prefs_(profile->GetPrefs()) {} + profile_prefs_(profile->GetPrefs()) { +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + pref_change_registrar_.Init(profile_prefs_); + pref_change_registrar_.Add(brave_rewards::prefs::kBraveRewardsEnabled, + base::Bind(&BraveComponentLoader::HandleRewardsEnabledStatus, + base::Unretained(this))); +#endif +} BraveComponentLoader::~BraveComponentLoader() { } @@ -89,12 +100,8 @@ void BraveComponentLoader::AddDefaultComponentExtensions( } #if BUILDFLAG(BRAVE_REWARDS_ENABLED) - if (!command_line.HasSwitch(switches::kDisableBraveRewardsExtension)) { - base::FilePath brave_rewards_path(FILE_PATH_LITERAL("")); - brave_rewards_path = - brave_rewards_path.Append(FILE_PATH_LITERAL("brave_rewards")); - Add(IDR_BRAVE_REWARDS, brave_rewards_path); - } + // Enable rewards extension if already opted-in + HandleRewardsEnabledStatus(); #endif #if BUILDFLAG(BRAVE_WALLET_ENABLED) @@ -106,6 +113,28 @@ void BraveComponentLoader::AddDefaultComponentExtensions( #endif } +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) +void BraveComponentLoader::AddRewardsExtension() { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (!command_line.HasSwitch(switches::kDisableBraveRewardsExtension) && + !Exists(brave_rewards_extension_id)) { + base::FilePath brave_rewards_path(FILE_PATH_LITERAL("")); + brave_rewards_path = + brave_rewards_path.Append(FILE_PATH_LITERAL("brave_rewards")); + Add(IDR_BRAVE_REWARDS, brave_rewards_path); + } +} + +void BraveComponentLoader::HandleRewardsEnabledStatus() { + const bool is_rewards_enabled = profile_prefs_->GetBoolean( + brave_rewards::prefs::kBraveRewardsEnabled); + if (is_rewards_enabled) { + AddRewardsExtension(); + } +} +#endif + #if BUILDFLAG(BRAVE_WALLET_ENABLED) void BraveComponentLoader::AddEthereumRemoteClientExtension() { if (profile_prefs_->GetBoolean(kBraveWalletEnabled)) { diff --git a/browser/extensions/brave_component_loader.h b/browser/extensions/brave_component_loader.h index 21ef8836d772..6467931a2347 100644 --- a/browser/extensions/brave_component_loader.h +++ b/browser/extensions/brave_component_loader.h @@ -9,10 +9,19 @@ #include #include "base/files/file_path.h" +#include "brave/components/brave_rewards/browser/buildflags/buildflags.h" #include "brave/components/brave_wallet/browser/buildflags/buildflags.h" #include "chrome/browser/extensions/component_loader.h" #include "components/prefs/pref_change_registrar.h" +class PrefService; +class Profile; + +namespace brave_rewards { +class RewardsService; +} + + namespace extensions { // For registering, loading, and unloading component extensions. @@ -29,6 +38,9 @@ class BraveComponentLoader : public ComponentLoader { void AddDefaultComponentExtensions(bool skip_session_components) override; void OnComponentRegistered(std::string extension_id); +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + void AddRewardsExtension(); +#endif #if BUILDFLAG(BRAVE_WALLET_ENABLED) void AddEthereumRemoteClientExtension(); #endif @@ -48,9 +60,13 @@ class BraveComponentLoader : public ComponentLoader { void AddHangoutServicesExtension() override; #endif // BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + void HandleRewardsEnabledStatus(); +#endif + Profile* profile_; PrefService* profile_prefs_; - PrefChangeRegistrar registrar_; + PrefChangeRegistrar pref_change_registrar_; std::string ethereum_remote_client_manifest_; base::FilePath ethereum_remote_client_install_dir_; diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index 502e5ac07e71..835f11325ced 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -185,7 +185,7 @@ source_set("ui") { deps += [ "//brave/app:brave_generated_resources_grit" ] } - if (enable_extensions) { + if (enable_extensions && toolkit_views) { sources += [ "brave_actions/brave_action_icon_with_badge_image_source.cc", "brave_actions/brave_action_icon_with_badge_image_source.h", @@ -213,6 +213,13 @@ source_set("ui") { "webui/settings/brave_default_extensions_handler.h", ] + if (brave_rewards_enabled) { + sources += [ + "views/brave_actions/brave_rewards_action_stub_view.cc", + "views/brave_actions/brave_rewards_action_stub_view.h", + ] + } + deps += [ "//brave/browser/resources/extensions:resources", "//brave/components/brave_extension:generated_resources", diff --git a/browser/ui/views/brave_actions/brave_actions_container.cc b/browser/ui/views/brave_actions/brave_actions_container.cc index 1bfe2838c722..5c020d5204bf 100644 --- a/browser/ui/views/brave_actions/brave_actions_container.cc +++ b/browser/ui/views/brave_actions/brave_actions_container.cc @@ -9,14 +9,21 @@ #include #include +#include "base/command_line.h" #include "base/one_shot_event.h" +#include "brave/browser/extensions/brave_component_loader.h" #include "brave/browser/ui/brave_actions/brave_action_view_controller.h" +#include "brave/browser/ui/brave_actions/constants.h" #include "brave/browser/ui/views/brave_actions/brave_action_view.h" +#include "brave/browser/ui/views/brave_actions/brave_rewards_action_stub_view.h" #include "brave/browser/ui/views/rounded_separator.h" +#include "brave/common/brave_switches.h" #include "brave/common/extensions/extension_constants.h" #include "brave/common/pref_names.h" +#include "brave/components/brave_rewards/browser/buildflags/buildflags.h" #include "brave/components/brave_rewards/common/pref_names.h" #include "chrome/browser/extensions/extension_action_manager.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/layout_constants.h" @@ -47,6 +54,7 @@ void BraveActionsContainer::BraveActionInfo::Reset() { BraveActionsContainer::BraveActionsContainer(Browser* browser, Profile* profile) : views::View(), browser_(browser), + extension_system_(extensions::ExtensionSystem::Get(profile)), extension_action_api_(extensions::ExtensionActionAPI::Get(profile)), extension_registry_(extensions::ExtensionRegistry::Get(profile)), extension_action_manager_( @@ -55,7 +63,7 @@ BraveActionsContainer::BraveActionsContainer(Browser* browser, Profile* profile) extension_action_observer_(this), weak_ptr_factory_(this) { // Handle when the extension system is ready - extensions::ExtensionSystem::Get(profile)->ready().Post( + extension_system_->ready().Post( FROM_HERE, base::Bind(&BraveActionsContainer::OnExtensionSystemReady, weak_ptr_factory_.GetWeakPtr())); } @@ -118,20 +126,26 @@ bool BraveActionsContainer::ShouldAddAction(const std::string& id) const { } bool BraveActionsContainer::ShouldAddBraveRewardsAction() const { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kDisableBraveRewardsExtension)) { + return false; + } const PrefService* prefs = browser_->profile()->GetPrefs(); return prefs->GetBoolean(brave_rewards::prefs::kBraveRewardsEnabled) || !prefs->GetBoolean(kHideBraveRewardsButton); } -void BraveActionsContainer::AddAction(const extensions::Extension* extension, - int pos) { +void BraveActionsContainer::AddAction(const extensions::Extension* extension) { DCHECK(extension); if (!ShouldAddAction(extension->id())) return; VLOG(1) << "AddAction (" << extension->id() << "), was already loaded: " << static_cast(actions_[extension->id()].view_); - if (!actions_[extension->id()].view_) { + if (!actions_[extension->id()].view_controller_) { const auto& id = extension->id(); + // Remove existing stub view, if present + actions_[id].Reset(); // Create a ExtensionActionViewController for the extension // Passing |nullptr| instead of ToolbarActionsBar since we // do not require that logic. @@ -144,30 +158,59 @@ void BraveActionsContainer::AddAction(const extensions::Extension* extension, // The button view actions_[id].view_ = std::make_unique( actions_[id].view_controller_.get(), this); - // Add extension view after separator view - // `AddChildView` should be called first, so that changes that modify - // layout (e.g. preferred size) are forwarded to its parent - if (actions_[id].position_ != ACTION_ANY_POSITION) { - DCHECK_GT(actions_[id].position_, 0); - AddChildViewAt(actions_[id].view_.get(), actions_[id].position_); - } else { - AddChildView(actions_[id].view_.get()); + AttachAction(actions_[id]); + // Handle if we are in a continuing pressed state for this extension. + if (is_rewards_pressed_ && id == brave_rewards_extension_id) { + is_rewards_pressed_ = false; + actions_[id].view_controller_->ExecuteAction(true); } - // we control destruction - actions_[id].view_->set_owned_by_client(); - // Sets overall size of button but not image graphic. We set a large width - // in order to give space for the bubble. - actions_[id].view_->SetPreferredSize(gfx::Size(34, 24)); - Update(); } } -void BraveActionsContainer::AddAction(const std::string& id, int pos) { +void BraveActionsContainer::AddActionStubForRewards() { + const std::string id = brave_rewards_extension_id; + if (!ShouldAddAction(id)) { + return; + } + if (actions_[id].view_) { + return; + } +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + actions_[id].view_ = std::make_unique(this); + AttachAction(actions_[id]); +#endif +} + +void BraveActionsContainer::AttachAction(BraveActionInfo &action) { + // Add extension view after separator view + // `AddChildView` should be called first, so that changes that modify + // layout (e.g. preferred size) are forwarded to its parent + if (action.position_ != ACTION_ANY_POSITION) { + DCHECK_GT(action.position_, 0); + AddChildViewAt(action.view_.get(), action.position_); + } else { + AddChildView(action.view_.get()); + } + // we control destruction + action.view_->set_owned_by_client(); + Update(); +} + +void BraveActionsContainer::AddAction(const std::string& id) { DCHECK(extension_registry_); const extensions::Extension* extension = extension_registry_->enabled_extensions().GetByID(id); - if (extension) - AddAction(extension, pos); + if (extension) { + AddAction(extension); + return; + } +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + if (id == brave_rewards_extension_id) { + AddActionStubForRewards(); + return; + } +#endif + LOG(ERROR) << "Extension not found for Brave Action: " << id; } void BraveActionsContainer::RemoveAction(const std::string& id) { @@ -240,10 +283,9 @@ views::LabelButton* BraveActionsContainer::GetOverflowReferenceView() const { // ToolbarActionView::Delegate members gfx::Size BraveActionsContainer::GetToolbarActionSize() { - // Shields icon should be square, and full-height - gfx::Rect rect(gfx::Size(height(), height())); - rect.Inset(-GetLayoutInsets(LOCATION_BAR_ICON_INTERIOR_PADDING)); - return rect.size(); + // Width > Height to give space for a large bubble (especially for shields). + // TODO(petemill): Generate based on toolbar size. + return gfx::Size(34, 24); } void BraveActionsContainer::WriteDragDataForView(View* sender, @@ -264,20 +306,34 @@ bool BraveActionsContainer::CanStartDragForView(View* sender, } // end ToolbarActionView::Delegate members +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) +// BraveRewardsActionStubView::Delegate members +void BraveActionsContainer::OnRewardsStubButtonClicked() { + // Keep button state visually pressed until new extension button + // takes over. + actions_[brave_rewards_extension_id].view_->SetState( + views::Button::STATE_PRESSED); + extensions::ExtensionService* service = + extension_system_->extension_service(); + if (service) { + is_rewards_pressed_ = true; + extensions::ComponentLoader* loader = service->component_loader(); + static_cast(loader)-> + AddRewardsExtension(); + } +} +// end BraveRewardsActionStubView::Delegate members +#endif + void BraveActionsContainer::OnExtensionSystemReady() { // observe changes in extension system extension_registry_observer_.Add(extension_registry_); extension_action_observer_.Add(extension_action_api_); - // Check if brave extension already loaded - const extensions::Extension* extension = - extension_registry_->enabled_extensions().GetByID(brave_extension_id); - if (extension) - AddAction(extension); - // Check if brave rewards extension already loaded - extension = extension_registry_->enabled_extensions().GetByID( - brave_rewards_extension_id); - if (extension) - AddAction(extension); + // Check if extensions already loaded + AddAction(brave_extension_id); +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + AddAction(brave_rewards_extension_id); +#endif } // ExtensionRegistry::Observer diff --git a/browser/ui/views/brave_actions/brave_actions_container.h b/browser/ui/views/brave_actions/brave_actions_container.h index cf2140d1542e..711b5404bceb 100644 --- a/browser/ui/views/brave_actions/brave_actions_container.h +++ b/browser/ui/views/brave_actions/brave_actions_container.h @@ -10,6 +10,7 @@ #include #include +#include "brave/components/brave_rewards/browser/buildflags/buildflags.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/browser.h" @@ -19,6 +20,10 @@ #include "extensions/common/extension.h" #include "ui/views/view.h" +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) +#include "brave/browser/ui/views/brave_actions/brave_rewards_action_stub_view.h" +#endif + class BraveActionsContainerTest; class BraveRewardsBrowserTest; @@ -27,13 +32,21 @@ class ExtensionActionManager; class ExtensionRegistry; } +namespace views { +class Button; +} + // This View contains all the built-in BraveActions such as Shields and Payments // TODO(petemill): consider splitting to separate model, like // ToolbarActionsModel and ToolbarActionsBar class BraveActionsContainer : public views::View, public extensions::ExtensionActionAPI::Observer, public extensions::ExtensionRegistryObserver, - public ToolbarActionView::Delegate { + public ToolbarActionView::Delegate, +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + public BraveRewardsActionStubView::Delegate +#endif + { public: BraveActionsContainer(Browser* browser, Profile* profile); ~BraveActionsContainer() override; @@ -61,6 +74,11 @@ class BraveActionsContainer : public views::View, const gfx::Point& press_pt, const gfx::Point& p) override; +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) + // BraveRewardsActionStubView::Delegate + void OnRewardsStubButtonClicked() override; +#endif + // ExtensionRegistryObserver: void OnExtensionLoaded(content::BrowserContext* browser_context, const extensions::Extension* extension) override; @@ -102,7 +120,7 @@ class BraveActionsContainer : public views::View, void Reset(); int position_; - std::unique_ptr view_; + std::unique_ptr view_; std::unique_ptr view_controller_; }; @@ -111,18 +129,21 @@ class BraveActionsContainer : public views::View, // Actions operations bool ShouldAddAction(const std::string& id) const; - bool ShouldAddBraveRewardsAction() const; bool IsContainerAction(const std::string& id) const; - void AddAction(const extensions::Extension* extension, - int pos = ACTION_ANY_POSITION); - void AddAction(const std::string& id, int pos = ACTION_ANY_POSITION); + void AddAction(const extensions::Extension* extension); + void AddAction(const std::string& id); + bool ShouldAddBraveRewardsAction() const; + void AddActionStubForRewards(); void RemoveAction(const std::string& id); void ShowAction(const std::string& id, bool show); bool IsActionShown(const std::string& id) const; void UpdateActionState(const std::string& id); + void AttachAction(BraveActionInfo &action); bool should_hide_ = false; + bool is_rewards_pressed_ = false; + // The Browser this LocationBarView is in. Note that at least // chromeos::SimpleWebViewDialog uses a LocationBarView outside any browser // window, so this may be NULL. @@ -130,6 +151,7 @@ class BraveActionsContainer : public views::View, void OnExtensionSystemReady(); + extensions::ExtensionSystem* extension_system_; extensions::ExtensionActionAPI* extension_action_api_; extensions::ExtensionRegistry* extension_registry_; extensions::ExtensionActionManager* extension_action_manager_; diff --git a/browser/ui/views/brave_actions/brave_rewards_action_stub_view.cc b/browser/ui/views/brave_actions/brave_rewards_action_stub_view.cc new file mode 100644 index 000000000000..3dde00e190e6 --- /dev/null +++ b/browser/ui/views/brave_actions/brave_rewards_action_stub_view.cc @@ -0,0 +1,106 @@ +// Copyright (c) 2019 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/brave_actions/brave_rewards_action_stub_view.h" + +#include +#include +#include + +#include "brave/browser/ui/brave_actions/brave_action_icon_with_badge_image_source.h" // NOLINT +#include "brave/browser/ui/brave_actions/constants.h" +#include "brave/components/brave_rewards/resources/extension/grit/brave_rewards_extension_resources.h" // NOLINT +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" +#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/canvas_image_source.h" +#include "ui/gfx/image/image_skia_source.h" +#include "ui/views/view.h" +#include "ui/views/view_class_properties.h" +#include "ui/views/animation/ink_drop_impl.h" +#include "ui/views/controls/button/label_button_border.h" + +namespace { + constexpr SkColor kRewardsBadgeBg = SkColorSetRGB(0xfb, 0x54, 0x2b); + const std::string kRewardsInitialBadgeText = "1"; +} + +BraveRewardsActionStubView::BraveRewardsActionStubView( + BraveRewardsActionStubView::Delegate* delegate) + : LabelButton(this, base::string16()), + delegate_(delegate) { + SetInkDropMode(InkDropMode::ON); + set_has_ink_drop_action_on_click(true); + SetHorizontalAlignment(gfx::ALIGN_CENTER); + set_ink_drop_visible_opacity(kToolbarInkDropVisibleOpacity); + // Create badge-and-image source like an extension icon would + auto preferred_size = GetPreferredSize(); + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + std::unique_ptr image_source( + new BraveActionIconWithBadgeImageSource(preferred_size)); + // Set icon on badge using actual extension icon resource + const auto image = gfx::Image( + rb.GetImageNamed(IDR_BRAVE_REWARDS_ICON_64).AsImageSkia() + .DeepCopy()); + image_source->SetIcon(image); + // Set text on badge + std::unique_ptr badge; + badge.reset(new IconWithBadgeImageSource::Badge( + kRewardsInitialBadgeText, + SK_ColorWHITE, + kRewardsBadgeBg)); + image_source->SetBadge(std::move(badge)); + image_source->set_paint_page_action_decoration(false); + gfx::ImageSkia icon(gfx::Image( + gfx::ImageSkia( + std::move(image_source), + preferred_size)) + .AsImageSkia()); + // Use badge-and-icon source for button's image in all states + SetImage(views::Button::STATE_NORMAL, icon); + // Set the highlight path for the toolbar button, + // making it inset so that the badge can show outside it in the + // fake margin on the right that we are creating. + gfx::Insets highlight_insets(0, 0, 0, brave_actions::kBraveActionRightMargin); + gfx::Rect rect(preferred_size); + rect.Inset(highlight_insets); + const int radii = ChromeLayoutProvider::Get()->GetCornerRadiusMetric( + views::EMPHASIS_MAXIMUM, rect.size()); + auto path = std::make_unique(); + path->addRoundRect(gfx::RectToSkRect(rect), radii, radii); + SetProperty(views::kHighlightPathKey, path.release()); +} + +BraveRewardsActionStubView::~BraveRewardsActionStubView() {} + +void BraveRewardsActionStubView::ButtonPressed( + Button* sender, const ui::Event& event) { + delegate_->OnRewardsStubButtonClicked(); +} + +gfx::Size BraveRewardsActionStubView::CalculatePreferredSize() const { + return delegate_->GetToolbarActionSize(); +} + +std::unique_ptr BraveRewardsActionStubView:: + CreateDefaultBorder() const { + std::unique_ptr border = + LabelButton::CreateDefaultBorder(); + border->set_insets( + gfx::Insets(0, 0, 0, 0)); + return border; +} + +SkColor BraveRewardsActionStubView::GetInkDropBaseColor() const { + return GetToolbarInkDropBaseColor(this); +} + +std::unique_ptr +BraveRewardsActionStubView::CreateInkDropHighlight() const { + return CreateToolbarInkDropHighlight(this); +} diff --git a/browser/ui/views/brave_actions/brave_rewards_action_stub_view.h b/browser/ui/views/brave_actions/brave_rewards_action_stub_view.h new file mode 100644 index 000000000000..d76da72733ab --- /dev/null +++ b/browser/ui/views/brave_actions/brave_rewards_action_stub_view.h @@ -0,0 +1,49 @@ +// Copyright (c) 2019 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_BRAVE_ACTIONS_BRAVE_REWARDS_ACTION_STUB_VIEW_H_ +#define BRAVE_BROWSER_UI_VIEWS_BRAVE_ACTIONS_BRAVE_REWARDS_ACTION_STUB_VIEW_H_ + +#include + +#include "ui/views/controls/button/label_button.h" +#include "ui/views/view.h" + +// A button to take the place of an extension that will be loaded in the future. +// Call SetImage with the BraveActionIconWithBadgeImageSource +// Call highlight etc from ToolbarActionView +class BraveRewardsActionStubView : public views::LabelButton, + public views::ButtonListener { + public: + class Delegate { + public: + virtual void OnRewardsStubButtonClicked() = 0; + virtual gfx::Size GetToolbarActionSize() = 0; + protected: + ~Delegate() {} + }; + + explicit BraveRewardsActionStubView(Delegate* delegate); + ~BraveRewardsActionStubView() override; + + // views::ButtonListener + void ButtonPressed(Button* sender, const ui::Event& event) override; + + // views::LabelButton: + std::unique_ptr CreateDefaultBorder() + const override; + SkColor GetInkDropBaseColor() const override; + std::unique_ptr CreateInkDropHighlight() + const override; + + private: + gfx::Size CalculatePreferredSize() const override; + + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(BraveRewardsActionStubView); +}; + +#endif // BRAVE_BROWSER_UI_VIEWS_BRAVE_ACTIONS_BRAVE_REWARDS_ACTION_STUB_VIEW_H_ diff --git a/chromium_src/chrome/browser/extensions/extension_action_manager.cc b/chromium_src/chrome/browser/extensions/extension_action_manager.cc new file mode 100644 index 000000000000..d5521e8ec544 --- /dev/null +++ b/chromium_src/chrome/browser/extensions/extension_action_manager.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2019 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/common/extensions/extension_constants.h" +#include "brave/browser/ui/brave_actions/constants.h" + +// Avoid a jump from small image to large image when the non-default +// image is set. +#define BRAVE_GET_EXTENSION_ACTION \ + if (action->default_icon() && ( \ + extension.id() == brave_rewards_extension_id || \ + extension.id() == brave_extension_id)) { \ + action->SetDefaultIconImage(std::make_unique( \ + profile_, &extension, *action->default_icon(), \ + brave_actions::kBraveActionGraphicSize, \ + ExtensionAction::FallbackIcon().AsImageSkia(), nullptr)); \ + } +#include "../../../../../chrome/browser/extensions/extension_action_manager.cc" +#undef BRAVE_GET_EXTENSION_ACTION diff --git a/components/brave_rewards/browser/rewards_service_browsertest.cc b/components/brave_rewards/browser/rewards_service_browsertest.cc index b2c085e615bb..710448f09e09 100644 --- a/components/brave_rewards/browser/rewards_service_browsertest.cc +++ b/components/brave_rewards/browser/rewards_service_browsertest.cc @@ -439,6 +439,34 @@ class BraveRewardsBrowserTest : wait_for_insufficient_notification_loop_->Run(); } + void WaitForSelector(content::WebContents* contents, + const std::string& selector) const { + auto script = content::JsReplace( + "new Promise((resolve) => {" + " let count = 20;" + " let interval = setInterval(function() {" + " if (count == 0) {" + " clearInterval(interval);" + " resolve(false);" + " } else {" + " count -= 1;" + " }" + " const element = document.querySelector($1);" + " if (element) {" + " clearInterval(interval);" + " resolve(true);" + " }" + " }, 500);" + "});", + selector); + auto js_result = EvalJs( + contents, + script, + content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, + content::ISOLATED_WORLD_ID_CONTENT_END); + ASSERT_TRUE(js_result.ExtractBool()); + } + void GetReconcileTime() { rewards_service()->GetReconcileTime( base::Bind(&BraveRewardsBrowserTest::OnGetReconcileTime, @@ -487,6 +515,7 @@ class BraveRewardsBrowserTest : static_cast&>( popup_observer.source()); + WaitForSelector(source.ptr(), "#panel-slider"); return source.ptr(); } @@ -668,14 +697,6 @@ class BraveRewardsBrowserTest : // Wait for grant to finish WaitForGrantFinished(); - // Goes to final step - if (use_panel) { - ASSERT_TRUE(ExecJs(contents, - "document.getElementsByTagName('button')[0].click();", - content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, - content::ISOLATED_WORLD_ID_CONTENT_END)); - } - // Ensure that grant looks as expected EXPECT_STREQ(grant_.altcurrency.c_str(), "BAT"); EXPECT_STREQ(grant_.probi.c_str(), "30000000000000000000"); diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 4e24139cb0c5..532d74dceb2e 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -34,28 +34,7 @@ chrome.tabs.query({ rewardsPanelActions.init(tabs) }) -chrome.runtime.onInstalled.addListener(function (details) { - if (details.reason === 'install') { - const initialNotificationDismissed = 'false' - chrome.storage.local.set({ - 'is_dismissed': initialNotificationDismissed - }, function () { - chrome.browserAction.setBadgeText({ - text: '1' - }) - }) - } -}) - chrome.runtime.onStartup.addListener(function () { - chrome.storage.local.get(['is_dismissed'], function (result) { - if (result && result['is_dismissed'] === 'false') { - chrome.browserAction.setBadgeText({ - text: '1' - }) - } - }) - chrome.runtime.onConnect.addListener(function (externalPort) { chrome.storage.local.set({ 'rewards_panel_open': 'true' @@ -69,17 +48,6 @@ chrome.runtime.onStartup.addListener(function () { }) }) -chrome.runtime.onConnect.addListener(function () { - chrome.storage.local.get(['is_dismissed'], function (result) { - if (result && result['is_dismissed'] === 'false') { - chrome.browserAction.setBadgeText({ - text: '' - }) - chrome.storage.local.remove(['is_dismissed']) - } - }) -}) - const tipTwitterMedia = (mediaMetaData: RewardsTip.MediaMetaData) => { mediaMetaData.mediaType = 'twitter' chrome.tabs.query({ diff --git a/components/brave_rewards/resources/extension/brave_rewards/background/events/rewardsEvents.ts b/components/brave_rewards/resources/extension/brave_rewards/background/events/rewardsEvents.ts index 459dabb6796e..e79d1edc59b1 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background/events/rewardsEvents.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background/events/rewardsEvents.ts @@ -4,10 +4,7 @@ import rewardsPanelActions from '../actions/rewardsPanelActions' -chrome.braveRewards.getAllNotifications((list: RewardsExtension.Notification[]) => { - rewardsPanelActions.onAllNotifications(list) -}) - +// Handle all rewards events and pass to actions chrome.braveRewards.onWalletInitialized.addListener((result: RewardsExtension.Result) => { rewardsPanelActions.onWalletInitialized(result) }) @@ -117,3 +114,20 @@ chrome.braveRewards.onDisconnectWallet.addListener((properties: {result: number, }) } }) + +// Fetch initial data required to refresh state, keeping in mind +// that the extension process be restarted at any time. +// TODO(petemill): Move to initializer function or single 'init' action. +chrome.braveRewards.getRewardsMainEnabled((enabledMain: boolean) => { + rewardsPanelActions.onEnabledMain(enabledMain) + if (enabledMain) { + chrome.braveRewards.getWalletProperties() + chrome.braveRewards.getGrants() + chrome.braveRewards.fetchBalance((balance: RewardsExtension.Balance) => { + rewardsPanelActions.onBalance(balance) + }) + chrome.braveRewards.getAllNotifications((list: RewardsExtension.Notification[]) => { + rewardsPanelActions.onAllNotifications(list) + }) + } +}) diff --git a/components/brave_rewards/resources/extension/brave_rewards/background/reducers/rewards_panel_reducer.ts b/components/brave_rewards/resources/extension/brave_rewards/background/reducers/rewards_panel_reducer.ts index 2ebce3a7d346..7fe558425a48 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background/reducers/rewards_panel_reducer.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background/reducers/rewards_panel_reducer.ts @@ -130,8 +130,14 @@ export const rewardsPanelReducer = (state: RewardsExtension.State | undefined, a chrome.braveRewards.getWalletProperties() break case types.ON_WALLET_PROPERTIES: { - state = { ...state } - state.walletProperties = payload.properties + state = { + ...state, + walletCreated: true, + walletCreateFailed: false, + walletCreating: false, + walletCorrupted: false, + walletProperties: payload.properties + } break } case types.GET_CURRENT_REPORT: diff --git a/patches/chrome-browser-extensions-extension_action_manager.cc.patch b/patches/chrome-browser-extensions-extension_action_manager.cc.patch new file mode 100644 index 000000000000..813189dbc8d5 --- /dev/null +++ b/patches/chrome-browser-extensions-extension_action_manager.cc.patch @@ -0,0 +1,12 @@ +diff --git a/chrome/browser/extensions/extension_action_manager.cc b/chrome/browser/extensions/extension_action_manager.cc +index 90884f9916494778fc182c49ac7709bc91f536b9..0b099db863682c226da5f6e2f67e684ed56da3ef 100644 +--- a/chrome/browser/extensions/extension_action_manager.cc ++++ b/chrome/browser/extensions/extension_action_manager.cc +@@ -109,6 +109,7 @@ ExtensionAction* ExtensionActionManager::GetExtensionAction( + ExtensionAction::ActionIconSize(), + ExtensionAction::FallbackIcon().AsImageSkia(), nullptr)); + } ++ BRAVE_GET_EXTENSION_ACTION + + ExtensionAction* raw_action = action.get(); + actions_[extension.id()] = std::move(action);