Skip to content

feat: add a hinge sensor type to useAnimatedSensor - #10651

Draft
pawicao wants to merge 2 commits into
@pawicao/sensor-availability-rerenderfrom
@pawicao/animated-sensor-hinge
Draft

pawicao wants to merge 2 commits into
@pawicao/sensor-availability-rerenderfrom
@pawicao/animated-sensor-hinge

Conversation

@pawicao

@pawicao pawicao commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Note

This PR description is AI-generated.

Requires #10662.

Summary

Foldable devices expose a hinge angle, but useAnimatedSensor had no sensor type for it. I added SensorType.HINGE, which reports the angle in radians and a HingeStatus from Sensor.TYPE_HINGE_ANGLE on Android and UIHingeInteraction on iOS 27.1, takes no config, and has no web counterpart. iOS reveals a hinge only through the updates of the interaction, so ReanimatedHingeProbe attaches one to a hidden window when the app's first scene connects, and the answer arrives a few milliseconds later, before JS renders. isAvailable is therefore correct on the first render on both platforms, the hook keeps reading it with useMemo, and the probe moves to another scene when its scene disconnects so the hinge data keeps flowing. I also made iOS cancel its sensors when the module is invalidated and added two example screens.

Test plan

Jest sensor tests and the tstyche tests for useAnimatedSensor pass. On the iOS 27.1 iPhone Duo simulator and on an Android emulator with a virtual hinge, isAvailable is true on the first render and the angle and status follow the hinge, also after a JS reload on iOS.

Changelog

  • I added a changelog fragment with yarn changelog:add for each changed package, or this PR does not change react-native-reanimated or react-native-worklets.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: d31592a1-8282-41d1-b8ea-912269ed9d43

📥 Commits

Reviewing files that changed from the base of the PR and between 63c6c5a and e750495.

📒 Files selected for processing (5)
  • packages/react-native-reanimated/__tests__/sensorsAvailability.test.ts
  • packages/react-native-reanimated/__typetests__/miscTest.tst.ts
  • packages/react-native-reanimated/changelog/animated-sensor-hinge.feature.md
  • packages/react-native-reanimated/src/Sensor.ts
  • packages/react-native-reanimated/src/hook/useAnimatedSensor.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The change adds hinge sensor support to the Reanimated API, including angle and status values, availability tracking, and Android and Apple platform handling. Web registration returns an unsupported result for hinge sensors. The common app adds book and horse examples that use hinge data, and the tests cover hinge values, availability behavior, mocks, and types.

Priority: ➖ Normal

Change: Feature

Merge Risk: 🟡 Moderate · up to e7504

Hinge sensing may remain unavailable after a temporary startup window failure, and components may show stale sensor availability after registration changes. Resolve these behaviors before merging unless their impact is explicitly accepted.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a hinge sensor type to useAnimatedSensor.
Description check ✅ Passed The description directly explains the hinge sensor implementation, platform support, API behavior, examples, tests, and changelog updates.

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.

@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from c0870b9 to 1acbe5c Compare September 22, 2026 09:17

@coderabbitai coderabbitai 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.

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 23ba4350-4f80-4e82-9ddc-7b52fbf20ad0

📥 Commits

Reviewing files that changed from the base of the PR and between 96b7e25 and 1acbe5c.

📒 Files selected for processing (26)
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeExample.tsx
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/HingeCodeExample.tsx
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/RunningHorse.tsx
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/colors.ts
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/highlightCode.ts
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/horseFrames.ts
  • apps/common-app/src/apps/reanimated/examples/AnimatedHingeHorseExample/index.tsx
  • apps/common-app/src/apps/reanimated/examples/index.ts
  • packages/react-native-reanimated/CHANGELOG.md
  • packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.cpp
  • packages/react-native-reanimated/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h
  • packages/react-native-reanimated/__tests__/sensors.test.ts
  • packages/react-native-reanimated/__tests__/sensorsAvailability.test.ts
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorListener.kt
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorType.kt
  • packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.h
  • packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.m
  • packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensorType.h
  • packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts
  • packages/react-native-reanimated/src/Sensor.ts
  • packages/react-native-reanimated/src/SensorContainer.ts
  • packages/react-native-reanimated/src/commonTypes.ts
  • packages/react-native-reanimated/src/core.ts
  • packages/react-native-reanimated/src/hook/useAnimatedSensor.ts
  • packages/react-native-reanimated/src/index.ts
  • packages/react-native-reanimated/src/mock.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment thread packages/react-native-reanimated/__tests__/sensorsAvailability.test.ts Outdated
