From f50de9b11e1046015e9aa892194650f55c7ad85b Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 25 Jan 2021 10:24:39 -0800 Subject: [PATCH] Add species-face picker to item page previews Note that it doesn't do any compatibility checking, graying out, hiding unneeded faces, etc. They just exist now is all! --- src/app/ItemPage.js | 603 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 528 insertions(+), 75 deletions(-) diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js index 5588282..fe811c3 100644 --- a/src/app/ItemPage.js +++ b/src/app/ItemPage.js @@ -14,6 +14,10 @@ import { useColorModeValue, useTheme, useToast, + useToken, + Stack, + Wrap, + WrapItem, } from "@chakra-ui/react"; import { CheckIcon, @@ -27,7 +31,7 @@ import { useQuery, useMutation } from "@apollo/client"; import { Link, useParams } from "react-router-dom"; import ItemPageLayout, { SubtleSkeleton } from "./ItemPageLayout"; -import { Delay, usePageTitle } from "./util"; +import { Delay, ErrorMessage, usePageTitle } from "./util"; import { itemAppearanceFragment, petAppearanceFragment, @@ -601,90 +605,539 @@ function ItemPageOutfitPreview({ itemId }) { const isIncompatible = Array.isArray(layers) && layers.length === 0; return ( - - - - + + + + + {hasAnimations && ( + setIsPaused(!isPaused)} + /> + )} + + + + + { + setPetState({ + speciesId: species.id, + colorId: color.id, + pose: closestPose, + appearanceId: null, + }); + }} + size="sm" + showPlaceholders + // This is just a UX affordance: while we could handle invalid states + // from a UI perspective, we figure that, if a pet preview is already + // visible and responsive to changes, it feels better to treat the + // changes as atomic and always-valid. + stateMustAlwaysBeValid /> - {hasAnimations && ( - : } - aria-label={isPaused ? "Play" : "Pause"} - onClick={() => setIsPaused(!isPaused)} - borderRadius="full" - boxShadow="md" - color="gray.50" - backgroundColor="blackAlpha.700" - position="absolute" - bottom="2" - left="2" - _hover={{ backgroundColor: "blackAlpha.900" }} - _focus={{ backgroundColor: "blackAlpha.900" }} - /> - )} + + {isIncompatible && ( + + + + )} + - - - - { + + + setPetState({ - speciesId: species.id, - colorId: color.id, - pose: closestPose, + speciesId, + colorId, + pose: idealPose, appearanceId: null, - }); - }} - size="sm" - showPlaceholders - // This is just a UX affordance: while we could handle invalid states - // from a UI perspective, we figure that, if a pet preview is already - // visible and responsive to changes, it feels better to treat the - // changes as atomic and always-valid. - stateMustAlwaysBeValid + }) + } + isLoading={loading} /> - - {isIncompatible && ( - - - - )} - - + ); } +function PlayPauseButton({ isPaused, onClick }) { + return ( + : } + aria-label={isPaused ? "Play" : "Pause"} + onClick={onClick} + borderRadius="full" + boxShadow="md" + color="gray.50" + backgroundColor="blackAlpha.700" + position="absolute" + bottom="2" + left="2" + _hover={{ backgroundColor: "blackAlpha.900" }} + _focus={{ backgroundColor: "blackAlpha.900" }} + /> + ); +} + +function SpeciesFacesPicker({ + itemId, + selectedSpeciesId, + onChange, + isLoading, +}) { + const selectedBorderColor = useColorModeValue("green.600", "green.400"); + const selectedBackgroundColor = useColorModeValue("green.200", "green.600"); + const [ + selectedBorderColorValue, + selectedBackgroundColorValue, + ] = useToken("colors", [selectedBorderColor, selectedBackgroundColor]); + + const allSpeciesFaces = speciesFaces.sort((a, b) => + a.speciesName.localeCompare(b.speciesName) + ); + + return ( + + {({ css }) => ( + + {allSpeciesFaces.map(({ speciesId, speciesName, colorId, src }) => ( + + onChange({ speciesId, colorId })} + /> + + & { + opacity: 1; + filter: saturate(110%); + } + `} + /> + + + ))} + + )} + + ); +} + +// HACK: I'm just hardcoding all this, rather than connecting up to the +// database and adding a loading state. Tbh I'm not sure it's a good idea +// to load this dynamically until we have SSR to make it come in fast! +// And it's not so bad if this gets out of sync with the database, +// because the SpeciesColorPicker will still be usable! +const colors = { BLUE: "8", RED: "61", GREEN: "34", YELLOW: "84" }; +const speciesFaces = [ + { + speciesId: "1", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/obxdjm88/1/1.png", + colorId: colors.GREEN, + speciesName: "Acara", + }, + { + speciesId: "2", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/n9ozx4z5/1/1.png", + colorId: colors.BLUE, + speciesName: "Aisha", + }, + { + speciesId: "3", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/kfonqhdc/1/1.png", + colorId: colors.YELLOW, + speciesName: "Blumaroo", + }, + { + speciesId: "4", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/sc2hhvhn/1/1.png", + colorId: colors.YELLOW, + speciesName: "Bori", + }, + { + speciesId: "5", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/wqz8xn4t/1/1.png", + colorId: colors.YELLOW, + speciesName: "Bruce", + }, + { + speciesId: "6", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jc9klfxm/1/1.png", + colorId: colors.YELLOW, + speciesName: "Buzz", + }, + { + speciesId: "7", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/4lrb4n3f/1/1.png", + colorId: colors.RED, + speciesName: "Chia", + }, + { + speciesId: "8", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/bdml26md/1/1.png", + colorId: colors.YELLOW, + speciesName: "Chomby", + }, + { + speciesId: "9", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/xl6msllv/1/1.png", + colorId: colors.GREEN, + speciesName: "Cybunny", + }, + { + speciesId: "10", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/bob39shq/1/1.png", + colorId: colors.YELLOW, + speciesName: "Draik", + }, + { + speciesId: "11", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jhhhbrww/1/1.png", + colorId: colors.RED, + speciesName: "Elephante", + }, + { + speciesId: "12", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/6kngmhvs/1/1.png", + colorId: colors.RED, + speciesName: "Eyrie", + }, + { + speciesId: "13", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/47vt32x2/1/1.png", + colorId: colors.GREEN, + speciesName: "Flotsam", + }, + { + speciesId: "14", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/5nrd2lvd/1/1.png", + colorId: colors.YELLOW, + speciesName: "Gelert", + }, + { + speciesId: "15", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/6c275jcg/1/1.png", + colorId: colors.BLUE, + speciesName: "Gnorbu", + }, + { + speciesId: "16", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/j7q65fv4/1/1.png", + colorId: colors.BLUE, + speciesName: "Grarrl", + }, + { + speciesId: "17", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/5xn4kjf8/1/1.png", + colorId: colors.GREEN, + speciesName: "Grundo", + }, + { + speciesId: "18", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jsfvcqwt/1/1.png", + colorId: colors.RED, + speciesName: "Hissi", + }, + { + speciesId: "19", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/w32r74vo/1/1.png", + colorId: colors.GREEN, + speciesName: "Ixi", + }, + { + speciesId: "20", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/kz43rnld/1/1.png", + colorId: colors.YELLOW, + speciesName: "Jetsam", + }, + { + speciesId: "21", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/m267j935/1/1.png", + colorId: colors.GREEN, + speciesName: "Jubjub", + }, + { + speciesId: "22", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/4gsrb59g/1/1.png", + colorId: colors.YELLOW, + speciesName: "Kacheek", + }, + { + speciesId: "23", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/ktlxmrtr/1/1.png", + colorId: colors.BLUE, + speciesName: "Kau", + }, + { + speciesId: "24", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/42j5q3zx/1/1.png", + colorId: colors.GREEN, + speciesName: "Kiko", + }, + { + speciesId: "25", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/ncfn87wk/1/1.png", + colorId: colors.GREEN, + speciesName: "Koi", + }, + { + speciesId: "26", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/omx9c876/1/1.png", + colorId: colors.RED, + speciesName: "Korbat", + }, + { + speciesId: "27", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/rfsbh59t/1/1.png", + colorId: colors.BLUE, + speciesName: "Kougra", + }, + { + speciesId: "28", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/hxgsm5d4/1/1.png", + colorId: colors.BLUE, + speciesName: "Krawk", + }, + { + speciesId: "29", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/blxmjgbk/1/1.png", + colorId: colors.YELLOW, + speciesName: "Kyrii", + }, + { + speciesId: "30", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/8r94jhfq/1/1.png", + colorId: colors.YELLOW, + speciesName: "Lenny", + }, + { + speciesId: "31", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/z42535zh/1/1.png", + colorId: colors.YELLOW, + speciesName: "Lupe", + }, + { + speciesId: "32", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/qgg6z8s7/1/1.png", + colorId: colors.BLUE, + speciesName: "Lutari", + }, + { + speciesId: "33", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/kk2nn2jr/1/1.png", + colorId: colors.YELLOW, + speciesName: "Meerca", + }, + { + speciesId: "34", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jgkoro5z/1/1.png", + colorId: colors.GREEN, + speciesName: "Moehog", + }, + { + speciesId: "35", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/xwlo9657/1/1.png", + colorId: colors.BLUE, + speciesName: "Mynci", + }, + { + speciesId: "36", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/bx7fho8x/1/1.png", + colorId: colors.BLUE, + speciesName: "Nimmo", + }, + { + speciesId: "37", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/rjzmx24v/1/1.png", + colorId: colors.YELLOW, + speciesName: "Ogrin", + }, + { + speciesId: "38", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/kokc52kh/1/1.png", + colorId: colors.RED, + speciesName: "Peophin", + }, + { + speciesId: "39", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/fw6lvf3c/1/1.png", + colorId: colors.GREEN, + speciesName: "Poogle", + }, + { + speciesId: "40", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/tjhwbro3/1/1.png", + colorId: colors.RED, + speciesName: "Pteri", + }, + { + speciesId: "41", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jdto7mj4/1/1.png", + colorId: colors.YELLOW, + speciesName: "Quiggle", + }, + { + speciesId: "42", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/qsgbm5f6/1/1.png", + colorId: colors.BLUE, + speciesName: "Ruki", + }, + { + speciesId: "43", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/hkjoncsx/1/1.png", + colorId: colors.RED, + speciesName: "Scorchio", + }, + { + speciesId: "44", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/mmvn4tkg/1/1.png", + colorId: colors.YELLOW, + speciesName: "Shoyru", + }, + { + speciesId: "45", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/fc4cxk3t/1/1.png", + colorId: colors.RED, + speciesName: "Skeith", + }, + { + speciesId: "46", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/84gvowmj/1/1.png", + colorId: colors.YELLOW, + speciesName: "Techo", + }, + { + speciesId: "47", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/jd433863/1/1.png", + colorId: colors.BLUE, + speciesName: "Tonu", + }, + { + speciesId: "48", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/q39wn6vq/1/1.png", + colorId: colors.YELLOW, + speciesName: "Tuskaninny", + }, + { + speciesId: "49", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/njzvoflw/1/1.png", + colorId: colors.GREEN, + speciesName: "Uni", + }, + { + speciesId: "50", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/rox4mgh5/1/1.png", + colorId: colors.RED, + speciesName: "Usul", + }, + { + speciesId: "51", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/dnr2kj4b/1/1.png", + colorId: colors.YELLOW, + speciesName: "Wocky", + }, + { + speciesId: "52", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/tdkqr2b6/1/1.png", + colorId: colors.RED, + speciesName: "Xweetok", + }, + { + speciesId: "53", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/h95cs547/1/1.png", + colorId: colors.RED, + speciesName: "Yurble", + }, + { + speciesId: "54", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/x8c57g2l/1/1.png", + colorId: colors.BLUE, + speciesName: "Zafara", + }, + { + speciesId: "55", + src: "https://pets.neopets-asset-proxy.openneo.net/cp/xkntzsww/1/1.png", + colorId: colors.YELLOW, + speciesName: "Vandagyre", + }, +]; + export default ItemPage;