From 752828b4b0104c5bff92f449e14dbbcac1943198 Mon Sep 17 00:00:00 2001 From: Matt Dunn-Rankin Date: Sat, 2 May 2020 22:04:20 -0700 Subject: [PATCH] PosePicker is a radio! --- src/app/PosePicker.js | 135 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 25 deletions(-) diff --git a/src/app/PosePicker.js b/src/app/PosePicker.js index 2c42efe..2158b18 100644 --- a/src/app/PosePicker.js +++ b/src/app/PosePicker.js @@ -11,6 +11,7 @@ import { PopoverArrow, PopoverContent, PopoverTrigger, + VisuallyHidden, useTheme, } from "@chakra-ui/core"; @@ -23,17 +24,18 @@ import twemojiSick from "../images/twemoji/sick.svg"; import twemojiMasc from "../images/twemoji/masc.svg"; import twemojiFem from "../images/twemoji/fem.svg"; import { OutfitLayers } from "./OutfitPreview"; -import { safeImageUrl } from "./util"; function PosePicker({ outfitState, onLockFocus, onUnlockFocus }) { const theme = useTheme(); const { speciesId, colorId } = outfitState; - const { loading, error, poses } = useAvailablePoses({ + const { loading, error, poses, selectPose } = usePoses({ speciesId, colorId, }); + const checkedInputRef = React.useRef(); + if (loading) { return null; } @@ -52,10 +54,11 @@ function PosePicker({ outfitState, onLockFocus, onUnlockFocus }) { return ( {({ isOpen }) => ( <> @@ -92,7 +95,16 @@ function PosePicker({ outfitState, onLockFocus, onUnlockFocus }) { - +
{ + const [emotion, genderPresentation] = e.target.value.split( + "-" + ); + selectPose({ emotion, genderPresentation }); + }} + >
@@ -161,31 +173,96 @@ function Cell({ children, as }) { ); } +const EMOTION_STRINGS = { + HAPPY: "Happy", + SAD: "Sad", + SICK: "Sick", +}; + +const GENDER_PRESENTATION_STRINGS = { + MASCULINE: "Masculine", + FEMININE: "Feminine", +}; + function PoseButton({ pose, speciesId }) { + const theme = useTheme(); + if (!pose) { return null; } + const genderPresentationStr = + GENDER_PRESENTATION_STRINGS[pose.genderPresentation]; + const emotionStr = EMOTION_STRINGS[pose.emotion]; + return ( { + // HACK: We need the timeout to beat the popover's focus stealing! + const input = e.currentTarget.querySelector("input"); + setTimeout(() => input.focus(), 0); + }} > - + ); } @@ -194,7 +271,12 @@ function EmojiImage({ src, "aria-label": ariaLabel }) { return ; } -function useAvailablePoses({ speciesId, colorId }) { +function usePoses({ speciesId, colorId }) { + const [selectedPose, selectPose] = React.useState({ + emotion: "HAPPY", + genderPresentation: "FEMININE", + }); + const { loading, error, data } = useQuery( gql` query PosePicker($speciesId: ID!, $colorId: ID!) { @@ -212,21 +294,24 @@ function useAvailablePoses({ speciesId, colorId }) { ); const petAppearances = data?.petAppearances || []; - const findAppearanceFor = (e, gp) => - petAppearances.find( + const buildPose = (e, gp) => ({ + ...petAppearances.find( (pa) => pa.emotion === e && pa.genderPresentation === gp - ); + ), + isSelected: + selectedPose.emotion === e && selectedPose.genderPresentation === gp, + }); const poses = { - happyMasc: findAppearanceFor("HAPPY", "MASCULINE"), - sadMasc: findAppearanceFor("SAD", "MASCULINE"), - sickMasc: findAppearanceFor("SICK", "MASCULINE"), - happyFem: findAppearanceFor("HAPPY", "FEMININE"), - sadFem: findAppearanceFor("SAD", "FEMININE"), - sickFem: findAppearanceFor("SICK", "FEMININE"), + happyMasc: buildPose("HAPPY", "MASCULINE"), + sadMasc: buildPose("SAD", "MASCULINE"), + sickMasc: buildPose("SICK", "MASCULINE"), + happyFem: buildPose("HAPPY", "FEMININE"), + sadFem: buildPose("SAD", "FEMININE"), + sickFem: buildPose("SICK", "FEMININE"), }; - return { loading, error, poses }; + return { loading, error, poses, selectPose }; } const transformsBySpeciesId = {