impress/app/javascript/wardrobe-2020/loaders/alt-styles.js
Emi Matchu 56d550e86c Skip loading alt styles on item preview page
Ah yeah, if you're not on the wardrobe page (so we don't need the Alt
Styles UI), and the outfit's `altStyleId` is null (as is the case for
the item preview page), then there's no need to load the alt styles for
that species.

So before this change, going to `/items/123` would include an XHR
request to `/species/<id>/alt-styles.json`, which would not be used for
anything. After this change, that request is no longer sent. Hooray!
2024-02-24 17:23:57 -08:00

83 lines
2.2 KiB
JavaScript

import { useQuery } from "@tanstack/react-query";
export function useAltStylesForSpecies(speciesId, options = {}) {
return useQuery({
...options,
queryKey: ["altStylesForSpecies", String(speciesId)],
queryFn: () => loadAltStylesForSpecies(speciesId),
enabled: (options.enabled ?? true) && speciesId != null,
});
}
// NOTE: This is actually just a wrapper for `useAltStylesForSpecies`, to share
// the same cache key!
export function useAltStyle(id, speciesId, options = {}) {
const query = useAltStylesForSpecies(speciesId, {
...options,
enabled: (options.enabled ?? true) && id != null,
});
return {
...query,
data: query.data?.find((s) => s.id === id) ?? null,
};
}
async function loadAltStylesForSpecies(speciesId) {
const res = await fetch(
`/species/${encodeURIComponent(speciesId)}/alt-styles.json`,
);
if (!res.ok) {
throw new Error(
`loading alt styles failed: ${res.status} ${res.statusText}`,
);
}
return res.json().then(normalizeAltStyles);
}
function normalizeAltStyles(altStylesData) {
return altStylesData.map(normalizeAltStyle);
}
function normalizeAltStyle(altStyleData) {
return {
id: String(altStyleData.id),
speciesId: String(altStyleData.species_id),
colorId: String(altStyleData.color_id),
bodyId: String(altStyleData.body_id),
seriesName: altStyleData.series_name,
adjectiveName: altStyleData.adjective_name,
thumbnailUrl: altStyleData.thumbnail_url,
// This matches the PetAppearanceForOutfitPreview GQL fragment!
appearance: {
bodyId: String(altStyleData.body_id),
pose: "UNKNOWN",
isGlitched: false,
species: { id: String(altStyleData.species_id) },
color: { id: String(altStyleData.species_id) },
layers: altStyleData.swf_assets.map(normalizeSwfAssetToLayer),
restrictedZones: [],
},
};
}
function normalizeSwfAssetToLayer(swfAssetData) {
return {
id: String(swfAssetData.id),
zone: {
id: String(swfAssetData.zone.id),
depth: swfAssetData.zone.depth,
label: swfAssetData.zone.label,
},
bodyId: swfAssetData.body_id,
knownGlitches: swfAssetData.known_glitches,
svgUrl: swfAssetData.urls.svg,
canvasMovieLibraryUrl: swfAssetData.urls.canvas_library,
imageUrl: swfAssetData.urls.png,
swfUrl: swfAssetData.urls.swf,
};
}