diff --git a/firefox-ios/Client/Coordinators/Browser/BrowserCoordinator.swift b/firefox-ios/Client/Coordinators/Browser/BrowserCoordinator.swift index c2373b6e0080..32407071f013 100644 --- a/firefox-ios/Client/Coordinators/Browser/BrowserCoordinator.swift +++ b/firefox-ios/Client/Coordinators/Browser/BrowserCoordinator.swift @@ -137,7 +137,11 @@ class BrowserCoordinator: BaseCoordinator, screenshotService.screenshotableView = nil } - func showHomepage(overlayManager: OverlayModeManager, isZeroSearch: Bool) { + func showHomepage( + overlayManager: OverlayModeManager, + isZeroSearch: Bool, + statusBarScrollDelegate: StatusBarScrollDelegate + ) { let homepageCoordinator = childCoordinators[HomepageCoordinator.self] ?? HomepageCoordinator( windowUUID: windowUUID, profile: profile, @@ -148,7 +152,8 @@ class BrowserCoordinator: BaseCoordinator, let homepageController = self.homepageViewController ?? HomepageViewController( windowUUID: windowUUID, homepageDelegate: homepageCoordinator, - overlayManager: overlayManager + overlayManager: overlayManager, + statusBarScrollDelegate: statusBarScrollDelegate ) guard browserViewController.embedContent(homepageController) else { logger.log("Unable to embed new homepage", level: .debug, category: .coordinator) diff --git a/firefox-ios/Client/Coordinators/Browser/BrowserDelegate.swift b/firefox-ios/Client/Coordinators/Browser/BrowserDelegate.swift index 53be422b7935..2f3a716769d8 100644 --- a/firefox-ios/Client/Coordinators/Browser/BrowserDelegate.swift +++ b/firefox-ios/Client/Coordinators/Browser/BrowserDelegate.swift @@ -24,7 +24,11 @@ protocol BrowserDelegate: AnyObject { ) /// Show the new homepage to the user as part of the homepage rebuild project - func showHomepage(overlayManager: OverlayModeManager, isZeroSearch: Bool) + func showHomepage( + overlayManager: OverlayModeManager, + isZeroSearch: Bool, + statusBarScrollDelegate: StatusBarScrollDelegate + ) /// Show the private homepage to the user as part of felt privacy func showPrivateHomepage(overlayManager: OverlayModeManager) diff --git a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift index 5f002b720a91..59a8c606aa3f 100644 --- a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift +++ b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift @@ -1313,7 +1313,11 @@ class BrowserViewController: UIViewController, func frontEmbeddedContent(_ viewController: ContentContainable) { contentContainer.update(content: viewController) - statusBarOverlay.resetState(isHomepage: contentContainer.hasLegacyHomepage) + if featureFlags.isFeatureEnabled(.homepageRebuild, checking: .buildOnly) { + statusBarOverlay.resetState(isHomepage: contentContainer.hasHomepage) + } else { + statusBarOverlay.resetState(isHomepage: contentContainer.hasLegacyHomepage) + } } /// Embed a ContentContainable inside the content container @@ -1326,7 +1330,11 @@ class BrowserViewController: UIViewController, viewController.willMove(toParent: self) contentContainer.add(content: viewController) viewController.didMove(toParent: self) - statusBarOverlay.resetState(isHomepage: contentContainer.hasLegacyHomepage) + if featureFlags.isFeatureEnabled(.homepageRebuild, checking: .buildOnly) { + statusBarOverlay.resetState(isHomepage: contentContainer.hasHomepage) + } else { + statusBarOverlay.resetState(isHomepage: contentContainer.hasLegacyHomepage) + } UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: nil) return true @@ -1352,7 +1360,11 @@ class BrowserViewController: UIViewController, } if featureFlags.isFeatureEnabled(.homepageRebuild, checking: .buildOnly) { - browserDelegate?.showHomepage(overlayManager: overlayManager, isZeroSearch: inline) + browserDelegate?.showHomepage( + overlayManager: overlayManager, + isZeroSearch: inline, + statusBarScrollDelegate: statusBarOverlay + ) } else { browserDelegate?.showLegacyHomepage( inline: inline, diff --git a/firefox-ios/Client/Frontend/Home/Homepage Rebuild/HomepageViewController.swift b/firefox-ios/Client/Frontend/Home/Homepage Rebuild/HomepageViewController.swift index 96b9d48d750c..359cdfeee7c4 100644 --- a/firefox-ios/Client/Frontend/Home/Homepage Rebuild/HomepageViewController.swift +++ b/firefox-ios/Client/Frontend/Home/Homepage Rebuild/HomepageViewController.swift @@ -26,6 +26,15 @@ final class HomepageViewController: UIViewController, let windowUUID: WindowUUID var currentWindowUUID: UUID? { return windowUUID } + // MARK: - Layout variables + var statusBarFrame: CGRect? { + guard let keyWindow = UIWindow.keyWindow else { return nil } + + return keyWindow.windowScene?.statusBarManager?.statusBarFrame + } + + weak var statusBarScrollDelegate: StatusBarScrollDelegate? + // MARK: - Private variables private typealias a11y = AccessibilityIdentifiers.FirefoxHomepage private weak var homepageDelegate: HomepageDelegate? @@ -47,6 +56,7 @@ final class HomepageViewController: UIViewController, homepageDelegate: HomepageDelegate? = nil, themeManager: ThemeManager = AppContainer.shared.resolve(), overlayManager: OverlayModeManager, + statusBarScrollDelegate: StatusBarScrollDelegate? = nil, notificationCenter: NotificationProtocol = NotificationCenter.default, logger: Logger = DefaultLogger.shared ) { @@ -55,6 +65,7 @@ final class HomepageViewController: UIViewController, self.themeManager = themeManager self.notificationCenter = notificationCenter self.overlayManager = overlayManager + self.statusBarScrollDelegate = statusBarScrollDelegate self.logger = logger homepageState = HomepageState(windowUUID: windowUUID) super.init(nibName: nil, bundle: nil) @@ -112,6 +123,17 @@ final class HomepageViewController: UIViewController, wallpaperView.updateImageForOrientationChange() } + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if homepageState.wallpaperState.wallpaperConfiguration.hasImage { + let theme = themeManager.getCurrentTheme(for: windowUUID) + statusBarScrollDelegate?.scrollViewDidScroll( + scrollView, + statusBarFrame: statusBarFrame, + theme: theme + ) + } + } + // MARK: - Redux func subscribeToRedux() { let action = ScreenAction( @@ -154,11 +176,6 @@ final class HomepageViewController: UIViewController, } // MARK: - Layout - var statusBarFrame: CGRect? { - guard let keyWindow = UIWindow.keyWindow else { return nil } - - return keyWindow.windowScene?.statusBarManager?.statusBarFrame - } func configureWallpaperView() { view.addSubview(wallpaperView) diff --git a/firefox-ios/Client/Frontend/Home/Homepage Rebuild/Redux/HomepageState.swift b/firefox-ios/Client/Frontend/Home/Homepage Rebuild/Redux/HomepageState.swift index 2dcc174727c8..bd850af0d2e2 100644 --- a/firefox-ios/Client/Frontend/Home/Homepage Rebuild/Redux/HomepageState.swift +++ b/firefox-ios/Client/Frontend/Home/Homepage Rebuild/Redux/HomepageState.swift @@ -9,10 +9,10 @@ struct HomepageState: ScreenState, Equatable { var windowUUID: WindowUUID // Homepage sections state in the order they appear on the collection view - var headerState: HeaderState - var topSitesState: TopSitesSectionState - var pocketState: PocketState - var wallpaperState: WallpaperState + let headerState: HeaderState + let topSitesState: TopSitesSectionState + let pocketState: PocketState + let wallpaperState: WallpaperState init(appState: AppState, uuid: WindowUUID) { guard let homepageState = store.state.screenState( diff --git a/firefox-ios/Client/Frontend/Home/Wallpaper/Redux/WallpaperState.swift b/firefox-ios/Client/Frontend/Home/Wallpaper/Redux/WallpaperState.swift index 25459d7f7f11..3264fc0218d4 100644 --- a/firefox-ios/Client/Frontend/Home/Wallpaper/Redux/WallpaperState.swift +++ b/firefox-ios/Client/Frontend/Home/Wallpaper/Redux/WallpaperState.swift @@ -48,19 +48,22 @@ struct WallpaperConfiguration: Equatable { var textColor: UIColor? var cardColor: UIColor? var logoTextColor: UIColor? + var hasImage: Bool init( landscapeImage: UIImage? = nil, portraitImage: UIImage? = nil, textColor: UIColor? = nil, cardColor: UIColor? = nil, - logoTextColor: UIColor? = nil + logoTextColor: UIColor? = nil, + hasImage: Bool = false ) { self.landscapeImage = landscapeImage self.portraitImage = portraitImage self.textColor = textColor self.cardColor = cardColor self.logoTextColor = logoTextColor + self.hasImage = hasImage } init(wallpaper: Wallpaper) { @@ -69,7 +72,8 @@ struct WallpaperConfiguration: Equatable { portraitImage: wallpaper.portrait, textColor: wallpaper.textColor, cardColor: wallpaper.cardColor, - logoTextColor: wallpaper.logoTextColor + logoTextColor: wallpaper.logoTextColor, + hasImage: wallpaper.hasImage ) } } diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Coordinators/BrowserCoordinatorTests.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Coordinators/BrowserCoordinatorTests.swift index 1e2f531bfead..654b76a5ed56 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Coordinators/BrowserCoordinatorTests.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Coordinators/BrowserCoordinatorTests.swift @@ -141,7 +141,11 @@ final class BrowserCoordinatorTests: XCTestCase, FeatureFlaggable { func testShowNewHomepage_setsProperViewController() { let subject = createSubject() - subject.showHomepage(overlayManager: overlayModeManager, isZeroSearch: false) + subject.showHomepage( + overlayManager: overlayModeManager, + isZeroSearch: false, + statusBarScrollDelegate: scrollDelegate + ) XCTAssertNotNil(subject.homepageViewController) XCTAssertNil(subject.webviewController) @@ -150,11 +154,19 @@ final class BrowserCoordinatorTests: XCTestCase, FeatureFlaggable { func testShowNewHomepage_hasSameInstance() { let subject = createSubject() - subject.showHomepage(overlayManager: overlayModeManager, isZeroSearch: false) + subject.showHomepage( + overlayManager: overlayModeManager, + isZeroSearch: false, + statusBarScrollDelegate: scrollDelegate + ) let firstHomepage = subject.homepageViewController XCTAssertNotNil(subject.homepageViewController) - subject.showHomepage(overlayManager: overlayModeManager, isZeroSearch: false) + subject.showHomepage( + overlayManager: overlayModeManager, + isZeroSearch: false, + statusBarScrollDelegate: scrollDelegate + ) let secondHomepage = subject.homepageViewController XCTAssertEqual(firstHomepage, secondHomepage) } diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageDiffableDataSourceTests.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageDiffableDataSourceTests.swift index 8ce80be70ae4..7eb4ab48a21d 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageDiffableDataSourceTests.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageDiffableDataSourceTests.swift @@ -53,9 +53,14 @@ final class HomepageDiffableDataSourceTests: XCTestCase { logoTextColor: .blue ) - let wallpaperState = WallpaperState(windowUUID: .XCTestDefaultUUID, wallpaperConfiguration: wallpaperConfig) - var state = HomepageState(windowUUID: .XCTestDefaultUUID) - state.wallpaperState = wallpaperState + let state = HomepageState.reducer( + HomepageState(windowUUID: .XCTestDefaultUUID), + WallpaperAction( + wallpaperConfiguration: wallpaperConfig, + windowUUID: .XCTestDefaultUUID, + actionType: WallpaperMiddlewareActionType.wallpaperDidInitialize + ) + ) dataSource.updateSnapshot(state: state) diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageViewControllerTests.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageViewControllerTests.swift index 5f9ba31fe153..0ba5a7cfd651 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageViewControllerTests.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage Rebuild/HomepageViewControllerTests.swift @@ -75,7 +75,29 @@ final class HomepageViewControllerTests: XCTestCase { XCTAssertEqual(mockNotificationCenter?.removeObserverCallCount, 1) } - private func createSubject() -> HomepageViewController { + func test_scrollViewDidScroll_updatesStatusBarScrollDelegate() { + let mockStatusBarScrollDelegate = MockStatusBarScrollDelegate() + let homepageVC = createSubject(statusBarScrollDelegate: mockStatusBarScrollDelegate) + let wallpaperConfiguration = WallpaperConfiguration(hasImage: true) + let newState = HomepageState.reducer( + HomepageState(windowUUID: .XCTestDefaultUUID), + WallpaperAction( + wallpaperConfiguration: wallpaperConfiguration, + windowUUID: .XCTestDefaultUUID, + actionType: WallpaperMiddlewareActionType.wallpaperDidInitialize + ) + ) + homepageVC.newState(state: newState) + let scrollView = UIScrollView() + + XCTAssertNil(mockStatusBarScrollDelegate.savedScrollView) + + homepageVC.scrollViewDidScroll(scrollView) + + XCTAssertEqual(mockStatusBarScrollDelegate.savedScrollView, scrollView) + } + + private func createSubject(statusBarScrollDelegate: StatusBarScrollDelegate? = nil) -> HomepageViewController { let notificationCenter = MockNotificationCenter() let themeManager = MockThemeManager() let mockOverlayManager = MockOverlayModeManager() @@ -85,6 +107,7 @@ final class HomepageViewControllerTests: XCTestCase { windowUUID: .XCTestDefaultUUID, themeManager: themeManager, overlayManager: mockOverlayManager, + statusBarScrollDelegate: statusBarScrollDelegate, notificationCenter: notificationCenter ) trackForMemoryLeaks(homepageViewController)