Skip to content

Commit

Permalink
Add rewards notification for insufficient funds
Browse files Browse the repository at this point in the history
Notify the user about upcoming contribution when they don't have
enough funds to cover the donations. The notification occurs 3 days
before the contribution will be made.
  • Loading branch information
emerick committed Dec 4, 2018
1 parent b0c4a7b commit 51822ac
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 2 deletions.
1 change: 1 addition & 0 deletions common/pref_names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ const char kReferralCheckedForPromoCodeFile[] = "brave.referral.checked_for_prom
const char kHTTPSEVerywhereControlType[] = "brave.https_everywhere_default";
const char kNoScriptControlType[] = "brave.no_script_default";
const char kRewardsNotifications[] = "brave.rewards.notifications";
const char kRewardsAddFundsNotification[] = "brave.rewards.add_funds_notification";
const char kMigratedMuonProfile[] = "brave.muon.migrated_profile";
const char kBravePaymentsPinnedItemCount[] = "brave.muon.import_pinned_item_count";
1 change: 1 addition & 0 deletions common/pref_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern const char kReferralCheckedForPromoCodeFile[];
extern const char kHTTPSEVerywhereControlType[];
extern const char kNoScriptControlType[];
extern const char kRewardsNotifications[];
extern const char kRewardsAddFundsNotification[];
extern const char kMigratedMuonProfile[];
extern const char kBravePaymentsPinnedItemCount[];

Expand Down
2 changes: 2 additions & 0 deletions components/brave_rewards/browser/rewards_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "brave/components/brave_rewards/browser/rewards_service.h"

#include "base/logging.h"
#include "base/time/time.h"
#include "brave/common/pref_names.h"
#include "brave/components/brave_rewards/browser/buildflags/buildflags.h"
#include "brave/components/brave_rewards/browser/rewards_notification_service_impl.h"
Expand Down Expand Up @@ -41,6 +42,7 @@ void RewardsService::RemoveObserver(RewardsServiceObserver* observer) {
// static
void RewardsService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(kRewardsNotifications, "");
registry->RegisterTimePref(kRewardsAddFundsNotification, base::Time());
}

} // namespace brave_rewards
46 changes: 46 additions & 0 deletions components/brave_rewards/browser/rewards_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ RewardsServiceImpl::RewardsServiceImpl(Profile* profile)

RewardsServiceImpl::~RewardsServiceImpl() {
file_task_runner_->DeleteSoon(FROM_HERE, publisher_info_backend_.release());
StopNotificationTimer();
}

