Skip to content

chore: upgrade reanimated to v4#6720

Open
Rohit3523 wants to merge 122 commits intodevelopfrom
reanimated-v4
Open

chore: upgrade reanimated to v4#6720
Rohit3523 wants to merge 122 commits intodevelopfrom
reanimated-v4

Conversation

@Rohit3523
Copy link
Copy Markdown
Contributor

@Rohit3523 Rohit3523 commented Oct 12, 2025

Proposed changes

This PR upgrades react-native-reanimated from v3 to v4.

Short Summary of the changes

  • Updated react-native-reanimated from 3.17.1 to 4.1.3
  • Added react-native-worklets (0.6.1), which is now a separate package required by Reanimated v4
  • Migrated all animation callback APIs to use the new scheduleOnRN function (replaces the deprecated runOnJS)
  • Update audio player seek bar gesture handler to use the current Gesture API because useAnimatedGestureHandler is removed in v4

Issue(s)

https://rocketchat.atlassian.net/browse/COMM-46

How to test or reproduce

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Summary by CodeRabbit

  • Refactor
    • Improved gesture handling and event scheduling across interactive components for smoother animations and more reliable input responses.
  • Tests
    • Updated test setup mocks for bottom-sheet and removed legacy runOnJS mock.
  • Build
    • Switched Babel plugin to enable worklet scheduling and runtime changes.
  • Dependencies
    • Updated react-native-reanimated, added react-native-worklets, and bumped @gorhom/bottom-sheet.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 12, 2025

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd26762f-aea7-4c78-9cf5-51a806f48fed

📥 Commits

Reviewing files that changed from the base of the PR and between 72abc55 and 121329c.

📒 Files selected for processing (1)
  • app/containers/AudioPlayer/Seek.tsx
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: ESLint and Test / run-eslint-and-test
🔇 Additional comments (5)
app/containers/AudioPlayer/Seek.tsx (5)

3-12: LGTM!

Import changes align correctly with the Reanimated v4 migration: Gesture/GestureDetector replaces the old PanGestureHandler pattern, and scheduleOnRN from react-native-worklets is the documented replacement for the deprecated runOnJS.


52-52: LGTM!

The contextX shared value correctly implements the gesture context pattern, capturing the initial position on start for delta-based translation calculation.


82-89: LGTM!

The onFinalize handler correctly implements gesture cancellation recovery using the didSucceed parameter. When the gesture fails or is cancelled, it properly restores translateX to the captured contextX and recalculates currentTime using the same formula as useDerivedValue.


130-132: LGTM!

The GestureDetector wrapper correctly replaces the previous PanGestureHandler pattern, following the recommended Gesture Handler v2 API.


79-80: Verify unit consistency: onChangeTime may expect seconds, not milliseconds.

Line 80 multiplies currentTime.value * 1000 before passing to onChangeTime (which is bound to setPosition). Confirm whether currentTime.value is in seconds and whether setPosition expects milliseconds, or if both use the same unit. If there's a unit mismatch, this could cause a 1000× error in seek position.


Walkthrough

Migrates worklet scheduling from runOnJS to scheduleOnRN, replaces the audio seeker's PanGestureHandler implementation with Gesture.Pan() + GestureDetector, updates related type imports, and adjusts Babel, Jest setup, and package dependencies for react-native-worklets and Reanimated v4 compatibility.

Changes

