Skip to content

Rationalise URLs #970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/language-server/pyright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export const pyright = (language: string): LanguageServerClient | undefined => {
return undefined;
}
// Needed to support review branches that use a path location.
const { origin, pathname } = window.location;
const base = `${origin}${pathname}${pathname.endsWith("/") ? "" : "/"}`;
const workerScript = `${base}workers/${workerScriptName}`;
const workerScript = `${
process.env.PUBLIC_URL || "/"
}workers/${workerScriptName}`;
const foreground = new Worker(workerScript, {
name: "Pyright-foreground",
});
Expand Down
63 changes: 42 additions & 21 deletions src/router-hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,34 @@ type RouterContextValue = [

const RouterContext = createContext<RouterContextValue | undefined>(undefined);

const parse = (search: string): RouterState => {
const parse = (pathname: string, search: string): RouterState => {
const params = new URLSearchParams(search);
return {
tab: params.get("tab") ?? undefined,
api: anchorForParam(params.get("api")),
reference: anchorForParam(params.get("reference")),
idea: anchorForParam(params.get("idea")),
};
if (params.get("tab")) {
// Legacy
return {
tab: params.get("tab") ?? undefined,
api: anchorForParam(params.get("api")),
reference: anchorForParam(params.get("reference")),
idea: anchorForParam(params.get("idea")),
};
}
const base = process.env.PUBLIC_URL || "/";
pathname = pathname.slice(base.length);
if (pathname) {
const parts = pathname.split("/");
const tab = parts[0];
switch (tab) {
case "api":
return { tab: "api", api: anchorForParam(parts[1]) };
case "reference":
return { tab: "reference", reference: anchorForParam(parts[1]) };
case "idea":
return { tab: "ideas", idea: anchorForParam(parts[1]) };
default:
return { tab };
}
}
return {};
};

/**
Expand All @@ -95,28 +115,29 @@ export const useRouterState = (): RouterContextValue => {
};

export const toUrl = (state: RouterState): string => {
const query = Object.entries(state)
.filter(([k, v]) => k !== "focus" && !!v)
.map(([k, v]) => {
return `${encodeURIComponent(k)}=${encodeURIComponent(
serializeValue(v)
)}`;
})
.join("&");
return window.location.toString().split("?")[0] + (query ? "?" + query : "");
// This could be cleaned up if we always set the tab.
const parts = [
state.tab ??
(state.tab === "api" || state.api ? "api" : undefined) ??
(state.reference ? "reference" : undefined) ??
(state.idea ? "ideas" : undefined),
state.api?.id ?? state.reference?.id ?? state.idea?.id,
];
const base = process.env.PUBLIC_URL || "/";
const pathname = base + parts.filter((x): x is string => !!x).join("/");
return window.location.toString().split("/", 1)[0] + pathname;
};

const serializeValue = (value: Anchor | string) =>
typeof value === "string" ? value : value.id;

export const RouterProvider = ({ children }: { children: ReactNode }) => {
const logging = useLogging();
const [state, setState] = useState(parse(window.location.search));
const [state, setState] = useState(
parse(window.location.pathname, window.location.search)
);
useEffect(() => {
// This detects browser navigation but not our programatic changes,
// so we need to update state there ourselves.
const listener = (_: PopStateEvent) => {
const newState = parse(window.location.search);
const newState = parse(window.location.pathname, window.location.search);
setState(newState);
};
window.addEventListener("popstate", listener);
Expand Down