void RewardsServiceImpl::Init() {
Expand Down Expand Up @@ -564,6 +565,7 @@ void RewardsServiceImpl::OnWalletInitialized(ledger::Result result) {
if (result == ledger::Result::WALLET_CREATED) {
SetRewardsMainEnabled(true);
SetAutoContribute(true);
StartNotificationTimer();
result = ledger::Result::LEDGER_OK;
}

Expand Down Expand Up @@ -664,6 +666,9 @@ void RewardsServiceImpl::OnLedgerStateLoaded(
handler->OnLedgerStateLoaded(data.empty() ? ledger::Result::LEDGER_ERROR
: ledger::Result::LEDGER_OK,
data);
if (ledger_->GetRewardsMainEnabled()) {
StartNotificationTimer();
}
}

void RewardsServiceImpl::LoadPublisherState(
Expand Down Expand Up @@ -1657,6 +1662,47 @@ RewardsNotificationService* RewardsServiceImpl::GetNotificationService() const {
return notification_service_.get();
}

void RewardsServiceImpl::StartNotificationTimer() {
notification_timer_ = std::make_unique<base::RepeatingTimer>();
notification_timer_->Start(FROM_HERE, base::TimeDelta::FromMinutes(15), this,
&RewardsServiceImpl::OnNotificationTimerFired);
DCHECK(notification_timer_->IsRunning());
}

void RewardsServiceImpl::StopNotificationTimer() {
notification_timer_.reset();
}

void RewardsServiceImpl::OnNotificationTimerFired() {
base::Time now = base::Time::Now();
if (ledger_->GetReconcileStamp() - now.ToJsTime() <
3 * base::Time::kMillisecondsPerDay) {
if (!HasSufficientBalanceToReconcile() &&
ShouldShowNotificationAddFunds()) {
ShowNotificationAddFunds();
}
}
}

bool RewardsServiceImpl::HasSufficientBalanceToReconcile() const {
return (ledger_->GetBalance() >= ledger_->GetContributionAmount());
}

bool RewardsServiceImpl::ShouldShowNotificationAddFunds() const {
base::Time next_time =
profile_->GetPrefs()->GetTime(kRewardsAddFundsNotification);
return (next_time.is_null() || base::Time::Now() > next_time);
}

void RewardsServiceImpl::ShowNotificationAddFunds() {
base::Time next_time = base::Time::Now() + base::TimeDelta::FromDays(3);
profile_->GetPrefs()->SetTime(kRewardsAddFundsNotification, next_time);
RewardsNotificationService::RewardsNotificationArgs args;
notification_service_->AddNotification(
RewardsNotificationService::REWARDS_NOTIFICATION_INSUFFICIENT_FUNDS, args,
"rewards_notification_insufficient_funds");
}

std::unique_ptr<ledger::LogStream> RewardsServiceImpl::Log(
const char* file,
int line,
Expand Down
9 changes: 9 additions & 0 deletions components/brave_rewards/browser/rewards_service_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,14 @@ class RewardsServiceImpl : public RewardsService,
// URLFetcherDelegate impl
void OnURLFetchComplete(const net::URLFetcher* source) override;

void StartNotificationTimer();
void StopNotificationTimer();
void OnNotificationTimerFired();

bool HasSufficientBalanceToReconcile() const;
bool ShouldShowNotificationAddFunds() const;
void ShowNotificationAddFunds();

Profile* profile_; // NOT OWNED
std::unique_ptr<ledger::Ledger> ledger_;
#if BUILDFLAG(ENABLE_EXTENSIONS)
Expand All @@ -309,6 +317,7 @@ class RewardsServiceImpl : public RewardsService,
std::map<uint32_t, std::unique_ptr<base::OneShotTimer>> timers_;
std::vector<std::string> current_media_fetchers_;
std::vector<BitmapFetcherService::RequestId> request_ids_;
std::unique_ptr<base::RepeatingTimer> notification_timer_;

uint32_t next_timer_id_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@
"message": "You have a grant waiting for you.",
"description": "Description for new grant notification"
},
"insufficientFundsNotification": {
"message": "Your Brave Payments account is waiting for a deposit.",
"description": "Description for new insufficient funds notification"
},
"insufficientFunds": {
"message": "Insufficient Funds",
"description": "Title for insufficient funds notification"
},
"braveRewardsCreatingText": {
"message": "Creating wallet",
"description": "Used in a button displaying wallet creation process"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const getUIMessages = (): Record<string, string> => {
'for',
'grants',
'includeInAuto',
'insufficientFunds',
'monthApr',
'monthAug',
'monthDec',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,22 @@ export class Panel extends React.Component<Props, State> {

const notification: RewardsExtension.Notification = notifications[currentNotification]

// Note: This declaration must match the RewardsNotificationType enum in
// brave/components/brave_rewards/browser/rewards_notification_service.h
enum RewardsNotificationType {
REWARDS_NOTIFICATION_INVALID = 0,
REWARDS_NOTIFICATION_AUTO_CONTRIBUTE,
REWARDS_NOTIFICATION_GRANT,
REWARDS_NOTIFICATION_FAILED_CONTRIBUTION,
REWARDS_NOTIFICATION_IMPENDING_CONTRIBUTION,
REWARDS_NOTIFICATION_INSUFFICIENT_FUNDS,
}

let type: NotificationType = ''
let text = ''
let isAlert = ''
switch (notification.type) {
case 1:
case RewardsNotificationType.REWARDS_NOTIFICATION_AUTO_CONTRIBUTE:
{
if (!notification.args ||
!Array.isArray(notification.args) ||
Expand Down Expand Up @@ -228,10 +239,14 @@ export class Panel extends React.Component<Props, State> {
type = 'contribute'
break
}
case 2:
case RewardsNotificationType.REWARDS_NOTIFICATION_GRANT:
type = 'grant'
text = getMessage('grantNotification')
break
case RewardsNotificationType.REWARDS_NOTIFICATION_INSUFFICIENT_FUNDS:
type = 'insufficientFunds'
text = getMessage('insufficientFundsNotification')
break
}

if (isAlert) {
Expand Down

0 comments on commit 51822ac

Please sign in to comment.