Cohort / File(s) Summary
Audio seeker (gesture refactor)
app/containers/AudioPlayer/Seek.tsx
Replaced PanGestureHandler + useAnimatedGestureHandler with Gesture.Pan() + GestureDetector. Introduced contextX shared value, clamp-based translateX updates, withTiming scale animation, and moved time-change notification to scheduleOnRN(onChangeTime, Math.round(...)) on end. Removed Animated.addWhitelistedNativeProps.
Animation scheduling migration
app/containers/MessageComposer/hooks/useEmojiKeyboard.tsx, app/containers/RoomItem/Actions.tsx, app/containers/RoomItem/Touchable.tsx, app/views/RoomView/List/components/List.tsx
Replaced runOnJS(...) calls with scheduleOnRN(...) for syncing React state or invoking JS callbacks from Reanimated worklets; updated imports to use scheduleOnRN from react-native-worklets.
Type imports update
app/containers/RoomItem/interfaces.ts
Changed transX types from Animated.SharedValue<number> to SharedValue<number> and adjusted imports accordingly.
Build, tests & deps
babel.config.js, jest.setup.js, package.json
Swapped Babel plugin to react-native-worklets/plugin. Removed runOnJS mock and changed mocked bottom-sheet to @gorhom/bottom-sheet in Jest setup. package.json: added react-native-worklets, updated react-native-reanimated, removed @discord/bottom-sheet, and bumped @gorhom/bottom-sheet devDependency.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  rect rgba(200,220,255,0.5)
    participant User
    participant UI as GestureDetector
    participant Worklet as Reanimated Worklet
    participant RN as React Native (JS)
    participant State as App State / onChangeTime
  end

  User->>UI: Pan start / move / end
  UI->>Worklet: .onStart / .onUpdate / .onEnd handlers
  Worklet->>Worklet: update shared values (contextX, translateX, scale)
  alt gesture ends with change
    Worklet->>RN: scheduleOnRN(onChangeTime, Math.round(currentTime * 1000))
    RN->>State: apply time change
  else gesture finalizes/no change
    Worklet->>Worklet: restore translateX/currentTime, animate scale -> 1
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: upgrading react-native-reanimated to version 4, which is the central objective of the PR.
Linked Issues check ✅ Passed The PR addresses the Reanimated v4 upgrade objective by updating the dependency (v3.17.1 to v4.1.3), adding react-native-worklets, migrating deprecated runOnJS to scheduleOnRN, and updating gesture handlers to use the current API.
Out of Scope Changes check ✅ Passed All changes are directly related to the Reanimated v4 upgrade: dependency updates, API migrations (runOnJS to scheduleOnRN), gesture handler updates, and related test/build configuration adjustments are all necessary for the upgrade.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Rohit3523 Rohit3523 temporarily deployed to approve_e2e_testing October 12, 2025 22:05 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 changed the title chore: Reanimated v4 chore: reanimated v4 Oct 12, 2025
@Rohit3523 Rohit3523 temporarily deployed to experimental_android_build October 12, 2025 22:09 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 had a problem deploying to official_android_build October 12, 2025 22:09 — with GitHub Actions Failure
@Rohit3523 Rohit3523 had a problem deploying to experimental_ios_build October 12, 2025 22:09 — with GitHub Actions Failure
@Rohit3523 Rohit3523 had a problem deploying to upload_experimental_android October 12, 2025 22:49 — with GitHub Actions Failure
@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.66.0.107555

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNTOBmiQlkEe-OeA3KvdurMOyXgF0YILJjAwuhDsPx5-LdCpHYt19pvHOiftS6iCycG0q6ZpQ_pgK-UBglwa

