diff --git a/src/app/HomePage.js b/src/app/HomePage.js
index c5ebb95..c752c3b 100644
--- a/src/app/HomePage.js
+++ b/src/app/HomePage.js
@@ -105,6 +105,8 @@ function StartOutfitForm({ onChange }) {
colorId={colorId}
idealPose={idealPose}
showPlaceholders
+ colorPlaceholderText="Blue"
+ speciesPlaceholderText="Acara"
onChange={(species, color, isValid, closestPose) => {
setSpeciesId(species.id);
setColorId(color.id);
diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js
index 13305ad..bca1e9c 100644
--- a/src/app/ItemPage.js
+++ b/src/app/ItemPage.js
@@ -443,41 +443,64 @@ function ItemPageOutfitPreview({ itemId }) {
[]
);
const [petState, setPetState] = React.useState({
- // Start by looking up Acara appearance data.
- speciesId: "1",
- colorId: "8",
- pose: idealPose,
+ // We'll fill this in once the canonical appearance data arrives.
+ speciesId: null,
+ colorId: null,
+ pose: null,
});
// Start by loading the "canonical" pet and item appearance for the outfit
// preview. We'll use this to initialize both the preview and the picker.
- const { loading, error, data } = useQuery(gql`
- query ItemPageOutfitPreview($itemId: ID!) {
- item(id: $itemId) {
- id
- canonicalAppearance {
+ const { loading, error } = useQuery(
+ gql`
+ query ItemPageOutfitPreview($itemId: ID!) {
+ item(id: $itemId) {
id
- ...ItemAppearanceFragment
- body {
+ canonicalAppearance {
id
- canonicalAppearance {
+ ...ItemAppearanceForOutfitPreview
+ body {
id
- ...PetAppearanceFragment
+ canonicalAppearance {
+ id
+ species {
+ id
+ }
+ color {
+ id
+ }
+ pose
+
+ ...PetAppearanceForOutfitPreview
+ }
}
}
}
}
- }
- ${itemAppearanceFragment}
- ${petAppearanceFragment}
- `);
+ ${itemAppearanceFragment}
+ ${petAppearanceFragment}
+ `,
+ {
+ variables: { itemId },
+ onCompleted: (data) => {
+ const canonicalBody = data?.item?.canonicalAppearance?.body;
+ const canonicalPetAppearance = canonicalBody?.canonicalAppearance;
+
+ setPetState({
+ speciesId: canonicalPetAppearance?.species?.id,
+ colorId: canonicalPetAppearance?.color?.id,
+ pose: canonicalPetAppearance?.pose,
+ });
+ },
+ }
+ );
// To check whether the item is compatible with this pet, query for the
// appearance, but only against the cache. That way, we don't send a
// redundant network request just for this (the OutfitPreview component will
// handle it!), but we'll get an update once it arrives in the cache.
- const { cachedData } = useQuery(
+ const { data: cachedData } = useQuery(
gql`
query ItemPageOutfitPreview_CacheOnly(
$itemId: ID!
@@ -500,17 +523,29 @@ function ItemPageOutfitPreview({ itemId }) {
colorId: petState.colorId,
},
fetchPolicy: "cache-only",
+ onCompleted: (data) => console.log("data", data),
}
);
+ const borderColor = useColorModeValue("green.700", "green.400");
+ const errorColor = useColorModeValue("red.600", "red.400");
+
+ if (error) {
+ return {error.message};
+ }
+
// If the layers are null-y, then we're still loading. Otherwise, if the
// layers are an empty array, then we're incomaptible. Or, if they're a
// non-empty array, then we're compatible!
const layers = cachedData?.item?.appearanceOn?.layers;
const isIncompatible = Array.isArray(layers) && layers.length === 0;
-
- const borderColor = useColorModeValue("green.700", "green.400");
- const errorColor = useColorModeValue("red.600", "red.400");
+ console.log(
+ petState.speciesId,
+ petState.colorId,
+ itemId,
+ layers,
+ isIncompatible
+ );
return (
@@ -531,6 +566,7 @@ function ItemPageOutfitPreview({ itemId }) {
colorId={petState.colorId}
pose={petState.pose}
wornItemIds={[itemId]}
+ isLoading={loading}
spinnerVariant="corner"
loadingDelayMs={2000}
/>
diff --git a/src/app/components/OutfitPreview.js b/src/app/components/OutfitPreview.js
index d87fdbb..7957baa 100644
--- a/src/app/components/OutfitPreview.js
+++ b/src/app/components/OutfitPreview.js
@@ -27,6 +27,7 @@ function OutfitPreview({
pose,
wornItemIds,
appearanceId = null,
+ isLoading = false,
placeholder,
loadingDelayMs,
spinnerVariant,
@@ -57,7 +58,7 @@ function OutfitPreview({
return (
getValidPoses(valids, speciesId, c.id).size > 0
);
@@ -180,13 +187,19 @@ function SpeciesColorPicker({
isDisabled={isDisabled}
onChange={onChangeColor}
>
- {allColors.length === 0 && (
- <>
- {/* The default case, and a long name for sizing! */}
-
-
- >
- )}
+ {
+ // If the selected color isn't in the set we have here, show the
+ // placeholder. (Can happen during loading, or if an invalid color ID
+ // like null is intentionally provided while the real value loads.)
+ !visibleColors.some((c) => c.id === colorId) && (
+
+ )
+ }
+ {
+ // A long name for sizing! Should appear below the placeholder, out
+ // of view.
+ visibleColors.length === 0 &&
+ }
{visibleColors.map((color) => (
-
- >
- )}
+ {
+ // If the selected species isn't in the set we have here, show the
+ // placeholder. (Can happen during loading, or if an invalid species
+ // ID like null is intentionally provided while the real value
+ // loads.)
+ !allSpecies.some((s) => s.id === speciesId) && (
+
+ )
+ }
+ {
+ // A long name for sizing! Should appear below the placeholder, out
+ // of view.
+ allSpecies.length === 0 &&
+ }
{allSpecies.map((species) => (