Skip to content

Commit 99d6c02

Browse files
MelvinBottruph01
andcommitted
Merge remote-tracking branch 'origin/main' into claude-notFoundPageGoBackToHome
Co-authored-by: truph01 <truph01@users.noreply.github.com>
2 parents 457e18a + 24b9fff commit 99d6c02

313 files changed

Lines changed: 7881 additions & 3429 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/commands/review-code-pr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*)
2+
allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*),Bash(check-compiler.sh:*)
33
description: Review a code contribution pull request
44
---
55

.claude/scripts/check-compiler.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
# Secure proxy script to run React Compiler compliance check on a single file.
4+
# Validates the filepath before passing it to the underlying npm script.
5+
set -eu
6+
7+
if [[ $# -lt 1 ]]; then
8+
echo "Usage: $0 <filepath>" >&2
9+
exit 1
10+
fi
11+
12+
readonly FILEPATH="$1"
13+
14+
# Strict filepath validation - reject shell metacharacters
15+
if ! [[ "$FILEPATH" =~ ^[a-zA-Z0-9_./@-]+$ ]]; then
16+
echo "Error: Invalid filepath (contains disallowed characters)" >&2
17+
exit 1
18+
fi
19+
20+
npm run react-compiler-compliance-check -- check "$FILEPATH"

.claude/skills/coding-standards/rules/clean-react-0-compiler.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ function Avatar({source, size}: AvatarProps) {
9898
Before flagging, verify that the file actually compiles with React Compiler:
9999

100100
```bash
101-
npx react-compiler-healthcheck --src "<filepath>" --verbose
101+
check-compiler.sh <filepath>
102102
```
103103

104104
If the output contains **"Failed to compile"** for the file under review, the rule **does not apply** — the author may have no alternative to manual memoization until the compilation issue is resolved.

.github/workflows/claude-review.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
prompt: "/review-code-pr REPO: ${{ github.repository }} PR_NUMBER: ${{ github.event.pull_request.number }}"
7575
claude_args: |
7676
--model claude-opus-4-6
77-
--allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*)" --json-schema '${{ steps.schema.outputs.json }}'
77+
--allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(check-compiler.sh:*)" --json-schema '${{ steps.schema.outputs.json }}'
7878
7979
- name: Post code review results
8080
if: steps.code-review.outcome == 'success' && steps.filter.outputs.code == 'true'

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009033803
115-
versionName "9.3.38-3"
114+
versionCode 1009033903
115+
versionName "9.3.39-3"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"

assets/images/car-plus.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/images/document-plus.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/images/envelope-open-star.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# InteractionManager Migration
2+
3+
## Why
4+
5+
`InteractionManager` is being removed from React Native. We currently maintain a patch to keep it working, but that's a temporary measure and upstream libraries will also drop support over time.
6+
7+
Rather than keep patching, we're replacing `InteractionManager.runAfterInteractions` with purpose-built alternatives that are more precise.
8+
9+
## Current state
10+
11+
`runAfterInteractions` is used across the codebase for a wide range of reasons: waiting for navigation transitions, deferring work after modals close, managing input focus, delaying scroll operations, and many other cases that are hard to classify.
12+
13+
## The problem
14+
15+
`runAfterInteractions` is a global queue with no granularity. This made it a convenient catch-all, but the intent behind each call is often unclear. Many usages exist simply because it "just worked" as a timing workaround, not because it was the right tool for the job.
16+
17+
This makes the migration non-trivial: you have to understand *what each call is actually waiting for* before you can pick the right replacement.
18+
19+
## The approach
20+
21+
**TransitionTracker** is the backbone. It tracks navigation transitions explicitly, so other APIs can hook into transition lifecycle without relying on a global queue.
22+
23+
On top of TransitionTracker, existing APIs gain transition-aware callbacks:
24+
25+
- Navigation methods accept `afterTransition` — a callback that runs after the triggered navigation transition completes
26+
- Navigation methods accept `waitForTransition` — the call waits for all ongoing transitions to finish before navigating
27+
- Keyboard methods accept `afterTransition` — a callback that runs after the keyboard transition completes
28+
- `useConfirmModal` hook's `showConfirmModal` returns a Promise that resolves **after the modal close transition completes**, so any work awaited after it naturally runs post-transition — no explicit `afterTransition` callback needed
29+
30+
This makes the code self-descriptive: instead of a generic `runAfterInteractions`, each call site says exactly what it's waiting for and why.
31+
32+
> **Note:** `TransitionTracker.runAfterTransitions` is an internal primitive. Application code should use the higher-level APIs (`Navigation`, `useConfirmModal`, etc.) rather than importing TransitionTracker directly.
33+
34+
## How
35+
The migration is split into 9 issues. Current status of the migration can be found in the parent Github issue [here](https://github.com/Expensify/App/issues/71913).
36+
37+
## Primitives comparison
38+
39+
For reference, here's how the available timing primitives compare:
40+
41+
### `requestAnimationFrame` (rAF)
42+
43+
- Fires **before the next paint** (~16ms at 60fps)
44+
- Guaranteed to run every frame if the thread isn't blocked
45+
- Use for: UI updates that need to happen on the next frame (scroll, layout measurement, enabling a button after a state flush)
46+
47+
### `requestIdleCallback`
48+
49+
- Fires when the runtime has **idle time** — no pending frames, no urgent work
50+
- May be delayed indefinitely if the main thread stays busy
51+
- Accepts a `timeout` option to force execution after a deadline
52+
- Use for: Non-urgent background work (Pusher subscriptions, search API calls, contact imports)
53+
54+
### `InteractionManager.runAfterInteractions` (legacy — do not use)
55+
56+
- React Native-specific. Fires after all **ongoing interactions** (animations, touches) complete
57+
- Tracks interactions via `createInteractionHandle()` — anything that calls `handle.done()` unblocks the queue
58+
- In practice, this means "run after the current navigation transition finishes"
59+
- Problem: it's a global queue with no granularity — you can't say "after _this specific_ transition"
60+
61+
### Summary
62+
63+
| | Timing | Granularity | Platform |
64+
| ---------------------- | ------------------------- | ------------------------- | --------------------- |
65+
| `rAF` | Next frame (~16ms) | None — just "next paint" | Web + RN |
66+
| `requestIdleCallback` | When idle (unpredictable) | None — "whenever free" | Web + RN (polyfilled) |
67+
| `runAfterInteractions` | After animations finish | Global — all interactions | RN only |

0 commit comments

Comments
 (0)