Repository navigation
chore(mobile): bump versions for native release 1.5.188 - #14654
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Dependency limit exceeded — report not shown. This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report. Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard. Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account. |
…14647) Prepares react-native-track-player 4.1.2 (Apache-2.0) for the new architecture. It ships with 1.5.188 on the old architecture, where it changes nothing. **Base: `chore/mobile-rn-0.81` (#14642).** Rebased 2026-10-08 after #14642 moved onto the 1.5.188 release branch (#14654). Merge #14652 into this branch first, then this into #14642. Don't merge to main on its own. We are staying on RNTP 4.1.2. v5 (`@rntp/player`) is commercially licensed. 4.1.2 is the last 4.x release, and the fixes below were never published for it. ## Changes (Android only, in `patches/react-native-track-player+4.1.2.patch`) **1. Event emission in bridgeless mode** (doublesymmetry/react-native-track-player#2593, #2619) - `MusicService.emit()` / `emitList()` read the context from `reactNativeHost.reactInstanceManager.currentReactContext`. That is null in bridgeless mode, so every native-to-JS event was dropped: playback state, active track, remote/notification controls, progress and errors. - They now use the `reactContext` getter that `HeadlessJsTaskService` already provides. It returns `ReactInstanceManager.currentReactContext` on the old architecture (the same call as before) and `ReactHost.currentReactContext` in bridgeless mode. - That getter throws if `ReactHost` is null. Emission, `startTask` in `onStartCommand`, and `super.onDestroy()` now log and carry on instead of crashing the service. This is the same approach as upstream's fix for #2619 (ed52dc5, v5 line). **2. `@ReactMethod`s return `Unit`** - Every `TrackPlayerModule` method was written as `fun play(callback: Promise) = scope.launch { ... }`, so each one returned a `Job`. - The bridgeless TurboModule interop layer rejects a non-void return on an async method, so it threw while loading the module: > Unable to parse @ReactMethod annotations from native module: TrackPlayerModule On the new architecture the app aborted at startup (found in the spike, #14648). - They are now `fun play(callback: Promise) { scope.launch { ... } }`. The old bridge ignored the return value, so nothing changes there. The diff touches only the first and last line of each of the 37 methods. **Not applicable to 4.1.2:** - #2670 (`BackgroundServiceStartNotAllowedException` while emitting in the background) and #2662 (Android Auto cold start never starting the headless task) are v5 issues. In v5, emitting an event starts a `TrackPlayerTaskService`. In 4.1.2, `emit` never starts a service, and `onStartCommand` already calls `startTask`, which creates the React host when there is none. That cold path was checked on the new architecture in the spike. - iOS needs no change. The Swift `RCTEventEmitter` module works through the interop layer as it is. ## Verification (old architecture, `prodRelease` arm64 signed with the debug keystore, Android 16 emulator) I tested with a temporary JS harness that was not committed. It wraps the root component, logs every RNTP event with `console.warn` (visible in logcat) and in an on-screen overlay, queues 3 public tracks, seeks, and then seeks near the end. Signed out, `pm clear` before each launch, and logcat confirmed `Loading JS bundle from "assets://index.android.bundle"`. | Check | Result | |---|---| | Release build | ✅ | | Runtime arch | ✅ `bridgeless:false, fabric:false`, "Legacy Architecture" warning | | `PlaybackState` / `PlaybackActiveTrackChanged` reach JS | ✅ stopped → loading → buffering → ready → playing, `index:0` | | Seek | ✅ `seekTo(60)` → position 60–62.8 | | Auto-advance | ✅ `active-track-changed` 0 → 1 at the end of track 0, `getActiveTrackIndex()` = 1 | | `adb shell cmd media_session dispatch pause/play/next` | ✅ `remote-pause` / `remote-play` / `remote-next` reach JS, and the state follows | | Notification shade pause / play / previous | ✅ `remote-pause`, `remote-play`, `remote-previous` reach JS | | Screen off and backgrounded for 75 s | ✅ progress events kept arriving, MediaSession `PLAYING` | | iOS Release (old arch, 26.5 sim) | ✅ unchanged: events, seek and auto-advance all work | The same harness on the new architecture is in the spike PR. ## Still needs a real device Lock-screen and notification controls, Bluetooth, and background playback for more than 2 minutes, together with the rest of the 1.5.188 checklist in #14642. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ver (#14651) Moves the play bar tracker, the now playing scrubber and the track-list eq bars off JS-driven `Animated` and onto the native driver. JS-only, so it can ship as an OTA. ## Why All three used `useNativeDriver: false`, so every frame ran in JS and committed through `setNativeProps`. On old arch that's cheap. On the new architecture each one is a full `ShadowTree::commit`, and Reanimated 3's commit hook clones the tree on every commit. It was half of the CPU regression in #14648 (blocker 6): playing with the drawer open went from ~15% to ~50%. ## What changed - `animateLinear` in `utils/animation.ts` runs a long linear animation as 10 s native-driver segments. The native driver precomputes one frame per 16 ms, which is why the old code avoided it for track-length animations (the old comment about Hermes). Each segment starts from the wall-clock position, so the bar can't drift after the app is backgrounded. - `TrackingBar` and `Slider` use it with the start position passed in explicitly (from `seek` or `TrackPlayer.getProgress()`), instead of continuing from whatever the JS value was. Seeking, dragging and pausing behave the same. The scrubber's 100 ms tap-to-seek timing moved to the native driver too, because a value can't mix drivers. Both stop the chain on unmount. - `AnimatedEqBars` animated `height`, which the native driver can't do. Each bar is now a full-height bar slid down with `translateY` inside a clip view with the same 2 px radius. The visible shape at every height matches the old one (rounded top from the bar, rounded bottom from the clip). ## Base **Base: `chore/mobile-rn-0.81` (#14642), shipping in native release 1.5.188 (#14654).** Rebased 2026-10-08 after #14642 moved onto the release branch. Merge this into #14642, not main. The svg `LinearGradient` it imports is on main since 1.5.187, so it no longer depends on #14642's code, but it ships with 1.5.188 so the new native-driver animations get device-tested on the RC builds. It doesn't overlap the iOS queue fix (#14649, on main): that change is in `AudioPlayer.tsx` and `addTracksAroundCurrent.ts`, which this PR doesn't touch. ## Measurements (iOS 26.5 simulator, Release, signed in, 30 s `top` averages) | Scenario | Old arch before → after | New arch before → after | |---|---|---| | Feed, playing | 17.1% → 12.9% | 50.4% → 15.3% | | Now playing drawer open, playing | 15.3% → 13.7% | 50.6% → 15.6% | | Background, playing | 9.5% → 12.2% | 12.2% → 14.5% | New-arch "after" also includes #14648's svg and Lottie fixes, which don't affect these screens. Old-arch "after" is the #14642 Release app with this branch's JS bundle swapped in. ## Testing - Simulator, both architectures: the bar and the scrubber advance at the right rate on a 56-minute and a 3-minute track. Tap-to-seek to the middle lands at 28:02 and keeps going. The play bar is at the right position after 30 s in the background. - `tsc` and `eslint` clean on the changed files. - Not checked by eye: the eq bars. In album track lists, the `TrackImage` children (eq bars, play icon overlay) don't show on either architecture, before or after this change. That looks like an existing bug and is out of scope here. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Phase 1 of the React Native upgrade: 0.79.5 → 0.81.6 with the old architecture still on. **Base: `chore/mobile-native-release-1.5.188` (#14654).** Rebased onto it after 1.5.187 (#14645, which squashed #14627, #14640 and #14650) merged to main; the two lib-swap commits are gone from this branch. Merge #14647 and #14651 into this branch first, then this into #14654, then #14654 into main as one push (see #14654 for the full order). ## Rebase onto 1.5.187 (2026-10-08) - `patches/react-native+0.79.5.patch` (the ExceptionsManager Hermes fix from #14643) is renamed to `react-native+0.81.6.patch`. The anchors are unchanged in 0.81.6, and `scripts/patch-package.sh` applies it with `--error-on-fail` during `npm install` (checked: `getErrorStackSafe` is in the installed `ExceptionsManager.js`). - notifee and Firebase from #14640 are kept as they are: `@notifee/react-native` 9.1.8 is the latest release and `@react-native-firebase/app`/`messaging` 24.1.1 build on 0.81.6 on the old arch (both declare `react-native: *`). No bump needed. - The Firebase Android BoM stays pinned to 33.16.0. This branch moves Kotlin to 2.1.20, and BoM 34 needs 2.2, so the pin still applies; the comment now says so. - The UIScene and notifee lines in `AppDelegate.mm` (#14626, #14640) are untouched by this branch. - `package-lock.json` and `Podfile.lock` were regenerated (`npm install`, then `RCT_NEW_ARCH_ENABLED=0 bundle exec pod install`); the release xcconfig has no `RCT_NEW_ARCH_ENABLED=1`. The SwiftAudioEx post_install patch (#14650) still applies. **Needs a native release (1.5.188).** Don't OTA this JS onto older binaries. Old architecture stays on: Android `newArchEnabled=false`, iOS `RCTNewArchEnabled=false`, pods installed with `RCT_NEW_ARCH_ENABLED=0`. Two commits, one per step. Each step builds on iOS and Android: 1. 0.79.5 → 0.80.3 2. 0.80.3 → 0.81.6 (0.81.6 is the latest 0.81 patch on npm) ## Version bumps | Package | From | To | Why | |---|---|---|---| | react-native | 0.79.5 | 0.81.6 | the upgrade | | `@react-native/*` (babel-preset, eslint-config, metro-config, metro-babel-transformer, typescript-config) | 0.79.5 | 0.81.6 | must match RN | | `@react-native-community/cli`, `cli-platform-android`, `cli-platform-ios` | 18.0.0 | 20.1.3 | CLI line for 0.81; the platform packages were left at 18 on the old ladder branch | | react, react-dom, react-test-renderer (whole monorepo, root `overrides` too) | 19.0.0 | **19.1.4** | RN's bundled renderer throws at startup unless `react` is **exactly** its version: 19.1.0 for 0.80.3, 19.1.4 for 0.81.6. The old ladder branch used 19.1.8, which would throw "Incompatible React versions" on launch. | | @types/react / @types/react-dom | 19.0.0 | 19.1.17 / 19.1.11 | match React 19.1 | | react-native-gesture-handler | 2.25.0 | 2.28.0 | 2.28 is the first 2.x with official 0.81 support (2.25's table stops at 0.79). Stays on 2.x; v3 drops the old architecture. | | @amplitude/analytics-react-native | 1.4.11 | 1.4.14 | Kotlin 2.1 (RN 0.80+) turns the deprecated `toUpperCase(Locale)` in 1.4.11 into a compile error | | tiktok-opensdk-react-native | ^0.10.7 | 0.10.7 (pinned) | it now carries a patch. 0.10.9 fixes the Android signature, but drops the `handleOpenURL`/`handleUserActivity` declarations that SceneDelegate imports | Patches added (`patches/`): - `react-native-track-player+4.1.2.patch`: Kotlin 2.1 rejects `Arguments.fromBundle(Bundle?)`. Now resolves `null` when there is no item. 4.1.2 is the last 4.x and has no fixed release. - `tiktok-opensdk-react-native+0.10.7.patch`: `onNewIntent(intent: Intent)` (RN 0.80 made `ActivityEventListener` non-null) and `reactApplicationContext.currentActivity`. Checked against 0.81 on the old architecture and left alone: Reanimated 3.19.5 (the official table lists 3.19.x for 0.78–0.81 on Paper; Reanimated 4 is out of scope), track-player 4.1.2 (patched above), collapsible-tab-view 8.0.1 (JS only), screens 4.18.0 (0.81 support since 4.14; `react-native-screens+4.18.0.patch` still applies; 4.25+ drops the old arch), pager-view 6.7.1 (7+ drops the old arch), video 6.18.0, svg 15.15.0 (0.81 support since 15.12.1), google-cast 4.6.2 (5.x is new-arch only), notifications 5.1.0, code-push 12.3.2 (README lists 0.77–0.86; 13.x needs a new OTA history), bootsplash 6.3.11, safe-area-context 5.6.2, keyboard-controller 1.19.0, flash-list 1.8.3, datetimepicker 8.3.0 (builds against 0.81.6). ## Template changes (rn-diff-purge 0.79.5 → 0.81.6) - Android: Kotlin 2.0.21 → 2.1.20, Gradle 8.13 → 8.14.3, new `gradlew`/`gradlew.bat`/wrapper jar, `MainApplication` uses `loadReactNative(this)` in place of `SoLoader.init` plus `load()`, and `edgeToEdgeEnabled=false` is added as in the template. The app already draws edge-to-edge through react-native-bars and the SDK 36 target, so this flag changes nothing. - AGP comes from RN: 8.8 → 8.11.0, which supports compileSdk 36, so `android.suppressUnsupportedCompileSdk=36` is removed. - `settings.gradle` resolves `@react-native/gradle-plugin` through `require.resolve` from `react-native`, not a hard-coded hoisted path. With this lockfile npm nests it under `node_modules/react-native/node_modules`. - Kept: `newArchEnabled=false`, the `AudiusScrypt` module (`ScryptPackage` is still registered), the debug manifest (it adds `SYSTEM_ALERT_WINDOW`), and `android:enableOnBackInvokedCallback="false"`. - **Back handling:** since 0.80, `ReactActivity` registers an `OnBackPressedCallback` when targetSdk ≥ 36, which calls `onBackPressed()` → JS `BackHandler`. Our `invokeDefaultOnBackPressed` override (`moveTaskToBack`) still runs. The manifest opt-out is kept as asked and can probably go in a later release. - iOS: no template change between 0.79.5 and 0.81.6. `Info.plist` and `RichPushExtension/Info.plist` now set `RCTNewArchEnabled=false`, which RN 0.80+ reads **at runtime**; a missing key means new arch. `pod install` writes the key and re-sorts the plist each time, so the sorted version is committed. ## AppDelegate / UIScene No code change needed. `RCTAppDelegate` is marked deprecated in 0.81 in favour of `RCTReactNativeFactory`, so there is a `-Wdeprecated-declarations` warning, but every API we use is unchanged: `automaticallyLoadReactNativeWindow`, `rootViewFactory`, `createRootViewController`, `setRootView:toRootViewController:`, `customizeRootView:`, `bundleURL`, and `dependencyProvider`. `didFinishLaunching` still creates the factory and skips the window. Moving to `RCTReactNativeFactory` can wait for the 0.82+ phase. Verified on a Release build: cold launch, a deep link while killed, and a deep link while backgrounded, on iOS 26.5 and iOS 27. iOS 27 needs UIScene and showed no launch crash. ## Web / React 19.1 - Typecheck: web, common and harmony are clean, and so is mobile. - `vite build` (prod env): succeeds. - web vitest: 178 passed, 9 skipped. `TrackTile › Public Premium (non-owner)` timed out once while the machine was under heavy load, then passed 3 out of 3 when run alone. ## Verification matrix (before the rebase; see the bottom for the rebased stack) | | iOS 26.5 sim (Release) | iOS 27 sim (Release) | Android API 36 emu (prodRelease, arm64) | |---|---|---|---| | Build | ✅ Xcode 27, `generic/platform=iOS Simulator` | same binary | ✅ debug keystore | | Old arch at runtime | ✅ JS thread `com.facebook.react.JavaScript` | – | ✅ `ReactRootView` + "Legacy Architecture" warning | | Launch past splash | ✅ | ✅ | ✅ `assets://index.android.bundle` | | Sign-up / sign-in screens | (signed in) | ✅ | ✅ including Create Password | | Signed-in feed, scroll | ✅ | – | – | | Playback + now playing drawer (open, drag closed) | ✅ | – | – | | Background → foreground while playing | ✅ audio kept going (0:09 → 0:41) | – | – | | Search | ✅ | – | – | | Profile: collapsible header + tab swipe | ✅ | – | – | | Deep link, warm | ✅ `audius://audius` | ✅ link delivered | – | | Deep link, cold | ✅ `audius://deadmau5` | ✅ (signed out → sign-on) | – | | Hardware Back | – | – | ✅ pops Create Password; at root backgrounds the app without killing it | | Sign-on footer above nav bar | – | – | ✅ | | Red JS errors | none, apart from a recurring `JSON Parse error: Unexpected character: <` (not yet traced) | none | none | The CodePush folder was moved aside or cleared before every cold launch, so all results above are from the bundled JS. ## Still needs a real device - background audio with the screen locked for more than 2 minutes - lock-screen and notification controls - Chromecast - push notifications ## Notes - A Release build that downloads a production OTA built for 1.5.186 or 1.5.187 runs a 0.79 bundle on a 0.81 binary. 1.5.188 ships with its own package.json version (#14654) so it never receives those OTAs. - The Hermes `ExceptionsManager` fix now applies through patch-package (#14643), renamed for 0.81.6 above. ## Verification of the rebased stack (2026-10-08) Built from a local, unpushed integration branch: #14652's tip (which contains #14647) merged with #14651, on top of #14654. | Check | Result | |---|---| | `npx tsc --noEmit -p packages/mobile` | pass | | eslint on the touched files / `turbo run verify` lint | pass (1 existing warning in `HostRemixContestDrawer.tsx`) | | `cd packages/mobile && npm test` | 9 suites, 34 tests pass | | iOS Release, `generic/platform=iOS Simulator`, arm64, `ENVFILE=.env.prod` | builds; Info.plist 1.1.201, `RCTNewArchEnabled=false`; bundle carries 1.5.188 | | Android `assembleProdRelease`, arm64-v8a, debug keystore | builds; versionName 1.1.537 | | iOS 26.5 sim, installed over the signed-in app, CodePush moved aside | launch to feed; JS thread `com.facebook.react.JavaScript` (old arch) | | Playback from the 2nd feed track | plays; play bar tracker moves | | Auto-advance | seek to 2:43/2:45 on track 2, advanced to track 3 | | Now playing drawer | opens, scrubber advances, tap-to-seek works | | Profile tabs | swipe Tracks → Albums, tap Reposts | | notifee/RNFB APNs token | a temporary console log (not committed, rebuilt without it afterwards) printed an 80-byte lowercase APNs token at startup | | Android 16 emulator, `pm clear` | `Loading JS bundle from "assets://index.android.bundle"`, "Legacy Architecture" warning, sign-up and sign-in screens render | | Android hardware Back | **not verified**: the emulator's system_server was killed by its watchdog three times under host load, so Back never got a clean run | | JS errors on iOS | only `Could not cache profile images` (content node timeout) | 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Version bump for native release 1.5.188. Merging it starts the RC and production native builds.
packages/mobile/package.json: 1.5.187 → 1.5.188 (and the matchingpackage-lock.jsonentry)CFBundleShortVersionString: 1.1.200 → 1.1.201versionName: 1.1.536 → 1.1.5371.5.188 contains (all still on the old architecture):
Unitmodule methods (no change on old arch)shouldBeRecycled NOpatch (no change on old arch)1.5.189 is then only the new-architecture flag flip.
Stack
Verification of the rebased stack (2026-10-08)
Built from a local, unpushed integration branch: #14652's tip (which contains #14647) merged with #14651, on top of #14654.
npx tsc --noEmit -p packages/mobileturbo run verifylintHostRemixContestDrawer.tsx)cd packages/mobile && npm testgeneric/platform=iOS Simulator, arm64,ENVFILE=.env.prodRCTNewArchEnabled=false; bundle carries 1.5.188assembleProdRelease, arm64-v8a, debug keystorecom.facebook.react.JavaScript(old arch)pm clearLoading JS bundle from "assets://index.android.bundle", "Legacy Architecture" warning, sign-up and sign-in screens renderCould not cache profile images(content node timeout)Merge order
production/1.5.187. Do not dispatch-f binary_version=1.5.186or1.5.185from main any more: main now carries fix(mobile): replace fs and gradient native libs #14627, which callsTurboModuleRegistry.getEnforcing('ReactNativeFs')at import, so that JS crashes 1.5.186 and older binaries. If 1.5.186 users still need a fix, dispatch from a commit before 5c4ee7e.1.5.188histories.com.facebook.react.JavaScript; Android "Legacy Architecture" warning)🤖 Generated with Claude Code