Skip to content

Abstract workflow page transition animation behind sealed class #3430

Merged
vegaro merged 4 commits into
mainfrom
cesar/2026-05-03-android-workflow-animation-abstraction
May 5, 2026
Merged

Abstract workflow page transition animation behind sealed class #3430
vegaro merged 4 commits into
mainfrom
cesar/2026-05-03-android-workflow-animation-abstraction

Conversation

@vegaro

@vegaro vegaro commented May 4, 2026

Copy link
Copy Markdown
Member

Refactor creating a WorkflowTransitionAnimation that can be easily extended in the future. This PR doesn't change any behavior


Note

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/WorkflowTransitionState sealed-class abstraction, keeping the current Slide-In/Out behavior as the default.

LoadedWorkflowPaywall and related composables now use rememberWorkflowTransitionState and Modifier.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.

…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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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 c2a49f9. Configure here.

@codecov

codecov Bot commented May 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.45%. Comparing base (8383c70) to head (27b6750).
⚠️ Report is 3 commits behind head on main.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just some naming suggestions, but overall looks good!

val animatingDirection: NavigationDirection?,
val animatable: Animatable<Float, AnimationVector1D>,
)
val transition: WorkflowTransitionAnimation,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[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.

@vegaro vegaro requested a review from tonidero May 5, 2026 15:48
@vegaro vegaro added this pull request to the merge queue May 5, 2026
Merged via the queue into main with commit 67a763d May 5, 2026
36 checks passed
@vegaro vegaro deleted the cesar/2026-05-03-android-workflow-animation-abstraction branch May 5, 2026 18:39
matteinn pushed a commit to matteinn/purchases-android that referenced this pull request Jun 5, 2026
**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 -->
matteinn pushed a commit to matteinn/purchases-android that referenced this pull request Jun 5, 2026
…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>
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.

2 participants