fix(directory-picker): address review — modal layering, root nav, stale state
- HIGH: the "Browse Folders..." entry in the New Session RN <Modal> expanded
a sibling BottomSheet, which a native Modal always covers (a
BottomSheetModal through the root portal would be covered too), so the
primary entry point was invisible/untouchable. The modal is now closed
before the sheet expands and restored on cancel via a new onDismiss
callback (restoreNewSessionOnDismiss ref); picking a folder proceeds to
session creation without reopening the modal.
- MEDIUM: parentOf("/") returned "/" so Up at the POSIX root looped forever;
it now returns null at "/", "\" and Windows drive roots alike, disabling
the Up button there.
- LOW: opening the sheet with no known start directory (server home not
loaded yet) showed the previous open's stale entries; it now clears state,
invalidates in-flight loads, and shows an "Enter a path above to start
browsing" empty state. Sheet init also no longer re-runs on snap-point
drags (wasOpen guard).
- Extracted the pure path helpers (stripTrailingSlash/parentOf/nameOf) into
src/lib/path-utils.ts (no RN imports) with node --test coverage for POSIX
root, Windows drive roots, trailing slashes, and backslash paths.
typecheck clean; 97/97 tests pass (16 new).
This commit is contained in:
@@ -275,17 +275,28 @@ export default function SessionsScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
// The browser sheet is a sibling of the New Session <Modal>. A native RN
|
||||
// Modal layers above everything in the React root (including bottom-sheet
|
||||
// portals), so the modal must be closed before the sheet is shown; this ref
|
||||
// remembers to bring it back if the user cancels without picking a folder.
|
||||
const restoreNewSessionOnDismiss = useRef(false)
|
||||
|
||||
const openBrowser = useCallback(
|
||||
(startDir: string | null, mode: "create" | "switch") => {
|
||||
setBrowseStartDir(startDir || serverHome || null)
|
||||
setBrowseMode(mode)
|
||||
if (mode === "create" && showNewSession) {
|
||||
restoreNewSessionOnDismiss.current = true
|
||||
setShowNewSession(false)
|
||||
}
|
||||
browserSheetRef.current?.expand()
|
||||
},
|
||||
[serverHome],
|
||||
[serverHome, showNewSession],
|
||||
)
|
||||
|
||||
const onBrowserSelect = useCallback(
|
||||
(directory: string) => {
|
||||
restoreNewSessionOnDismiss.current = false
|
||||
if (browseMode === "switch") {
|
||||
handleSwitchDirectory(directory)
|
||||
dirSheetRef.current?.close()
|
||||
@@ -296,6 +307,13 @@ export default function SessionsScreen() {
|
||||
[browseMode, handleSwitchDirectory, onCreateInDirectory],
|
||||
)
|
||||
|
||||
const onBrowserDismiss = useCallback(() => {
|
||||
if (restoreNewSessionOnDismiss.current) {
|
||||
restoreNewSessionOnDismiss.current = false
|
||||
setShowNewSession(true)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onFabPress = () => {
|
||||
// Quick create in current project
|
||||
onCreateSession()
|
||||
@@ -666,6 +684,7 @@ export default function SessionsScreen() {
|
||||
clientForDirectory={clientForDirectory}
|
||||
isDark={isDark}
|
||||
onSelect={onBrowserSelect}
|
||||
onDismiss={onBrowserDismiss}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user