simplify PetAppearance client-side caching
Previously, we would load all `petAppearances` in `PosePicker`, and use cache keys to instantly find it again as a single `petAppearance` in `OutfitPreview` after switching poses. In this change, we instead have `PosePicker` explicitly load all 6 poses as separate `petAppearance` queries. This simplifies cache sharing between the two components' queries: Apollo can do it automatically, because they were queried the same way in the first place. I'm doing this in preparation for changing the `id` field of `PetAppearance`, to become `petStateId`. This will help me build pet appearance support tools, by giving the appearances stable identifiers that won't be affected by editing which pose an appearance is!
This commit is contained in:
parent
5f4952b123
commit
bf21716db0
2 changed files with 79 additions and 31 deletions
|
@ -376,36 +376,93 @@ function usePoses(speciesId, colorId, selectedPose) {
|
||||||
const { loading, error, data } = useQuery(
|
const { loading, error, data } = useQuery(
|
||||||
gql`
|
gql`
|
||||||
query PosePicker($speciesId: ID!, $colorId: ID!) {
|
query PosePicker($speciesId: ID!, $colorId: ID!) {
|
||||||
petAppearances(speciesId: $speciesId, colorId: $colorId) {
|
happyMasc: petAppearance(
|
||||||
id
|
speciesId: $speciesId
|
||||||
petStateId
|
colorId: $colorId
|
||||||
bodyId
|
pose: HAPPY_MASC
|
||||||
pose
|
) {
|
||||||
...PetAppearanceForOutfitPreview
|
...PetAppearanceForPosePicker
|
||||||
}
|
}
|
||||||
|
sadMasc: petAppearance(
|
||||||
|
speciesId: $speciesId
|
||||||
|
colorId: $colorId
|
||||||
|
pose: SAD_MASC
|
||||||
|
) {
|
||||||
|
...PetAppearanceForPosePicker
|
||||||
|
}
|
||||||
|
sickMasc: petAppearance(
|
||||||
|
speciesId: $speciesId
|
||||||
|
colorId: $colorId
|
||||||
|
pose: SICK_MASC
|
||||||
|
) {
|
||||||
|
...PetAppearanceForPosePicker
|
||||||
|
}
|
||||||
|
happyFem: petAppearance(
|
||||||
|
speciesId: $speciesId
|
||||||
|
colorId: $colorId
|
||||||
|
pose: HAPPY_FEM
|
||||||
|
) {
|
||||||
|
...PetAppearanceForPosePicker
|
||||||
|
}
|
||||||
|
sadFem: petAppearance(
|
||||||
|
speciesId: $speciesId
|
||||||
|
colorId: $colorId
|
||||||
|
pose: SAD_FEM
|
||||||
|
) {
|
||||||
|
...PetAppearanceForPosePicker
|
||||||
|
}
|
||||||
|
sickFem: petAppearance(
|
||||||
|
speciesId: $speciesId
|
||||||
|
colorId: $colorId
|
||||||
|
pose: SICK_FEM
|
||||||
|
) {
|
||||||
|
...PetAppearanceForPosePicker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment PetAppearanceForPosePicker on PetAppearance {
|
||||||
|
id
|
||||||
|
petStateId
|
||||||
|
bodyId
|
||||||
|
pose
|
||||||
|
...PetAppearanceForOutfitPreview
|
||||||
}
|
}
|
||||||
${petAppearanceFragment}
|
${petAppearanceFragment}
|
||||||
`,
|
`,
|
||||||
{ variables: { speciesId, colorId } }
|
{ variables: { speciesId, colorId } }
|
||||||
);
|
);
|
||||||
|
|
||||||
const petAppearances = data?.petAppearances || [];
|
|
||||||
const buildPoseInfo = (pose) => {
|
|
||||||
const appearance = petAppearances.find((pa) => pa.pose === pose);
|
|
||||||
return {
|
|
||||||
...appearance,
|
|
||||||
isAvailable: Boolean(appearance),
|
|
||||||
isSelected: selectedPose === pose,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const poseInfos = {
|
const poseInfos = {
|
||||||
happyMasc: buildPoseInfo("HAPPY_MASC"),
|
happyMasc: {
|
||||||
sadMasc: buildPoseInfo("SAD_MASC"),
|
...data?.happyMasc,
|
||||||
sickMasc: buildPoseInfo("SICK_MASC"),
|
isAvailable: Boolean(data?.happyMasc),
|
||||||
happyFem: buildPoseInfo("HAPPY_FEM"),
|
isSelected: selectedPose === "HAPPY_MASC",
|
||||||
sadFem: buildPoseInfo("SAD_FEM"),
|
},
|
||||||
sickFem: buildPoseInfo("SICK_FEM"),
|
sadMasc: {
|
||||||
|
...data?.sadMasc,
|
||||||
|
isAvailable: Boolean(data?.sadMasc),
|
||||||
|
isSelected: selectedPose === "SAD_MASC",
|
||||||
|
},
|
||||||
|
sickMasc: {
|
||||||
|
...data?.sickMasc,
|
||||||
|
isAvailable: Boolean(data?.sickMasc),
|
||||||
|
isSelected: selectedPose === "SICK_MASC",
|
||||||
|
},
|
||||||
|
happyFem: {
|
||||||
|
...data?.happyFem,
|
||||||
|
isAvailable: Boolean(data?.happyFem),
|
||||||
|
isSelected: selectedPose === "HAPPY_FEM",
|
||||||
|
},
|
||||||
|
sadFem: {
|
||||||
|
...data?.sadFem,
|
||||||
|
isAvailable: Boolean(data?.sadFem),
|
||||||
|
isSelected: selectedPose === "SAD_FEM",
|
||||||
|
},
|
||||||
|
sickFem: {
|
||||||
|
...data?.sickFem,
|
||||||
|
isAvailable: Boolean(data?.sickFem),
|
||||||
|
isSelected: selectedPose === "SICK_FEM",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return { loading, error, poseInfos };
|
return { loading, error, poseInfos };
|
||||||
|
|
|
@ -16,15 +16,6 @@ const typePolicies = {
|
||||||
toReference({ __typename: "Item", id }, true)
|
toReference({ __typename: "Item", id }, true)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Teach Apollo how to serve `petAppearance` queries from the cache. That
|
|
||||||
// way, when you switch pet poses, Apollo knows it already has the
|
|
||||||
// appearance data and doesn't need to ask the server again!
|
|
||||||
petAppearance: (_, { args, toReference }) => {
|
|
||||||
const { speciesId, colorId, pose } = args;
|
|
||||||
const id = `${speciesId}-${colorId}-${pose}`;
|
|
||||||
return toReference({ __typename: "PetAppearance", id }, true);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue