diff --git a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js index 3a22fc3a..4d956ede 100644 --- a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js +++ b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js @@ -495,7 +495,8 @@ function getOutfitStateFromOutfitData(outfit) { function findItemConflicts(itemIdToAdd, state, apolloClient) { const { wornItemIds, speciesId, colorId, altStyleId } = state; - const { items } = apolloClient.readQuery({ + const itemIds = [itemIdToAdd, ...wornItemIds]; + const data = apolloClient.readQuery({ query: gql` query OutfitStateItemConflicts( $itemIds: [ID!]! @@ -524,12 +525,21 @@ function findItemConflicts(itemIdToAdd, state, apolloClient) { } `, variables: { - itemIds: [itemIdToAdd, ...wornItemIds], + itemIds, speciesId, colorId, altStyleId, }, }); + if (data == null) { + throw new Error( + `[findItemConflicts] Cache lookup failed for: ` + + `items=${itemIds.join(",")}, speciesId=${speciesId}, ` + + `colorId=${colorId}, altStyleId=${altStyleId}`, + ); + } + + const { items } = data; const itemToAdd = items.find((i) => i.id === itemIdToAdd); if (!itemToAdd.appearanceOn) { return []; diff --git a/app/javascript/wardrobe-2020/loaders/items.js b/app/javascript/wardrobe-2020/loaders/items.js index 36ac315f..8c23b4ef 100644 --- a/app/javascript/wardrobe-2020/loaders/items.js +++ b/app/javascript/wardrobe-2020/loaders/items.js @@ -1,5 +1,7 @@ +import gql from "graphql-tag"; import { useQuery } from "@tanstack/react-query"; +import apolloClient from "../apolloClient"; import { normalizeSwfAssetToLayer, normalizeZone } from "./shared-types"; export function useItemAppearances(id, options = {}) { @@ -87,12 +89,77 @@ async function loadItemSearch(searchOptions) { ); } - return res - .json() - .then((data) => normalizeItemSearchData(data, searchOptions)); + const data = await res.json(); + const result = normalizeItemSearchData(data, searchOptions); + + for (const item of result.items) { + writeItemToApolloCache(item, searchOptions.withAppearancesFor); + } + + return result; } window.loadItemSearch = loadItemSearch; +/** + * writeItemToApolloCache is one last important bridge between our loaders and + * GQL! In `useOutfitState`, we consult the GraphQL cache to look up basic item + * info like zones, to decide when wearing an item would trigger a conflict + * with another. + */ +function writeItemToApolloCache(item, { speciesId, colorId, altStyleId }) { + apolloClient.writeQuery({ + query: gql` + query WriteItemFromLoader( + $itemId: ID! + $speciesId: ID! + $colorId: ID! + $altStyleId: ID + ) { + item(id: $itemId) { + id + name + thumbnailUrl + isNc + isPb + currentUserOwnsThis + currentUserWantsThis + appearanceOn( + speciesId: $speciesId + colorId: $colorId + altStyleId: $altStyleId + ) { + id + layers { + id + remoteId + bodyId + knownGlitches + svgUrl + canvasMovieLibraryUrl + imageUrl + swfUrl + zone { + id + } + } + + restrictedZones { + id + } + } + } + } + `, + variables: { + itemId: item.id, + speciesId, + colorId, + altStyleId, + }, + data: { item }, + }); +} + function normalizeItemAppearancesData(data) { return { name: data.name, @@ -106,9 +173,11 @@ function normalizeItemAppearancesData(data) { function normalizeItemSearchData(data, searchOptions) { return { + __typename: "ItemSearchResultV2", id: buildItemSearchParams(searchOptions), numTotalPages: data.total_pages, items: data.items.map((item) => ({ + __typename: "Item", id: String(item.id), name: item.name, thumbnailUrl: item.thumbnail_url, @@ -130,6 +199,7 @@ function normalizeItemSearchAppearance(data, item) { } return { + __typename: "ItemAppearance", id: `item-${item.id}-body-${data.body.id}`, layers: data.swf_assets.map(normalizeSwfAssetToLayer), restrictedZones: data.swf_assets @@ -145,6 +215,7 @@ function normalizeBody(body) { } return { + __typename: "Body", id: String(body.id), species: { id: String(body.species.id), diff --git a/app/javascript/wardrobe-2020/loaders/shared-types.js b/app/javascript/wardrobe-2020/loaders/shared-types.js index 9558e2f3..3736dff4 100644 --- a/app/javascript/wardrobe-2020/loaders/shared-types.js +++ b/app/javascript/wardrobe-2020/loaders/shared-types.js @@ -1,5 +1,6 @@ export function normalizeSwfAssetToLayer(data) { return { + __typename: "AppearanceLayer", id: String(data.id), remoteId: String(data.remote_id), zone: normalizeZone(data.zone), @@ -15,6 +16,7 @@ export function normalizeSwfAssetToLayer(data) { export function normalizeZone(data) { return { + __typename: "Zone", id: String(data.id), depth: data.depth, label: data.label,