add items to outfit thumbnails
Now that wasn't so hard! :3
This commit is contained in:
parent
9a2308fd41
commit
b01feba038
3 changed files with 73 additions and 6 deletions
|
@ -7,6 +7,7 @@ import { ErrorMessage, Heading1 } from "./util";
|
|||
import {
|
||||
getVisibleLayers,
|
||||
petAppearanceFragmentForGetVisibleLayers,
|
||||
itemAppearanceFragmentForGetVisibleLayers,
|
||||
} from "./components/useOutfitAppearance";
|
||||
import HangerSpinner from "./components/HangerSpinner";
|
||||
import useRequireLogin from "./components/useRequireLogin";
|
||||
|
@ -43,10 +44,20 @@ function UserOutfitsPageContent() {
|
|||
}
|
||||
...PetAppearanceForGetVisibleLayers
|
||||
}
|
||||
itemAppearances {
|
||||
id
|
||||
layers {
|
||||
id
|
||||
svgUrl
|
||||
imageUrl(size: $size)
|
||||
}
|
||||
...ItemAppearanceForGetVisibleLayers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${petAppearanceFragmentForGetVisibleLayers}
|
||||
${itemAppearanceFragmentForGetVisibleLayers}
|
||||
`,
|
||||
{ variables: { size: "SIZE_" + getBestImageSize() }, skip: userLoading }
|
||||
);
|
||||
|
@ -77,7 +88,10 @@ function UserOutfitsPageContent() {
|
|||
}
|
||||
|
||||
function OutfitCard({ outfit }) {
|
||||
const thumbnailUrl = buildOutfitThumbnailUrl(outfit.petAppearance, []);
|
||||
const thumbnailUrl = buildOutfitThumbnailUrl(
|
||||
outfit.petAppearance,
|
||||
outfit.itemAppearances
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
@ -105,6 +119,14 @@ function buildOutfitThumbnailUrl(petAppearance, itemAppearances) {
|
|||
return `/api/outfitImage?size=${size}&layerUrls=${layerUrls.join(",")}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* getBestImageSize returns the right image size to render at 150x150, for the
|
||||
* current device.
|
||||
*
|
||||
* On high-DPI devices, we'll download a 300x300 image to render at 150x150
|
||||
* scale. On standard-DPI devices, we'll download a 150x150 image, to save
|
||||
* bandwidth.
|
||||
*/
|
||||
function getBestImageSize() {
|
||||
if (window.devicePixelRatio > 1) {
|
||||
return 300;
|
||||
|
|
|
@ -137,6 +137,22 @@ export function getVisibleLayers(petAppearance, itemAppearances) {
|
|||
return visibleLayers;
|
||||
}
|
||||
|
||||
export const itemAppearanceFragmentForGetVisibleLayers = gql`
|
||||
fragment ItemAppearanceForGetVisibleLayers on ItemAppearance {
|
||||
id
|
||||
layers {
|
||||
id
|
||||
zone {
|
||||
id
|
||||
depth @client
|
||||
}
|
||||
}
|
||||
restrictedZones {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const itemAppearanceFragment = gql`
|
||||
fragment ItemAppearanceForOutfitPreview on ItemAppearance {
|
||||
id
|
||||
|
@ -149,15 +165,13 @@ export const itemAppearanceFragment = gql`
|
|||
swfUrl # HACK: This is for Support tools, but other views don't need it
|
||||
bodyId
|
||||
zone {
|
||||
id
|
||||
depth @client
|
||||
label @client # HACK: This is for Support tools, but other views don't need it
|
||||
}
|
||||
}
|
||||
restrictedZones {
|
||||
id
|
||||
}
|
||||
...ItemAppearanceForGetVisibleLayers
|
||||
}
|
||||
|
||||
${itemAppearanceFragmentForGetVisibleLayers}
|
||||
`;
|
||||
|
||||
export const petAppearanceFragmentForGetVisibleLayers = gql`
|
||||
|
|
|
@ -7,6 +7,10 @@ const typeDefs = gql`
|
|||
petAppearance: PetAppearance!
|
||||
wornItems: [Item!]!
|
||||
closetedItems: [Item!]!
|
||||
|
||||
# This is a convenience field: you could query this from the combination of
|
||||
# petAppearance and wornItems, but this gets you it in one shot!
|
||||
itemAppearances: [ItemAppearance!]!
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
|
@ -24,6 +28,33 @@ const resolvers = {
|
|||
const outfit = await outfitLoader.load(id);
|
||||
return { id: outfit.petStateId };
|
||||
},
|
||||
itemAppearances: async (
|
||||
{ id },
|
||||
_,
|
||||
{
|
||||
outfitLoader,
|
||||
petStateLoader,
|
||||
petTypeLoader,
|
||||
itemOutfitRelationshipsLoader,
|
||||
}
|
||||
) => {
|
||||
const [petType, relationships] = await Promise.all([
|
||||
outfitLoader
|
||||
.load(id)
|
||||
.then((outfit) => petStateLoader.load(outfit.petStateId))
|
||||
.then((petState) => petTypeLoader.load(petState.petTypeId)),
|
||||
itemOutfitRelationshipsLoader.load(id),
|
||||
]);
|
||||
|
||||
const wornItemIds = relationships
|
||||
.filter((oir) => oir.isWorn)
|
||||
.map((oir) => oir.itemId);
|
||||
|
||||
return wornItemIds.map((itemId) => ({
|
||||
item: { id: itemId },
|
||||
bodyId: petType.bodyId,
|
||||
}));
|
||||
},
|
||||
wornItems: async ({ id }, _, { itemOutfitRelationshipsLoader }) => {
|
||||
const relationships = await itemOutfitRelationshipsLoader.load(id);
|
||||
return relationships
|
||||
|
|
Loading…
Reference in a new issue