Repository navigation
fix: smooth swipe back from activity details - #1853
Conversation
Navigation 2.10 rewrote NavHost predictive back. A swipe back started soon after a forward navigation seeks with the forward transitions (the screen slides left and dims while the previous one comes in from the right), holds, then snaps. A later swipe uses the new default scaleOut instead of the destination's pop transitions. Pin 2.9.6, which 3.1.0 shipped, and keep Dependabot off 2.10. Closes #1852
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
[Medium impact] This PR appears safe to merge; no actionable regression was found. SummaryReturns Navigation Compose and its test library to 2.9.6 to restore smooth swipe-back transitions.
Reviews (1) · Last reviewed commit: "fix: pin navigation-compose to 2.9.6" · Reviewed by Greptile |
talosmachina
left a comment
There was a problem hiding this comment.
No findings. Pins navigation-compose (and navigation-testing) back to 2.9.6 to restore the pop transitions on predictive back, and adds a Dependabot ignore so the gradle group bump cannot bring 2.10 back. Reviewed c8b4f49, full tier (dependency manifest).
What I checked, and 3 candidates I ruled out
Read in full: gradle/libs.versions.toml, .github/dependabot.yml, the navigation deps in app/build.gradle.kts
Build: not run here. Auto reviews of bitkit-android do not build the branch, so this is static plus CI. At review time build-local (assembles the app against 2.9.6) was green; build-and-test, lint, compose-ui / ui-tests and the e2e jobs were still running.
Ruled out
- Something still resolving navigation 2.10 transitively, silently undoing the pin:
hilt-navigation-compose1.4.0 asks fornavigation-compose2.9.0 (its POM on Google Maven), so Gradle settles on 2.9.6; no other catalog entry (lottie, haze, coil, compose-charts, glance) depends on androidx.navigation. - Code written against 2.10-only API: no use of
predictivePopEnterTransition/predictivePopExitTransitionor other 2.10 symbols underapp/src, andbuild-localcompiles on 2.9.6. - Dependabot ignore not matching:
androidx.navigation:*withversions: [">= 2.10.0"]is the documented Maven range form and covers bothnavigation-composeandnavigation-testing, which sharenavCompose; patch bumps inside 2.9.x still flow.
Merge confidence: 4/5, a dependency manifest change whose behaviour no test covers (the transition evidence is the author's emulator recordings), with build-and-test and lint still pending at review time.
Reviewer model: claude-opus-5-5
Reasoning effort: Not exposed (the run's metadata available to this reviewer does not report it)
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
coreyphillips
left a comment
There was a problem hiding this comment.
Two independent reviews.
worth doing, does not block
- Pin to 2.9.6 skips 2.9.8's NavHost predictive-back crash fix (gradle/libs.versions.toml:14)
- The selected version restores a predictive-back crash (gradle/libs.versions.toml:14)
nits
- Changelog fragment covers only the early swipe and a regression no release had (changelog.d/next/1853.fixed.md:1)
the reviewers disagree, your call
- External intents regain access to the internal seed screen (gradle/libs.versions.toml:14)
2.9.8 is the newest 2.9.x and fixes a NavHost predictive-back race (b/500945998). The changelog fragment now covers both swipe timings.
Navigation 2.10 honours deepLinkIds only from the app itself; 2.9 honours them from any caller. Bitkit never sets them, so MainActivity removes them before NavHost reads the intent.
NavController.KEY_DEEP_LINK_IDS and KEY_DEEP_LINK_ARGS are restricted to androidx.navigation, so lint rejects them; the literals match their values.
coreyphillips
left a comment
There was a problem hiding this comment.
Rechecked after 3 new commits (d8be263, c47eba0, e2403ad). Nothing blocking remains.
addressed
- Pin to 2.9.6 skips 2.9.8's NavHost predictive-back crash fix (gradle/libs.versions.toml:14). Fixed:
gradle/libs.versions.toml:14is nownavCompose = "2.9.8". I unzipped the CI APK built from e2403ad, and its META-INF lists navigation-compose, navigation-runtime and navigation-common all at 2.9.8. In the 2.9.8 sources, NavHost.kt:512-541 still choosescreatePopEnterTransition/createPopExitTransitionwhileinPredictiveBackis set, which agrees with your device results for cases 1 to 3. - Changelog fragment covers only the early swipe and a regression no release had (changelog.d/next/1853.fixed.md:1). Fixed:
changelog.d/next/1853.fixed.mdnow says swiping back "slides it out like the Back button does". That covers both swipe timings, and with "again" gone it no longer implies 3.1.0 shipped the bug. - External intents regain access to the internal seed screen (gradle/libs.versions.toml:14). Fixed:
MainActivity.kt:117strips the extras inonCreatebefore any NavHost composes,:286strips them inonNewIntentbeforesuper/setIntent, and:296-299holds the strip helper. The literals matchKEY_DEEP_LINK_IDS/KEY_DEEP_LINK_ARGSin 2.9.8's NavController.android.kt:1158,1160. 2.9.8'shandleDeepLink(Intent)has no trust check and reads those keys only from the intent, andonGraphCreatedpasses itactivity.intent, which is the object that was stripped. Release builds declare nonavDeepLinks, so the unstrippeddeepLinkExtraskey cannot select a destination on its own. I did not rerun case 4 on a device. - The selected version restores a predictive-back crash (gradle/libs.versions.toml:14). Fixed: Same pin as point 1. In the 2.9.8 sources, NavHost.kt:521-529 now returns early when the back stack has fewer than two entries, and it binds
currentBackStackEntryas non-null fromcurrentBackStack.last(). That removes the path where the entry stayed null and was dereferenced later.
|
Auto-merge on: approved by @coreyphillips on e2403ad, all four review threads fixed and resolved. It merges once the two remaining e2e jobs pass. |
coreyphillips
left a comment
There was a problem hiding this comment.
Rechecked after replies, with no new commit since e2403ad. Nothing blocking remains.
Closes #1852
This PR pins navigation-compose to 2.9.8, the newest 2.9.x, so a swipe back from Activity details slides the screen out smoothly instead of stalling and snapping.
Description
scaleOut(0.7f), then snaps.NullPointerException.deepLinkIdsanddeepLinkArgsextras from launch intents inMainActivity. 2.10 honours them only from Bitkit itself; 2.9 honours them from any app, which could open an internal screen such as the recovery phrase. Bitkit never sets them.androidx.navigation:*from 2.10.0, so the monthly gradle group bump doesn't bring the bug back.Out of Scope
ContentView.kt: the NavHost-levelpredictivePopEnterTransition/predictivePopExitTransitionthat 2.10 adds. Setting them changed neither swipe on an emulator: the late swipe still shrank to 70% and snapped, and the early one kept the forward pair. They wait until a navigation release fixes predictive back.compileSdkstays at 37. 2.9.8 doesn't need it, but other libraries in chore: bump the gradle group across 1 directory with 41 updates #1787 do.Design
N/A — no UI changes.
Preview
Swipe back about 0.6 s after opening Activity details, then the Back key:
before-fast2x.mp4
after298-fast2x.mp4
Swipe back 2.5 s after opening Activity details, then the Back key:
before-slow2x.mp4
after298-slow2x.mp4
QA Notes
Setup
Journeys
N/A — not drivable; see Manual Tests.
Manual Tests
regression:Home → tap an activity → Back key → details slides out to the right — transition frames not in Capabilitiesadb shell), launchMainActivitywith the int-array extraandroid-support-nav:controller:deepLinkIds=0,-898289677→ Bitkit opens on Home, not Mnemonic PhraseAutomated Checks
./gradlew compileDevDebugUnitTestKotlin compileDevDebugAndroidTestKotlin— tests compile against navigation 2.9.8Evidence
Gaps
Models used
claude-opus-5-5(reasoning:medium)claude-opus-5-5(reasoning:medium)