Matchu
81b2a2b4a2
We add jsbuilding-rails to get esbuild running in the app, and then we copy-paste the files we need from impress-2020 into here! I stopped at the point where it was building successfully, but it's not running correctly: it's not sure about `process.env` in `next`, and I think the right next step is to delete the NextJS deps altogether and use React Router instead.
99 lines
2.8 KiB
JavaScript
99 lines
2.8 KiB
JavaScript
import React from "react";
|
|
import { Box, Center, DarkMode } from "@chakra-ui/react";
|
|
import gql from "graphql-tag";
|
|
import { useQuery } from "@apollo/client";
|
|
import * as Sentry from "@sentry/react";
|
|
|
|
import OutfitThumbnail from "../components/OutfitThumbnail";
|
|
import { useOutfitPreview } from "../components/OutfitPreview";
|
|
import { loadable, MajorErrorMessage, TestErrorSender } from "../util";
|
|
|
|
const OutfitControls = loadable(() => import("./OutfitControls"));
|
|
|
|
function WardrobePreviewAndControls({
|
|
isLoading,
|
|
outfitState,
|
|
dispatchToOutfit,
|
|
}) {
|
|
// Whether the current outfit preview has animations. Determines whether we
|
|
// show the play/pause button.
|
|
const [hasAnimations, setHasAnimations] = React.useState(false);
|
|
|
|
const { appearance, preview } = useOutfitPreview({
|
|
isLoading: isLoading,
|
|
speciesId: outfitState.speciesId,
|
|
colorId: outfitState.colorId,
|
|
pose: outfitState.pose,
|
|
appearanceId: outfitState.appearanceId,
|
|
wornItemIds: outfitState.wornItemIds,
|
|
onChangeHasAnimations: setHasAnimations,
|
|
placeholder: <OutfitThumbnailIfCached outfitId={outfitState.id} />,
|
|
"data-test-id": "wardrobe-outfit-preview",
|
|
});
|
|
|
|
return (
|
|
<Sentry.ErrorBoundary fallback={MajorErrorMessage}>
|
|
<TestErrorSender />
|
|
<Center position="absolute" top="0" bottom="0" left="0" right="0">
|
|
<DarkMode>{preview}</DarkMode>
|
|
</Center>
|
|
<Box position="absolute" top="0" bottom="0" left="0" right="0">
|
|
<OutfitControls
|
|
outfitState={outfitState}
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
showAnimationControls={hasAnimations}
|
|
appearance={appearance}
|
|
/>
|
|
</Box>
|
|
</Sentry.ErrorBoundary>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* OutfitThumbnailIfCached will render an OutfitThumbnail as a placeholder for
|
|
* the outfit preview... but only if we already have the data to generate the
|
|
* thumbnail stored in our local Apollo GraphQL cache.
|
|
*
|
|
* This means that, when you come from the Your Outfits page, we can show the
|
|
* outfit thumbnail instantly while everything else loads. But on direct
|
|
* navigation, this does nothing, and we just wait for the preview to load in
|
|
* like usual!
|
|
*/
|
|
function OutfitThumbnailIfCached({ outfitId }) {
|
|
const { data } = useQuery(
|
|
gql`
|
|
query OutfitThumbnailIfCached($outfitId: ID!) {
|
|
outfit(id: $outfitId) {
|
|
id
|
|
updatedAt
|
|
}
|
|
}
|
|
`,
|
|
{
|
|
variables: {
|
|
outfitId,
|
|
},
|
|
skip: outfitId == null,
|
|
fetchPolicy: "cache-only",
|
|
onError: (e) => console.error(e),
|
|
}
|
|
);
|
|
|
|
if (!data?.outfit) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<OutfitThumbnail
|
|
outfitId={data.outfit.id}
|
|
updatedAt={data.outfit.updatedAt}
|
|
alt=""
|
|
objectFit="contain"
|
|
width="100%"
|
|
height="100%"
|
|
filter="blur(2px)"
|
|
/>
|
|
);
|
|
}
|
|
|
|
export default WardrobePreviewAndControls;
|