sync outfit url to location bar

This commit is contained in:
Matt Dunn-Rankin 2020-04-30 00:45:01 -07:00
parent c61612125c
commit fa92101b58
2 changed files with 43 additions and 41 deletions

View file

@ -69,7 +69,7 @@ function OutfitPreview({ outfitState, dispatchToOutfit }) {
visibleLayers visibleLayers
); );
const { onCopy, hasCopied } = useClipboard(getShareUrl(outfitState)); const { onCopy, hasCopied } = useClipboard(outfitState.url);
if (error) { if (error) {
return ( return (
@ -378,29 +378,4 @@ function useDownloadableImage(visibleLayers) {
return [downloadImageUrl, prepareDownload]; return [downloadImageUrl, prepareDownload];
} }
function getShareUrl(outfitState) {
const {
name,
speciesId,
colorId,
wornItemIds,
closetedItemIds,
} = outfitState;
const params = new URLSearchParams();
params.append("name", name);
params.append("species", speciesId);
params.append("color", colorId);
for (const itemId of wornItemIds) {
params.append("objects[]", itemId);
}
for (const itemId of closetedItemIds) {
params.append("closet[]", itemId);
}
const { origin, pathname } = window.location;
const url = origin + pathname + "?" + params.toString();
return url;
}
export default OutfitPreview; export default OutfitPreview;

View file

@ -35,21 +35,6 @@ function useOutfitState() {
} }
); );
React.useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has("species")) {
dispatchToOutfit({
type: "reset",
name: urlParams.get("name"),
speciesId: urlParams.get("species"),
colorId: urlParams.get("color"),
wornItemIds: urlParams.getAll("objects[]"),
closetedItemIds: urlParams.getAll("closet[]"),
});
}
window.history.replaceState(null, "", window.location.href.split("?")[0]);
});
const { name, speciesId, colorId } = state; const { name, speciesId, colorId } = state;
// It's more convenient to manage these as a Set in state, but most callers // It's more convenient to manage these as a Set in state, but most callers
@ -99,6 +84,8 @@ function useOutfitState() {
closetedItemIds closetedItemIds
); );
const url = buildOutfitUrl(state);
const outfitState = { const outfitState = {
zonesAndItems, zonesAndItems,
name, name,
@ -107,8 +94,29 @@ function useOutfitState() {
allItemIds, allItemIds,
speciesId, speciesId,
colorId, colorId,
url,
}; };
// Get the state from the URL the first time we load.
React.useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has("species")) {
dispatchToOutfit({
type: "reset",
name: urlParams.get("name"),
speciesId: urlParams.get("species"),
colorId: urlParams.get("color"),
wornItemIds: urlParams.getAll("objects[]"),
closetedItemIds: urlParams.getAll("closet[]"),
});
}
}, []);
// Afterwards, keep the URL up-to-date, but don't listen to it anymore.
React.useEffect(() => {
window.history.replaceState(null, "", url);
}, [url]);
return { loading, error, outfitState, dispatchToOutfit }; return { loading, error, outfitState, dispatchToOutfit };
} }
@ -306,4 +314,23 @@ function getZonesAndItems(itemsById, wornItemIds, closetedItemIds) {
return zonesAndItems; return zonesAndItems;
} }
function buildOutfitUrl(state) {
const { name, speciesId, colorId, wornItemIds, closetedItemIds } = state;
const params = new URLSearchParams();
params.append("name", name);
params.append("species", speciesId);
params.append("color", colorId);
for (const itemId of wornItemIds) {
params.append("objects[]", itemId);
}
for (const itemId of closetedItemIds) {
params.append("closet[]", itemId);
}
const { origin, pathname } = window.location;
const url = origin + pathname + "?" + params.toString();
return url;
}
export default useOutfitState; export default useOutfitState;