blob: 1dd48489171ac9c68257fe889f32f0bf0b413969 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/commerce/discounts_page_action_controller.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/feature_utils.h"
#include "components/commerce/core/shopping_service.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
namespace commerce {
DiscountsPageActionController::DiscountsShownData::DiscountsShownData() =
default;
DiscountsPageActionController::DiscountsShownData::~DiscountsShownData() =
default;
DiscountsPageActionController::DiscountsPageActionController(
base::RepeatingCallback<void()> notify_callback,
ShoppingService* shopping_service)
: CommercePageActionController(std::move(notify_callback)),
shopping_service_(shopping_service) {}
DiscountsPageActionController::~DiscountsPageActionController() = default;
// static
DiscountsPageActionController::DiscountsShownData*
DiscountsPageActionController::GetOrCreate(ShoppingService* shopping_service) {
DiscountsShownData* data =
static_cast<DiscountsShownData*>(shopping_service->GetUserData(
DiscountsPageActionController::kDiscountsShownDataKey));
if (!data) {
auto discounts_shown_data = std::make_unique<DiscountsShownData>();
data = discounts_shown_data.get();
shopping_service->SetUserData(
DiscountsPageActionController::kDiscountsShownDataKey,
std::move(discounts_shown_data));
}
return data;
}
std::optional<bool> DiscountsPageActionController::ShouldShowForNavigation() {
if (!shopping_service_ || !IsDiscountEligibleToShowOnNavigation(
shopping_service_->GetAccountChecker())) {
return false;
}
if (!got_discounts_response_for_page_) {
return std::nullopt;
}
return !discounts_.empty();
}
bool DiscountsPageActionController::WantsExpandedUi() {
if (!got_discounts_response_for_page_ || discounts_.empty()) {
return false;
}
if (!commerce::kDiscountOnShoppyPage.Get()) {
return true;
}
std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
last_committed_url_,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
DiscountsShownData* shown_data =
DiscountsPageActionController::GetOrCreate(shopping_service_);
bool has_been_shown_on_domain =
shown_data->discount_shown_on_domains.contains(domain);
if (!has_been_shown_on_domain) {
shown_data->discount_shown_on_domains.insert(domain);
return true;
}
for (const auto& discount_info : discounts_) {
if (ShouldAutoShowBubble(discount_info.id,
discount_info.is_merchant_wide)) {
return true;
}
}
return false;
}
void DiscountsPageActionController::ResetForNewNavigation(const GURL& url) {
if (!shopping_service_ || !IsDiscountEligibleToShowOnNavigation(
shopping_service_->GetAccountChecker())) {
return;
}
// Cancel any pending callbacks.
weak_ptr_factory_.InvalidateWeakPtrs();
discounts_ = {};
got_discounts_response_for_page_ = false;
last_committed_url_ = url;
NotifyHost();
shopping_service_->GetDiscountInfoForUrl(
url,
base::BindOnce(&DiscountsPageActionController::HandleDiscountInfoResponse,
weak_ptr_factory_.GetWeakPtr()));
}
void DiscountsPageActionController::HandleDiscountInfoResponse(
const GURL& url,
const std::vector<DiscountInfo> discounts) {
if (url != last_committed_url_ || discounts.empty()) {
got_discounts_response_for_page_ = true;
NotifyHost();
return;
}
discounts_ = std::move(discounts);
got_discounts_response_for_page_ = true;
NotifyHost();
}
const std::vector<DiscountInfo>& DiscountsPageActionController::GetDiscounts() {
return discounts_;
}
void DiscountsPageActionController::CouponCodeCopied() {
coupon_code_copied_ = true;
}
bool DiscountsPageActionController::IsCouponCodeCopied() {
bool coupon_code_copied = coupon_code_copied_;
coupon_code_copied_ = false;
return coupon_code_copied;
}
bool DiscountsPageActionController::ShouldAutoShowBubble(
uint64_t discount_id,
bool is_merchant_wide) {
if (!shopping_service_ || !IsDiscountEligibleToShowOnNavigation(
shopping_service_->GetAccountChecker())) {
return false;
}
auto behavior = is_merchant_wide
? static_cast<commerce::DiscountDialogAutoPopupBehavior>(
commerce::kMerchantWideBehavior.Get())
: static_cast<commerce::DiscountDialogAutoPopupBehavior>(
commerce::kNonMerchantWideBehavior.Get());
switch (behavior) {
case commerce::DiscountDialogAutoPopupBehavior::kAutoPopupOnce: {
DiscountsShownData* shown_data =
DiscountsPageActionController::GetOrCreate(shopping_service_);
if (shown_data->shown_discount_ids.contains(discount_id)) {
return false;
}
return true;
}
case commerce::DiscountDialogAutoPopupBehavior::kAlwaysAutoPopup:
return true;
case commerce::DiscountDialogAutoPopupBehavior::kNoAutoPopup:
return false;
}
}
void DiscountsPageActionController::DiscountsBubbleShown(uint64_t discount_id) {
DiscountsShownData* shown_data =
DiscountsPageActionController::GetOrCreate(shopping_service_);
shown_data->shown_discount_ids.insert(discount_id);
}
} // namespace commerce