Add fit info to homepage
I wasn't sure how to fill the space for items that are fully modeled, then realized some basic at-a-glance "who does this fit" would help! The load time isn't great, I think I need to break out that dependent subquery, but maybe the stale-while-revalidate will cover it well enough at first.
This commit is contained in:
parent
2a5ecb688a
commit
af493f6719
3 changed files with 96 additions and 23 deletions
|
@ -385,6 +385,24 @@ function NewItemsSectionContent() {
|
|||
id
|
||||
name
|
||||
}
|
||||
compatibleBodiesAndTheirZones {
|
||||
body {
|
||||
id
|
||||
representsAllBodies
|
||||
species {
|
||||
id
|
||||
name
|
||||
}
|
||||
canonicalAppearance {
|
||||
id
|
||||
color {
|
||||
id
|
||||
name
|
||||
isStandard
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
@ -478,9 +496,46 @@ function ItemModelingSummary({ item }) {
|
|||
);
|
||||
}
|
||||
|
||||
const bodies = item.compatibleBodiesAndTheirZones.map((bz) => bz.body);
|
||||
|
||||
const fitsAllPets = bodies.some((b) => b.representsAllBodies);
|
||||
if (fitsAllPets) {
|
||||
return (
|
||||
<Box fontSize="xs" fontStyle="italic" opacity="0.8">
|
||||
For all pets
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const colors = bodies.map((b) => b.canonicalAppearance.color);
|
||||
const specialColor = colors.find((c) => !c.isStandard);
|
||||
if (specialColor && bodies.length === 1) {
|
||||
return (
|
||||
<Box fontSize="xs" fontStyle="italic" opacity="0.8">
|
||||
{specialColor.name} {bodies[0].species.name} only
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (bodies.length === 1) {
|
||||
return (
|
||||
<Box fontSize="xs" fontStyle="italic" opacity="0.8">
|
||||
{bodies[0].species.name} only
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (specialColor) {
|
||||
return (
|
||||
<Box fontSize="xs" fontStyle="italic" opacity="0.8">
|
||||
{specialColor.name} only
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box fontSize="xs" fontStyle="italic" opacity="0.8">
|
||||
Fully modeled!
|
||||
For all species
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -657,6 +657,37 @@ const buildItemAllOccupiedZonesLoader = (db) =>
|
|||
});
|
||||
});
|
||||
|
||||
const buildItemCompatibleBodiesAndTheirZonesLoader = (db) =>
|
||||
new DataLoader(async (itemIds) => {
|
||||
const qs = itemIds.map((_) => "?").join(", ");
|
||||
const [rows] = await db.query(
|
||||
`
|
||||
SELECT
|
||||
items.id as itemId,
|
||||
swf_assets.body_id AS bodyId,
|
||||
(SELECT species_id FROM pet_types WHERE body_id = bodyId LIMIT 1)
|
||||
AS speciesId,
|
||||
GROUP_CONCAT(DISTINCT swf_assets.zone_id) AS zoneIds
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = "Item"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
WHERE items.id IN (${qs})
|
||||
GROUP BY items.id, swf_assets.body_id
|
||||
-- We have some invalid data where the asset has a body ID that
|
||||
-- matches no pet type. Huh! Well, ignore those bodies!
|
||||
HAVING speciesId IS NOT NULL OR bodyId = 0;
|
||||
`,
|
||||
itemIds
|
||||
);
|
||||
|
||||
const entities = rows.map(normalizeRow);
|
||||
|
||||
return itemIds.map((itemId) => entities.filter((e) => e.itemId === itemId));
|
||||
});
|
||||
|
||||
const buildItemTradesLoader = (db, loaders) =>
|
||||
new DataLoader(
|
||||
async (itemIdOwnedPairs) => {
|
||||
|
@ -1368,6 +1399,9 @@ function buildLoaders(db) {
|
|||
db
|
||||
);
|
||||
loaders.itemAllOccupiedZonesLoader = buildItemAllOccupiedZonesLoader(db);
|
||||
loaders.itemCompatibleBodiesAndTheirZonesLoader = buildItemCompatibleBodiesAndTheirZonesLoader(
|
||||
db
|
||||
);
|
||||
loaders.itemTradesLoader = buildItemTradesLoader(db, loaders);
|
||||
loaders.itemWakaValueLoader = buildItemWakaValueLoader();
|
||||
loaders.petTypeLoader = buildPetTypeLoader(db, loaders);
|
||||
|
|
|
@ -559,28 +559,12 @@ const resolvers = {
|
|||
const bodies = bodyIds.map((id) => ({ id }));
|
||||
return bodies;
|
||||
},
|
||||
compatibleBodiesAndTheirZones: async ({ id }, _, { db }) => {
|
||||
const [rows] = await db.query(
|
||||
`
|
||||
SELECT
|
||||
swf_assets.body_id AS bodyId,
|
||||
(SELECT species_id FROM pet_types WHERE body_id = bodyId LIMIT 1)
|
||||
AS speciesId,
|
||||
GROUP_CONCAT(DISTINCT swf_assets.zone_id) AS zoneIds
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = "Item"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
WHERE items.id = ?
|
||||
GROUP BY swf_assets.body_id
|
||||
-- We have some invalid data where the asset has a body ID that
|
||||
-- matches no pet type. Huh! Well, ignore those bodies!
|
||||
HAVING speciesId IS NOT NULL OR bodyId = 0;
|
||||
`,
|
||||
[id]
|
||||
);
|
||||
compatibleBodiesAndTheirZones: async (
|
||||
{ id },
|
||||
_,
|
||||
{ itemCompatibleBodiesAndTheirZonesLoader }
|
||||
) => {
|
||||
const rows = await itemCompatibleBodiesAndTheirZonesLoader.load(id);
|
||||
return rows.map((row) => ({
|
||||
body: {
|
||||
id: row.bodyId,
|
||||
|
|
Loading…
Reference in a new issue