Repository navigation
Conversation
The visibility gate starts every non-overlay screen blocked, so its animated style first parks the screen off-screen (translateY = height * 2 + 1) and a reaction later flips it to visible on the UI thread. The first route of a stack never runs an open transition (use-open-transition-intent skips it unless experimental_animateOnInitialMount is set), so that single style update is the only thing that ever makes it visible. When it is lost, the screen stays off-screen while the gate state says "visible". Start such a screen unblocked. Pushed screens keep starting blocked, since their open is requested in a layout effect after the first render. Co-Authored-By: Claude Opus 5.5 <[email protected]>
✅ Deploy Preview for rnst-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
useMaybeBlockVisibilitystarts every non-overlay screen blocked (useSharedValue(!isFloatingOverlay)), so its animated style first parks the screen off-screen (translateY = getVisibilityBlockOffset(height)=height * 2 + 1) and the gate reaction later flips it to visible on the UI thread.The first route of a stack never runs an open transition —
useOpenTransitionIntentskips it whenisFirstKey && !experimental_animateOnInitialMount. For that screen,progressstays at 0 and the gate never "opens"; the screen is visible only because the reaction computesshouldBlock: falseand the style mapper appliestranslateY: 0. That one UI-thread update is the only thing that ever makes it visible.In a production app (Expo SDK 57, RN 0.86, Reanimated 4.5, expo-router integration) that update was sometimes lost: after a second logout → signup → onboarding in the same JS session, the root BlankStack scene stayed parked at
translateY = 2H + 1and the app showed a blank screen, even though:shouldBlock: false.Re-running the style mapper from the debugger (toggling the scene's
entering1 → 0) made the screen appear instantly, which confirms the computed state was correct and only the applied style was stale.The same initial value is still present in
4.1.0-rc.0(providers/motion/hooks/use-maybe-block-visibility.tsx).Change
resolveInitialVisibilityBlocked({ isFloatingOverlay, isFirstKey, animateOnInitialMount })next toresolveScreenVisibilityGate. It returnsfalsefor floating overlays (unchanged) and for a first-key screen that does not animate on initial mount;trueotherwise.useMaybeBlockVisibilityseedslocalVisibilityBlocked/effectiveVisibilityBlockedwith it, usingisFirstKeyandoptions.experimental_animateOnInitialMountfrom the descriptors store, the same conditionuseOpenTransitionIntentuses.Pushed screens keep starting blocked (their open is requested in a layout effect after the first render, so an unblocked start would flash them). The initial-destination style gate is unaffected: it only applies to screens with a
destinationPairKey, which a first-key screen does not have.Test plan
resolveInitialVisibilityBlockedcases invisibility-gate.test.ts: first screen starts visible, first screen withanimateOnInitialMountstarts blocked, pushed screens start blocked, floating overlays never block.bun test: 480 pass, 0 failbun run lint: cleanbun run typecheck: cleanRelated: #159 (same app, separate BlankStack fix).
🤖 Generated with Claude Code