diff --git a/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift b/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift index 559be0dea809..7b2d49d7d96f 100644 --- a/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift @@ -162,6 +162,7 @@ class MySiteViewController: UIViewController, NoResultsViewHost { subscribeToPostPublished() startObservingQuickStart() startObservingOnboardingPrompt() + subscribeToWillEnterForeground() } override func viewWillAppear(_ animated: Bool) { @@ -184,6 +185,8 @@ class MySiteViewController: UIViewController, NoResultsViewHost { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + displayOverlayIfNeeded() + workaroundLargeTitleCollapseBug() if AppConfiguration.showsWhatIsNew { @@ -262,6 +265,13 @@ class MySiteViewController: UIViewController, NoResultsViewHost { NotificationCenter.default.addObserver(self, selector: #selector(handlePostPublished), name: .newPostPublished, object: nil) } + private func subscribeToWillEnterForeground() { + NotificationCenter.default.addObserver(self, + selector: #selector(displayOverlayIfNeeded), + name: UIApplication.willEnterForegroundNotification, + object: nil) + } + func updateNavigationTitle(for blog: Blog) { let blogName = blog.settings?.name let title = blogName != nil && blogName?.isEmpty == false @@ -1024,3 +1034,13 @@ extension MySiteViewController: BlogDetailsPresentationDelegate { } } } + +// MARK: Jetpack Features Removal + +private extension MySiteViewController { + @objc func displayOverlayIfNeeded() { + if isViewOnScreen() { + JetpackFeaturesRemovalCoordinator.presentOverlayIfNeeded(from: .appOpen, in: self) + } + } +} diff --git a/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackFeaturesRemovalCoordinator.swift b/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackFeaturesRemovalCoordinator.swift index 25653a97cd24..9c3ad515214d 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackFeaturesRemovalCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackFeaturesRemovalCoordinator.swift @@ -40,6 +40,20 @@ class JetpackFeaturesRemovalCoordinator { case card case login case appOpen = "app_open" + + /// Used to differentiate between last saved dates for different phases. + /// Should return a dynamic value if each phase should be treated differently. + /// Should return nil if all phases should be treated the same. + func frequencyTrackerPhaseString(phase: GeneralPhase) -> String? { + switch self { + case .login: + fallthrough + case .appOpen: + return phase.rawValue // Shown once per phase + default: + return nil // Phase is irrelevant. + } + } } static func generalPhase(featureFlagStore: RemoteFeatureFlagStore = RemoteFeatureFlagStore()) -> GeneralPhase { @@ -100,8 +114,11 @@ class JetpackFeaturesRemovalCoordinator { static func presentOverlayIfNeeded(from source: OverlaySource, in viewController: UIViewController) { let phase = generalPhase() let frequencyConfig = phase.frequencyConfig + let frequencyTrackerPhaseString = source.frequencyTrackerPhaseString(phase: phase) let viewModel = JetpackFullscreenOverlayGeneralViewModel(phase: phase, source: source) - let frequencyTracker = JetpackOverlayFrequencyTracker(frequencyConfig: frequencyConfig, source: source) + let frequencyTracker = JetpackOverlayFrequencyTracker(frequencyConfig: frequencyConfig, + phaseString: frequencyTrackerPhaseString, + source: source) guard viewModel.shouldShowOverlay, frequencyTracker.shouldShow() else { return } diff --git a/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackOverlayFrequencyTracker.swift b/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackOverlayFrequencyTracker.swift index ee73ead9bc08..213975e03a69 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackOverlayFrequencyTracker.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackOverlayFrequencyTracker.swift @@ -3,9 +3,17 @@ import Foundation class JetpackOverlayFrequencyTracker { private let frequencyConfig: FrequencyConfig + private let phaseString: String? private let source: JetpackFeaturesRemovalCoordinator.OverlaySource private let persistenceStore: UserPersistentRepository + private var sourceDateKey: String { + guard let phaseString = phaseString else { + return "\(Constants.lastDateKeyPrefix)-\(source.rawValue)" + } + return "\(Constants.lastDateKeyPrefix)-\(source.rawValue)-\(phaseString)" + } + private var lastSavedGenericDate: Date? { get { let key = Constants.lastDateKeyPrefix @@ -19,19 +27,19 @@ class JetpackOverlayFrequencyTracker { private var lastSavedSourceDate: Date? { get { - let sourceKey = "\(Constants.lastDateKeyPrefix)-\(source.rawValue)" - return persistenceStore.object(forKey: sourceKey) as? Date + return persistenceStore.object(forKey: sourceDateKey) as? Date } set { - let sourceKey = "\(Constants.lastDateKeyPrefix)-\(source.rawValue)" - persistenceStore.set(newValue, forKey: sourceKey) + persistenceStore.set(newValue, forKey: sourceDateKey) } } init(frequencyConfig: FrequencyConfig = .defaultConfig, + phaseString: String? = nil, source: JetpackFeaturesRemovalCoordinator.OverlaySource, persistenceStore: UserPersistentRepository = UserDefaults.standard) { self.frequencyConfig = frequencyConfig + self.phaseString = phaseString self.source = source self.persistenceStore = persistenceStore } diff --git a/WordPress/Classes/ViewRelated/Jetpack/Branding/Menu Card/JetpackBrandingMenuCardCell.swift b/WordPress/Classes/ViewRelated/Jetpack/Branding/Menu Card/JetpackBrandingMenuCardCell.swift index 25ea813e53e6..67c21a803508 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Branding/Menu Card/JetpackBrandingMenuCardCell.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Branding/Menu Card/JetpackBrandingMenuCardCell.swift @@ -146,7 +146,7 @@ class JetpackBrandingMenuCardCell: UITableViewCell { } private func setupContent() { - logosAnimationView.play() + logosAnimationView.currentProgress = 1.0 let config = presenter.cardConfig() descriptionLabel.text = config?.description learnMoreSuperview.isHidden = config?.learnMoreButtonURL == nil diff --git a/WordPress/WordPressTest/JetpackOverlayFrequencyTrackerTests.swift b/WordPress/WordPressTest/JetpackOverlayFrequencyTrackerTests.swift index d7d961c3a252..906423947eae 100644 --- a/WordPress/WordPressTest/JetpackOverlayFrequencyTrackerTests.swift +++ b/WordPress/WordPressTest/JetpackOverlayFrequencyTrackerTests.swift @@ -49,9 +49,11 @@ final class JetpackOverlayFrequencyTrackerTests: XCTestCase { func testShowLoginOverlayOnlyOnce() { // Given - let key = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix + "-login" + let key = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix + "-login-phaseString" let genericKey = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix - let tracker = JetpackOverlayFrequencyTracker(source: .login, persistenceStore: mockUserDefaults) + let tracker = JetpackOverlayFrequencyTracker(phaseString: "phaseString", + source: .login, + persistenceStore: mockUserDefaults) // When & Then XCTAssertTrue(tracker.shouldShow()) @@ -67,9 +69,11 @@ final class JetpackOverlayFrequencyTrackerTests: XCTestCase { func testShowAppOpenOverlayOnlyOnce() { // Given - let key = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix + "-app_open" + let key = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix + "-app_open-phaseString" let genericKey = JetpackOverlayFrequencyTracker.Constants.lastDateKeyPrefix - let tracker = JetpackOverlayFrequencyTracker(source: .appOpen, persistenceStore: mockUserDefaults) + let tracker = JetpackOverlayFrequencyTracker(phaseString: "phaseString", + source: .appOpen, + persistenceStore: mockUserDefaults) // When & Then XCTAssertTrue(tracker.shouldShow())