From 5a9d2f656640b89e0476e060c32de447e79649b1 Mon Sep 17 00:00:00 2001 From: Matchu Date: Wed, 22 Jul 2020 22:07:45 -0700 Subject: [PATCH] show a preview of color/species on the homepage Using the newly extracted OutfitPreview! I'm really happy with how this turned out :3 It also makes the pageload after clicking Start super smooth, no spinner! Thanks Apollo cache!! --- src/app/HomePage.js | 37 +++++++++++++++---- src/app/components/OutfitPreview.js | 45 +++++++++++++++++++++-- src/app/components/useOutfitAppearance.js | 1 + 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/app/HomePage.js b/src/app/HomePage.js index cf499c4..73d636f 100644 --- a/src/app/HomePage.js +++ b/src/app/HomePage.js @@ -6,6 +6,7 @@ import { useHistory } from "react-router-dom"; import { useLazyQuery } from "@apollo/react-hooks"; import { Heading1, usePageTitle } from "./util"; +import OutfitPreview from "./components/OutfitPreview"; import HomepageSplashImg from "../images/homepage-splash.png"; import HomepageSplashImg2x from "../images/homepage-splash@2x.png"; @@ -14,6 +15,8 @@ import SpeciesColorPicker from "./components/SpeciesColorPicker"; function HomePage() { usePageTitle("Dress to Impress"); + const [previewState, setPreviewState] = React.useState(null); + return ( + overflow="hidden" + > + + } + /> + Dress to Impress - + or @@ -47,7 +62,7 @@ function HomePage() { ); } -function StartOutfitForm() { +function StartOutfitForm({ onChange }) { const history = useHistory(); const idealPose = React.useMemo( @@ -89,6 +104,14 @@ function StartOutfitForm() { setColorId(color.id); setIsValid(isValid); setClosestPose(closestPose); + + if (isValid) { + onChange({ + speciesId: species.id, + colorId: color.id, + pose: closestPose, + }); + } }} /> diff --git a/src/app/components/OutfitPreview.js b/src/app/components/OutfitPreview.js index 5998441..c59eb9b 100644 --- a/src/app/components/OutfitPreview.js +++ b/src/app/components/OutfitPreview.js @@ -12,10 +12,16 @@ import useOutfitAppearance from "./useOutfitAppearance"; * fetches the appearance data for it, and preloads and renders the layers * together. * + * If the species/color/pose fields are null and a `placeholder` node is + * provided instead, we'll render the placeholder. And then, once those props + * become non-null, we'll keep showing the placeholder below the loading + * overlay until loading completes. (We use this on the homepage to show the + * beach splash until outfit data arrives!) + * * TODO: There's some duplicate work happening in useOutfitAppearance and * useOutfitState both getting appearance data on first load... */ -function OutfitPreview({ speciesId, colorId, pose, wornItemIds }) { +function OutfitPreview({ speciesId, colorId, pose, wornItemIds, placeholder }) { const { loading, error, visibleLayers } = useOutfitAppearance({ speciesId, colorId, @@ -43,6 +49,7 @@ function OutfitPreview({ speciesId, colorId, pose, wornItemIds }) { ); @@ -52,9 +59,34 @@ function OutfitPreview({ speciesId, colorId, pose, wornItemIds }) { * OutfitLayers is the raw UI component for rendering outfit layers. It's * used both in the main outfit preview, and in other minor UIs! */ -export function OutfitLayers({ loading, visibleLayers, doAnimations = false }) { +export function OutfitLayers({ + loading, + visibleLayers, + placeholder, + doAnimations = false, +}) { + const [isMounted, setIsMounted] = React.useState(false); + React.useEffect(() => { + setTimeout(() => setIsMounted(true), 0); + }, []); + + console.log("opacity", isMounted && loading ? 1 : 0); + console.log("transition delay", loading ? "0.5s" : "0s"); + return ( + {placeholder && ( + + + {placeholder} + + + )} {visibleLayers.map((layer) => ( diff --git a/src/app/components/useOutfitAppearance.js b/src/app/components/useOutfitAppearance.js index 58b4401..9771a37 100644 --- a/src/app/components/useOutfitAppearance.js +++ b/src/app/components/useOutfitAppearance.js @@ -38,6 +38,7 @@ export default function useOutfitAppearance(outfitState) { colorId, pose, }, + skip: speciesId == null || colorId == null || pose == null, } );