Comment thread packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.m Outdated
Comment on lines +202 to +204
if (hinge == nil) {
[strongSelf reportHingeUnavailable];
return;

@coderabbitai coderabbitai Bot Sep 22, 2026 •

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.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Do not convert transient hierarchy loss into permanent sensor unavailability.

Apple reports a nil hinge when the interaction leaves a hierarchy that supplies hinge updates. A missing key window is also a transient UI state. Both paths emit REANIMATED_HINGE_STATUS_UNAVAILABLE, which causes Sensor.markUnavailable() to unregister the sensor and permanently reject later subscriptions for this sensor key. Keep the interaction recoverable when the hierarchy or key window returns, or add reversible availability state. (developer.apple.com)

Also applies to: 214-216

Source: MCP tools

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i believe that is addressed now?

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.

@pawicao, this addresses the transient hinge == nil case. Later nil updates no longer mark the sensor unavailable.

The missing-key-window case remains. After REANIMATED_HINGE_ATTACH_ATTEMPTS retries, attachHingeInteractionWithAttemptsLeft: calls reportHingeUnavailable. This still permanently marks the sensor unavailable if the key window becomes available after the retry limit.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

check it again, close this thread if it is completed

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
git rev-parse --short HEAD
ast-grep outline packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.m --match 'attachHingeInteractionWithAttemptsLeft|initializeHinge|reportHingeUnavailable'
ast-grep outline packages/react-native-reanimated/src/Sensor.ts --match 'markUnavailable|register'
ast-grep outline packages/react-native-reanimated/src/hook/useAnimatedSensor.ts --match 'useAnimatedSensor'
rg -n -C 6 'REANIMATED_HINGE_ATTACH_ATTEMPTS|attachHingeInteractionWithAttemptsLeft|reportHingeUnavailable|handleHingeUpdate|markSensorUnavailable|markUnavailable\(' packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.m packages/react-native-reanimated/src/Sensor.ts packages/react-native-reanimated/src/SensorContainer.ts packages/react-native-reanimated/src/hook/useAnimatedSensor.ts

Length of output: 16159


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,112p' packages/react-native-reanimated/src/Sensor.ts
sed -n '145,213p' packages/react-native-reanimated/src/hook/useAnimatedSensor.ts
sed -n '32,95p' packages/react-native-reanimated/src/SensorContainer.ts

Length of output: 6362


@pawicao, the additional check confirms the finding.

Sensor.markUnavailable() sets sensorId to -1. SensorContainer.registerSensor() then rejects future registrations because sensor.isAvailable() returns false. Therefore, when the key window appears after the retry limit, the hinge sensor cannot recover.

The thread must remain open.

You are interacting with an AI system.

Comment thread packages/react-native-reanimated/src/hook/useAnimatedSensor.ts Outdated
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from 1acbe5c to 9f4df20 Compare September 22, 2026 11:11
@pawicao
pawicao added this pull request to stack #10660 September 22, 2026 11:36
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from 9f4df20 to adce1f0 Compare September 22, 2026 11:59
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from adce1f0 to ff1951c Compare September 22, 2026 13:09

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 599501b8-be5a-406d-b840-c488f5f130d2

📥 Commits

Reviewing files that changed from the base of the PR and between adce1f0 and 4002d29.

📒 Files selected for processing (4)
  • packages/react-native-reanimated/__tests__/sensors.test.ts
  • packages/react-native-reanimated/__tests__/sensorsAvailability.test.ts
  • packages/react-native-reanimated/apple/reanimated/apple/sensor/ReanimatedSensor.m
  • packages/react-native-reanimated/src/hook/useAnimatedSensor.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Comment thread packages/react-native-reanimated/src/hook/useAnimatedSensor.ts Outdated
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch 2 times, most recently from 464070c to ca444a6 Compare September 22, 2026 13:46
Base automatically changed from @pawicao/scene-delegate-example to main September 22, 2026 13:47
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch 2 times, most recently from 2f04caf to 63c6c5a Compare September 22, 2026 15:30
@pawicao

pawicao commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from 63c6c5a to 840d745 Compare September 23, 2026 09:47
@pawicao

pawicao commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from e750495 to 03e837a Compare September 23, 2026 10:33
@pawicao
pawicao removed this pull request from stack #10660 September 23, 2026 10:34
@pawicao
pawicao changed the base branch from main to @pawicao/sensor-availability-rerender September 23, 2026 10:34
@pawicao
pawicao added this pull request to stack #10674 September 23, 2026 10:34
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from 03e837a to 504c6e4 Compare September 23, 2026 10:36
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch 3 times, most recently from 44493f5 to 9f44ff2 Compare September 24, 2026 12:23
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from 9f44ff2 to d5760ec Compare September 24, 2026 13:10
SensorType.HINGE reports the hinge angle in radians and a HingeStatus, and takes no
config. Android reads Sensor.TYPE_HINGE_ANGLE and derives the status from the angle.
iOS reads UIHingeInteraction, which reveals a hinge only through its updates, so
ReanimatedHingeProbe attaches one to a hidden window when the app's first scene
connects. The answer arrives a few milliseconds later, before JS renders, so
isAvailable is correct on the first render like for every other sensor. A nil hinge
update is dropped. Web has no hinge sensor.
@pawicao
pawicao force-pushed the @pawicao/animated-sensor-hinge branch from d5760ec to 06aef74 Compare September 24, 2026 14:16

This branch has not been deployed

No deployments
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