diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index de6b78ef14e1..e6ba202647ec 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -291,5 +291,139 @@ ExtensionFunction::ResponseAction BraveRewardsSaveSettingFunction::Run() { return RespondNow(NoArguments()); } +BraveRewardsSaveRecurringTipFunction:: +~BraveRewardsSaveRecurringTipFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsSaveRecurringTipFunction::Run() { + std::unique_ptr params( + brave_rewards::SaveRecurringTip::Params::Create(*args_)); + + Profile* profile = Profile::FromBrowserContext(browser_context()); + RewardsService* rewards_service_ = + RewardsServiceFactory::GetForProfile(profile); + + if (rewards_service_) { + rewards_service_->SaveRecurringTip(params->publisher_key, + params->new_amount); + } + + return RespondNow(NoArguments()); +} + +BraveRewardsRemoveRecurringTipFunction:: +~BraveRewardsRemoveRecurringTipFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsRemoveRecurringTipFunction::Run() { + std::unique_ptr params( + brave_rewards::RemoveRecurringTip::Params::Create(*args_)); + + Profile* profile = Profile::FromBrowserContext(browser_context()); + RewardsService* rewards_service_ = + RewardsServiceFactory::GetForProfile(profile); + + if (rewards_service_) { + rewards_service_->RemoveRecurringTip(params->publisher_key); + } + + return RespondNow(NoArguments()); +} + +BraveRewardsGetRecurringTipsFunction:: +~BraveRewardsGetRecurringTipsFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsGetRecurringTipsFunction::Run() { + Profile* profile = Profile::FromBrowserContext(browser_context()); + RewardsService* rewards_service = + RewardsServiceFactory::GetForProfile(profile); + + if (!rewards_service) { + return RespondNow(Error("Rewards service is not initialized")); + } + + rewards_service->GetRecurringTipsUI(base::Bind( + &BraveRewardsGetRecurringTipsFunction::OnGetRecurringTips, + this)); + return RespondLater(); +} + +void BraveRewardsGetRecurringTipsFunction::OnGetRecurringTips( + std::unique_ptr<::brave_rewards::ContentSiteList> list) { + std::unique_ptr result(new base::DictionaryValue()); + auto recurringTips = std::make_unique(); + + if (!list->empty()) { + for (auto const& item : *list) { + auto tip = std::make_unique(); + tip->SetString("publisherKey", item.id); + tip->SetInteger("amount", item.weight); + recurringTips->Append(std::move(tip)); + } + } + + result->SetList("recurringTips", std::move(recurringTips)); + Respond(OneArgument(std::move(result))); +} + +BraveRewardsGetPublisherBannerFunction:: +~BraveRewardsGetPublisherBannerFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsGetPublisherBannerFunction::Run() { + std::unique_ptr params( + brave_rewards::GetPublisherBanner::Params::Create(*args_)); + + Profile* profile = Profile::FromBrowserContext(browser_context()); + RewardsService* rewards_service = + RewardsServiceFactory::GetForProfile(profile); + + if (!rewards_service) { + return RespondNow(Error("Rewards service is not initialized")); + } + + rewards_service->GetPublisherBanner( + params->publisher_key, + base::BindOnce( + &BraveRewardsGetPublisherBannerFunction::OnPublisherBanner, + this)); + return RespondLater(); +} + +void BraveRewardsGetPublisherBannerFunction::OnPublisherBanner( + std::unique_ptr<::brave_rewards::PublisherBanner> banner) { + std::unique_ptr result(new base::DictionaryValue()); + + if (banner) { + result->SetString("publisherKey", banner->publisher_key); + result->SetString("title", banner->title); + result->SetString("name", banner->name); + result->SetString("description", banner->description); + result->SetString("background", banner->background); + result->SetString("logo", banner->logo); + result->SetString("provider", banner->provider); + result->SetBoolean("verified", banner->verified); + + auto amounts = std::make_unique(); + for (int const& value : banner->amounts) { + amounts->AppendInteger(value); + } + result->SetList("amounts", std::move(amounts)); + + auto social = std::make_unique(); + for (auto const& item : banner->social) { + social->SetString(item.first, item.second); + } + result->SetDictionary("social", std::move(social)); + } + + Respond(OneArgument(std::move(result))); +} + } // namespace api } // namespace extensions diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index 7004f0e9102a..8b945dd97e43 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -6,7 +6,11 @@ #ifndef BRAVE_BROWSER_EXTENSIONS_API_BRAVE_REWARDS_API_H_ #define BRAVE_BROWSER_EXTENSIONS_API_BRAVE_REWARDS_API_H_ +#include + #include "extensions/browser/extension_function.h" +#include "brave/components/brave_rewards/browser/content_site.h" +#include "brave/components/brave_rewards/browser/publisher_banner.h" namespace extensions { namespace api { @@ -165,6 +169,59 @@ class BraveRewardsSaveSettingFunction : public UIThreadExtensionFunction { ResponseAction Run() override; }; +class BraveRewardsSaveRecurringTipFunction : + public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("braveRewards.saveRecurringTip", UNKNOWN) + + protected: + ~BraveRewardsSaveRecurringTipFunction() override; + + ResponseAction Run() override; +}; + +class BraveRewardsRemoveRecurringTipFunction : + public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("braveRewards.removeRecurringTip", UNKNOWN) + + protected: + ~BraveRewardsRemoveRecurringTipFunction() override; + + ResponseAction Run() override; +}; + +class BraveRewardsGetRecurringTipsFunction : + public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("braveRewards.getRecurringTips", UNKNOWN) + + protected: + ~BraveRewardsGetRecurringTipsFunction() override; + + ResponseAction Run() override; + + private: + void OnGetRecurringTips( + std::unique_ptr list); +}; + +class BraveRewardsGetPublisherBannerFunction : +public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION( + "braveRewards.getPublisherBanner", UNKNOWN) + + protected: + ~BraveRewardsGetPublisherBannerFunction() override; + + ResponseAction Run() override; + + private: + void OnPublisherBanner( + std::unique_ptr<::brave_rewards::PublisherBanner> banner); +}; + } // namespace api } // namespace extensions diff --git a/browser/ui/webui/brave_donate_ui.cc b/browser/ui/webui/brave_donate_ui.cc index b7cf9852674d..77608736f31c 100644 --- a/browser/ui/webui/brave_donate_ui.cc +++ b/browser/ui/webui/brave_donate_ui.cc @@ -57,6 +57,9 @@ class RewardsDonateDOMHandler : public WebUIMessageHandler, void OnGetRecurringTips( std::unique_ptr list); + void OnPublisherBanner( + std::unique_ptr banner); + // RewardsServiceObserver implementation void OnWalletProperties( brave_rewards::RewardsService* rewards_service, @@ -64,8 +67,8 @@ class RewardsDonateDOMHandler : public WebUIMessageHandler, std::unique_ptr wallet_properties) override; - void OnPublisherBanner(brave_rewards::RewardsService* rewards_service, - const brave_rewards::PublisherBanner banner) override; + void OnRecurringTipSaved(brave_rewards::RewardsService* rewards_service, + bool success) override; void OnRecurringTipRemoved(brave_rewards::RewardsService* rewards_service, bool success) override; @@ -118,7 +121,10 @@ void RewardsDonateDOMHandler::GetPublisherDonateData( const base::ListValue* args) { std::string publisher_key; args->GetString(0, &publisher_key); - rewards_service_->GetPublisherBanner(publisher_key); + rewards_service_->GetPublisherBanner( + publisher_key, + base::Bind(&RewardsDonateDOMHandler::OnPublisherBanner, + weak_factory_.GetWeakPtr())); } void RewardsDonateDOMHandler::GetWalletProperties(const base::ListValue* args) { @@ -229,33 +235,34 @@ void RewardsDonateDOMHandler::OnGetRecurringTips( } void RewardsDonateDOMHandler::OnPublisherBanner( - brave_rewards::RewardsService* rewards_service, - const brave_rewards::PublisherBanner banner) { + std::unique_ptr banner) { if (!web_ui()->CanCallJavascript()) { return; } base::DictionaryValue result; - result.SetString("publisherKey", banner.publisher_key); - result.SetString("title", banner.title); - result.SetString("name", banner.name); - result.SetString("description", banner.description); - result.SetString("background", banner.background); - result.SetString("logo", banner.logo); - result.SetString("provider", banner.provider); - result.SetBoolean("verified", banner.verified); - - auto amounts = std::make_unique(); - for (int const& value : banner.amounts) { - amounts->AppendInteger(value); - } - result.SetList("amounts", std::move(amounts)); + if (banner) { + result.SetString("publisherKey", banner->publisher_key); + result.SetString("title", banner->title); + result.SetString("name", banner->name); + result.SetString("description", banner->description); + result.SetString("background", banner->background); + result.SetString("logo", banner->logo); + result.SetString("provider", banner->provider); + result.SetBoolean("verified", banner->verified); + + auto amounts = std::make_unique(); + for (int const& value : banner->amounts) { + amounts->AppendInteger(value); + } + result.SetList("amounts", std::move(amounts)); - auto social = std::make_unique(); - for (auto const& item : banner.social) { - social->SetString(item.first, item.second); + auto social = std::make_unique(); + for (auto const& item : banner->social) { + social->SetString(item.first, item.second); + } + result.SetDictionary("social", std::move(social)); } - result.SetDictionary("social", std::move(social)); web_ui()->CallJavascriptFunctionUnsafe( "brave_rewards_donate.publisherBanner", result); @@ -312,5 +319,16 @@ void RewardsDonateDOMHandler::OnRecurringTipRemoved( "brave_rewards_donate.recurringTipRemoved", base::Value(success)); } +void RewardsDonateDOMHandler::OnRecurringTipSaved( + brave_rewards::RewardsService* rewards_service, + bool success) { + if (!web_ui()->CanCallJavascript()) { + return; + } + + web_ui()->CallJavascriptFunctionUnsafe( + "brave_rewards_donate.recurringTipSaved", base::Value(success)); +} + BraveDonateUI::~BraveDonateUI() { } diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index 8189dde6a074..01dcd78ed4da 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -287,6 +287,28 @@ } } ] + }, + { + "name": "onRecurringTipSaved", + "type": "function", + "description": "Fired when publisher recurring tip is saved", + "parameters": [ + { + "name": "success", + "type": "boolean" + } + ] + }, + { + "name": "onRecurringTipRemoved", + "type": "function", + "description": "Fired when publisher recurring tip is removed", + "parameters": [ + { + "name": "success", + "type": "boolean" + } + ] } ], "functions": [ @@ -477,6 +499,70 @@ "type": "string" } ] + }, + { + "name": "saveRecurringTip", + "type": "function", + "description": "Updates recurring tip amount for rewards panel", + "parameters": [ + { + "name": "publisher_key", + "type": "string" + }, + { + "name": "new_amount", + "type": "integer" + } + ] + }, + { + "name": "removeRecurringTip", + "type": "function", + "description": "Removes recurring tip for rewards panel", + "parameters": [ + { + "name": "publisher_key", + "type": "string" + } + ] + }, + { + "name": "getRecurringTips", + "type": "function", + "description": "Gets list of sites with recurring tip data", + "parameters": [ + { + "type": "function", + "name": "callback", + "parameters": [ + { + "name": "tips", + "type": "any" + } + ] + } + ] + }, + { + "name": "getPublisherBanner", + "type": "function", + "description": "Retrieves data for publisher banner", + "parameters": [ + { + "name": "publisher_key", + "type": "string" + }, + { + "name": "callback", + "type": "function", + "parameters": [ + { + "name": "banner", + "type": "any" + } + ] + } + ] } ] } diff --git a/components/brave_rewards/browser/content_site.cc b/components/brave_rewards/browser/content_site.cc index 47e1a78c6ace..171c39ca6fd3 100644 --- a/components/brave_rewards/browser/content_site.cc +++ b/components/brave_rewards/browser/content_site.cc @@ -12,6 +12,7 @@ namespace brave_rewards { percentage(0), verified(false), excluded(0), + weight(0), reconcile_stamp(0) { } @@ -26,6 +27,7 @@ namespace brave_rewards { url = properties.url; provider = properties.provider; id = properties.id; + weight = properties.weight; reconcile_stamp = properties.reconcile_stamp; } diff --git a/components/brave_rewards/browser/content_site.h b/components/brave_rewards/browser/content_site.h index 13e5a205d950..4dcf23280e72 100644 --- a/components/brave_rewards/browser/content_site.h +++ b/components/brave_rewards/browser/content_site.h @@ -31,6 +31,7 @@ struct ContentSite { std::string favicon_url; std::string url; std::string provider; + double weight; uint64_t reconcile_stamp; }; diff --git a/components/brave_rewards/browser/extension_rewards_service_observer.cc b/components/brave_rewards/browser/extension_rewards_service_observer.cc index 329b86ee6483..9d9485580b7f 100644 --- a/components/brave_rewards/browser/extension_rewards_service_observer.cc +++ b/components/brave_rewards/browser/extension_rewards_service_observer.cc @@ -325,4 +325,40 @@ void ExtensionRewardsServiceObserver::OnExcludedSitesChanged( event_router->BroadcastEvent(std::move(event)); } +void ExtensionRewardsServiceObserver::OnRecurringTipSaved( + RewardsService* rewards_service, + bool success) { + auto* event_router = extensions::EventRouter::Get(profile_); + if (!event_router) { + return; + } + + std::unique_ptr args( + extensions::api::brave_rewards::OnRecurringTipSaved::Create( + success).release()); + std::unique_ptr event(new extensions::Event( + extensions::events::BRAVE_START, + extensions::api::brave_rewards::OnRecurringTipSaved::kEventName, + std::move(args))); + event_router->BroadcastEvent(std::move(event)); +} + +void ExtensionRewardsServiceObserver::OnRecurringTipRemoved( + RewardsService* rewards_service, + bool success) { + auto* event_router = extensions::EventRouter::Get(profile_); + if (!event_router) { + return; + } + + std::unique_ptr args( + extensions::api::brave_rewards::OnRecurringTipRemoved::Create( + success).release()); + std::unique_ptr event(new extensions::Event( + extensions::events::BRAVE_START, + extensions::api::brave_rewards::OnRecurringTipRemoved::kEventName, + std::move(args))); + event_router->BroadcastEvent(std::move(event)); +} + } // namespace brave_rewards diff --git a/components/brave_rewards/browser/extension_rewards_service_observer.h b/components/brave_rewards/browser/extension_rewards_service_observer.h index 9f1a01c2b680..4f0bcca605fe 100644 --- a/components/brave_rewards/browser/extension_rewards_service_observer.h +++ b/components/brave_rewards/browser/extension_rewards_service_observer.h @@ -40,6 +40,12 @@ class ExtensionRewardsServiceObserver : public RewardsServiceObserver, std::string publisher_key, bool excluded) override; + void OnRecurringTipSaved(RewardsService* rewards_service, + bool success) override; + + void OnRecurringTipRemoved(RewardsService* rewards_service, + bool success) override; + // RewardsServicePrivateObserver implementation void OnGetCurrentBalanceReport(RewardsService* rewards_service, const BalanceReport& balance_report) override; diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index df6997af81fe..ad464a996592 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -75,6 +75,8 @@ using GetRecurringTipsCallback = base::OnceCallback)>; using GetOneTimeTipsCallback = base::OnceCallback)>; +using GetPublisherBannerCallback = + base::OnceCallback)>; class RewardsService : public KeyedService { public: @@ -156,7 +158,8 @@ class RewardsService : public KeyedService { const std::string& publisher_blob) = 0; virtual void GetContributionAmount( const GetContributionAmountCallback& callback) = 0; - virtual void GetPublisherBanner(const std::string& publisher_id) = 0; + virtual void GetPublisherBanner(const std::string& publisher_id, + GetPublisherBannerCallback callback) = 0; virtual void OnDonate(const std::string& publisher_key, int amount, bool recurring, const ledger::PublisherInfo* publisher_info = NULL) = 0; virtual void OnDonate(const std::string& publisher_key, int amount, @@ -192,6 +195,9 @@ class RewardsService : public KeyedService { static void RegisterProfilePrefs(PrefRegistrySimple* registry); + virtual void SaveRecurringTip(const std::string& publisher_key, + const int amount) = 0; + protected: base::ObserverList observers_; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 73b0443e50a0..d546fa36559e 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -157,6 +157,7 @@ ContentSite PublisherInfoToContentSite( content_site.provider = publisher_info.provider; content_site.favicon_url = publisher_info.favicon_url; content_site.id = publisher_info.id; + content_site.weight = publisher_info.weight; content_site.reconcile_stamp = publisher_info.reconcile_stamp; return content_site; } @@ -2104,46 +2105,47 @@ void RewardsServiceImpl::OnSetOnDemandFaviconComplete( callback(success, favicon_url); } -void RewardsServiceImpl::GetPublisherBanner(const std::string& publisher_id) { +void RewardsServiceImpl::GetPublisherBanner( + const std::string& publisher_id, + GetPublisherBannerCallback callback) { if (!Connected()) return; bat_ledger_->GetPublisherBanner(publisher_id, - base::BindOnce(&RewardsServiceImpl::OnPublisherBannerMojoProxy, - AsWeakPtr())); + base::BindOnce(&RewardsServiceImpl::OnPublisherBanner, + AsWeakPtr(), + std::move(callback))); } -void RewardsServiceImpl::OnPublisherBannerMojoProxy( +void RewardsServiceImpl::OnPublisherBanner( + GetPublisherBannerCallback callback, const std::string& banner) { + std::unique_ptr new_banner; + new_banner.reset(new brave_rewards::PublisherBanner()); + std::unique_ptr publisher_banner; + publisher_banner.reset(new ledger::PublisherBanner()); + if (!banner.empty()) { - publisher_banner.reset(new ledger::PublisherBanner()); publisher_banner->loadFromJson(banner); } - OnPublisherBanner(std::move(publisher_banner)); -} -void RewardsServiceImpl::OnPublisherBanner( - std::unique_ptr banner) { - brave_rewards::PublisherBanner new_banner; - - if (!banner) { + if (!publisher_banner) { return; } - new_banner.publisher_key = banner->publisher_key; - new_banner.title = banner->title; - new_banner.name = banner->name; - new_banner.description = banner->description; - new_banner.background = banner->background; - new_banner.logo = banner->logo; - new_banner.amounts = banner->amounts; - new_banner.social = banner->social; - new_banner.provider = banner->provider; - new_banner.verified = banner->verified; + new_banner->publisher_key = publisher_banner->publisher_key; + new_banner->title = publisher_banner->title; + new_banner->name = publisher_banner->name; + new_banner->description = publisher_banner->description; + new_banner->background = publisher_banner->background; + new_banner->logo = publisher_banner->logo; + new_banner->amounts = publisher_banner->amounts; + new_banner->social = publisher_banner->social; + new_banner->provider = publisher_banner->provider; + new_banner->verified = publisher_banner->verified; - for (auto& observer : observers_) - observer.OnPublisherBanner(this, new_banner); + std::move(callback).Run(std::move(new_banner)); } void RewardsServiceImpl::OnDonate_PublisherInfoSaved(ledger::Result result, diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 40a56259eb96..c5f0e0c2491d 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -160,8 +160,10 @@ class RewardsServiceImpl : public RewardsService, const std::string& publisher_blob) override; void GetContributionAmount( const GetContributionAmountCallback& callback) override; - void GetPublisherBanner(const std::string& publisher_id) override; - void OnPublisherBanner(std::unique_ptr banner); + void GetPublisherBanner(const std::string& publisher_id, + GetPublisherBannerCallback callback) override; + void OnPublisherBanner(GetPublisherBannerCallback callback, + const std::string& banner); void RemoveRecurringTip(const std::string& publisher_key) override; void OnGetRecurringTipsUI( GetRecurringTipsCallback callback, @@ -200,6 +202,9 @@ class RewardsServiceImpl : public RewardsService, void GetOneTimeTipsUI(GetOneTimeTipsCallback callback) override; + void SaveRecurringTip(const std::string& publisher_key, + const int amount) override; + // Testing methods void SetLedgerEnvForTesting(); @@ -264,8 +269,6 @@ class RewardsServiceImpl : public RewardsService, void OnContributionInfoSaved(const ledger::REWARDS_CATEGORY category, bool success); void OnRecurringTipSaved(bool success); - void SaveRecurringTip(const std::string& publisher_key, - const int amount); void OnGetRecurringTips( const ledger::PublisherInfoListCallback callback, const ledger::PublisherInfoList list); @@ -441,7 +444,6 @@ class RewardsServiceImpl : public RewardsService, void ShowNotificationTipsPaid(bool ac_enabled); // Mojo Proxy methods - void OnPublisherBannerMojoProxy(const std::string& banner); void OnGetConfirmationsHistory( brave_rewards::ConfirmationsHistoryCallback callback, const std::string& transactions); diff --git a/components/brave_rewards/browser/rewards_service_observer.h b/components/brave_rewards/browser/rewards_service_observer.h index f96b1d2ac38c..d549a1666b94 100644 --- a/components/brave_rewards/browser/rewards_service_observer.h +++ b/components/brave_rewards/browser/rewards_service_observer.h @@ -61,9 +61,6 @@ class RewardsServiceObserver : public base::CheckedObserver { const std::string& viewing_id, const std::string& category, const std::string& probi) {} - virtual void OnPublisherBanner( - brave_rewards::RewardsService* rewards_service, - const brave_rewards::PublisherBanner banner) {} virtual void OnRewardsMainEnabled( brave_rewards::RewardsService* rewards_service, bool rewards_main_enabled) {} diff --git a/components/brave_rewards/resources/donate/actions/donate_actions.ts b/components/brave_rewards/resources/donate/actions/donate_actions.ts index 531fb192f5bd..f586fe0c22f5 100644 --- a/components/brave_rewards/resources/donate/actions/donate_actions.ts +++ b/components/brave_rewards/resources/donate/actions/donate_actions.ts @@ -41,3 +41,7 @@ export const onReconcileStamp = (stamp: number) => action(types.ON_RECONCILE_STA export const onRecurringTipRemoved = (success: boolean) => action(types.ON_RECURRING_TIP_REMOVED, { success }) + +export const onRecurringTipSaved = (success: boolean) => action(types.ON_RECURRING_TIP_SAVED, { + success +}) diff --git a/components/brave_rewards/resources/donate/brave_donate.tsx b/components/brave_rewards/resources/donate/brave_donate.tsx index 36ff9d8eb68f..eff1ff988524 100644 --- a/components/brave_rewards/resources/donate/brave_donate.tsx +++ b/components/brave_rewards/resources/donate/brave_donate.tsx @@ -79,13 +79,18 @@ window.cr.define('brave_rewards_donate', function () { getActions().onRecurringTipRemoved(success) } + function recurringTipSaved (success: boolean) { + getActions().onRecurringTipSaved(success) + } + return { initialize, publisherBanner, walletProperties, recurringTips, reconcileStamp, - recurringTipRemoved + recurringTipRemoved, + recurringTipSaved } }) diff --git a/components/brave_rewards/resources/donate/constants/donate_types.ts b/components/brave_rewards/resources/donate/constants/donate_types.ts index fdcbd95f12a4..a41c8eed6011 100644 --- a/components/brave_rewards/resources/donate/constants/donate_types.ts +++ b/components/brave_rewards/resources/donate/constants/donate_types.ts @@ -12,5 +12,6 @@ export const enum types { ON_RECURRING_TIPS = '@@rewards/ON_RECURRING_TIPS', GET_RECONCILE_STAMP = '@@rewards/GET_RECONCILE_STAMP', ON_RECONCILE_STAMP = '@@rewards/ON_RECONCILE_STAMP', - ON_RECURRING_TIP_REMOVED = '@@rewards/ON_RECURRING_TIP_REMOVED' + ON_RECURRING_TIP_REMOVED = '@@rewards/ON_RECURRING_TIP_REMOVED', + ON_RECURRING_TIP_SAVED = '@@rewards/ON_RECURRING_TIP_SAVED' } diff --git a/components/brave_rewards/resources/donate/reducers/donate_reducer.ts b/components/brave_rewards/resources/donate/reducers/donate_reducer.ts index d3618e8aba70..a8a4a085c402 100644 --- a/components/brave_rewards/resources/donate/reducers/donate_reducer.ts +++ b/components/brave_rewards/resources/donate/reducers/donate_reducer.ts @@ -37,7 +37,9 @@ const publishersReducer: Reducer = (state: RewardsDonate.St state.publishers = {} } const publisher: RewardsDonate.Publisher = payload.data - state.publishers[publisher.publisherKey] = publisher + if (publisher && publisher.publisherKey) { + state.publishers[publisher.publisherKey] = publisher + } break } case types.GET_WALLET_PROPERTIES: @@ -69,6 +71,7 @@ const publishersReducer: Reducer = (state: RewardsDonate.St } case types.GET_RECURRING_TIPS: case types.ON_RECURRING_TIP_REMOVED: + case types.ON_RECURRING_TIP_SAVED: chrome.send('brave_rewards_donate.getRecurringTips') break case types.ON_RECURRING_TIPS: diff --git a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json index 2eda806df35d..5d8b17fb25cb 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json +++ b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json @@ -388,5 +388,9 @@ "serviceTextPanelWelcome": { "message": "By clicking ‘Join Rewards’, you indicate that you have read and agree to the", "description": "Terms of service panel opt-in text" + }, + "bat": { + "message": "BAT", + "description": "BAT text for displaying converted tip amount." } } diff --git a/components/brave_rewards/resources/extension/brave_rewards/actions/rewards_panel_actions.ts b/components/brave_rewards/resources/extension/brave_rewards/actions/rewards_panel_actions.ts index 4271871d0136..6c0d4f27c5c8 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/actions/rewards_panel_actions.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/actions/rewards_panel_actions.ts @@ -114,3 +114,21 @@ export const onSettingSave = (key: string, value: any) => action(types.ON_SETTIN key, value }) + +export const saveRecurringTip = (publisherKey: string, newAmount: number) => action(types.SAVE_RECURRING_TIP, { + publisherKey, + newAmount +}) + +export const removeRecurringTip = (publisherKey: string) => action(types.REMOVE_RECURRING_TIP, { + publisherKey +}) + +export const onRecurringTips = (result: RewardsExtension.RecurringTips) => action(types.ON_RECURRING_TIPS, { + result +}) + +export const onPublisherBanner = (banner: RewardsExtension.PublisherBanner) => + action(types.ON_PUBLISHER_BANNER, { + banner + }) diff --git a/components/brave_rewards/resources/extension/brave_rewards/background/api/locale_api.ts b/components/brave_rewards/resources/extension/brave_rewards/background/api/locale_api.ts index 7880f827e285..e4f5bcc9d7f3 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background/api/locale_api.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background/api/locale_api.ts @@ -26,6 +26,7 @@ export const getUIMessages = (): Record => { 'backupNow', 'backupWalletNotification', 'backupWalletTitle', + 'bat', 'braveAdsTitle', 'braveContributeTitle', 'braveRewards', 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 eff0d9b62706..52d2bbab2f9b 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 @@ -10,6 +10,13 @@ chrome.braveRewards.onWalletCreated.addListener(() => { chrome.braveRewards.onPublisherData.addListener((windowId: number, publisher: RewardsExtension.Publisher) => { rewardsPanelActions.onPublisherData(windowId, publisher) + + // Get publisher amounts + if (publisher && publisher.publisher_key) { + chrome.braveRewards.getPublisherBanner(publisher.publisher_key, ((banner: RewardsExtension.PublisherBanner) => { + rewardsPanelActions.onPublisherBanner(banner) + })) + } }) chrome.braveRewards.onWalletProperties.addListener((properties: RewardsExtension.WalletProperties) => { @@ -63,3 +70,19 @@ chrome.braveRewards.onPublisherListNormalized.addListener((properties: RewardsEx chrome.braveRewards.onExcludedSitesChanged.addListener((properties: RewardsExtension.ExcludedSitesChanged) => { rewardsPanelActions.onExcludedSitesChanged(properties) }) + +chrome.braveRewards.onRecurringTipSaved.addListener((success: boolean) => { + if (success) { + chrome.braveRewards.getRecurringTips((tips: RewardsExtension.RecurringTips) => { + rewardsPanelActions.onRecurringTips(tips) + }) + } +}) + +chrome.braveRewards.onRecurringTipRemoved.addListener((success: boolean) => { + if (success) { + chrome.braveRewards.getRecurringTips((tips: RewardsExtension.RecurringTips) => { + rewardsPanelActions.onRecurringTips(tips) + }) + } +}) 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 c9d6e7963766..a76d048e966d 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 @@ -305,6 +305,44 @@ export const rewardsPanelReducer = (state: RewardsExtension.State | undefined, a } break } + case types.REMOVE_RECURRING_TIP: { + let publisherKey = payload.publisherKey + if (publisherKey == null) { + break + } + chrome.braveRewards.removeRecurringTip(publisherKey) + break + } + case types.SAVE_RECURRING_TIP: { + let newAmount = payload.newAmount + let publisherKey = payload.publisherKey + + if (newAmount < 0 || + isNaN(newAmount) || + publisherKey == null) { + break + } + + chrome.braveRewards.saveRecurringTip(publisherKey, newAmount) + break + } + case types.ON_RECURRING_TIPS: { + state = { ...state } + state.recurringTips = payload.result.recurringTips + break + } + case types.ON_PUBLISHER_BANNER: { + if (!payload.banner || !payload.banner.publisherKey) { + break + } + + state = { ...state } + if (!state.tipAmounts) { + state.tipAmounts = {} + } + state.tipAmounts[payload.banner.publisherKey] = payload.banner.amounts + break + } } return state } diff --git a/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts b/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts index caf9e337997e..ad1f580363dd 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts @@ -35,7 +35,9 @@ export const defaultState: RewardsExtension.State = { enabledMain: false, enabledAC: false, grants: [], - currentGrant: undefined + currentGrant: undefined, + recurringTips: [], + tipAmounts: {} } const cleanData = (state: RewardsExtension.State) => { diff --git a/components/brave_rewards/resources/extension/brave_rewards/components/app.tsx b/components/brave_rewards/resources/extension/brave_rewards/components/app.tsx index baa8329477cb..e8cedbf4eea5 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/components/app.tsx +++ b/components/brave_rewards/resources/extension/brave_rewards/components/app.tsx @@ -40,9 +40,14 @@ export class RewardsPanel extends React.Component { chrome.braveRewards.getRewardsMainEnabled(((enabled: boolean) => { this.props.actions.onEnabledMain(enabled) })) + chrome.braveRewards.getACEnabled(((enabled: boolean) => { this.props.actions.onEnabledAC(enabled) })) + + chrome.braveRewards.getRecurringTips((tips: RewardsExtension.RecurringTips) => { + this.props.actions.onRecurringTips(tips) + }) } componentDidUpdate (prevProps: Props, prevState: State) { diff --git a/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx b/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx index 859b29523737..43250088abf2 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx +++ b/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx @@ -28,12 +28,15 @@ interface State { } export class Panel extends React.Component { + private defaultTipAmounts: number[] + constructor (props: Props) { super(props) this.state = { showSummary: true, publisherKey: null } + this.defaultTipAmounts = [1, 5, 10] } get actions () { @@ -335,6 +338,64 @@ export class Panel extends React.Component { } } + onContributionAmountChange = (event: React.ChangeEvent) => { + const newValue = parseInt(event.target.value, 10) + const publisher: RewardsExtension.Publisher | undefined = this.getPublisher() + + if (!publisher || !publisher.publisher_key) { + return + } + + const publisherKey = publisher.publisher_key + + if (newValue === 0) { + this.actions.removeRecurringTip(publisherKey) + } else { + this.actions.saveRecurringTip(publisherKey, newValue) + } + } + + generateAmounts = (publisher?: RewardsExtension.Publisher) => { + const { tipAmounts } = this.props.rewardsPanelData + const { rates } = this.props.rewardsPanelData.walletProperties + + const publisherKey = publisher && publisher.publisher_key + const initialAmounts = ( + !publisherKey || + !tipAmounts || + !tipAmounts[publisherKey] || + tipAmounts[publisherKey].length === 0 + ) ? this.defaultTipAmounts : tipAmounts[publisherKey] + + const amounts = [0, ...initialAmounts] + + return amounts.map((value: number) => { + return { + tokens: value.toFixed(1), + converted: utils.convertBalance(value.toString(), rates), + selected: false + } + }) + } + + getContribution = (publisher?: RewardsExtension.Publisher) => { + let defaultContribution = '0.0' + const { recurringTips } = this.props.rewardsPanelData + + if (!recurringTips || + (!publisher || !publisher.publisher_key)) { + return defaultContribution + } + + recurringTips.map((tip: any) => { + if (tip.publisherKey === publisher.publisher_key) { + defaultContribution = tip.amount.toFixed(1) + } + }) + + return defaultContribution + } + render () { const { pendingContributionTotal, enabledAC } = this.props.rewardsPanelData const { balance, rates, grants } = this.props.rewardsPanelData.walletProperties @@ -345,6 +406,10 @@ export class Panel extends React.Component { const notificationType = this.getNotificationProp('type', notification) const notificationClick = this.getNotificationClickEvent(notificationType, notificationId) const { currentGrant } = this.props.rewardsPanelData + const defaultContribution = this.getContribution(publisher) + const tipAmounts = defaultContribution !== '0.0' + ? this.generateAmounts(publisher) + : undefined const pendingTotal = parseFloat( (pendingContributionTotal || 0).toFixed(1)) @@ -398,17 +463,18 @@ export class Panel extends React.Component { platform={publisher.provider as Provider} publisherName={publisher.name} publisherImg={faviconUrl} - monthlyAmount={'10.0'} + monthlyAmount={defaultContribution} isVerified={publisher.verified} tipsEnabled={true} includeInAuto={!publisher.excluded} attentionScore={(publisher.percentage || 0).toString()} onToggleTips={this.doNothing} donationAction={this.showDonateToSiteDetail} - onAmountChange={this.doNothing} + onAmountChange={this.onContributionAmountChange} onIncludeInAuto={this.switchAutoContribute} showUnVerified={!publisher.verified} acEnabled={enabledAC} + donationAmounts={tipAmounts} moreLink={'https://brave.com/faq-rewards/#unclaimed-funds'} /> : null diff --git a/components/brave_rewards/resources/extension/brave_rewards/constants/rewards_panel_types.ts b/components/brave_rewards/resources/extension/brave_rewards/constants/rewards_panel_types.ts index 2811e4a38df2..c4733657c1b0 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/constants/rewards_panel_types.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/constants/rewards_panel_types.ts @@ -30,7 +30,11 @@ export const enum types { ON_ENABLED_AC = '@@rewards_panel/ON_ENABLED_AC', ON_PUBLISHER_LIST_NORMALIZED = '@@rewards_panel/ON_PUBLISHER_LIST_NORMALIZED', ON_EXCLUDED_SITES_CHANGED = '@@rewards_panel/ON_EXCLUDED_SITES_CHANGED', - ON_SETTING_SAVE = '@@rewards_panel/ON_SETTING_SAVE' + ON_SETTING_SAVE = '@@rewards_panel/ON_SETTING_SAVE', + SAVE_RECURRING_TIP = '@@rewards_panel/SAVE_RECURRING_TIP', + REMOVE_RECURRING_TIP = '@@rewards_panel/REMOVE_RECURRING_TIP', + ON_RECURRING_TIPS = '@@rewards_panel/ON_RECURRING_TIPS', + ON_PUBLISHER_BANNER = '@@rewards_panel/ON_PUBLISHER_BANNER' } // Note: This declaration must match the RewardsNotificationType enum in diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index 4aaed0ff3de3..52d2221c8f1e 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -64,6 +64,16 @@ declare namespace chrome.braveRewards { addListener: (callback: (properties: RewardsExtension.ExcludedSitesChanged) => void) => void } const saveSetting: (key: string, value: string) => {} + const getRecurringTips: (callback: (tips: RewardsExtension.RecurringTips) => void) => {} + const saveRecurringTip: (publisherKey: string, newAmount: string) => {} + const removeRecurringTip: (publisherKey: string) => {} + const getPublisherBanner: (publisherKey: string, callback: (banner: RewardsExtension.PublisherBanner) => void) => {} + const onRecurringTipSaved: { + addListener: (callback: (success: boolean) => void) => void + } + const onRecurringTipRemoved: { + addListener: (callback: (success: boolean) => void) => void + } } declare namespace chrome.rewardsNotifications { diff --git a/components/definitions/rewardsExtensions.d.ts b/components/definitions/rewardsExtensions.d.ts index a881db197690..f57d812d5b94 100644 --- a/components/definitions/rewardsExtensions.d.ts +++ b/components/definitions/rewardsExtensions.d.ts @@ -13,6 +13,8 @@ declare namespace RewardsExtension { walletCreating: boolean walletCreateFailed: boolean walletProperties: WalletProperties + recurringTips: Record[] + tipAmounts: Record } interface ApplicationState { @@ -125,4 +127,21 @@ declare namespace RewardsExtension { publisher_key: string excluded: boolean } + + interface RecurringTips { + recurringTips: Record[] + } + + interface PublisherBanner { + publisherKey: string + name: string + title: string + description: string + background: string + logo: string + amounts: number[], + provider: string + social: Record + verified: boolean + } } diff --git a/package-lock.json b/package-lock.json index f3e35badf8ed..afea65ebd7c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1597,8 +1597,8 @@ } }, "brave-ui": { - "version": "github:brave/brave-ui#d59401050d87a59bc15f743dab8ce06454b08671", - "from": "github:brave/brave-ui#d59401050d87a59bc15f743dab8ce06454b08671", + "version": "github:brave/brave-ui#1b1ee01094d6caa3336dcd42298c4178e6930185", + "from": "github:brave/brave-ui#1b1ee01094d6caa3336dcd42298c4178e6930185", "dev": true, "requires": { "@ctrl/tinycolor": "^2.2.1", diff --git a/package.json b/package.json index 7b3badbc3152..6d84c3be151a 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,7 @@ "@types/react-redux": "6.0.4", "@types/redux-logger": "^3.0.7", "awesome-typescript-loader": "^5.2.1", - "brave-ui": "github:brave/brave-ui#d59401050d87a59bc15f743dab8ce06454b08671", + "brave-ui": "github:brave/brave-ui#1b1ee01094d6caa3336dcd42298c4178e6930185", "css-loader": "^2.1.1", "csstype": "^2.5.5", "deep-freeze-node": "^1.1.3",