Abstract workflow page transition animation behind sealed class #3430
Conversation
…lass Introduces WorkflowTransitionAnimation as the single seam for swapping the workflow paywall page transition. WorkflowSlideState now carries the active transition; rememberWorkflowSlideState derives the AnimationSpec from it and Modifier.workflowSlide dispatches the visual transform via a when-branch. Default behavior is unchanged (Slide, 350ms, FastOutSlowInEasing). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 c2a49f9. Configure here.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3430 +/- ##
=======================================
Coverage 79.45% 79.45%
=======================================
Files 362 362
Lines 14539 14539
Branches 1976 1976
=======================================
Hits 11552 11552
Misses 2190 2190
Partials 797 797 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
tonidero
left a comment
There was a problem hiding this comment.
Just some naming suggestions, but overall looks good!
| val animatingDirection: NavigationDirection?, | ||
| val animatable: Animatable<Float, AnimationVector1D>, | ||
| ) | ||
| val transition: WorkflowTransitionAnimation, |
There was a problem hiding this comment.
Hmm it's a bit weird to have a WorkflowTransitionAnimation as part of a WorkflowSlideState. Maybe we should rename this one to WorkflowTransitionState as well?
Or maybe we want to create different types of states per animation types, since some properties might not make sense for all animations (for example, direction seems unnecessary if using a fade)
| internal fun rememberWorkflowSlideState( | ||
| workflowState: WorkflowPaywallUiState, | ||
| onTransitionComplete: (transitionId: Int) -> Unit, | ||
| transition: WorkflowTransitionAnimation = WorkflowTransitionAnimation.Slide(), |
There was a problem hiding this comment.
Same here about the rememberWorkflowSlideState maybe could be rememberWorkflowTransitionState
| * 3. Adding a `when` branch in [rememberWorkflowSlideState] for the animation spec. | ||
| */ | ||
| internal sealed class WorkflowTransitionAnimation { | ||
| data class Slide( |
There was a problem hiding this comment.
[Unrelated to this PR]
But maybe we could be clearer about the type of slide this is. For example, is it a SlideInOut (so the previous screen also slides out) or is it SlideIn only (so only the new screen slides on top). But this is not new from this PR and we can leave as is.
**This is an automatic release.** ## RevenueCat SDK ### ✨ New Features * Add optional support for setting obfuscated account id to product changes (RevenueCat#3428) via Mark Villacampa (@MarkVillacampa) ## RevenueCatUI SDK ### Paywallv2 #### ✨ New Features * Add slide transition to workflow paywalls (RevenueCat#3418) via Cesar de la Vega (@vegaro) * Workflow state & ViewModel infrastructure (RevenueCat#3416) via Cesar de la Vega (@vegaro) #### 🐞 Bugfixes * Fix paywall layout direction for RTL locale overrides (PWENG-39) (RevenueCat#3425) via Monika Mateska (@MonikaMateska) * Apply ripple shape clip on a sibling Box to avoid clipping content (RevenueCat#3395) via Toni Rico (@tonidero) ### 🔄 Other Changes * build(deps): bump fastlane-plugin-revenuecat_internal from `21e02ec` to `af7bb5c` (RevenueCat#3442) via dependabot[bot] (@dependabot[bot]) * Abstract workflow page transition animation behind sealed class (RevenueCat#3430) via Cesar de la Vega (@vegaro) * Add `single_step_fallback_id` field to `PublishedWorkflow` (RevenueCat#3436) via Cesar de la Vega (@vegaro) * build(deps): bump fastlane-plugin-revenuecat_internal from `2d11430` to `21e02ec` (RevenueCat#3429) via dependabot[bot] (@dependabot[bot]) * Generalize `PaywallComponentsScaffold` for workflow reuse (RevenueCat#3417) via Cesar de la Vega (@vegaro) * perf: pre-warm workflow paywall step states off-thread (RevenueCat#3420) via Cesar de la Vega (@vegaro) * Update baseline profiles (RevenueCat#3427) via RevenueCat Git Bot (@RCGitBot) * build(deps): bump fastlane-plugin-revenuecat_internal from `d24ab26` to `2d11430` (RevenueCat#3426) via dependabot[bot] (@dependabot[bot]) * Replace unauthenticated SDKMAN install with SHA-pinned orb command (RevenueCat#3407) via Rick (@rickvdl) * Auto load paywall in paywall tester via local.properties (RevenueCat#3405) via Cesar de la Vega (@vegaro) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: this is a version/release cut that mainly updates version strings, changelogs, and doc deployment targets with no functional logic changes beyond version identifiers. > > **Overview** > Cuts the `10.4.0` release by removing `-SNAPSHOT` across the project (core `VERSION_NAME`, `Config.frameworkVersion`, sample/test app dependency versions, and the root `.version` file). > > Updates release collateral and publishing to point at `10.4.0`, including changelogs (`CHANGELOG.md`/`CHANGELOG.latest.md`), docs redirect (`docs/index.html`), and the CircleCI `docs-deploy` S3 sync path (from `10.4.0-SNAPSHOT` to `10.4.0`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f7b3604. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…evenueCat#3441) Cleanup from a review comment on RevenueCat#3430. `visibleStepIds: Set` was redundant with `animatingFromStepId: String?`: the set was always either `{from, to}` or `{to}`, derivable from the from/to pair. Replaced both with explicit `animatingFromStepId` + `animatingToStepId`. This was there becuase I was attempting some performance improvements in other branch that used a set, but we are going with just from and to for now. Also dropped some dead code: - the unreachable parked-step branch in `applyWorkflowTransition` (vestige of an old "render all steps" design) - the `currentStepId` param of `workflowTransition`, now read off `state.animatingToStepId` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate risk because it changes which workflow steps are kept in composition and how slide translations are computed, which could cause visual/animation regressions if edge cases exist. > > **Overview** > Simplifies workflow paywall transitions by removing `visibleStepIds` and making `WorkflowTransitionState` explicitly track `animatingFromStepId` and `animatingToStepId`. > > Rendering now only composes the outgoing + incoming steps during a transition (via `listOfNotNull(from,to)`), and `workflowTransition` no longer requires `currentStepId`, instead deriving positioning from `state.animatingToStepId`. Dead/unused “parked step” translation logic is removed. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 67fadd3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

Refactor creating a
WorkflowTransitionAnimationthat can be easily extended in the future. This PR doesn't change any behaviorNote
Low Risk
Low risk refactor that preserves existing slide behavior but rewires workflow-step transition plumbing; main risk is subtle regressions in step/header selection or animation timing.
Overview
Refactors workflow paywall step transitions to be driven by a new
WorkflowTransitionAnimation/WorkflowTransitionStatesealed-class abstraction, keeping the current Slide-In/Out behavior as the default.LoadedWorkflowPaywalland related composables now userememberWorkflowTransitionStateandModifier.workflowTransition(instead of the slide-specific state/modifier), and header selection logic is updated to derive any pending transition from the active transition-state subtype.Reviewed by Cursor Bugbot for commit 27b6750. Bugbot is set up for automated code reviews on this repo. Configure here.