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 SpeciesColorPicker from "../components/SpeciesColorPicker";
import useOutfitAppearance from "./useOutfitAppearance";
import useOutfitAppearance from "../components/useOutfitAppearance";
import { Link } from "react-router-dom";
/**

View file

@ -14,7 +14,11 @@ import {
useTheme,
} 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!
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 twemojiMasc from "../../images/twemoji/masc.svg";
import twemojiFem from "../../images/twemoji/fem.svg";
import { OutfitLayers } from "./OutfitPreview";
function PosePicker({
outfitState,

View file

@ -5,7 +5,7 @@ import { useQuery } from "@apollo/react-hooks";
import { Delay, Heading1, useDebounce } from "../util";
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

View file

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

View file

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

View file

@ -1,28 +1,33 @@
import React from "react";
import { css, cx } from "emotion";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { Box, Flex, Text } from "@chakra-ui/core";
import { WarningIcon } from "@chakra-ui/icons";
import HangerSpinner from "../components/HangerSpinner";
import HangerSpinner from "./HangerSpinner";
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 }) {
const {
loading: loading1,
error: error1,
visibleLayers,
} = useOutfitAppearance(outfitState);
function OutfitPreview({ speciesId, colorId, pose, wornItemIds }) {
const { loading, error, visibleLayers } = useOutfitAppearance({
speciesId,
colorId,
pose,
wornItemIds,
});
const { loading: loading2, error: error2, loadedLayers } = usePreloadLayers(
visibleLayers
);
if (error1 || error2) {
if (error || error2) {
return (
<FullScreenCenter>
<Text color="gray.50" d="flex" alignItems="center">
@ -36,7 +41,7 @@ function OutfitPreview({ outfitState }) {
return (
<OutfitLayers
loading={loading1 || loading2}
loading={loading || loading2}
visibleLayers={loadedLayers}
doAnimations
/>
@ -129,7 +134,7 @@ export function OutfitLayers({ loading, visibleLayers, doAnimations = false }) {
);
}
function FullScreenCenter({ children }) {
export function FullScreenCenter({ children }) {
return (
<Flex
pos="absolute"
@ -171,7 +176,7 @@ function loadImage(url) {
* 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!
*/
function usePreloadLayers(layers) {
export function usePreloadLayers(layers) {
const [error, setError] = React.useState(null);
const [loadedLayers, setLoadedLayers] = React.useState([]);