diff --git a/src/app/components/useOutfitAppearance.js b/src/app/components/useOutfitAppearance.js index ecae211..95ff445 100644 --- a/src/app/components/useOutfitAppearance.js +++ b/src/app/components/useOutfitAppearance.js @@ -116,6 +116,7 @@ export function getVisibleLayers(petAppearance, itemAppearances) { export const itemAppearanceFragment = gql` fragment ItemAppearanceForOutfitPreview on ItemAppearance { + id layers { id remoteId # HACK: This is for Support tools, but other views don't need it @@ -129,7 +130,6 @@ export const itemAppearanceFragment = gql` label @client # HACK: This is for Support tools, but other views don't need it } } - restrictedZones { id } diff --git a/src/server/index.js b/src/server/index.js index 2113535..8e45e3b 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -71,7 +71,10 @@ const typeDefs = gql` thumbnailUrl: String! rarityIndex: Int! isNc: Boolean! - appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance + + # How this item appears on the given species/color combo. If it does not + # fit the pet, we'll return an empty ItemAppearance with no layers. + appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance! # This is set manually by Support users, when the pet is only for e.g. # Maraquan pets, and our usual auto-detection isn't working. We provide @@ -101,7 +104,10 @@ const typeDefs = gql` } type ItemAppearance { - layers: [AppearanceLayer!]! + id: ID! + item: Item! + bodyId: ID! + layers: [AppearanceLayer!] restrictedZones: [Zone!]! } @@ -275,37 +281,13 @@ const resolvers = { appearanceOn: async ( { id }, { speciesId, colorId }, - { petTypeBySpeciesAndColorLoader, itemSwfAssetLoader, itemLoader } + { petTypeBySpeciesAndColorLoader } ) => { - const itemPromise = itemLoader.load(id); const petType = await petTypeBySpeciesAndColorLoader.load({ - speciesId: speciesId, - colorId: colorId, + speciesId, + colorId, }); - const allSwfAssets = await itemSwfAssetLoader.load({ - itemId: id, - bodyId: petType.bodyId, - }); - - if (allSwfAssets.length === 0) { - // If there's no assets at all, treat it as non-fitting: no appearance. - // (If there are assets but they're non-SWF, we'll treat this as - // fitting, but with an *empty* appearance.) - return null; - } - - const swfAssets = allSwfAssets.filter((sa) => sa.url.endsWith(".swf")); - - const restrictedZones = []; - const item = await itemPromise; - for (const [i, bit] of Array.from(item.zonesRestrict).entries()) { - if (bit === "1") { - const zone = { id: i + 1 }; - restrictedZones.push(zone); - } - } - - return { layers: swfAssets, restrictedZones }; + return { item: { id }, bodyId: petType.bodyId }; }, manualSpecialColor: async ({ id }, _, { itemLoader }) => { const item = await itemLoader.load(id); @@ -318,6 +300,28 @@ const resolvers = { return item.explicitlyBodySpecific; }, }, + ItemAppearance: { + id: ({ item, bodyId }) => `item-${item.id}-body-${bodyId}`, + layers: async ({ item, bodyId }, _, { itemSwfAssetLoader }) => { + const allSwfAssets = await itemSwfAssetLoader.load({ + itemId: item.id, + bodyId, + }); + + return allSwfAssets.filter((sa) => sa.url.endsWith(".swf")); + }, + restrictedZones: async ({ item: { id: itemId } }, _, { itemLoader }) => { + const item = await itemLoader.load(itemId); + const restrictedZones = []; + for (const [i, bit] of Array.from(item.zonesRestrict).entries()) { + if (bit === "1") { + const zone = { id: i + 1 }; + restrictedZones.push(zone); + } + } + return restrictedZones; + }, + }, PetAppearance: { color: async ({ id }, _, { petStateLoader, petTypeLoader }) => { const petState = await petStateLoader.load(id); diff --git a/src/server/query-tests/Item.test.js b/src/server/query-tests/Item.test.js index 774b0b9..f91c10a 100644 --- a/src/server/query-tests/Item.test.js +++ b/src/server/query-tests/Item.test.js @@ -102,14 +102,6 @@ describe("Item", () => { "37375", ], ], - Array [ - "SELECT * FROM items WHERE id IN (?,?,?)", - Array [ - "38912", - "38911", - "37375", - ], - ], Array [ "SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)", Array [ @@ -132,6 +124,14 @@ describe("Item", () => { "180", ], ], + Array [ + "SELECT * FROM items WHERE id IN (?,?,?)", + Array [ + "38912", + "38911", + "37375", + ], + ], Array [ "SELECT * FROM zones WHERE id IN (?,?,?)", Array [ @@ -191,12 +191,6 @@ describe("Item", () => { "42829", ], ], - Array [ - "SELECT * FROM items WHERE id IN (?)", - Array [ - "42829", - ], - ], Array [ "SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)", Array [ @@ -215,6 +209,12 @@ describe("Item", () => { "180", ], ], + Array [ + "SELECT * FROM items WHERE id IN (?)", + Array [ + "42829", + ], + ], ] `); }); diff --git a/src/server/query-tests/__snapshots__/Item.test.js.snap b/src/server/query-tests/__snapshots__/Item.test.js.snap index 4675b65..b5c1fc4 100644 --- a/src/server/query-tests/__snapshots__/Item.test.js.snap +++ b/src/server/query-tests/__snapshots__/Item.test.js.snap @@ -62,7 +62,7 @@ Object { "layers": Array [ Object { "id": "30203", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-0", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-1598519675000", "remoteId": "6829", "svgUrl": null, "zone": Object {