diff --git a/src/app/SupportPetAppearancesPage.js b/src/app/SupportPetAppearancesPage.js index 287c5eb..b0b1dfe 100644 --- a/src/app/SupportPetAppearancesPage.js +++ b/src/app/SupportPetAppearancesPage.js @@ -10,10 +10,6 @@ import { } from "@chakra-ui/popover"; import { Link } from "react-router-dom"; import HangerSpinner from "./components/HangerSpinner"; -import { - getValidPoses, - useAllValidPetPoses, -} from "./components/SpeciesColorPicker"; import { ErrorMessage, Heading1 } from "./util"; import useSupport from "./WardrobePage/support/useSupport"; @@ -27,16 +23,6 @@ function SupportPetAppearancesPage() { return ( <> Support: Pet appearances - - - ); -} - -function UnlabeledPetAppearancesList() { - const { loading, error, speciesColorPairs } = useUnlabeledPetAppearances(); - - return ( - These species/color combinations have some UNKNOWN{" "} appearances that need labeled! Please take a look! @@ -48,28 +34,67 @@ function UnlabeledPetAppearancesList() { This includes species/color combinations that have at least one{" "} - UNKNOWN pose, and are missing at least one of the - standard 6 mood/gender-presentation poses. + non-glitched UNKNOWN pose, and still need a + non-glitched version of at least one of the standard 6 + mood/gender-presentation poses. - {loading && ( - - - - )} - {error && {error.message}} - {speciesColorPairs.length > 0 && ( - - {speciesColorPairs.map(({ species, color }) => ( - - - - ))} - - )} - + + + ); +} + +function UnlabeledPetAppearancesList() { + const { loading, error, data } = useQuery(gql` + query SupportUnlabeledSpeciesColorPairs { + speciesColorPairsThatNeedSupportLabeling { + id + species { + id + name + } + color { + id + name + } + } + } + `); + + if (loading) { + return ( + + + + ); + } + + if (error) { + return {error.message}; + } + + const speciesColorPairs = [ + ...data.speciesColorPairsThatNeedSupportLabeling, + ].sort((a, b) => + `${a.species.name} ${a.color.name}`.localeCompare( + `${b.species.name} ${b.color.name}` + ) + ); + + if (speciesColorPairs.length === 0) { + return <>…never mind, they're all done! Wow, go team!! 🎉; + } + + return ( + + {speciesColorPairs.map(({ species, color }) => ( + + + + ))} + ); } @@ -91,57 +116,4 @@ function SpeciesColorEditorLink({ species, color }) { ); } -function useUnlabeledPetAppearances() { - const { - loading: loadingValids, - error: errorValids, - valids, - } = useAllValidPetPoses({ headers: { "Cache-Control": "no-cache" } }); - const { loading: loadingGQL, error: errorGQL, data } = useQuery(gql` - query SupportUnlabeledPetAppearances { - allColors { - id - name - } - - allSpecies { - id - name - } - } - `); - - const loading = loadingValids || loadingGQL; - const error = errorValids || errorGQL; - const speciesColorPairs = - valids && data?.allColors && data?.allSpecies - ? data?.allSpecies - .map((species) => data.allColors.map((color) => ({ species, color }))) - .flat() - .filter(({ species, color }) => { - const poses = getValidPoses(valids, species.id, color.id); - const hasAllStandardPoses = - poses.has("HAPPY_MASC") && - poses.has("HAPPY_FEM") && - poses.has("SAD_MASC") && - poses.has("SAD_FEM") && - poses.has("SICK_MASC") && - poses.has("SICK_FEM"); - const hasAtLeastOneUnknownPose = poses.has("UNKNOWN"); - return !hasAllStandardPoses && hasAtLeastOneUnknownPose; - }) - .sort((a, b) => - `${a.species.name} ${a.color.name}`.localeCompare( - `${b.species.name} ${b.color.name}` - ) - ) - : []; - - return { - loading, - error, - speciesColorPairs, - }; -} - export default SupportPetAppearancesPage; diff --git a/src/server/types/PetAppearance.js b/src/server/types/PetAppearance.js index 926ce25..2c64948 100644 --- a/src/server/types/PetAppearance.js +++ b/src/server/types/PetAppearance.js @@ -4,6 +4,7 @@ import { capitalize, getPoseFromPetState, getRestrictedZoneIds, + normalizeRow, oneWeek, oneDay, oneHour, @@ -115,6 +116,11 @@ const typeDefs = gql` # version here (even if the standard pose picker is still showing outdated # cached canonical poses). petAppearances(speciesId: ID!, colorId: ID!): [PetAppearance!]! + + # The SpeciesColorPairs that don't have all 6 standard poses labeled yet, + # and have at least one UNKNOWN pose to label. For Support users, on + # /support/petAppearances. + speciesColorPairsThatNeedSupportLabeling: [SpeciesColorPair!]! } `; @@ -387,6 +393,40 @@ const resolvers = { const petStates = await petStatesForPetTypeLoader.load(petType.id); return petStates.map((petState) => ({ id: petState.id })); }, + speciesColorPairsThatNeedSupportLabeling: async ( + _, + __, + { db, petTypeLoader } + ) => { + const [rows] = await db.query( + ` + SELECT * FROM pet_types WHERE + -- Does not have all 6 standard poses + ( + SELECT COUNT(DISTINCT mood_id, female) + FROM pet_states + WHERE + pet_type_id = pet_types.id AND mood_id IS NOT NULL AND female IS NOT NULL AND glitched = 0 + ) < 6 + -- And has at least one of the UNKNOWN pose + AND ( + SELECT COUNT(*) + FROM pet_states + WHERE + pet_type_id = pet_types.id + AND mood_id IS NULL AND female IS NULL + AND (unconverted = 0 OR unconverted IS NULL) + AND glitched = 0 + ) >= 1; + ` + ); + const petTypes = rows.map(normalizeRow); + + // Prime the cache, so the resolvers downstream don't re-query for them. + petTypes.forEach((petType) => petTypeLoader.prime(petType.id, petType)); + + return petTypes.map(({ id }) => ({ id })); + }, }, };