impress-2020/src/app/WardrobePage/WardrobeOutfitPreview.js
Matchu 2a8be58973 Show thumbnail in wardrobe page while outfit loads
To help the load time for outfits feel shorter, we now reuse the outfit thumbnail from the Your Outfits page as a placeholder!

This doesn't add any overhead when the thumbnail data _isn't_ in your session cache, e.g. if you navigate to the outfit directly. But if we have the thumbnail on hand already, we just show it, easy peasy!
2021-01-08 01:23:24 -08:00

78 lines
2.1 KiB
JavaScript

import React from "react";
import gql from "graphql-tag";
import { useQuery } from "@apollo/client";
import OutfitThumbnail, {
outfitThumbnailFragment,
getOutfitThumbnailRenderSize,
} from "../components/OutfitThumbnail";
import OutfitPreview from "../components/OutfitPreview";
function WardrobeOutfitPreview({
isLoading,
outfitState,
onChangeHasAnimations,
}) {
return (
<OutfitPreview
isLoading={isLoading}
speciesId={outfitState.speciesId}
colorId={outfitState.colorId}
pose={outfitState.pose}
appearanceId={outfitState.appearanceId}
wornItemIds={outfitState.wornItemIds}
onChangeHasAnimations={onChangeHasAnimations}
placeholder={<OutfitThumbnailIfCached outfitId={outfitState.id} />}
/>
);
}
/**
* 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!, $size: LayerImageSize!) {
outfit(id: $outfitId) {
id
...OutfitThumbnailFragment
}
}
${outfitThumbnailFragment}
`,
{
variables: {
outfitId,
// NOTE: This parameter is used inside `OutfitThumbnailFragment`!
size: "SIZE_" + getOutfitThumbnailRenderSize(),
},
fetchPolicy: "cache-only",
}
);
if (!data?.outfit) {
return null;
}
return (
<OutfitThumbnail
petAppearance={data.outfit.petAppearance}
itemAppearances={data.outfit.itemAppearances}
alt=""
objectFit="contain"
width="100%"
height="100%"
filter="blur(2px)"
/>
);
}
export default WardrobeOutfitPreview;