@Rohit3523 Rohit3523 changed the title chore: reanimated v4 chore: upgrade reanimated to v4 Oct 15, 2025
@OtavioStasiak OtavioStasiak marked this pull request as ready for review January 16, 2026 21:59
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/AudioPlayer/Seek.tsx`:
- Around line 76-80: The scale-up animation is currently run inside onUpdate
causing it to restart every frame; move the withTiming(1.3, { duration: 150 })
call into the onStart handler so it runs once when the gesture begins. Update
the gesture handlers around onStart, onUpdate, and onEnd: in onStart call
scale.value = withTiming(1.3, { duration: 150 }) (and set any initial
contextX.value if used), in onUpdate keep only the translation logic using
contextX, translateX and maxWidth (clamp newX), and in onEnd revert scale with
withTiming(1, { duration: 150 }) to restore the original size. Ensure you
reference the existing scale, translateX, contextX, maxWidth,
onStart/onUpdate/onEnd functions so behavior and state remain consistent.
- Line 84: The call to scheduleOnRN(onChangeTime, Math.round(currentTime.value *
1000)) from the gesture handler can cause iOS crashes when it bridges into the
main thread and calls AudioManager.setPositionAsync; update Seek.tsx to detect
iOS and avoid a single-shot scheduleOnRN call: add a platform check (iOS) around
scheduleOnRN, and implement a safe fallback such as queuing the position update
on the RN main thread with a short retry/backoff (e.g., try up to N times with
small delays) or call a native-safe bridge method instead of directly invoking
AudioManager.setPositionAsync from the worklet; ensure you reference
scheduleOnRN, onChangeTime, currentTime.value and the code path that ultimately
calls AudioManager.setPositionAsync when adding the workaround.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4049f5e3-0a17-4646-b519-d0591066f65a

📥 Commits

Reviewing files that changed from the base of the PR and between d3f516b and 4ff6637.

📒 Files selected for processing (3)
  • app/containers/AudioPlayer/Seek.tsx
  • app/containers/MessageComposer/hooks/useEmojiKeyboard.tsx
  • app/containers/RoomItem/Actions.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/containers/RoomItem/Actions.tsx
  • app/containers/MessageComposer/hooks/useEmojiKeyboard.tsx
📜 Review details
🔇 Additional comments (3)
app/containers/AudioPlayer/Seek.tsx (3)

3-12: Imports look correct for the Reanimated v4 migration.

The migration to Gesture/GestureDetector API and scheduleOnRN from react-native-worklets aligns with the PR objectives. The removal of runOnJS import is expected as it's replaced by scheduleOnRN.


52-52: Good addition of contextX shared value.

This correctly replaces the context parameter from useAnimatedGestureHandler to capture the starting position at gesture start.


125-127: Correct usage of GestureDetector wrapper.

The migration from PanGestureHandler component to GestureDetector with the composed gesture object follows the recommended react-native-gesture-handler v2+ pattern.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/AudioPlayer/Seek.tsx`:
- Around line 67-81: The onEnd handler schedules onChangeTime (an async
Promise-returning function) directly via scheduleOnRN which can cause unhandled
rejections; create a RN-scoped wrapper in the component (e.g., seekOnRN) that
calls onChangeTime(Math.round(currentTime.value * 1000)), catches any rejection
and forwards it to the component's existing error path/handler, and then pass
that wrapper to scheduleOnRN in panGesture.onEnd instead of onChangeTime.
- Around line 82-85: onFinalize currently always resets isPanning and scale but
doesn’t restore state when a pan is cancelled; update the onFinalize callback to
check the provided didSucceed flag and if didSucceed === false restore the
pre-pan position by setting translateX back to the captured contextX and
resetting currentTime.value from contextX (the same context captured during
gesture start), otherwise (didSucceed === true) call onChangeTime to commit the
seek; ensure you still set isPanning.value = false and run scale.value =
withTiming(1, { duration: 150 }) in all cases.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 193f2f01-d5af-4b5d-b308-8a4a05d8e640

📥 Commits

Reviewing files that changed from the base of the PR and between d3f516b and a541660.

📒 Files selected for processing (3)
  • app/containers/AudioPlayer/Seek.tsx
  • app/containers/MessageComposer/hooks/useEmojiKeyboard.tsx
  • app/containers/RoomItem/Actions.tsx
✅ Files skipped from review due to trivial changes (1)
  • app/containers/RoomItem/Actions.tsx

@github-actions
Copy link
Copy Markdown

iOS Build Available

Rocket.Chat Experimental 4.71.0.108435

@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.71.0.108434

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNS1RtQubN6MMAV6ZUrFc1b0kUreKqDbpdWfbaPXjLGxe63axqkLb1yrncpK7nMv-7rvES64oTVal6fgsv-c

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/AudioPlayer/Seek.tsx`:
- Line 87: Remove the stray tab/extra whitespace on the empty line in the Seek
component file (Seek.tsx) to fix formatting; open the Seek component (function
or default export named Seek) and delete the trailing tab characters or
blank-line indentation so the file contains a clean empty line without
whitespace.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 11537494-2e4a-40c7-afaa-f96dc1276a6c

📥 Commits

Reviewing files that changed from the base of the PR and between a541660 and 72abc55.

📒 Files selected for processing (1)
  • app/containers/AudioPlayer/Seek.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: ESLint and Test / run-eslint-and-test
  • GitHub Check: format
🧰 Additional context used
🪛 ESLint
app/containers/AudioPlayer/Seek.tsx

[error] 87-87: Delete ↹↹↹

(prettier/prettier)

🔇 Additional comments (3)
app/containers/AudioPlayer/Seek.tsx (3)

1-12: LGTM!

Import changes correctly support the migration to the Gesture API and scheduleOnRN.


67-90: LGTM! Gesture migration is well implemented.

The migration from useAnimatedGestureHandler to Gesture.Pan() is correct:

  • Context capture in onStart for delta-based translation
  • Scale animation correctly placed in onStart (runs once)
  • Position restoration on cancelled gestures via onFinalize with didSucceed check
  • scheduleOnRN usage is the standard pattern for bridging to JS thread from gesture handlers

130-132: LGTM!

Correct usage of GestureDetector wrapping the interactive thumb element.

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