extract OutfitPreview into a shared component

I wanna use it in some other places soon, like a outfit-sharing page, and on the homepage to preview stuff
This commit is contained in:
Emi Matchu 2020-07-22 21:29:57 -07:00
parent 3e86d1f2e7
commit 9164d89240
7 changed files with 33 additions and 20 deletions

View file

@ -18,7 +18,7 @@ import {
import PosePicker from "./PosePicker"; import PosePicker from "./PosePicker";
import SpeciesColorPicker from "../components/SpeciesColorPicker"; import SpeciesColorPicker from "../components/SpeciesColorPicker";
import useOutfitAppearance from "./useOutfitAppearance"; import useOutfitAppearance from "../components/useOutfitAppearance";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
/** /**

View file

@ -14,7 +14,11 @@ import {
useTheme, useTheme,
} from "@chakra-ui/core"; } from "@chakra-ui/core";
import { getVisibleLayers, petAppearanceFragment } from "./useOutfitAppearance"; import {
getVisibleLayers,
petAppearanceFragment,
} from "../components/useOutfitAppearance";
import { OutfitLayers } from "../components/OutfitPreview";
// From https://twemoji.twitter.com/, thank you! // From https://twemoji.twitter.com/, thank you!
import twemojiSmile from "../../images/twemoji/smile.svg"; import twemojiSmile from "../../images/twemoji/smile.svg";
@ -22,7 +26,6 @@ import twemojiCry from "../../images/twemoji/cry.svg";
import twemojiSick from "../../images/twemoji/sick.svg"; import twemojiSick from "../../images/twemoji/sick.svg";
import twemojiMasc from "../../images/twemoji/masc.svg"; import twemojiMasc from "../../images/twemoji/masc.svg";
import twemojiFem from "../../images/twemoji/fem.svg"; import twemojiFem from "../../images/twemoji/fem.svg";
import { OutfitLayers } from "./OutfitPreview";
function PosePicker({ function PosePicker({
outfitState, outfitState,

View file

@ -5,7 +5,7 @@ import { useQuery } from "@apollo/react-hooks";
import { Delay, Heading1, useDebounce } from "../util"; import { Delay, Heading1, useDebounce } from "../util";
import { Item, ItemListContainer, ItemListSkeleton } from "./Item"; import { Item, ItemListContainer, ItemListSkeleton } from "./Item";
import { itemAppearanceFragment } from "./useOutfitAppearance"; import { itemAppearanceFragment } from "../components/useOutfitAppearance";
/** /**
* SearchPanel shows item search results to the user, so they can preview them * SearchPanel shows item search results to the user, so they can preview them

View file

@ -3,7 +3,7 @@ import { Box, Grid, useToast } from "@chakra-ui/core";
import loadable from "@loadable/component"; import loadable from "@loadable/component";
import ItemsAndSearchPanels from "./ItemsAndSearchPanels"; import ItemsAndSearchPanels from "./ItemsAndSearchPanels";
import OutfitPreview from "./OutfitPreview"; import OutfitPreview from "../components/OutfitPreview";
import useOutfitState from "./useOutfitState.js"; import useOutfitState from "./useOutfitState.js";
import { usePageTitle } from "../util"; import { usePageTitle } from "../util";
@ -64,7 +64,12 @@ function WardrobePage() {
> >
<Box gridArea="previewAndControls" bg="gray.900" pos="relative"> <Box gridArea="previewAndControls" bg="gray.900" pos="relative">
<Box position="absolute" top="0" bottom="0" left="0" right="0"> <Box position="absolute" top="0" bottom="0" left="0" right="0">
<OutfitPreview outfitState={outfitState} /> <OutfitPreview
speciesId={outfitState.speciesId}
colorId={outfitState.colorId}
pose={outfitState.pose}
wornItemIds={outfitState.wornItemIds}
/>
</Box> </Box>
<Box position="absolute" top="0" bottom="0" left="0" right="0"> <Box position="absolute" top="0" bottom="0" left="0" right="0">
<OutfitControls <OutfitControls

View file

@ -3,7 +3,7 @@ import gql from "graphql-tag";
import produce, { enableMapSet } from "immer"; import produce, { enableMapSet } from "immer";
import { useQuery, useApolloClient } from "@apollo/react-hooks"; import { useQuery, useApolloClient } from "@apollo/react-hooks";
import { itemAppearanceFragment } from "./useOutfitAppearance"; import { itemAppearanceFragment } from "../components/useOutfitAppearance";
enableMapSet(); enableMapSet();

View file

@ -1,28 +1,33 @@
import React from "react"; import React from "react";
import { css, cx } from "emotion"; import { css, cx } from "emotion";
import { CSSTransition, TransitionGroup } from "react-transition-group"; import { CSSTransition, TransitionGroup } from "react-transition-group";
import { Box, Flex, Text } from "@chakra-ui/core"; import { Box, Flex, Text } from "@chakra-ui/core";
import { WarningIcon } from "@chakra-ui/icons"; import { WarningIcon } from "@chakra-ui/icons";
import HangerSpinner from "../components/HangerSpinner"; import HangerSpinner from "./HangerSpinner";
import useOutfitAppearance from "./useOutfitAppearance"; import useOutfitAppearance from "./useOutfitAppearance";
/** /**
* OutfitPreview renders the actual image layers for the outfit we're viewing! * OutfitPreview is for rendering a full outfit! It accepts outfit data,
* fetches the appearance data for it, and preloads and renders the layers
* together.
*
* TODO: There's some duplicate work happening in useOutfitAppearance and
* useOutfitState both getting appearance data on first load...
*/ */
function OutfitPreview({ outfitState }) { function OutfitPreview({ speciesId, colorId, pose, wornItemIds }) {
const { const { loading, error, visibleLayers } = useOutfitAppearance({
loading: loading1, speciesId,
error: error1, colorId,
visibleLayers, pose,
} = useOutfitAppearance(outfitState); wornItemIds,
});
const { loading: loading2, error: error2, loadedLayers } = usePreloadLayers( const { loading: loading2, error: error2, loadedLayers } = usePreloadLayers(
visibleLayers visibleLayers
); );
if (error1 || error2) { if (error || error2) {
return ( return (
<FullScreenCenter> <FullScreenCenter>
<Text color="gray.50" d="flex" alignItems="center"> <Text color="gray.50" d="flex" alignItems="center">
@ -36,7 +41,7 @@ function OutfitPreview({ outfitState }) {
return ( return (
<OutfitLayers <OutfitLayers
loading={loading1 || loading2} loading={loading || loading2}
visibleLayers={loadedLayers} visibleLayers={loadedLayers}
doAnimations doAnimations
/> />
@ -129,7 +134,7 @@ export function OutfitLayers({ loading, visibleLayers, doAnimations = false }) {
); );
} }
function FullScreenCenter({ children }) { export function FullScreenCenter({ children }) {
return ( return (
<Flex <Flex
pos="absolute" pos="absolute"
@ -171,7 +176,7 @@ function loadImage(url) {
* when done. This enables us to keep the old outfit preview on screen until * when done. This enables us to keep the old outfit preview on screen until
* all the new layers are ready, then show them all at once! * all the new layers are ready, then show them all at once!
*/ */
function usePreloadLayers(layers) { export function usePreloadLayers(layers) {
const [error, setError] = React.useState(null); const [error, setError] = React.useState(null);
const [loadedLayers, setLoadedLayers] = React.useState([]); const [loadedLayers, setLoadedLayers] = React.useState([]);