diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt index 46a74516..3ceea516 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/ui/NowPlayingScreen.kt @@ -189,16 +189,29 @@ private fun rememberDragDismissConnection( object : NestedScrollConnection { private var accumulated = 0f + // One-shot latch. popBackStack is async — between the first + // dismissal and the screen actually leaving the composition, + // the user's finger is still down and more onPostScroll + // frames arrive. Without this guard the accumulator rebuilds + // and onDismiss() fires a second time, popping the screen + // BENEATH NowPlaying. If that leaves the back stack empty + // the NavHost renders nothing → black screen on resume. + private var dismissed = false + override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource, ): Offset { + // After dismissal, eat all remaining drag so the + // scrollable doesn't paint over-scroll deltas during the + // pop transition. + if (dismissed) return available if (source != NestedScrollSource.UserInput) return Offset.Zero return if (available.y > 0f) { accumulated += available.y if (accumulated >= thresholdPx) { - accumulated = 0f + dismissed = true onDismiss() } Offset(0f, available.y) @@ -209,6 +222,7 @@ private fun rememberDragDismissConnection( } override suspend fun onPreFling(available: Velocity): Velocity { + if (dismissed) return available accumulated = 0f return Velocity.Zero }