From b5c2c3915c96012ff75ce4354ae1a5d52995565f Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Tue, 18 Dec 2018 20:52:55 +0100 Subject: [PATCH] Shows grant notification only once Resolves https://github.com/brave/brave-browser/issues/2454 --- .../browser/rewards_notification_service.h | 5 +- .../rewards_notification_service_impl.cc | 77 ++++++++++++++++--- .../rewards_notification_service_impl.h | 8 +- 3 files changed, 77 insertions(+), 13 deletions(-) diff --git a/components/brave_rewards/browser/rewards_notification_service.h b/components/brave_rewards/browser/rewards_notification_service.h index c2c42c7e85db..f16b4e92292b 100644 --- a/components/brave_rewards/browser/rewards_notification_service.h +++ b/components/brave_rewards/browser/rewards_notification_service.h @@ -51,13 +51,14 @@ class RewardsNotificationService { virtual void AddNotification(RewardsNotificationType type, RewardsNotificationArgs args, - RewardsNotificationID id = "") = 0; + RewardsNotificationID id = "", + bool only_once = false) = 0; virtual void DeleteNotification(RewardsNotificationID id) = 0; virtual void DeleteAllNotifications() = 0; virtual void GetNotification(RewardsNotificationID id) = 0; virtual void GetAllNotifications() = 0; - virtual void ReadRewardsNotifications() = 0; + virtual void ReadRewardsNotificationsJSON() = 0; virtual void StoreRewardsNotifications() = 0; void AddObserver(RewardsNotificationServiceObserver* observer); diff --git a/components/brave_rewards/browser/rewards_notification_service_impl.cc b/components/brave_rewards/browser/rewards_notification_service_impl.cc index 11837f23c3bc..1e9b335ccb41 100644 --- a/components/brave_rewards/browser/rewards_notification_service_impl.cc +++ b/components/brave_rewards/browser/rewards_notification_service_impl.cc @@ -2,6 +2,8 @@ * 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 + #include "brave/components/brave_rewards/browser/rewards_notification_service_impl.h" #include "base/json/json_reader.h" @@ -33,7 +35,7 @@ RewardsNotificationServiceImpl::RewardsNotificationServiceImpl(Profile* profile) profile); AddObserver(extension_rewards_notification_service_observer_.get()); #endif - ReadRewardsNotifications(); + ReadRewardsNotificationsJSON(); } RewardsNotificationServiceImpl::~RewardsNotificationServiceImpl() { @@ -46,14 +48,28 @@ RewardsNotificationServiceImpl::~RewardsNotificationServiceImpl() { void RewardsNotificationServiceImpl::AddNotification( RewardsNotificationType type, RewardsNotificationArgs args, - RewardsNotificationID id) { + RewardsNotificationID id, + bool only_once) { DCHECK(type != REWARDS_NOTIFICATION_INVALID); - if (id.empty()) + if (id.empty()) { id = GenerateRewardsNotificationID(); + } else if (only_once) { + if (std::find( + rewards_notifications_displayed_.begin(), + rewards_notifications_displayed_.end(), + id) != rewards_notifications_displayed_.end()) { + return; + } + } + RewardsNotification rewards_notification( id, type, GenerateRewardsNotificationTimestamp(), std::move(args)); rewards_notifications_[id] = rewards_notification; OnNotificationAdded(rewards_notification); + + if (only_once) { + rewards_notifications_displayed_.push_back(id); + } } void RewardsNotificationServiceImpl::DeleteNotification(RewardsNotificationID id) { @@ -96,16 +112,47 @@ RewardsNotificationServiceImpl::GenerateRewardsNotificationTimestamp() const { return base::Time::NowFromSystemTime().ToTimeT(); } -void RewardsNotificationServiceImpl::ReadRewardsNotifications() { +void RewardsNotificationServiceImpl::ReadRewardsNotificationsJSON() { std::string json = profile_->GetPrefs()->GetString(kRewardsNotifications); if (json.empty()) return; - std::unique_ptr root = + std::unique_ptr dictionary = + base::DictionaryValue::From(base::JSONReader::Read(json)); + + // legacy read + if (!dictionary || !dictionary->is_dict()) { + std::unique_ptr list = base::ListValue::From(base::JSONReader::Read(json)); + if (!list) { + LOG(ERROR) << "Failed to deserialize rewards notifications on startup"; + return; + } + + ReadRewardsNotifications(std::move(list)); + return; + } + + base::ListValue* notifications; + dictionary->GetList("notifications", ¬ifications); + auto unique = std::make_unique(notifications->GetList()); + ReadRewardsNotifications(std::move(unique)); + + base::ListValue* displayed; + dictionary->GetList("displayed", &displayed); + if (displayed && displayed->is_list()) { + for (auto& it : *displayed) { + rewards_notifications_displayed_.push_back(it.GetString()); + } + } + +} + +void RewardsNotificationServiceImpl::ReadRewardsNotifications( + std::unique_ptr root) { if (!root) { - LOG(ERROR) << "Failed to deserialize rewards notifications on startup"; return; } + for (auto it = root->begin(); it != root->end(); ++it) { if (!it->is_dict()) continue; @@ -150,8 +197,9 @@ void RewardsNotificationServiceImpl::ReadRewardsNotifications() { } void RewardsNotificationServiceImpl::StoreRewardsNotifications() { - base::ListValue root; + base::DictionaryValue root; + auto notifications = std::make_unique(); for (auto& item : rewards_notifications_) { auto dict = std::make_unique(); dict->SetString("id", item.second.id_); @@ -162,9 +210,17 @@ void RewardsNotificationServiceImpl::StoreRewardsNotifications() { args->AppendString(arg); } dict->SetList("args", std::move(args)); - root.Append(std::move(dict)); + notifications->Append(std::move(dict)); } + auto displayed = std::make_unique(); + for (auto& item : rewards_notifications_displayed_) { + displayed->AppendString(item); + } + + root.SetList("notifications", std::move(notifications)); + root.SetList("displayed", std::move(displayed)); + std::string result; if (!base::JSONWriter::Write(root, &result)) { LOG(ERROR) << "Failed to serialize rewards notifications on shutdown"; @@ -234,7 +290,8 @@ if (error_code == ledger::Result::LEDGER_OK) { RewardsNotificationService::RewardsNotificationArgs args; AddNotification(RewardsNotificationService::REWARDS_NOTIFICATION_GRANT, args, - "rewards_notification_grant"); + "rewards_notification_grant_" + properties.promotionId, + true); } } @@ -242,6 +299,8 @@ void RewardsNotificationServiceImpl::OnGrantFinish( RewardsService* rewards_service, unsigned int result, Grant grant) { + DeleteNotification("rewards_notification_grant_" + grant.promotionId); + // We keep it for back compatibility DeleteNotification("rewards_notification_grant"); } diff --git a/components/brave_rewards/browser/rewards_notification_service_impl.h b/components/brave_rewards/browser/rewards_notification_service_impl.h index 5204fe92c2ac..f4f4290c8f77 100644 --- a/components/brave_rewards/browser/rewards_notification_service_impl.h +++ b/components/brave_rewards/browser/rewards_notification_service_impl.h @@ -8,6 +8,7 @@ #include #include +#include "base/values.h" #include "brave/components/brave_rewards/browser/rewards_notification_service.h" #include "brave/components/brave_rewards/browser/rewards_service_observer.h" #include "extensions/buildflags/buildflags.h" @@ -28,13 +29,15 @@ class RewardsNotificationServiceImpl void AddNotification(RewardsNotificationType type, RewardsNotificationArgs args, - RewardsNotificationID id = "") override; + RewardsNotificationID id = "", + bool only_once = false) override; void DeleteNotification(RewardsNotificationID id) override; void DeleteAllNotifications() override; void GetNotification(RewardsNotificationID id) override; void GetAllNotifications() override; - void ReadRewardsNotifications() override; + void ReadRewardsNotificationsJSON() override; + void ReadRewardsNotifications(std::unique_ptr); void StoreRewardsNotifications() override; private: @@ -73,6 +76,7 @@ class RewardsNotificationServiceImpl Profile* profile_; std::map rewards_notifications_; + std::vector rewards_notifications_displayed_; #if BUILDFLAG(ENABLE_EXTENSIONS) std::unique_ptr extension_rewards_notification_service_observer_;