2020-04-21 20:32:53 -07:00
|
|
|
import React from "react";
|
2020-09-10 02:54:22 -07:00
|
|
|
import { useToast } from "@chakra-ui/core";
|
2020-05-18 00:11:18 -07:00
|
|
|
import loadable from "@loadable/component";
|
2020-04-21 20:32:53 -07:00
|
|
|
|
2020-04-26 00:37:58 -07:00
|
|
|
import ItemsAndSearchPanels from "./ItemsAndSearchPanels";
|
2020-07-22 21:29:57 -07:00
|
|
|
import OutfitPreview from "../components/OutfitPreview";
|
2020-08-28 00:12:41 -07:00
|
|
|
import SupportOnly from "./support/SupportOnly";
|
2020-08-27 22:32:28 -07:00
|
|
|
import useOutfitState, { OutfitStateContext } from "./useOutfitState";
|
2020-07-20 21:41:26 -07:00
|
|
|
import { usePageTitle } from "../util";
|
2020-09-10 02:54:22 -07:00
|
|
|
import WardrobePageLayout from "./WardrobePageLayout";
|
2020-04-21 20:32:53 -07:00
|
|
|
|
2020-05-18 00:37:13 -07:00
|
|
|
const OutfitControls = loadable(() =>
|
|
|
|
import(/* webpackPreload: true */ "./OutfitControls")
|
|
|
|
);
|
2020-08-28 00:12:41 -07:00
|
|
|
const WardrobeDevHacks = loadable(() => import("./WardrobeDevHacks"));
|
2020-05-18 00:11:18 -07:00
|
|
|
|
2020-04-26 00:37:58 -07:00
|
|
|
/**
|
|
|
|
* WardrobePage is the most fun page on the site - it's where you create
|
|
|
|
* outfits!
|
|
|
|
*
|
|
|
|
* This page has two sections: the OutfitPreview, where we show the outfit as a
|
|
|
|
* big image; and the ItemsAndSearchPanels, which let you manage which items
|
|
|
|
* are in the outfit and find new ones.
|
|
|
|
*
|
|
|
|
* This component manages shared outfit state, and the fullscreen responsive
|
|
|
|
* page layout.
|
|
|
|
*/
|
2020-04-21 20:32:53 -07:00
|
|
|
function WardrobePage() {
|
2020-04-22 02:57:58 -07:00
|
|
|
const toast = useToast();
|
2020-04-26 00:37:58 -07:00
|
|
|
const { loading, error, outfitState, dispatchToOutfit } = useOutfitState();
|
2020-04-22 02:57:58 -07:00
|
|
|
|
2020-09-11 23:53:57 -07:00
|
|
|
usePageTitle(outfitState.name || "Untitled outfit");
|
2020-05-17 23:26:00 -07:00
|
|
|
|
2020-04-26 00:37:58 -07:00
|
|
|
// TODO: I haven't found a great place for this error UI yet, and this case
|
|
|
|
// isn't very common, so this lil toast notification seems good enough!
|
2020-04-22 15:24:38 -07:00
|
|
|
React.useEffect(() => {
|
|
|
|
if (error) {
|
2020-04-24 21:17:03 -07:00
|
|
|
console.log(error);
|
2020-04-22 15:24:38 -07:00
|
|
|
toast({
|
|
|
|
title: "We couldn't load this outfit 😖",
|
|
|
|
description: "Please reload the page to try again. Sorry!",
|
|
|
|
status: "error",
|
|
|
|
isClosable: true,
|
2020-04-24 21:17:03 -07:00
|
|
|
duration: 999999999,
|
2020-04-22 15:24:38 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}, [error, toast]);
|
|
|
|
|
2020-08-05 01:23:26 -07:00
|
|
|
// NOTE: Most components pass around outfitState directly, to make the data
|
|
|
|
// relationships more explicit... but there are some deep components
|
|
|
|
// that need it, where it's more useful and more performant to access
|
|
|
|
// via context.
|
2020-04-21 20:32:53 -07:00
|
|
|
return (
|
2020-08-05 00:25:25 -07:00
|
|
|
<OutfitStateContext.Provider value={outfitState}>
|
2020-08-28 00:12:41 -07:00
|
|
|
<SupportOnly>
|
|
|
|
<WardrobeDevHacks />
|
|
|
|
</SupportOnly>
|
2020-09-10 02:54:22 -07:00
|
|
|
<WardrobePageLayout
|
|
|
|
preview={
|
|
|
|
<OutfitPreview
|
|
|
|
speciesId={outfitState.speciesId}
|
|
|
|
colorId={outfitState.colorId}
|
|
|
|
pose={outfitState.pose}
|
|
|
|
appearanceId={outfitState.appearanceId}
|
|
|
|
wornItemIds={outfitState.wornItemIds}
|
2020-09-21 18:50:27 -07:00
|
|
|
engine="canvas"
|
2020-09-10 02:54:22 -07:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
controls={
|
|
|
|
<OutfitControls
|
|
|
|
outfitState={outfitState}
|
|
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
itemsAndSearch={
|
|
|
|
<ItemsAndSearchPanels
|
|
|
|
loading={loading}
|
|
|
|
outfitState={outfitState}
|
|
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
/>
|
2020-08-05 00:25:25 -07:00
|
|
|
</OutfitStateContext.Provider>
|
2020-04-21 20:32:53 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default WardrobePage;
|