use corner spinner on item page, and fix delay bug

Fading the whole preview to a black overlay for the loading state was feeling aggressive, especially since loading delay wasn't working correctly!

In this change, I fix loading delay, and I add a nice subtle "corner" variant for outfit preview spinners :)
This commit is contained in:
Emi Matchu 2020-09-13 04:12:14 -07:00
parent c11c2b1394
commit 351b9a88bd
4 changed files with 51 additions and 41 deletions

View file

@ -40,7 +40,7 @@ function HomePage() {
colorId={previewState?.colorId}
pose={previewState?.pose}
wornItemIds={[]}
loadingDelay="1.5s"
loadingDelayMs={1500}
placeholder={
<Box
as="img"

View file

@ -383,6 +383,8 @@ function ItemPageOutfitPreview({ itemId }) {
colorId="8"
pose="HAPPY_FEM"
wornItemIds={[itemId]}
spinnerVariant="corner"
loadingDelayMs={2000}
/>
</Box>
</AspectRatio>

View file

@ -86,12 +86,7 @@ function HangerSpinner({ size = "md", ...props }) {
`}
{...props}
>
<HangerIcon
boxSize={boxSize}
color={color}
transition="color 0.2s"
{...props}
/>
<HangerIcon boxSize={boxSize} color={color} transition="color 0.2s" />
</Box>
</>
);

View file

@ -1,7 +1,7 @@
import React from "react";
import { css, cx } from "emotion";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { Box, Flex, DarkMode, Text } from "@chakra-ui/core";
import { Box, DarkMode, Flex, Text } from "@chakra-ui/core";
import { WarningIcon } from "@chakra-ui/icons";
import HangerSpinner from "./HangerSpinner";
@ -25,10 +25,11 @@ function OutfitPreview({
speciesId,
colorId,
pose,
appearanceId = null,
wornItemIds,
appearanceId = null,
placeholder,
loadingDelay,
loadingDelayMs,
spinnerVariant,
}) {
const { loading, error, visibleLayers } = useOutfitAppearance({
speciesId,
@ -55,15 +56,14 @@ function OutfitPreview({
}
return (
<DarkMode>
<OutfitLayers
loading={loading || loading2}
visibleLayers={loadedLayers}
placeholder={placeholder}
loadingDelay={loadingDelay}
doAnimations
/>
</DarkMode>
<OutfitLayers
loading={loading || loading2}
visibleLayers={loadedLayers}
placeholder={placeholder}
loadingDelayMs={loadingDelayMs}
spinnerVariant={spinnerVariant}
doAnimations
/>
);
}
@ -75,13 +75,18 @@ export function OutfitLayers({
loading,
visibleLayers,
placeholder,
loadingDelay = "0.5s",
loadingDelayMs = 500,
spinnerVariant = "overlay",
doAnimations = false,
}) {
const [isMounted, setIsMounted] = React.useState(false);
React.useLayoutEffect(() => {
setIsMounted(true);
}, []);
const [loadingDelayHasPassed, setLoadingDelayHasPassed] = React.useState(
false
);
React.useEffect(() => {
const t = setTimeout(() => setLoadingDelayHasPassed(true), loadingDelayMs);
return () => clearTimeout(t);
}, [loadingDelayMs]);
return (
<Box
@ -164,24 +169,32 @@ export function OutfitLayers({
zIndex="9000"
// This is similar to our Delay util component, but Delay disappears
// immediately on load, whereas we want this to fade out smoothly. We
// also delay the fade-in by 0.5s, but don't delay the fade-out at all.
//
// We also use `isMounted` here to make sure it actually _fades_ in!
// (This starts the opacity at 0, then fires an immediate callback to
// set it to 1, triggering the transition.)
opacity={isMounted && loading ? 1 : 0}
transition={`opacity 0.2s ${loading ? loadingDelay : "0s"}`}
// also use a timeout to delay the fade-in by 0.5s, but don't delay the
// fade-out at all. (The timeout was an awkward choice, it was hard to
// find a good CSS way to specify this delay well!)
opacity={loading && loadingDelayHasPassed ? 1 : 0}
transition="opacity 0.2s"
>
<Box
position="absolute"
top="0"
left="0"
right="0"
bottom="0"
backgroundColor="gray.900"
opacity="0.7"
/>
<HangerSpinner />
{spinnerVariant === "overlay" && (
<>
<Box
position="absolute"
top="0"
left="0"
right="0"
bottom="0"
backgroundColor="gray.900"
opacity="0.7"
/>
{/* Against the dark overlay, use the Dark Mode spinner. */}
<DarkMode>
<HangerSpinner />
</DarkMode>
</>
)}
{spinnerVariant === "corner" && (
<HangerSpinner size="sm" position="absolute" bottom="2" right="2" />
)}
</FullScreenCenter>
</Box>
);