Skip to content

Commit

Permalink
Add domain registration card on dashboard (#20730)
Browse files Browse the repository at this point in the history
  • Loading branch information
salimbraksa authored May 30, 2023
1 parent 17ad862 commit c7bf2d3
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import UIKit
import WordPressFlux

final class DashboardDomainRegistrationCardCell: BaseDashboardDomainsCardCell {

// MARK: - View Model

override var viewModel: DashboardDomainsCardViewModel {
return cardViewModel
}

private lazy var cardViewModel: DashboardDomainsCardViewModel = {
let onViewTap: () -> Void = { [weak self] in
self?.cardTapped()
}
let onHideThisTap: UIActionHandler = { [weak self] _ in
self?.hideCardTapped()
}
return DashboardDomainsCardViewModel(
strings: .init(
title: Strings.title,
description: Strings.content,
hideThis: Strings.hideThis,
source: Strings.source
),
onViewTap: onViewTap,
onHideThisTap: onHideThisTap
)
}()

// MARK: - User Interaction

private func cardTapped() {
guard let props = makeUnwrappedProperties() else {
return
}
WPAnalytics.track(.domainCreditRedemptionTapped)
DomainsDashboardCoordinator.presentDomainsSuggestions(
in: props.presentingViewController,
source: Strings.source,
blog: props.blog
)
}

private func hideCardTapped() {
guard let props = makeUnwrappedProperties() else {
return
}
let service = BlogDashboardPersonalizationService(siteID: props.siteID.intValue)
service.setEnabled(false, for: .domainRegistration)
}

// MARK: - Constants

private static var hasLoggedDomainCreditPromptShownEvent: Bool = false

// MARK: - View Lifecycle

override func didMoveToSuperview() {
super.didMoveToSuperview()
guard !Self.hasLoggedDomainCreditPromptShownEvent else {
return
}
WPAnalytics.track(WPAnalyticsStat.domainCreditPromptShown)
Self.hasLoggedDomainCreditPromptShownEvent = true
}

// MARK: - Helpers

private func makeUnwrappedProperties() -> Unwrapped? {
return Unwrapped(presentingViewController: presentingViewController, blog: blog)
}

// MARK: - Supporting Types

/// Encapsulates the unwrapping logic and returns nil if one of the passed in parameters is nil.
private struct Unwrapped {
let presentingViewController: BlogDashboardViewController
let blog: Blog
let siteID: NSNumber

init?(presentingViewController: BlogDashboardViewController?,
blog: Blog?) {
guard let presentingViewController,
let blog,
let siteID = blog.dotComID else {
return nil
}
self.presentingViewController = presentingViewController
self.blog = blog
self.siteID = siteID
}
}
}

// MARK: - Extensions

extension DashboardDomainRegistrationCardCell {

private enum Strings {
static let title = NSLocalizedString(
"Register Domain",
comment: "Action to redeem domain credit."
)
static let content = NSLocalizedString(
"All WordPress.com plans include a custom domain name. Register your free premium domain now.",
comment: "Information about redeeming domain credit on site dashboard."
)
static let hideThis = NSLocalizedString(
"domain.dashboard.card.menu.hide",
value: "Hide this",
comment: "Title for a menu action in the context menu on the Jetpack install card."
)
static let source = "domain_registration_dashboard_card"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum DashboardCard: String, CaseIterable {
case blaze
case domainsDashboardCard
case freeToPaidPlansDashboardCard
case domainRegistration
case todaysStats = "todays_stats"
case draftPosts
case scheduledPosts
Expand Down Expand Up @@ -59,6 +60,8 @@ enum DashboardCard: String, CaseIterable {
return DashboardDomainsCardCell.self
case .freeToPaidPlansDashboardCard:
return FreeToPaidPlansDashboardCardCell.self
case .domainRegistration:
return DashboardDomainRegistrationCardCell.self
case .empty:
return BlogDashboardEmptyStateCell.self
case .personalize:
Expand Down Expand Up @@ -107,6 +110,8 @@ enum DashboardCard: String, CaseIterable {
return DomainsDashboardCardHelper.shouldShowCard(for: blog) && !FreeToPaidPlansDashboardCardHelper.shouldShowCard(for: blog)
case .freeToPaidPlansDashboardCard:
return FreeToPaidPlansDashboardCardHelper.shouldShowCard(for: blog)
case .domainRegistration:
return DomainCreditEligibilityChecker.canRedeemDomainCredit(blog: blog)
case .empty:
return false // Controlled manually based on other cards visibility
case .personalize:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ private func makeKey(for card: DashboardCard) -> String? {
return "domains-dashboard-card-enabled-site-settings"
case .freeToPaidPlansDashboardCard:
return "free-to-paid-plans-dashboard-card-enabled-site-settings"
case .domainRegistration:
return "register-domain-dashboard-card"
case .activityLog:
return "activity-log-card-enabled-site-settings"
case .pages:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1020,13 +1020,15 @@ - (void)configureTableViewData
[marr addNullableObject:[self jetpackCardSectionViewModel]];
}

if ([DomainCreditEligibilityChecker canRedeemDomainCreditWithBlog:self.blog]) {
if (!self.hasLoggedDomainCreditPromptShownEvent) {
[WPAnalytics track:WPAnalyticsStatDomainCreditPromptShown];
self.hasLoggedDomainCreditPromptShownEvent = YES;
}
[marr addNullableObject:[self domainCreditSectionViewModel]];
}
// This code will be removed in a future PR.
// if ([DomainCreditEligibilityChecker canRedeemDomainCreditWithBlog:self.blog]) {
// if (!self.hasLoggedDomainCreditPromptShownEvent) {
// [WPAnalytics track:WPAnalyticsStatDomainCreditPromptShown];
// self.hasLoggedDomainCreditPromptShownEvent = YES;
// }
// [marr addNullableObject:[self domainCreditSectionViewModel]];
// }

if ([self shouldShowQuickStartChecklist]) {
[marr addNullableObject:[self quickStartSectionViewModel]];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private extension DashboardCard {
return NSLocalizedString("personalizeHome.dashboardCard.activityLog", value: "Recent activity", comment: "Card title for the pesonalization menu")
case .pages:
return NSLocalizedString("personalizeHome.dashboardCard.pages", value: "Pages", comment: "Card title for the pesonalization menu")
case .quickStart, .nextPost, .createPost, .ghost, .failure, .personalize, .jetpackBadge, .jetpackInstall, .domainsDashboardCard, .freeToPaidPlansDashboardCard, .empty:
case .quickStart, .nextPost, .createPost, .ghost, .failure, .personalize, .jetpackBadge, .jetpackInstall, .domainsDashboardCard, .freeToPaidPlansDashboardCard, .domainRegistration, .empty:
assertionFailure("\(self) card should not appear in the personalization menus")
return "" // These cards don't appear in the personalization menus
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class DomainCreditEligibilityChecker: NSObject {
@objc static func canRedeemDomainCredit(blog: Blog) -> Bool {
return (blog.isHostedAtWPcom || blog.isAtomic()) && blog.hasDomainCredit && JetpackFeaturesRemovalCoordinator.jetpackFeaturesEnabled()
return blog.canRegisterDomainWithPaidPlan && JetpackFeaturesRemovalCoordinator.jetpackFeaturesEnabled()
}
}
6 changes: 6 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3492,6 +3492,8 @@
F1F083F6241FFE930056D3B1 /* AtomicAuthenticationServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F083F5241FFE930056D3B1 /* AtomicAuthenticationServiceTests.swift */; };
F1F163C125658B4D003DC13B /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F163C025658B4D003DC13B /* IntentHandler.swift */; };
F1F163D625658B4D003DC13B /* WordPressIntents.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F1F163BE25658B4D003DC13B /* WordPressIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
F4026B1D2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4026B1C2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift */; };
F4026B1E2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4026B1C2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift */; };
F41BDD73290BBDCA00B7F2B0 /* MigrationActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD72290BBDCA00B7F2B0 /* MigrationActionsView.swift */; };
F41BDD792910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD782910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift */; };
F41BDD7B29114E2400B7F2B0 /* MigrationStep.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD7A29114E2400B7F2B0 /* MigrationStep.swift */; };
Expand Down Expand Up @@ -8877,6 +8879,7 @@
F1F163C225658B4D003DC13B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F1F163C825658B4D003DC13B /* IntentsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IntentsUI.framework; path = System/Library/Frameworks/IntentsUI.framework; sourceTree = SDKROOT; };
F373612EEEEF10E500093FF3 /* Pods-Apps-WordPress.release-alpha.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Apps-WordPress.release-alpha.xcconfig"; path = "../Pods/Target Support Files/Pods-Apps-WordPress/Pods-Apps-WordPress.release-alpha.xcconfig"; sourceTree = "<group>"; };
F4026B1C2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardDomainRegistrationCardCell.swift; sourceTree = "<group>"; };
F40CC35C2954991C00D75A95 /* WordPress 146.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 146.xcdatamodel"; sourceTree = "<group>"; };
F41BDD72290BBDCA00B7F2B0 /* MigrationActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationActionsView.swift; sourceTree = "<group>"; };
F41BDD782910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationFlowCoordinator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -13616,6 +13619,7 @@
0CB4057B29C8DEE1008EED0A /* BlogDashboardPersonalizeCardCell.swift */,
011896A129D5AF0700D34BA9 /* BlogDashboardCardConfigurable.swift */,
0C35FFF529CBB5DE00D224EB /* BlogDashboardEmptyStateCell.swift */,
F4026B1C2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift */,
);
path = Cards;
sourceTree = "<group>";
Expand Down Expand Up @@ -21687,6 +21691,7 @@
B5DD04741CD3DAB00003DF89 /* NSFetchedResultsController+Helpers.swift in Sources */,
B55F1AA81C10936600FD04D4 /* BlogSettings+Discussion.swift in Sources */,
E155EC721E9B7DCE009D7F63 /* PostTagPickerViewController.swift in Sources */,
F4026B1D2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift in Sources */,
98A25BD1203CB25F006A5807 /* SignupEpilogueCell.swift in Sources */,
B57AF5FA1ACDC73D0075A7D2 /* NoteBlockActionsTableViewCell.swift in Sources */,
8BA125EB27D8F5E4008B779F /* UIView+PinSubviewPriority.swift in Sources */,
Expand Down Expand Up @@ -24202,6 +24207,7 @@
C31852A229670F8100A78BE9 /* JetpackScanViewController+JetpackBannerViewController.swift in Sources */,
FABB225D2602FC2C00C8785C /* NotificationDetailsViewController.swift in Sources */,
C7BB60172863609C00748FD9 /* QRLoginInternetConnectionChecker.swift in Sources */,
F4026B1E2A1BC88A00CC7781 /* DashboardDomainRegistrationCardCell.swift in Sources */,
C3234F5527EBBACA004ADB29 /* SiteIntentVertical.swift in Sources */,
FEF4DC5628439357003806BE /* ReminderScheduleCoordinator.swift in Sources */,
FABB225F2602FC2C00C8785C /* MediaURLExporter.swift in Sources */,
Expand Down

0 comments on commit c7bf2d3

Please sign in to comment.