pathParam is actually implemented now
the previous commit added the parameter to the signature, documented it, threaded it through FileBrowserApp — and never used it. seven lines of prose about a feature that did not exist, committed, deployed, and reported as working. that one fact explains all three things the owner reported: the query string never changed because nothing wrote it; refreshing "still went to the right place" because panelId memory was doing what it has always done; and the preview broke because the version before it passed `urlPath`, which writes `?view=<name>` — resolvable only when the folder is in the pathname, which in a panel it is not. the edit failed silently because I matched on four-space indentation in a file that uses two, and I did not check. third time today. this one asserts the replacement changed the file and fails loudly if it did not. what it does now, for real: current folder read from the named param, written back with `replace`, base folder expressed as the ABSENCE of the param, and a param pointing outside `basePath` ignored rather than obeyed — it comes from a URL somebody can edit, and the jail is the point of an embedded browser. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -82,14 +82,41 @@ export const useFileBrowserApp = (
|
|||||||
// visit still opens at home, because a URL with no `path` means the base. Either way the main
|
// visit still opens at home, because a URL with no `path` means the base. Either way the main
|
||||||
// (unscoped) browser mirrors its folder into files/currentPath so the Create Dashboard flow can
|
// (unscoped) browser mirrors its folder into files/currentPath so the Create Dashboard flow can
|
||||||
// default a new dashboard's cwd to it.
|
// default a new dashboard's cwd to it.
|
||||||
const currentPath = urlPath ? folderFromPathname(location.pathname) : localPath;
|
/*
|
||||||
|
Three sources, mutually exclusive by construction: the pathname for /files, a named query param for
|
||||||
|
an embedded browser, and component state for an ordinary panel.
|
||||||
|
|
||||||
|
A param naming a folder OUTSIDE the jail is ignored rather than obeyed — it arrives from a URL
|
||||||
|
somebody may have edited, and `basePath` is the whole promise of an embedded browser.
|
||||||
|
*/
|
||||||
|
const paramPath = pathParam ? searchParams.get(pathParam) : null;
|
||||||
|
const currentPath = urlPath
|
||||||
|
? folderFromPathname(location.pathname)
|
||||||
|
: pathParam
|
||||||
|
? paramPath && paramPath.startsWith(basePath)
|
||||||
|
? paramPath
|
||||||
|
: basePath
|
||||||
|
: localPath;
|
||||||
const setCurrentPath = (path: string) => {
|
const setCurrentPath = (path: string) => {
|
||||||
// Leaving a folder closes what was open in it. A pane shows a file from the folder you were in, so
|
// Leaving a folder closes what was open in it. A pane shows a file from the folder you were in, so
|
||||||
// carrying it into the next one leaves the two disagreeing — the listing says one place, the pane
|
// carrying it into the next one leaves the two disagreeing — the listing says one place, the pane
|
||||||
// another. Only the OVERLAY params go; anything else in the query (global UI state) is left alone,
|
// another. Only the OVERLAY params go; anything else in the query (global UI state) is left alone,
|
||||||
// which is the distinction a wholesale reset kept getting wrong.
|
// which is the distinction a wholesale reset kept getting wrong.
|
||||||
if (urlPath) navigate({ pathname: folderHref(path), search: withoutViewerParams(location.search) });
|
if (urlPath) navigate({ pathname: folderHref(path), search: withoutViewerParams(location.search) });
|
||||||
else {
|
else if (pathParam) {
|
||||||
|
setSearchParams(
|
||||||
|
(prev) => {
|
||||||
|
const next = new URLSearchParams(withoutViewerParams(prev.toString()));
|
||||||
|
// The base folder is the ABSENCE of the param, so a link to the top of an embedded browser is
|
||||||
|
// the plain screen URL and nothing accumulates for having gone nowhere.
|
||||||
|
if (path === basePath) next.delete(pathParam);
|
||||||
|
else next.set(pathParam, path);
|
||||||
|
return next;
|
||||||
|
},
|
||||||
|
// Browsing folders is not navigation anybody wants twenty back-button presses of.
|
||||||
|
{ replace: true },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
setLocalPath(path);
|
setLocalPath(path);
|
||||||
// Written here rather than in an effect on `currentPath`, so it records a NAVIGATION and not the
|
// Written here rather than in an effect on `currentPath`, so it records a NAVIGATION and not the
|
||||||
// initial render. An effect would fire once on mount with the restored value and persist it back,
|
// initial render. An effect would fire once on mount with the restored value and persist it back,
|
||||||
|
|||||||
Reference in New Issue
Block a user