From 90eab95f58ca8fcbcd05375ac439e38c08101423 Mon Sep 17 00:00:00 2001 From: Nejc Zdovc Date: Wed, 9 Jan 2019 16:58:10 +0100 Subject: [PATCH] Merge pull request #1236 from brave/contribution-nonverified Adds new contribution flow for unverified publishers --- browser/extensions/api/brave_rewards_api.cc | 22 ++- browser/extensions/api/brave_rewards_api.h | 9 +- browser/ui/webui/brave_rewards_ui.cc | 21 ++ browser/ui/webui/brave_webui_source.cc | 2 + common/extensions/api/brave_rewards.json | 8 +- .../browser/pending_contribution.cc | 16 ++ .../browser/pending_contribution.h | 27 +++ .../browser/publisher_info_database.cc | 119 +++++++++++- .../browser/publisher_info_database.h | 7 + .../browser/recurring_donation.h | 2 - .../brave_rewards/browser/rewards_service.h | 3 + .../browser/rewards_service_impl.cc | 44 +++++ .../browser/rewards_service_impl.h | 7 + .../_locales/en_US/messages.json | 16 +- .../actions/rewards_panel_actions.ts | 4 + .../background/api/locale_api.ts | 3 +- .../reducers/rewards_panel_reducer.ts | 6 + .../brave_rewards/background/storage.ts | 3 +- .../brave_rewards/components/panel.tsx | 29 ++- .../constants/rewards_panel_types.ts | 4 +- .../resources/ui/actions/rewards_actions.ts | 6 + .../resources/ui/brave_rewards.tsx | 7 +- .../resources/ui/components/contributeBox.tsx | 12 -- .../resources/ui/components/pageWallet.tsx | 19 +- .../resources/ui/components/settingsPage.tsx | 1 + .../resources/ui/constants/rewards_types.ts | 4 +- .../resources/ui/reducers/wallet_reducer.ts | 11 ++ .../brave_rewards/resources/ui/storage.ts | 3 +- components/definitions/chromel.d.ts | 2 +- components/definitions/rewards.d.ts | 1 + components/definitions/rewardsExtensions.d.ts | 1 + .../resources/brave_components_strings.grd | 4 +- package-lock.json | 4 +- package.json | 2 +- .../include/bat/ledger/ledger.h | 2 +- .../include/bat/ledger/ledger_client.h | 4 + .../include/bat/ledger/pending_contribution.h | 41 ++++ .../include/bat/ledger/publisher_info.h | 6 +- .../src/bat/ledger/ledger.cc | 71 +++++++ .../bat-native-ledger/src/bat_contribution.cc | 180 +++++++++++++----- .../bat-native-ledger/src/bat_contribution.h | 17 +- vendor/bat-native-ledger/src/bat_helper.cc | 48 ++++- vendor/bat-native-ledger/src/bat_helper.h | 5 +- .../bat-native-ledger/src/bat_publishers.cc | 28 +-- vendor/bat-native-ledger/src/bat_publishers.h | 12 +- vendor/bat-native-ledger/src/ledger_impl.cc | 28 ++- vendor/bat-native-ledger/src/ledger_impl.h | 6 +- .../src/rapidjson_bat_helper.h | 2 + 48 files changed, 728 insertions(+), 151 deletions(-) create mode 100644 components/brave_rewards/browser/pending_contribution.cc create mode 100644 components/brave_rewards/browser/pending_contribution.h create mode 100644 vendor/bat-native-ledger/include/bat/ledger/pending_contribution.h diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index cd9bf9a0395c..20fae2b79a59 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -138,22 +138,30 @@ ExtensionFunction::ResponseAction BraveRewardsGetGrantFunction::Run() { return RespondNow(NoArguments()); } -BraveRewardsGetNonVerifiedSettingsFunction:: -~BraveRewardsGetNonVerifiedSettingsFunction() { +BraveRewardsGetPendingContributionsTotalFunction:: +~BraveRewardsGetPendingContributionsTotalFunction() { } ExtensionFunction::ResponseAction -BraveRewardsGetNonVerifiedSettingsFunction::Run() { +BraveRewardsGetPendingContributionsTotalFunction::Run() { Profile* profile = Profile::FromBrowserContext(browser_context()); RewardsService* rewards_service_ = RewardsServiceFactory::GetForProfile(profile); - bool non_verified = true; - if (rewards_service_) { - non_verified = rewards_service_->GetPublisherAllowNonVerified(); + if (!rewards_service_) { + return RespondNow(OneArgument( + std::make_unique(0.0))); } - return RespondNow(OneArgument(std::make_unique(non_verified))); + rewards_service_->GetPendingContributionsTotal(base::Bind( + &BraveRewardsGetPendingContributionsTotalFunction::OnGetPendingTotal, + this)); + return RespondLater(); +} + +void BraveRewardsGetPendingContributionsTotalFunction::OnGetPendingTotal( + double amount) { + Respond(OneArgument(std::make_unique(amount))); } } // namespace api diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index 5739a93d44f8..3170b133086b 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -81,14 +81,17 @@ class BraveRewardsGetGrantFunction : public UIThreadExtensionFunction { ResponseAction Run() override; }; -class BraveRewardsGetNonVerifiedSettingsFunction : public UIThreadExtensionFunction { +class BraveRewardsGetPendingContributionsTotalFunction : public UIThreadExtensionFunction { public: - DECLARE_EXTENSION_FUNCTION("braveRewards.getNonVerifiedSettings", UNKNOWN) + DECLARE_EXTENSION_FUNCTION("braveRewards.getPendingContributionsTotal", UNKNOWN) protected: - ~BraveRewardsGetNonVerifiedSettingsFunction() override; + ~BraveRewardsGetPendingContributionsTotalFunction() override; ResponseAction Run() override; + + private: + void OnGetPendingTotal(double amount); }; } // namespace api diff --git a/browser/ui/webui/brave_rewards_ui.cc b/browser/ui/webui/brave_rewards_ui.cc index 14c21549eaa6..a9a5181398b9 100644 --- a/browser/ui/webui/brave_rewards_ui.cc +++ b/browser/ui/webui/brave_rewards_ui.cc @@ -67,6 +67,8 @@ class RewardsDOMHandler : public WebUIMessageHandler, void UpdateTipsList(const base::ListValue* args); void GetContributionList(const base::ListValue* args); void CheckImported(const base::ListValue* args); + void GetPendingContributionsTotal(const base::ListValue* args); + void OnGetPendingContributionsTotal(double amount); // RewardsServiceObserver implementation void OnWalletInitialized(brave_rewards::RewardsService* rewards_service, @@ -191,6 +193,9 @@ void RewardsDOMHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("brave_rewards.checkImported", base::BindRepeating(&RewardsDOMHandler::CheckImported, base::Unretained(this))); + web_ui()->RegisterMessageCallback("brave_rewards.getPendingContributionsTotal", + base::BindRepeating(&RewardsDOMHandler::GetPendingContributionsTotal, + base::Unretained(this))); } void RewardsDOMHandler::Init() { @@ -675,6 +680,22 @@ void RewardsDOMHandler::CheckImported(const base::ListValue *args) { } } +void RewardsDOMHandler::GetPendingContributionsTotal( + const base::ListValue* args) { + if (rewards_service_) { + rewards_service_->GetPendingContributionsTotal(base::Bind( + &RewardsDOMHandler::OnGetPendingContributionsTotal, + weak_factory_.GetWeakPtr())); + } +} + +void RewardsDOMHandler::OnGetPendingContributionsTotal(double amount) { + if (web_ui()->CanCallJavascript()) { + web_ui()->CallJavascriptFunctionUnsafe( + "brave_rewards.pendingContributionTotal", base::Value(amount)); + } +} + } // namespace BraveRewardsUI::BraveRewardsUI(content::WebUI* web_ui, const std::string& name) diff --git a/browser/ui/webui/brave_webui_source.cc b/browser/ui/webui/brave_webui_source.cc index 26acd5022ef6..4588b6e36f61 100644 --- a/browser/ui/webui/brave_webui_source.cc +++ b/browser/ui/webui/brave_webui_source.cc @@ -347,6 +347,8 @@ void CustomizeWebUIHTMLSource(const std::string &name, content::WebUIDataSource* { "recurringDonation", IDS_BRAVE_UI_RECURRING_DONATION }, { "recurringDonations", IDS_BRAVE_UI_RECURRING_DONATIONS }, { "remove", IDS_BRAVE_UI_REMOVE }, + { "reservedAmountText", IDS_BRAVE_UI_RESERVED_AMOUNT_TEXT }, + { "reservedMoreLink", IDS_BRAVE_UI_RESERVED_MORE_LINK }, { "restore", IDS_BRAVE_UI_RESTORE }, { "restoreAll", IDS_BRAVE_UI_RESTORE_ALL }, { "reviewSitesMsg", IDS_BRAVE_UI_REVIEW_SITE_MSG }, diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index e8ca262d3442..5a85b6e00ab2 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -258,17 +258,17 @@ "parameters": [] }, { - "name": "getNonVerifiedSettings", + "name": "getPendingContributionsTotal", "type": "function", - "description": "Gets auto contribute settings", + "description": "Gets pending contributions total", "parameters": [ { "type": "function", "name": "callback", "parameters": [ { - "name": "nonVerified", - "type": "boolean" + "name": "amount", + "type": "number" } ] } diff --git a/components/brave_rewards/browser/pending_contribution.cc b/components/brave_rewards/browser/pending_contribution.cc new file mode 100644 index 000000000000..8caefa9c387b --- /dev/null +++ b/components/brave_rewards/browser/pending_contribution.cc @@ -0,0 +1,16 @@ +/* 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/components/brave_rewards/browser/pending_contribution.h" + +namespace brave_rewards { + +PendingContribution::PendingContribution() : + amount(0), + added_date(0), + reconcile_date(0) { +} + +PendingContribution::~PendingContribution() { } + +} // namespace brave_rewards diff --git a/components/brave_rewards/browser/pending_contribution.h b/components/brave_rewards/browser/pending_contribution.h new file mode 100644 index 000000000000..368760b38b04 --- /dev/null +++ b/components/brave_rewards/browser/pending_contribution.h @@ -0,0 +1,27 @@ +/* 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_PAYMENTS_PENDING_CONTRIBUTION_ +#define BRAVE_BROWSER_PAYMENTS_PENDING_CONTRIBUTION_ + +#include + +namespace brave_rewards { + +struct PendingContribution { + PendingContribution(); + ~PendingContribution(); + PendingContribution(const PendingContribution& data) = default; + + std::string publisher_key; + double amount = 0; + uint32_t added_date = 0; + uint32_t reconcile_date = 0; +}; + +using PendingContributionList = std::vector; + +} // namespace brave_rewards + +#endif //BRAVE_BROWSER_PAYMENTS_PENDING_CONTRIBUTION_ diff --git a/components/brave_rewards/browser/publisher_info_database.cc b/components/brave_rewards/browser/publisher_info_database.cc index 48af188c99bf..73a1feb2f6c4 100644 --- a/components/brave_rewards/browser/publisher_info_database.cc +++ b/components/brave_rewards/browser/publisher_info_database.cc @@ -22,7 +22,7 @@ namespace brave_rewards { namespace { -const int kCurrentVersionNumber = 2; +const int kCurrentVersionNumber = 3; const int kCompatibleVersionNumber = 1; } // namespace @@ -56,12 +56,14 @@ bool PublisherInfoDatabase::Init() { !CreateContributionInfoTable() || !CreateActivityInfoTable() || !CreateMediaPublisherInfoTable() || - !CreateRecurringDonationTable()) + !CreateRecurringDonationTable() || + !CreatePendingContributionsTable()) return false; CreateContributionInfoIndex(); CreateActivityInfoIndex(); CreateRecurringDonationIndex(); + CreatePendingContributionsIndex(); // Version check. sql::InitStatus version_status = EnsureCurrentVersion(); @@ -664,6 +666,97 @@ bool PublisherInfoDatabase::RemoveRecurring(const std::string& publisher_key) { return statement.Run(); } +bool PublisherInfoDatabase::CreatePendingContributionsTable() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + const char* name = "pending_contribution"; + if (GetDB().DoesTableExist(name)) { + return true; + } + + std::string sql; + sql.append("CREATE TABLE "); + sql.append(name); + sql.append( + "(" + "publisher_id LONGVARCHAR NOT NULL," + "amount DOUBLE DEFAULT 0 NOT NULL," + "added_date INTEGER DEFAULT 0 NOT NULL," + "viewing_id LONGVARCHAR NOT NULL," + "category INTEGER NOT NULL," + "CONSTRAINT fk_pending_contribution_publisher_id" + " FOREIGN KEY (publisher_id)" + " REFERENCES publisher_info (publisher_id)" + " ON DELETE CASCADE)"); + return GetDB().Execute(sql.c_str()); +} + +bool PublisherInfoDatabase::CreatePendingContributionsIndex() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return GetDB().Execute( + "CREATE INDEX IF NOT EXISTS pending_contribution_publisher_id_index " + "ON pending_contribution (publisher_id)"); +} + +bool PublisherInfoDatabase::InsertPendingContribution +(const ledger::PendingContributionList& list) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + bool initialized = Init(); + DCHECK(initialized); + + if (!initialized) { + return false; + } + + base::Time now = base::Time::Now(); + double now_seconds = now.ToDoubleT(); + + sql::Transaction transaction(&GetDB()); + if (!transaction.Begin()) { + return false; + } + + for (const auto& item : list.list_) { + sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, + "INSERT INTO pending_contribution " + "(publisher_id, amount, added_date, viewing_id, category) " + "VALUES (?, ?, ?, ?, ?)")); + + statement.BindString(0, item.publisher_key); + statement.BindDouble(1, item.amount); + statement.BindInt64(2, now_seconds); + statement.BindString(3, item.viewing_id); + statement.BindInt(4, item.category); + statement.Run(); + } + + return transaction.Commit(); +} + +double PublisherInfoDatabase::GetReservedAmount() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + bool initialized = Init(); + DCHECK(initialized); + + double amount = 0.0; + + if (!initialized) { + return amount; + } + + sql::Statement info_sql( + db_.GetUniqueStatement("SELECT sum(amount) FROM pending_contribution")); + + if (info_sql.Step()) { + amount = info_sql.ColumnDouble(0); + } + + return amount; +} + // static int PublisherInfoDatabase::GetCurrentVersion() { return kCurrentVersionNumber; @@ -751,6 +844,16 @@ bool PublisherInfoDatabase::MigrateV1toV2() { return CreateRecurringDonationIndex(); } +bool PublisherInfoDatabase::MigrateV2toV3() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!CreatePendingContributionsTable()) { + return false; + } + + return CreatePendingContributionsIndex(); +} + sql::InitStatus PublisherInfoDatabase::EnsureCurrentVersion() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -763,15 +866,21 @@ sql::InitStatus PublisherInfoDatabase::EnsureCurrentVersion() { const int old_version = meta_table_.GetVersionNumber(); const int cur_version = GetCurrentVersion(); - // Migration from version 1 to version 2 - if (old_version == 1 && cur_version == 2) { + // to version 2 + if (old_version < 2 && cur_version < 3) { if (!MigrateV1toV2()) { LOG(ERROR) << "DB: Error with MigrateV1toV2"; } + } - meta_table_.SetVersionNumber(cur_version); + // to version 3 + if (old_version < 3 && cur_version < 4) { + if (!MigrateV2toV3()) { + LOG(ERROR) << "DB: Error with MigrateV2toV3"; + } } + meta_table_.SetVersionNumber(cur_version); return sql::INIT_OK; } diff --git a/components/brave_rewards/browser/publisher_info_database.h b/components/brave_rewards/browser/publisher_info_database.h index 397a1a8f543d..76ea55f790bd 100644 --- a/components/brave_rewards/browser/publisher_info_database.h +++ b/components/brave_rewards/browser/publisher_info_database.h @@ -14,7 +14,9 @@ #include "base/memory/memory_pressure_listener.h" #include "base/sequence_checker.h" #include "bat/ledger/publisher_info.h" +#include "bat/ledger/pending_contribution.h" #include "brave/components/brave_rewards/browser/contribution_info.h" +#include "brave/components/brave_rewards/browser/pending_contribution.h" #include "brave/components/brave_rewards/browser/recurring_donation.h" #include "build/build_config.h" #include "sql/database.h" @@ -50,6 +52,8 @@ class PublisherInfoDatabase { void GetRecurringDonations(ledger::PublisherInfoList* list); void GetTips(ledger::PublisherInfoList* list, ledger::PUBLISHER_MONTH month, int year); bool RemoveRecurring(const std::string& publisher_key); + bool InsertPendingContribution(const ledger::PendingContributionList& list); + double GetReservedAmount(); // Returns the current version of the publisher info database static int GetCurrentVersion(); @@ -72,6 +76,8 @@ class PublisherInfoDatabase { bool CreateActivityInfoIndex(); bool CreateRecurringDonationTable(); bool CreateRecurringDonationIndex(); + bool CreatePendingContributionsTable(); + bool CreatePendingContributionsIndex(); std::string BuildClauses(int start, int limit, @@ -84,6 +90,7 @@ class PublisherInfoDatabase { sql::InitStatus EnsureCurrentVersion(); bool MigrateV1toV2(); + bool MigrateV2toV3(); sql::Database db_; sql::MetaTable meta_table_; diff --git a/components/brave_rewards/browser/recurring_donation.h b/components/brave_rewards/browser/recurring_donation.h index a080d871c786..f235ebb468f8 100644 --- a/components/brave_rewards/browser/recurring_donation.h +++ b/components/brave_rewards/browser/recurring_donation.h @@ -7,8 +7,6 @@ #include -#include "brave/components/brave_rewards/browser/content_site.h" - namespace brave_rewards { struct RecurringDonation { RecurringDonation(); diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index 2a15835c265e..3e647ea62699 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -40,6 +40,7 @@ class RewardsServiceObserver; using GetCurrentContributeListCallback = base::Callback, uint32_t /* next_record */)>; +using GetPendingContributionsTotalCallback = base::Callback; class RewardsService : public KeyedService { public: @@ -111,6 +112,8 @@ class RewardsService : public KeyedService { std::string publisher_key, bool excluded, uint64_t windowId) = 0; virtual RewardsNotificationService* GetNotificationService() const = 0; virtual bool CheckImported() = 0; + virtual void GetPendingContributionsTotal( + const GetPendingContributionsTotalCallback& callback) = 0; void AddObserver(RewardsServiceObserver* observer); void RemoveObserver(RewardsServiceObserver* observer); diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 381a2ce0b989..6485dc172cc8 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -1722,4 +1722,48 @@ void RewardsServiceImpl::OnDonate( OnDonate(publisher_key, amount, recurring, &info); } +bool SavePendingContributionOnFileTaskRunner(PublisherInfoDatabase* backend, + const ledger::PendingContributionList& list) { + if (!backend) { + return false; + } + + return backend->InsertPendingContribution(list); +} + +void RewardsServiceImpl::OnSavePendingContribution(bool result) { + // TODO(nejczdovc) add callback with db result +} + +void RewardsServiceImpl::SavePendingContribution( + const ledger::PendingContributionList& list) { + base::PostTaskAndReplyWithResult( + file_task_runner_.get(), + FROM_HERE, + base::Bind(&SavePendingContributionOnFileTaskRunner, + publisher_info_backend_.get(), + list), + base::Bind(&RewardsServiceImpl::OnSavePendingContribution, + AsWeakPtr())); +} + +double PendingContributionsTotalOnFileTaskRunner( + PublisherInfoDatabase* backend) { + if (!backend) { + return 0; + } + + return backend->GetReservedAmount(); +} + +void RewardsServiceImpl::GetPendingContributionsTotal( + const GetPendingContributionsTotalCallback& callback) { + base::PostTaskAndReplyWithResult( + file_task_runner_.get(), + FROM_HERE, + base::Bind(&PendingContributionsTotalOnFileTaskRunner, + publisher_info_backend_.get()), + callback); +} + } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 1fc903f31a03..ef543744adf4 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -133,6 +133,8 @@ class RewardsServiceImpl : public RewardsService, std::unique_ptr info) override; void OnDonate(const std::string& publisher_key, int amount, bool recurring, std::unique_ptr site) override; + void GetPendingContributionsTotal( + const GetPendingContributionsTotalCallback& callback) override; private: friend void RunIOTaskCallback( @@ -280,6 +282,11 @@ class RewardsServiceImpl : public RewardsService, void OnIOTaskComplete(std::function callback); + void SavePendingContribution( + const ledger::PendingContributionList& list) override; + + void OnSavePendingContribution(bool result); + // URLFetcherDelegate impl void OnURLFetchComplete(const net::URLFetcher* source) override; 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 0aeb6f1e00c2..54f806dfed77 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 @@ -201,20 +201,24 @@ "message": "No activities yet…", "description": "Allows the user to see that there have been no transactions or other activity in their wallet" }, - "changeSettingsButton": { - "message": "Change Auto-Contribute settings", - "description": "CAT that user can do to open auto contribute settings" - }, "unVerifiedPublisher": { "message": "Not yet verified", "description": "Status of the publisher shown in the panel" }, "unVerifiedText": { - "message": "This creator has not yet signed up to receive contributions from Brave users.", + "message": "This creator has not yet signed up to receive contributions from Brave users. Any tips you send will remain in your wallet until they verify.", "description": "Notice about unverified publisher." }, "unVerifiedTextMore": { "message": "Learn more.", - "description": "Learn more button that opens FAQ" + "description": "Text for the link that explains more about reserved amount" + }, + "reservedAmountText": { + "message": "You’ve designated {{reservedAmount}} BAT for creators who haven’t yet signed up to receive contributions. Your browser will keep trying to contribute until they verify, or until 90 days have passed.", + "description": "Notification about how much BAT do you have reserved" + }, + "reservedMoreLink": { + "message": "Learn more.", + "description": "Text for the link that explains more about reserved 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 8f2fe2ec81ba..518ad635f0e3 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 @@ -62,3 +62,7 @@ export const includeInAutoContribution = (publisherKey: string, excluded: boolea }) export const getGrant = () => action(types.GET_GRANT, {}) + +export const OnPendingContributionsTotal = (amount: number) => action(types.ON_PENDING_CONTRIBUTIONS_TOTAL, { + amount +}) 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 05bb07d9c46f..6c9d791eb418 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,7 +26,6 @@ export const getUIMessages = (): Record => { 'braveContributeTitle', 'braveRewards', 'braveRewardsCreatingText', - 'changeSettingsButton', 'donateMonthly', 'donateNow', 'earningsAds', @@ -52,6 +51,8 @@ export const getUIMessages = (): Record => { 'on', 'oneTimeDonation', 'recurringDonations', + 'reservedAmountText', + 'reservedMoreLink', 'rewardsContribute', 'rewardsContributeAttentionScore', 'rewardsSummary', 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 c014ca8a563a..20e4967f5071 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 @@ -212,6 +212,12 @@ export const rewardsPanelReducer = (state: RewardsExtension.State | undefined, a chrome.braveRewards.getGrant() break } + case types.ON_PENDING_CONTRIBUTIONS_TOTAL: + { + state = { ...state } + state.pendingContributionTotal = payload.amount + break + } } if (state !== startingState) { 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 9f288d5a23eb..707ae99af962 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background/storage.ts @@ -29,7 +29,8 @@ const defaultState: RewardsExtension.State = { total: '0' }, notifications: {}, - currentNotification: undefined + currentNotification: undefined, + pendingContributionTotal: 0 } const cleanData = (state: RewardsExtension.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 32092c9f3ef2..c3edcff133c5 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx +++ b/components/brave_rewards/resources/extension/brave_rewards/components/panel.tsx @@ -24,7 +24,6 @@ interface Props extends RewardsExtension.ComponentProps { interface State { showSummary: boolean publisherKey: string | null - nonVerified: boolean } export class Panel extends React.Component { @@ -32,8 +31,7 @@ export class Panel extends React.Component { super(props) this.state = { showSummary: true, - publisherKey: null, - nonVerified: true + publisherKey: null } } @@ -55,10 +53,8 @@ export class Panel extends React.Component { this.actions.getWalletProperties() this.actions.getCurrentReport() - chrome.braveRewards.getNonVerifiedSettings(((nonVerified: boolean) => { - this.setState({ - nonVerified - }) + chrome.braveRewards.getPendingContributionsTotal(((amount: number) => { + this.actions.OnPendingContributionsTotal(amount) })) } @@ -263,18 +259,16 @@ export class Panel extends React.Component { } } - openSettings = () => { - chrome.tabs.create({ - url: 'brave://rewards/#ac-settings' - }) - } - render () { + const { pendingContributionTotal } = this.props.rewardsPanelData const { balance, rates, grants } = this.props.rewardsPanelData.walletProperties const publisher: RewardsExtension.Publisher | undefined = this.getPublisher() const converted = utils.convertBalance(balance.toString(), rates) const notification = this.getNotification() + const pendingTotal = parseFloat( + (pendingContributionTotal || 0).toFixed(1)) + let faviconUrl if (publisher && publisher.url) { faviconUrl = `chrome://favicon/size/48@2x/${publisher.url}` @@ -328,13 +322,16 @@ export class Panel extends React.Component { onAmountChange={this.doNothing} onIncludeInAuto={this.switchAutoContribute} showUnVerified={!publisher.verified} - showChangeSetting={this.state.nonVerified} moreLink={'https://brave.com/faq-rewards/#unclaimed-funds'} - onChangeSetting={this.openSettings} /> : 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 72fb44451e21..10de43b74935 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 @@ -17,5 +17,7 @@ export const enum types { ON_NOTIFICATION_DELETED = '@@rewards_panel/ON_NOTIFICATION_DELETED', DELETE_NOTIFICATION = '@@rewards_panel/DELETE_NOTIFICATION', INCLUDE_IN_AUTO_CONTRIBUTION = '@@rewards_panel/INCLUDE_IN_AUTO_CONTRIBUTION', - GET_GRANT = '@@rewards_panel/GET_GRANT' + GET_GRANT = '@@rewards_panel/GET_GRANT', + GET_PENDING_CONTRIBUTIONS_TOTAL = '@@rewards_panel/GET_PENDING_CONTRIBUTIONS_TOTAL', + ON_PENDING_CONTRIBUTIONS_TOTAL = '@@rewards_panel/ON_PENDING_CONTRIBUTIONS_TOTAL' } diff --git a/components/brave_rewards/resources/ui/actions/rewards_actions.ts b/components/brave_rewards/resources/ui/actions/rewards_actions.ts index b7893d2ba20c..3eaff953aa0a 100644 --- a/components/brave_rewards/resources/ui/actions/rewards_actions.ts +++ b/components/brave_rewards/resources/ui/actions/rewards_actions.ts @@ -138,3 +138,9 @@ export const checkImported = () => action(types.CHECK_IMPORTED) export const onImportedCheck = (imported: boolean) => action(types.ON_IMPORTED_CHECK, { imported }) + +export const getPendingContributionsTotal = () => action(types.GET_PENDING_CONTRIBUTION_TOTAL) + +export const onPendingContributionTotal = (amount: number) => action(types.ON_PENDING_CONTRIBUTION_TOTAL, { + amount +}) diff --git a/components/brave_rewards/resources/ui/brave_rewards.tsx b/components/brave_rewards/resources/ui/brave_rewards.tsx index 15048b544cb2..069941c9d58f 100644 --- a/components/brave_rewards/resources/ui/brave_rewards.tsx +++ b/components/brave_rewards/resources/ui/brave_rewards.tsx @@ -125,6 +125,10 @@ window.cr.define('brave_rewards', function () { getActions().onImportedCheck(imported) } + function pendingContributionTotal (amount: number) { + getActions().onPendingContributionTotal(amount) + } + return { initialize, walletCreated, @@ -145,7 +149,8 @@ window.cr.define('brave_rewards', function () { recurringDonationUpdate, currentTips, initAutoContributeSettings, - imported + imported, + pendingContributionTotal } }) diff --git a/components/brave_rewards/resources/ui/components/contributeBox.tsx b/components/brave_rewards/resources/ui/components/contributeBox.tsx index 7169d6cf7698..054083bc7ea0 100644 --- a/components/brave_rewards/resources/ui/components/contributeBox.tsx +++ b/components/brave_rewards/resources/ui/components/contributeBox.tsx @@ -41,10 +41,6 @@ class ContributeBox extends React.Component { } } - componentDidMount () { - this.isSettingsUrl() - } - getContributeRows = (list: Rewards.Publisher[]) => { return list.map((item: Rewards.Publisher) => { let faviconUrl = `chrome://favicon/size/48@1x/${item.url}` @@ -104,14 +100,6 @@ class ContributeBox extends React.Component { this.actions.onSettingSave(key, selected) } - isSettingsUrl = () => { - if (window && window.location && window.location.hash && window.location.hash === '#ac-settings') { - this.setState({ - settings: true - }) - } - } - contributeSettings = (monthlyList: MonthlyChoice[]) => { const { contributionMinTime, diff --git a/components/brave_rewards/resources/ui/components/pageWallet.tsx b/components/brave_rewards/resources/ui/components/pageWallet.tsx index 6f62b33a60fb..ba9f0d5f5026 100644 --- a/components/brave_rewards/resources/ui/components/pageWallet.tsx +++ b/components/brave_rewards/resources/ui/components/pageWallet.tsx @@ -267,11 +267,22 @@ class PageWallet extends React.Component { } render () { - const { connectedWallet, recoveryKey, enabledMain, addresses, walletInfo, ui } = this.props.rewardsData + const { + connectedWallet, + recoveryKey, + enabledMain, + addresses, + walletInfo, + ui, + pendingContributionTotal + } = this.props.rewardsData const { balance } = walletInfo const { walletRecoverySuccess, emptyWallet, modalBackup } = ui const addressArray = utils.getAddresses(addresses) + const pendingTotal = parseFloat( + (pendingContributionTotal || 0).toFixed(1)) + return ( <> { enabledMain ? emptyWallet ? - : + : : } diff --git a/components/brave_rewards/resources/ui/components/settingsPage.tsx b/components/brave_rewards/resources/ui/components/settingsPage.tsx index 830973f8db75..6fbd1a2f132a 100644 --- a/components/brave_rewards/resources/ui/components/settingsPage.tsx +++ b/components/brave_rewards/resources/ui/components/settingsPage.tsx @@ -51,6 +51,7 @@ class SettingsPage extends React.Component { this.actions.getDonationTable() this.actions.getContributeList() this.actions.checkImported() + this.actions.getPendingContributionsTotal() } componentWillUnmount () { diff --git a/components/brave_rewards/resources/ui/constants/rewards_types.ts b/components/brave_rewards/resources/ui/constants/rewards_types.ts index b685bd2de2d7..32afbd94da2d 100644 --- a/components/brave_rewards/resources/ui/constants/rewards_types.ts +++ b/components/brave_rewards/resources/ui/constants/rewards_types.ts @@ -43,5 +43,7 @@ export const enum types { GET_CONTRIBUTE_LIST = '@@rewards/GET_CONTRIBUTE_LIST', INIT_AUTOCONTRIBUTE_SETTINGS = '@@rewards/INIT_AUTOCONTRIBUTE_SETTINGS', CHECK_IMPORTED = '@@rewards/CHECK_IMPORTED', - ON_IMPORTED_CHECK = '@@rewards/ON_IMPORTED_CHECK' + ON_IMPORTED_CHECK = '@@rewards/ON_IMPORTED_CHECK', + GET_PENDING_CONTRIBUTION_TOTAL = '@@rewards/GET_PENDING_CONTRIBUTION_TOTAL', + ON_PENDING_CONTRIBUTION_TOTAL = '@@rewards/ON_PENDING_CONTRIBUTION_TOTAL' } diff --git a/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts b/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts index 3592c021dd5d..55967185fcf4 100644 --- a/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts +++ b/components/brave_rewards/resources/ui/reducers/wallet_reducer.ts @@ -197,6 +197,17 @@ const walletReducer: Reducer = (state: Rewards.State, state.contributionMonthly = action.payload.amount break } + case types.GET_PENDING_CONTRIBUTION_TOTAL: + { + chrome.send('brave_rewards.getPendingContributionsTotal') + break + } + case types.ON_PENDING_CONTRIBUTION_TOTAL: + { + state = { ...state } + state.pendingContributionTotal = action.payload.amount + break + } } return state diff --git a/components/brave_rewards/resources/ui/storage.ts b/components/brave_rewards/resources/ui/storage.ts index 656c745ebca2..01f3537858e5 100644 --- a/components/brave_rewards/resources/ui/storage.ts +++ b/components/brave_rewards/resources/ui/storage.ts @@ -46,7 +46,8 @@ export const defaultState: Rewards.State = { contributeLoad: false, recurringLoad: false, tipsLoad: false, - excluded: [] + excluded: [], + pendingContributionTotal: 0 } const cleanData = (state: Rewards.State) => state diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index 1d8e79c75ca0..a738c257f93c 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -32,7 +32,7 @@ declare namespace chrome.braveRewards { } const includeInAutoContribution: (publisherKey: string, excluded: boolean, windowId: number) => {} const getGrant: () => {} - const getNonVerifiedSettings: (callback: (nonVerified: boolean) => void) => {} + const getPendingContributionsTotal: (callback: (amount: number) => void) => {} } declare namespace chrome.rewardsNotifications { diff --git a/components/definitions/rewards.d.ts b/components/definitions/rewards.d.ts index 287f6d5c0a36..dfe4b789c499 100644 --- a/components/definitions/rewards.d.ts +++ b/components/definitions/rewards.d.ts @@ -43,6 +43,7 @@ declare namespace Rewards { firstLoad: boolean | null grant?: Grant numExcludedSites: number + pendingContributionTotal: number reconcileStamp: number recoveryKey: string recurringList: Publisher[] diff --git a/components/definitions/rewardsExtensions.d.ts b/components/definitions/rewardsExtensions.d.ts index e4a69d481a5d..92b678fb9a4f 100644 --- a/components/definitions/rewardsExtensions.d.ts +++ b/components/definitions/rewardsExtensions.d.ts @@ -4,6 +4,7 @@ declare namespace RewardsExtension { notifications: Record publishers: Record report: Report + pendingContributionTotal: number walletCreated: boolean walletCreateFailed: boolean walletProperties: WalletProperties diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 88fb4a6b41ed..89017f3a307d 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -349,6 +349,8 @@ Monthly Tips Monthly Tips remove + You’ve designated {{reservedAmount}} BAT for creators who haven’t yet signed up to receive contributions. Your browser will keep trying to contribute until they verify, or until 90 days have passed. + Learn more. Restore Restore All Your pinned sites have been moved to @@ -427,7 +429,7 @@ View Details Creating wallet NOTE: - This creator has not yet verified their site. As soon as they verify with Brave, they will receive your tip. + This creator has not yet signed up to receive contributions from Brave users. Your browser will keep trying to contribute until they verify, or until 90 days have passed. Learn more. diff --git a/package-lock.json b/package-lock.json index 6161e2a8d0bd..8788ffe8aa18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1237,8 +1237,8 @@ } }, "brave-ui": { - "version": "github:brave/brave-ui#7fbe676faf82a57f865e0e938799159f6fed0161", - "from": "github:brave/brave-ui#7fbe676faf82a57f865e0e938799159f6fed0161", + "version": "github:brave/brave-ui#816ffa868fe439f35688cd064881967491ae712b", + "from": "github:brave/brave-ui#816ffa868fe439f35688cd064881967491ae712b", "dev": true, "requires": { "emptykit.css": "^1.0.1", diff --git a/package.json b/package.json index 14111716f81a..b821d2aa86fc 100644 --- a/package.json +++ b/package.json @@ -272,7 +272,7 @@ "@types/react-dom": "^16.0.7", "@types/react-redux": "6.0.4", "awesome-typescript-loader": "^5.2.0", - "brave-ui": "github:brave/brave-ui#7fbe676faf82a57f865e0e938799159f6fed0161", + "brave-ui": "github:brave/brave-ui#816ffa868fe439f35688cd064881967491ae712b", "css-loader": "^0.28.9", "csstype": "^2.5.5", "emptykit.css": "^1.0.1", diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 07569de9157d..3b9bf2f2c7c9 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -88,7 +88,7 @@ class LEDGER_EXPORT Ledger { virtual void MakePayment(const PaymentData& payment_data) = 0; virtual void AddRecurringPayment(const std::string& publisher_id, const double& value) = 0; - virtual void DoDirectDonation(const PublisherInfo& publisher, const int amount, const std::string& currency) = 0; + virtual void DoDirectDonation(const PublisherInfo& publisher, int amount, const std::string& currency) = 0; virtual void OnLoad(const VisitData& visit_data, const uint64_t& current_time) = 0; virtual void OnUnload(uint32_t tab_id, const uint64_t& current_time) = 0; virtual void OnShow(uint32_t tab_id, const uint64_t& current_time) = 0; diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h b/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h index 0b39aa053c78..b36fca7cee1d 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h @@ -18,6 +18,7 @@ #include "bat/ledger/publisher_info.h" #include "bat/ledger/wallet_info.h" #include "bat/ledger/grant.h" +#include "bat/ledger/pending_contribution.h" namespace ledger { @@ -135,6 +136,9 @@ class LEDGER_EXPORT LedgerClient { bool excluded, uint64_t windowId) = 0; + virtual void SavePendingContribution( + const ledger::PendingContributionList& list) = 0; + // Log debug information virtual void Log(ledger::LogLevel level, const std::string& text) = 0; }; diff --git a/vendor/bat-native-ledger/include/bat/ledger/pending_contribution.h b/vendor/bat-native-ledger/include/bat/ledger/pending_contribution.h new file mode 100644 index 000000000000..a3809716b57c --- /dev/null +++ b/vendor/bat-native-ledger/include/bat/ledger/pending_contribution.h @@ -0,0 +1,41 @@ +/* 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 BAT_LEDGER_PENDING_CONTRIBUTION_HANDLER_ +#define BAT_LEDGER_PENDING_CONTRIBUTION_HANDLER_ + +#include +#include + +#include "bat/ledger/export.h" + +namespace ledger { + +LEDGER_EXPORT struct PendingContribution { + PendingContribution(); + ~PendingContribution(); + PendingContribution(const PendingContribution& data); + + bool loadFromJson(const std::string& json); + + std::string publisher_key; + double amount = 0; + uint64_t added_date = 0; + std::string viewing_id; + PUBLISHER_CATEGORY category; +}; + +LEDGER_EXPORT struct PendingContributionList { + PendingContributionList(); + ~PendingContributionList(); + PendingContributionList(const PendingContributionList& data); + + bool loadFromJson(const std::string& json); + + std::vector list_; +}; + +} // namespace ledger + +#endif // BAT_LEDGER_PENDING_CONTRIBUTION_HANDLER_ diff --git a/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h b/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h index 623fa5ccd27b..9c462bb33384 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h +++ b/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h @@ -14,10 +14,10 @@ namespace ledger { LEDGER_EXPORT enum PUBLISHER_CATEGORY { - AUTO_CONTRIBUTE = 1 << 1, + AUTO_CONTRIBUTE = 1 << 1, // 2 TIPPING = 1 << 2, - DIRECT_DONATION = 1 << 3, - RECURRING_DONATION = 1 << 4, + DIRECT_DONATION = 1 << 3, // 8 + RECURRING_DONATION = 1 << 4, // 21 ALL_CATEGORIES = (1 << 5) - 1, }; diff --git a/vendor/bat-native-ledger/src/bat/ledger/ledger.cc b/vendor/bat-native-ledger/src/bat/ledger/ledger.cc index 7c2e2567cb76..6fa5363134fa 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/ledger.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/ledger.cc @@ -249,4 +249,75 @@ BalanceReportInfo::~BalanceReportInfo() {} bool Ledger::IsMediaLink(const std::string& url, const std::string& first_party_url, const std::string& referrer) { return braveledger_bat_get_media::BatGetMedia::GetLinkType(url, first_party_url, referrer) == TWITCH_MEDIA_TYPE; } + +PendingContribution::PendingContribution () {} +PendingContribution::~PendingContribution () {} +PendingContribution::PendingContribution ( + const ledger::PendingContribution &properties) { + publisher_key = properties.publisher_key; + amount = properties.amount; + added_date = properties.added_date; + viewing_id = properties.viewing_id; + category = properties.category; +} + +bool PendingContribution::loadFromJson(const std::string& json) { + rapidjson::Document d; + d.Parse(json.c_str()); + + // has parser errors or wrong types + bool error = d.HasParseError(); + + if (false == error) { + error = !(d.HasMember("publisher_key") && d["publisher_key"].IsString() && + d.HasMember("amount") && d["amount"].IsDouble() && + d.HasMember("added_date") && d["added_date"].IsUint64() && + d.HasMember("viewing_id") && d["viewing_id"].IsString() && + d.HasMember("category") && d["category"].IsInt()); + } + + if (false == error) { + publisher_key = d["publisher_key"].GetString(); + amount = d["amount"].GetDouble(); + added_date = d["added_date"].GetUint64(); + viewing_id = d["viewing_id"].GetString(); + category = static_cast(d["category"].GetInt()); + } + + return !error; +} + +PendingContributionList::PendingContributionList () {} +PendingContributionList::~PendingContributionList () {} +PendingContributionList::PendingContributionList ( + const ledger::PendingContributionList &properties) { + list_ = properties.list_; } + +bool PendingContributionList::loadFromJson(const std::string& json) { + rapidjson::Document d; + d.Parse(json.c_str()); + + // has parser errors or wrong types + bool error = d.HasParseError(); + + if (false == error) { + error = !(d.HasMember("list") && d["list"].IsArray()); + } + + if (false == error) { + for (const auto& g : d["list"].GetArray()) { + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + g.Accept(writer); + + PendingContribution contribution; + contribution.loadFromJson(sb.GetString()); + list_.push_back(contribution); + } + } + + return !error; +} + +} // ledger diff --git a/vendor/bat-native-ledger/src/bat_contribution.cc b/vendor/bat-native-ledger/src/bat_contribution.cc index 75971ba20e4d..a6da6fadb751 100644 --- a/vendor/bat-native-ledger/src/bat_contribution.cc +++ b/vendor/bat-native-ledger/src/bat_contribution.cc @@ -78,12 +78,109 @@ std::string BatContribution::GetAnonizeProof( return proof; } +ledger::PublisherInfoList BatContribution::GetVerifiedListAuto( + const std::string& viewing_id, + const ledger::PublisherInfoList& list, + double& budget) { + ledger::PublisherInfoList verified; + ledger::PublisherInfoList temp; + ledger::PendingContributionList non_verified; + + double verified_total = 0.0; + double non_verified_bat = 0.0; + double ac_amount = ledger_->GetContributionAmount(); + + for (const auto& publisher : list) { + if (publisher.verified) { + verified.push_back(publisher); + verified_total += publisher.percent; + } else { + temp.push_back(publisher); + } + } + + // verified publishers + for (auto publisher : verified) { + ledger::PendingContribution contribution; + publisher.percent = static_cast( + static_cast(publisher.percent) / verified_total) * 100; + } + + // non-verified publishers + for (const auto& publisher : temp) { + ledger::PendingContribution contribution; + contribution.amount = + (static_cast(publisher.percent) / 100) * ac_amount; + contribution.publisher_key = publisher.id; + contribution.viewing_id = viewing_id; + contribution.category = ledger::PUBLISHER_CATEGORY::AUTO_CONTRIBUTE; + + non_verified_bat += contribution.amount; + non_verified.list_.push_back(contribution); + } + + if (non_verified.list_.size() > 0) { + ledger_->SaveUnverifiedContribution(non_verified); + } + + budget = ac_amount - non_verified_bat; + + return verified; +} + +ledger::PublisherInfoList BatContribution::GetVerifiedListRecurring( + const std::string& viewing_id, + const ledger::PublisherInfoList& list, + double& budget) { + ledger::PublisherInfoList verified; + ledger::PendingContributionList non_verified; + + for (const auto& publisher : list) { + if (publisher.id.empty()) { + continue; + } + + if (publisher.verified) { + verified.push_back(publisher); + budget += publisher.weight; + } else { + ledger::PendingContribution contribution; + contribution.amount = publisher.weight; + contribution.publisher_key = publisher.id; + contribution.viewing_id = viewing_id; + contribution.category = ledger::PUBLISHER_CATEGORY::RECURRING_DONATION; + + non_verified.list_.push_back(contribution); + } + } + + if (non_verified.list_.size() > 0) { + ledger_->SaveUnverifiedContribution(non_verified); + } + + return verified; +} + void BatContribution::ReconcilePublisherList( ledger::PUBLISHER_CATEGORY category, const ledger::PublisherInfoList& list, uint32_t next_record) { + std::string viewing_id = ledger_->GenerateGUID(); + ledger::PublisherInfoList verified_list; + double budget = 0.0; + + if (category == ledger::PUBLISHER_CATEGORY::AUTO_CONTRIBUTE) { + ledger::PublisherInfoList normalized_list; + ledger_->NormalizeContributeWinners(&normalized_list, false, list, 0); + std::sort(normalized_list.begin(), normalized_list.end()); + verified_list = GetVerifiedListAuto(viewing_id, normalized_list, budget); + } else { + verified_list = GetVerifiedListRecurring(viewing_id, list, budget); + } + braveledger_bat_helper::PublisherList new_list; - for (const auto &publisher : list) { + + for (const auto &publisher : verified_list) { braveledger_bat_helper::PUBLISHER_ST new_publisher; new_publisher.id_ = publisher.id; new_publisher.percent_ = publisher.percent; @@ -91,10 +188,11 @@ void BatContribution::ReconcilePublisherList( new_publisher.duration_ = publisher.duration; new_publisher.score_ = publisher.score; new_publisher.visits_ = publisher.visits; + new_publisher.verified_ = publisher.verified; new_list.push_back(new_publisher); } - StartReconcile(ledger_->GenerateGUID(), category, new_list); + StartReconcile(viewing_id, category, new_list, {}, budget); } void BatContribution::ResetReconcileStamp() { @@ -154,7 +252,8 @@ void BatContribution::StartReconcile( const std::string& viewing_id, const ledger::PUBLISHER_CATEGORY category, const braveledger_bat_helper::PublisherList& list, - const braveledger_bat_helper::Directions& directions) { + const braveledger_bat_helper::Directions& directions, + double budget) { if (ledger_->ReconcileExists(viewing_id)) { ledger_->Log(__func__, ledger::LogLevel::LOG_ERROR, @@ -168,35 +267,42 @@ void BatContribution::StartReconcile( double balance = ledger_->GetBalance(); if (category == ledger::PUBLISHER_CATEGORY::AUTO_CONTRIBUTE) { - double ac_amount = ledger_->GetContributionAmount(); - if (list.size() == 0 || ac_amount > balance) { - if (list.size() == 0) { + if (list.size() == 0 || budget > balance || budget == 0) { + if (list.size() == 0 || budget == 0) { ledger_->Log(__func__, ledger::LogLevel::LOG_INFO, {"AC table is empty"}); OnReconcileComplete(ledger::Result::AC_TABLE_EMPTY, viewing_id, category); + return; } - if (ac_amount > balance) { + if (budget > balance) { ledger_->Log(__func__, ledger::LogLevel::LOG_INFO, {"You don't have enough funds for AC contribution"}); OnReconcileComplete(ledger::Result::NOT_ENOUGH_FUNDS, viewing_id, category); + return; } - return; } reconcile.list_ = list; + fee = budget; } if (category == ledger::PUBLISHER_CATEGORY::RECURRING_DONATION) { double ac_amount = ledger_->GetContributionAmount(); - if (list.size() == 0) { + + // don't use ac amount if ac is disabled + if (!ShouldStartAutoContribute()) { + ac_amount = 0; + } + + if (list.size() == 0 || budget == 0) { ledger_->Log(__func__, ledger::LogLevel::LOG_INFO, {"recurring donation list is empty"}); @@ -204,24 +310,11 @@ void BatContribution::StartReconcile( return; } - for (const auto& publisher : list) { - if (publisher.id_.empty()) { - ledger_->Log(__func__, - ledger::LogLevel::LOG_ERROR, - {"recurring donation is missing publisher"}); - StartAutoContribute(); - // TODO(nejczdovc) what should we do in this case? - return; - } - - fee += publisher.weight_; - } - - if (fee + ac_amount > balance) { - ledger_->Log(__func__, - ledger::LogLevel::LOG_ERROR, - {"You don't have enough funds to " - "do recurring and AC contribution"}); + if (budget + ac_amount > balance) { + ledger_->Log(__func__, + ledger::LogLevel::LOG_ERROR, + {"You don't have enough funds to " + "do recurring and AC contribution"}); OnReconcileComplete(ledger::Result::NOT_ENOUGH_FUNDS, viewing_id, ledger::PUBLISHER_CATEGORY::AUTO_CONTRIBUTE); @@ -229,6 +322,7 @@ void BatContribution::StartReconcile( } reconcile.list_ = list; + fee = budget; } if (category == ledger::PUBLISHER_CATEGORY::DIRECT_DONATION) { @@ -243,7 +337,7 @@ void BatContribution::StartReconcile( return; } - if (direction.currency_ != CURRENCY) { + if (direction.currency_ != CURRENCY || direction.amount_ == 0) { ledger_->Log(__func__, ledger::LogLevel::LOG_ERROR, {"reconcile direction currency invalid for ", @@ -338,11 +432,7 @@ void BatContribution::CurrentReconcile(const std::string& viewing_id) { std::ostringstream amount; auto reconcile = ledger_->GetReconcileById(viewing_id); - if (reconcile.category_ == ledger::PUBLISHER_CATEGORY::AUTO_CONTRIBUTE) { - amount << ledger_->GetContributionAmount(); - } else { - amount << reconcile.fee_; - } + amount << reconcile.fee_; std::string currency = ledger_->GetCurrency(); std::string path = (std::string)WALLET_PROPERTIES + @@ -781,30 +871,26 @@ void BatContribution::GetContributeWinners( const unsigned int& ballots, const std::string& viewing_id, const braveledger_bat_helper::PublisherList& list) { - ledger::PublisherInfoList new_list; - ledger_->NormalizeContributeWinners(&new_list, false, list, 0); - std::sort(new_list.begin(), new_list.end()); - unsigned int total_votes = 0; std::vector votes; braveledger_bat_helper::Winners res; - // TODO there is underscore.shuffle - for (auto &item : new_list) { - if (item.percent <= 0) { + + for (auto &item : list) { + if (item.percent_ <= 0) { continue; } braveledger_bat_helper::WINNERS_ST winner; winner.votes_ = (unsigned int)std::lround( - (double) item.percent * (double)ballots / 100.0); + (double) item.percent_* (double)ballots / 100.0); total_votes += winner.votes_; - winner.publisher_data_.id_ = item.id; - winner.publisher_data_.duration_ = item.duration; - winner.publisher_data_.score_ = item.score; - winner.publisher_data_.visits_ = item.visits; - winner.publisher_data_.percent_ = item.percent; - winner.publisher_data_.weight_ = item.weight; + winner.publisher_data_.id_ = item.id_; + winner.publisher_data_.duration_ = item.duration_; + winner.publisher_data_.score_ = item.score_; + winner.publisher_data_.visits_ = item.visits_; + winner.publisher_data_.percent_ = item.percent_; + winner.publisher_data_.weight_ = item.weight_; res.push_back(winner); } diff --git a/vendor/bat-native-ledger/src/bat_contribution.h b/vendor/bat-native-ledger/src/bat_contribution.h index 175f4541ec33..92197994b705 100644 --- a/vendor/bat-native-ledger/src/bat_contribution.h +++ b/vendor/bat-native-ledger/src/bat_contribution.h @@ -114,7 +114,8 @@ class BatContribution { const std::string &viewing_id, const ledger::PUBLISHER_CATEGORY category, const braveledger_bat_helper::PublisherList& list, - const braveledger_bat_helper::Directions& directions = {}); + const braveledger_bat_helper::Directions& directions = {}, + double budget = 0); // Called when timer is triggered void OnTimer(uint32_t timer_id); @@ -136,6 +137,20 @@ class BatContribution { const std::string& id, std::string& pre_flight); + // AUTO CONTRIBUTE: from the list gets only verified publishers and + // save unverified to the db + ledger::PublisherInfoList GetVerifiedListAuto( + const std::string& viewing_id, + const ledger::PublisherInfoList& all, + double& budget); + + // RECURRING DONTAIONS: from the list gets only verified publishers and + // save unverified to the db + ledger::PublisherInfoList GetVerifiedListRecurring( + const std::string& viewing_id, + const ledger::PublisherInfoList& all, + double& budget); + // Entry point for contribution where we have publisher info list void ReconcilePublisherList(ledger::PUBLISHER_CATEGORY category, const ledger::PublisherInfoList& list, diff --git a/vendor/bat-native-ledger/src/bat_helper.cc b/vendor/bat-native-ledger/src/bat_helper.cc index ea21c03296f6..f58221b8fd21 100644 --- a/vendor/bat-native-ledger/src/bat_helper.cc +++ b/vendor/bat-native-ledger/src/bat_helper.cc @@ -730,7 +730,8 @@ static bool ignore_ = false; score_(0), visits_(0), percent_(0), - weight_(0) {} + weight_(0), + verified_(false) {} PUBLISHER_ST::~PUBLISHER_ST() {} @@ -760,6 +761,12 @@ static bool ignore_ = false; visits_ = d["visits"].GetUint(); percent_ = d["percent"].GetUint(); weight_ = d["pubs_load_timestamp"].GetDouble(); + + if (d.HasMember("verified") && d["verified"].IsBool()) { + verified_ = d["verified"].GetBool(); + } else { + verified_ = false; + } } return !error; @@ -786,6 +793,9 @@ static bool ignore_ = false; writer.String("weight"); writer.Double(data.weight_); + writer.String("verified"); + writer.Bool(data.verified_); + writer.EndObject(); } @@ -2409,4 +2419,40 @@ static bool ignore_ = false; return dist(eng); } + void saveToJson(JsonWriter& writer, + const ledger::PendingContribution& contribution) { + writer.StartObject(); + + writer.String("publisher_key"); + writer.String(contribution.publisher_key.c_str()); + + writer.String("amount"); + writer.Double(contribution.amount); + + writer.String("added_date"); + writer.Uint64(contribution.added_date); + + writer.String("viewing_id"); + writer.String(contribution.viewing_id.c_str()); + + writer.String("category"); + writer.Int(contribution.category); + + writer.EndObject(); + } + + void saveToJson(JsonWriter& writer, + const ledger::PendingContributionList& contributions) { + writer.StartObject(); + + writer.String("list"); + writer.StartArray(); + for (const auto& contribution : contributions.list_) { + saveToJson(writer, contribution); + } + writer.EndArray(); + + writer.EndObject(); + } + } // namespace braveledger_bat_helper diff --git a/vendor/bat-native-ledger/src/bat_helper.h b/vendor/bat-native-ledger/src/bat_helper.h index 31b0c010701e..3c7a4c3500cb 100644 --- a/vendor/bat-native-ledger/src/bat_helper.h +++ b/vendor/bat-native-ledger/src/bat_helper.h @@ -242,6 +242,7 @@ namespace braveledger_bat_helper { unsigned int visits_ = 0; unsigned int percent_ = 0; double weight_ = .0; + bool verified_ = false; }; struct WINNERS_ST { @@ -277,7 +278,9 @@ namespace braveledger_bat_helper { struct RECONCILE_DIRECTION { RECONCILE_DIRECTION(); - RECONCILE_DIRECTION(const std::string& publisher_key, const int amount, const std::string& currency); + RECONCILE_DIRECTION(const std::string& publisher_key, + int amount, + const std::string& currency); ~RECONCILE_DIRECTION(); bool loadFromJson(const std::string &json); diff --git a/vendor/bat-native-ledger/src/bat_publishers.cc b/vendor/bat-native-ledger/src/bat_publishers.cc index 42528a9d0f2b..7d03a6bf87bd 100644 --- a/vendor/bat-native-ledger/src/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat_publishers.cc @@ -504,28 +504,20 @@ bool BatPublishers::getPublisherAllowVideos() const { return state_->allow_videos_; } -void BatPublishers::NormalizeContributeWinners(ledger::PublisherInfoList* newList, bool saveData, - const braveledger_bat_helper::PublisherList& oldList, uint32_t record) { - - ledger::PublisherInfoList list; - - for(const auto& publisher: oldList) { - ledger::PublisherInfo new_publisher; - new_publisher.id = publisher.id_; - new_publisher.percent = publisher.percent_; - new_publisher.weight = publisher.weight_; - new_publisher.duration = publisher.duration_; - new_publisher.score = publisher.score_; - new_publisher.visits = publisher.visits_; - - list.push_back(new_publisher); - } +void BatPublishers::NormalizeContributeWinners( + ledger::PublisherInfoList* newList, + bool saveData, + const ledger::PublisherInfoList& list, + uint32_t record) { synopsisNormalizerInternal(newList, saveData, list, record); } -void BatPublishers::synopsisNormalizerInternal(ledger::PublisherInfoList* newList, bool saveData, - const ledger::PublisherInfoList& oldList, uint32_t /* next_record */) { +void BatPublishers::synopsisNormalizerInternal( + ledger::PublisherInfoList* newList, + bool saveData, + const ledger::PublisherInfoList& oldList, + uint32_t /* next_record */) { // TODO SZ: We can pass non const value here to avoid copying ledger::PublisherInfoList list = oldList; if (list.size() == 0) { diff --git a/vendor/bat-native-ledger/src/bat_publishers.h b/vendor/bat-native-ledger/src/bat_publishers.h index 001cd6756c9c..180e42b699dd 100644 --- a/vendor/bat-native-ledger/src/bat_publishers.h +++ b/vendor/bat-native-ledger/src/bat_publishers.h @@ -126,11 +126,12 @@ class BatPublishers : public ledger::LedgerCallbackHandler { const uint64_t& currentReconcileStamp); void clearAllBalanceReports(); - void NormalizeContributeWinners( - ledger::PublisherInfoList* newList, - bool saveData, - const braveledger_bat_helper::PublisherList& list, - uint32_t /* next_record */); + void NormalizeContributeWinners(ledger::PublisherInfoList* newList, + bool saveData, + const ledger::PublisherInfoList& list, + uint32_t /* next_record */); + + bool isVerified(const std::string& publisher_id); private: @@ -145,7 +146,6 @@ class BatPublishers : public ledger::LedgerCallbackHandler { std::unique_ptr publisher_info); bool isEligibleForContribution(const ledger::PublisherInfo& info); - bool isVerified(const std::string& publisher_id); bool isExcluded(const std::string& publisher_id, const ledger::PUBLISHER_EXCLUDE& excluded); void saveVisitInternal( std::string publisher_id, diff --git a/vendor/bat-native-ledger/src/ledger_impl.cc b/vendor/bat-native-ledger/src/ledger_impl.cc index 9fb01cde7c7a..616e80b46e04 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/ledger_impl.cc @@ -566,12 +566,36 @@ void LedgerImpl::SetBalanceReport(ledger::PUBLISHER_MONTH month, bat_publishers_->setBalanceReport(month, year, report_info); } -void LedgerImpl::DoDirectDonation(const ledger::PublisherInfo& publisher, const int amount, const std::string& currency) { +void LedgerImpl::SaveUnverifiedContribution( + const ledger::PendingContributionList& list) { + ledger_client_->SavePendingContribution(list); +} + +void LedgerImpl::DoDirectDonation(const ledger::PublisherInfo& publisher, + int amount, + const std::string& currency) { if (publisher.id.empty()) { // TODO add error flow return; } + bool is_verified = bat_publishers_->isVerified(publisher.id); + + // Save to the pending list if not verified + if (!is_verified) { + ledger::PendingContribution contribution; + contribution.publisher_key = publisher.id; + contribution.amount = amount; + contribution.category = ledger::PUBLISHER_CATEGORY::DIRECT_DONATION; + + ledger::PendingContributionList list; + list.list_ = std::vector { contribution }; + + SaveUnverifiedContribution(list); + + return; + } + auto direction = braveledger_bat_helper::RECONCILE_DIRECTION(publisher.id, amount, currency); auto direction_list = std::vector { direction }; braveledger_bat_helper::PublisherList list; @@ -970,7 +994,7 @@ void LedgerImpl::SaveContributionInfo(const std::string& probi, void LedgerImpl::NormalizeContributeWinners( ledger::PublisherInfoList* newList, bool saveData, - const braveledger_bat_helper::PublisherList& list, + const ledger::PublisherInfoList& list, uint32_t record) { bat_publishers_->NormalizeContributeWinners(newList, saveData, list, record); } diff --git a/vendor/bat-native-ledger/src/ledger_impl.h b/vendor/bat-native-ledger/src/ledger_impl.h index 11469a619291..5312f91148d1 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.h +++ b/vendor/bat-native-ledger/src/ledger_impl.h @@ -71,7 +71,7 @@ class LedgerImpl : public ledger::Ledger, const ledger::PublisherInfoFilter& filter, ledger::PublisherInfoListCallback callback) override; - void DoDirectDonation(const ledger::PublisherInfo& publisher, const int amount, const std::string& currency) override; + void DoDirectDonation(const ledger::PublisherInfo& publisher, int amount, const std::string& currency) override; void SetRewardsMainEnabled(bool enabled) override; void SetPublisherMinVisitTime(uint64_t duration_in_seconds) override; @@ -85,7 +85,7 @@ class LedgerImpl : public ledger::Ledger, void SetBalanceReport(ledger::PUBLISHER_MONTH month, int year, const ledger::BalanceReportInfo& report_info) override; - + void SaveUnverifiedContribution(const ledger::PendingContributionList& list); const std::string& GetBATAddress() const override; const std::string& GetBTCAddress() const override; const std::string& GetETHAddress() const override; @@ -268,7 +268,7 @@ class LedgerImpl : public ledger::Ledger, void NormalizeContributeWinners( ledger::PublisherInfoList* newList, bool saveData, - const braveledger_bat_helper::PublisherList& list, + const ledger::PublisherInfoList& list, uint32_t /* next_record */); void SetTimer(uint64_t time_offset, uint32_t& timer_id) const; diff --git a/vendor/bat-native-ledger/src/rapidjson_bat_helper.h b/vendor/bat-native-ledger/src/rapidjson_bat_helper.h index f3ecbfdab61d..8e572ce7a6a1 100644 --- a/vendor/bat-native-ledger/src/rapidjson_bat_helper.h +++ b/vendor/bat-native-ledger/src/rapidjson_bat_helper.h @@ -39,6 +39,8 @@ void saveToJson(JsonWriter & writer, const TRANSACTION_BALLOT_ST&); void saveToJson(JsonWriter & writer, const TRANSACTION_ST&); void saveToJson(JsonWriter & writer, const TWITCH_EVENT_INFO&); void saveToJson(JsonWriter & writer, const WALLET_INFO_ST&); +void saveToJson(JsonWriter & writer, const ledger::PendingContribution&); +void saveToJson(JsonWriter & writer, const ledger::PendingContributionList&); template void saveToJsonString(const T& t, std::string& json) {