Skip to content

Add PaywallsV2 header component#6548

Open
facumenzella wants to merge 11 commits intomainfrom
feat/paywalls-v2-header-component
Open

Add PaywallsV2 header component#6548
facumenzella wants to merge 11 commits intomainfrom
feat/paywalls-v2-header-component

Conversation

@facumenzella
Copy link
Copy Markdown
Member

@facumenzella facumenzella commented Apr 2, 2026

Summary

  • Adds PaywallComponent.HeaderComponent (SPI-only, mirrors StickyFooterComponent pattern) with encode/decode support
  • Wires components_config.header into PaywallComponentsConfig, cache warming, RootViewModel, and RootView
  • Safe-area and firstItemIgnoresSafeArea logic prefers header over root stack when header is present
  • Unsupported-condition traversal covers header stack
  • Tests: HeaderComponentTests, PaywallComponentsConfigHeaderTests, expanded ViewModelFactoryBadgeTests

Spec & cross-platform

Test plan

  • swift test --filter HeaderComponentTests passes
  • swift test --filter PaywallComponentsConfigHeaderTests passes
  • swift test --filter ViewModelFactoryBadgeTests passes
  • Xcode: UnitTests/HeaderComponentTests + UnitTests/PaywallComponentsConfigHeaderTests on iOS Simulator pass
  • Paywall with components_config.header renders header above the main stack

🤖 Generated with Claude Code


Note

Medium Risk
Adds a new components_config.header surface that affects paywall decoding, view-model construction, rendering layout, and asset prefetching; risk is mainly UI/layout regressions and compatibility with older configs.

Overview
Adds a new SPI PaywallComponent.HeaderComponent and exposes it on PaywallComponentsData.PaywallComponentsConfig as optional header, including JSON encode/decode coverage.

Wires the header through Paywalls V2 rendering by creating HeaderComponentViewModel/HeaderComponentView, updating RootViewModel/RootView to overlay the header above the main stack, and extending ViewModelFactory to build the header stack, propagate discardRules when header contains unsupported conditions, and adjust first-item safe-area ignore logic to prefer the header when present.

Updates paywall V2 cache warming to prefetch header image/video assets and adds focused unit/UI tests for header decoding/encoding and the new layout/rule-propagation behaviors.

Reviewed by Cursor Bugbot for commit 2e367fb. Bugbot is set up for automated code reviews on this repo. Configure here.

Implements components_config.header support — model, decoding, cache
warming, view/view-model, and root wiring — following the same pattern
as StickyFooterComponent. HeaderComponent is SPI-only (@_spi(Internal))
to avoid a source-breaking enum-case addition to PaywallComponent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
facumenzella and others added 7 commits April 2, 2026 15:09
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Register .header case in PaywallComponent enum and ComponentType
- Add .header to PaywallComponentViewModel and ViewModelFactory.toViewModel
- Add .header dispatch in ComponentsView
- Add .header to containsUnsupportedConditions in PresentedPartials
- Add .header to collectAllImageURLs/VideoURLs in PaywallV2CacheWarming
- Add spec layout tests (header+footer, header only, footer only, body only)
- Add "as PaywallComponent" deserialization test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirrors Android's ContainsUnsupportedConditionTests: verifies that
unsupported conditions inside a HeaderComponent's stack are detected
both when called directly on the component and when the header is
embedded as a child inside a stack.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove additionalPadding(top: headerHeight) from body stack so the header
  overlays content instead of pushing it down
- Fix findFirstItemIgnoresSafeAreaInfo to fall through to the body stack check
  when the header exists but doesn't start with a full-width image, so
  edgesIgnoringSafeArea(.top) is correctly applied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@facumenzella facumenzella marked this pull request as ready for review April 7, 2026 16:57
@facumenzella facumenzella requested review from a team as code owners April 7, 2026 16:57
The bottom padding should apply whenever there is no sticky footer,
regardless of header presence. The sticky footer handles its own bottom
safe area; the scroll content needs the inset in all other cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7f76cf4. Configure here.

@facumenzella facumenzella requested a review from vegaro April 8, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant