Repository navigation
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe CSS transitions manager tracks Fabric mount completion between draws. It skips clobbered-value repairs when no mount occurred, preserves animator state reporting, and unregisters the listener during cleanup. ChangesCSS transition repair
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: ⚪ Minimal · up to This localized performance change has no actionable merge-blocking risk remaining after normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ee764f7 to
9ee2ea5
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt`:
- Around line 32-48: Update CSSPlatformTransitionsManager to retain the
UIManagerListener registered in init, then remove that same listener during
teardown via removeUIManagerEventListener. Ensure NativeProxy.invalidate()
invokes the manager cleanup and clears its reference so the listener is detached
before a new CSSPlatformTransitionsManager is created.
- Around line 40-42: Update
CSSPlatformTransitionsManager.didMountItems(UIManager) so mountedSinceLastDraw
is set only when an actual React mount-item batch was dispatched, not for
command-only callbacks where the mount list is null. Track or consume the
preserved mount-item distinction through the relevant dispatch/listener flow,
while keeping command-only frames from triggering repairClobberedValues().
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6db8df1b-02a0-4dcf-a6d4-353bb6a440ed
📒 Files selected for processing (1)
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt
c509641 to
e1cfb18
Compare
9ee2ea5 to
695330c
Compare
e1cfb18 to
76b41d5
Compare
695330c to
207677c
Compare
76b41d5 to
9116dc6
Compare
207677c to
73e7ffc
Compare
9116dc6 to
50b1385
Compare
73e7ffc to
181a631
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt (1)
77-84: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHandle zero-duration delayed transitions.
durationMs == 0with a positive delay reachesanimateTransition. In this case,delayFraction == 1f, so the final interpolation returns0fand never writestoValue.Add an explicit full-delay case and a regression test.
Proposed fix
- override fun getInterpolation(input: Float): Float = - if (input <= delayFraction) 0f else inner.getInterpolation((input - delayFraction) / (1f - delayFraction)) + override fun getInterpolation(input: Float): Float = + when { + delayFraction >= 1f -> if (input >= 1f) 1f else 0f + input <= delayFraction -> 0f + else -> inner.getInterpolation((input - delayFraction) / (1f - delayFraction)) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt` around lines 77 - 84, Update HoldThenEase and the animateTransition path to handle durationMs == 0 with a positive delay: ensure the delayed transition reaches and writes toValue instead of remaining at 0f, while preserving normal interpolation for nonzero durations. Add a regression test covering a zero-duration delayed transition and verifying the final value is applied.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt`:
- Around line 77-84: Update HoldThenEase and the animateTransition path to
handle durationMs == 0 with a positive delay: ensure the delayed transition
reaches and writes toValue instead of remaining at 0f, while preserving normal
interpolation for nonzero durations. Add a regression test covering a
zero-duration delayed transition and verifying the final value is applied.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b132a6d9-bac6-4656-8327-7d99ab80b7c6
📒 Files selected for processing (1)
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt
50b1385 to
dbdc501
Compare
181a631 to
9a8fd6b
Compare
dbdc501 to
90753d5
Compare
9a8fd6b to
ea1977b
Compare
90753d5 to
824b5c8
Compare
ea1977b to
8e2206c
Compare
824b5c8 to
66fddc4
Compare
77866ff to
c382b26
Compare
24a0080 to
2c79ccd
Compare
c382b26 to
5c31d25
Compare
5c31d25 to
051e84d
Compare
0db10d0 to
f930a96
Compare
de63fcb to
6957bab
Compare
f930a96 to
2a9450d
Compare
React can overwrite an animated value only on frames where a mount ran, so a UIManagerListener records mounts and the repair returns immediately on every other frame instead of walking all running transitions.
d376c0d to
dd32131
Compare
2a9450d to
74324f2
Compare
The pre-draw repair re-asserts every running platform transition on every frame, but React can only overwrite an animated value on frames where it wrote props. A `UIManagerListener` records mounts and the repair returns immediately on all other frames, so the walk over running transitions happens at write rate rather than at the display refresh rate. That matters most after a transition settles: a persistent hold keeps its entry, so without the gate every later frame the window draws keeps walking the map. Measured on an emulator during a 3s transition, 201 of 240 pre-draw callbacks returned early. Synchronous updates run their mount item inline (`FabricUIManager.synchronouslyUpdateViewOnUIThread`), bypassing `MountItemDispatcher`, so no listener fires for them even though `opacity` is one of the props they carry. They therefore open the gate explicitly, which makes the invariant true by construction rather than by coincidence. Measured on device, such writes are rare and always landed on a frame where a mount had already opened the gate, so this is insurance rather than an observed fix. Identical in content to #10168, which this replaces. That one was based on the head branch of #10061, and closing #10061 instead of merging it left the base pointing at a branch with no live PR, so merging would not have reached `main`. GitHub refuses to change the base of a pull request that belongs to a stack, so recreating it was the only way to target `main`.
The pre-draw repair re-asserts every running platform transition on every frame, but React can only overwrite an animated value on frames where it wrote props. A
UIManagerListenerrecords mounts and the repair returns immediately on all other frames, so the walk over running transitions happens at write rate rather than at the display refresh rate.That matters most after a transition settles: a persistent hold keeps its entry, so without the gate every later frame the window draws keeps walking the map. Measured on an emulator during a 3s transition, 201 of 240 pre-draw callbacks returned early.
Synchronous updates run their mount item inline (
FabricUIManager.synchronouslyUpdateViewOnUIThread), bypassingMountItemDispatcher, so no listener fires for them even thoughopacityis one of the props they carry. They therefore open the gate explicitly, which makes the invariant true by construction rather than by coincidence. Measured on device, such writes are rare and always landed on a frame where a mount had already opened the gate, so this is insurance rather than an observed fix.