forked from OpenNeo/impress
Use /outfits/1234 URLs in the editor
Ohh I see, I made a mistake converting this from Next.js routing. It's not that we had a URL search parameter named `outfitId`; it's that if you were coming from the `/outfits/:outfitId` route, it would use that! I still haven't gotten the rest of the site to point that route to this page, but I'll do that in a later change.
This commit is contained in:
parent
a983ac9053
commit
3d07d7f360
2 changed files with 32 additions and 12 deletions
|
@ -97,6 +97,12 @@ function useOutfitState() {
|
||||||
// a better representation of the outfit in the URL. (If the saved outfit
|
// a better representation of the outfit in the URL. (If the saved outfit
|
||||||
// data isn't loaded yet, then this will be a customization state with
|
// data isn't loaded yet, then this will be a customization state with
|
||||||
// partial data, and that's okay.)
|
// partial data, and that's okay.)
|
||||||
|
console.debug(
|
||||||
|
`[useOutfitState] Outfit states:\n- Local: %o\n- Saved: %o\n- URL: %o`,
|
||||||
|
localOutfitState,
|
||||||
|
savedOutfitState,
|
||||||
|
urlOutfitState,
|
||||||
|
);
|
||||||
let outfitState;
|
let outfitState;
|
||||||
if (
|
if (
|
||||||
urlOutfitState.id === localOutfitState.id &&
|
urlOutfitState.id === localOutfitState.id &&
|
||||||
|
@ -106,17 +112,27 @@ function useOutfitState() {
|
||||||
// Use the reducer state: they're both for the same saved outfit, or both
|
// Use the reducer state: they're both for the same saved outfit, or both
|
||||||
// for an unsaved outfit (null === null). But we don't use it when it's
|
// for an unsaved outfit (null === null). But we don't use it when it's
|
||||||
// *only* got the ID, and no other fields yet.
|
// *only* got the ID, and no other fields yet.
|
||||||
console.debug("[useOutfitState] Choosing local outfit state");
|
console.debug(
|
||||||
|
"[useOutfitState] Choosing local outfit state",
|
||||||
|
localOutfitState,
|
||||||
|
);
|
||||||
outfitState = localOutfitState;
|
outfitState = localOutfitState;
|
||||||
} else if (urlOutfitState.id && urlOutfitState.id === savedOutfitState.id) {
|
} else if (urlOutfitState.id && urlOutfitState.id === savedOutfitState.id) {
|
||||||
// Use the saved outfit state: it's for the saved outfit the URL points to.
|
// Use the saved outfit state: it's for the saved outfit the URL points to.
|
||||||
console.debug("[useOutfitState] Choosing saved outfit state");
|
console.debug(
|
||||||
|
"[useOutfitState] Choosing saved outfit state",
|
||||||
|
savedOutfitState,
|
||||||
|
);
|
||||||
outfitState = savedOutfitState;
|
outfitState = savedOutfitState;
|
||||||
} else {
|
} else {
|
||||||
// Use the URL state: it's more up-to-date than any of the others. (Worst
|
// Use the URL state: it's more up-to-date than any of the others. (Worst
|
||||||
// case, it's empty except for ID, which is fine while the saved outfit
|
// case, it's empty except for ID, which is fine while the saved outfit
|
||||||
// data loads!)
|
// data loads!)
|
||||||
console.debug("[useOutfitState] Choosing URL outfit state");
|
console.debug(
|
||||||
|
"[useOutfitState] Choosing URL outfit state",
|
||||||
|
urlOutfitState,
|
||||||
|
savedOutfitState,
|
||||||
|
);
|
||||||
outfitState = urlOutfitState;
|
outfitState = urlOutfitState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +277,11 @@ function useOutfitState() {
|
||||||
// Keep the URL up-to-date.
|
// Keep the URL up-to-date.
|
||||||
const path = buildOutfitPath(outfitState);
|
const path = buildOutfitPath(outfitState);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
console.debug(
|
||||||
|
`[useOutfitState] Navigating to latest outfit path:`,
|
||||||
|
path,
|
||||||
|
outfitState,
|
||||||
|
);
|
||||||
navigate(path, { replace: true });
|
navigate(path, { replace: true });
|
||||||
}, [path]);
|
}, [path]);
|
||||||
|
|
||||||
|
@ -398,30 +419,28 @@ function useParseOutfitUrl() {
|
||||||
// We memoize this to make `outfitStateWithoutExtras` an even more reliable
|
// We memoize this to make `outfitStateWithoutExtras` an even more reliable
|
||||||
// stable object!
|
// stable object!
|
||||||
const memoizedOutfitState = React.useMemo(
|
const memoizedOutfitState = React.useMemo(
|
||||||
() => readOutfitStateFromSearchParams(mergedParams),
|
() => readOutfitStateFromSearchParams(location.pathname, mergedParams),
|
||||||
[mergedParams.toString()],
|
[location.pathname, mergedParams.toString()],
|
||||||
);
|
);
|
||||||
|
|
||||||
return memoizedOutfitState;
|
return memoizedOutfitState;
|
||||||
}
|
}
|
||||||
|
|
||||||
function readOutfitStateFromSearchParams(searchParams) {
|
function readOutfitStateFromSearchParams(pathname, searchParams) {
|
||||||
// For the /outfits/:id page, ignore the query string, and just wait for the
|
// For the /outfits/:id page, ignore the query string, and just wait for the
|
||||||
// outfit data to load in!
|
// outfit data to load in!
|
||||||
// NOTE: We now use `outfitId` when generating URLs, but historically we've
|
const pathnameMatch = pathname.match(/^\/outfits\/([0-9]+)/)
|
||||||
// used `outfit` too!
|
if (pathnameMatch) {
|
||||||
const outfitId = searchParams.get("outfitId") ?? searchParams.get("outfit");
|
|
||||||
if (outfitId != null) {
|
|
||||||
return {
|
return {
|
||||||
...EMPTY_CUSTOMIZATION_STATE,
|
...EMPTY_CUSTOMIZATION_STATE,
|
||||||
id: outfitId,
|
id: pathnameMatch[1],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, parse the query string, and fill in default values for anything
|
// Otherwise, parse the query string, and fill in default values for anything
|
||||||
// not specified.
|
// not specified.
|
||||||
return {
|
return {
|
||||||
id: null,
|
id: searchParams.get("outfit"),
|
||||||
name: searchParams.get("name"),
|
name: searchParams.get("name"),
|
||||||
speciesId: searchParams.get("species") || "1",
|
speciesId: searchParams.get("species") || "1",
|
||||||
colorId: searchParams.get("color") || "8",
|
colorId: searchParams.get("color") || "8",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { Box } from "@chakra-ui/react";
|
import { Box } from "@chakra-ui/react";
|
||||||
|
|
||||||
function OutfitThumbnail({ outfitId, updatedAt, ...props }) {
|
function OutfitThumbnail({ outfitId, updatedAt, ...props }) {
|
||||||
|
|
Loading…
Reference in a new issue