From 4e923746ce509d0c181192d88e7d8a32d3fb0737 Mon Sep 17 00:00:00 2001 From: Matchu Date: Sat, 29 Aug 2020 14:49:37 -0700 Subject: [PATCH] Show empty PosePicker for Support users For most users, I want to hide the pose picker if there's not actually anything to pick from. But I want Support users to be able to open it and use Support mode, to inspect and label Unknown poses! In this change, I add new UI to show a question mark pose picker button, and a note explaining the empty picker; but only show them for Support users. I also made a new `useSupport` hook, to replace `useSupportSecret`, now that I have a use case for "is support user?" that doesn't require the secret. Will migrate the rest! --- src/app/WardrobePage/PosePicker.js | 37 ++++++++++++++++--- .../WardrobePage/support/PosePickerSupport.js | 8 ++++ src/app/WardrobePage/support/useSupport.js | 29 +++++++++++++++ .../WardrobePage/support/useSupportSecret.js | 7 ++++ src/images/twemoji/question.svg | 1 + 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/app/WardrobePage/support/useSupport.js create mode 100644 src/images/twemoji/question.svg diff --git a/src/app/WardrobePage/PosePicker.js b/src/app/WardrobePage/PosePicker.js index d4f244e..b030d26 100644 --- a/src/app/WardrobePage/PosePicker.js +++ b/src/app/WardrobePage/PosePicker.js @@ -23,12 +23,14 @@ import { } from "../components/useOutfitAppearance"; import { OutfitLayers } from "../components/OutfitPreview"; import SupportOnly from "./support/SupportOnly"; +import useSupport from "./support/useSupport"; import { useLocalStorage } from "../util"; // From https://twemoji.twitter.com/, thank you! import twemojiSmile from "../../images/twemoji/smile.svg"; import twemojiCry from "../../images/twemoji/cry.svg"; import twemojiSick from "../../images/twemoji/sick.svg"; +import twemojiQuestion from "../../images/twemoji/question.svg"; import twemojiMasc from "../../images/twemoji/masc.svg"; import twemojiFem from "../../images/twemoji/fem.svg"; @@ -67,6 +69,7 @@ function PosePicker({ "DTIPosePickerIsInSupportMode", false ); + const { isSupportUser } = useSupport(); // Resize the Popover when we toggle support mode, because it probably will // affect the content size. @@ -89,10 +92,12 @@ function PosePicker({ } // If there's only one pose anyway, don't bother showing a picker! + // (Unless we're Support, in which case we want the ability to pop it open to + // inspect and label the Unknown poses!) const numAvailablePoses = Object.values(poseInfos).filter( (p) => p.isAvailable ).length; - if (numAvailablePoses <= 1) { + if (numAvailablePoses <= 1 && !isSupportUser) { return null; } @@ -147,6 +152,9 @@ function PosePicker({ {getEmotion(pose) === "SICK" && ( )} + {getEmotion(pose) === null && ( + + )} @@ -161,11 +169,28 @@ function PosePicker({ dispatchToOutfit={dispatchToOutfit} /> ) : ( - + <> + + {numAvailablePoses <= 1 && ( + + + The empty picker is hidden for most users! +
+ You can see it because you're a Support user. +
+
+ )} + )} diff --git a/src/app/WardrobePage/support/PosePickerSupport.js b/src/app/WardrobePage/support/PosePickerSupport.js index 29a25c5..d5963db 100644 --- a/src/app/WardrobePage/support/PosePickerSupport.js +++ b/src/app/WardrobePage/support/PosePickerSupport.js @@ -71,6 +71,13 @@ function PosePickerSupport({ ) { id } + unknown: petAppearance( + speciesId: $speciesId + colorId: $colorId + pose: UNKNOWN + ) { + id + } } `, { variables: { speciesId, colorId } } @@ -113,6 +120,7 @@ function PosePickerSupport({ HAPPY_FEM: data.happyFem?.id, SAD_FEM: data.sadFem?.id, SICK_FEM: data.sickFem?.id, + UNKNOWN: data.unknown?.id, }; const canonicalAppearanceIds = Object.values( canonicalAppearanceIdsByPose diff --git a/src/app/WardrobePage/support/useSupport.js b/src/app/WardrobePage/support/useSupport.js new file mode 100644 index 0000000..0c164ea --- /dev/null +++ b/src/app/WardrobePage/support/useSupport.js @@ -0,0 +1,29 @@ +import * as React from "react"; + +/** + * useSupport returns the Support secret that the server requires for Support + * actions... if the user has it set. For most users, this returns nothing! + * + * Specifically, we return an object of: + * - isSupportUser: true iff the `supportSecret` is set + * - supportSecret: the secret saved to this device, or null if not set + * + * To become a Support user, you visit /?supportSecret=..., which saves the + * secret to your device. + * + * Note that this hook doesn't check that the secret is *correct*, so it's + * possible that it will return an invalid secret. That's okay, because + * the server checks the provided secret for each Support request. + */ +function useSupport() { + const supportSecret = React.useMemo( + () => localStorage.getItem("supportSecret"), + [] + ); + + const isSupportUser = supportSecret != null; + + return { isSupportUser, supportSecret }; +} + +export default useSupport; diff --git a/src/app/WardrobePage/support/useSupportSecret.js b/src/app/WardrobePage/support/useSupportSecret.js index 84fc40d..160d200 100644 --- a/src/app/WardrobePage/support/useSupportSecret.js +++ b/src/app/WardrobePage/support/useSupportSecret.js @@ -11,9 +11,16 @@ import * as React from "react"; * Note that this hook doesn't check that the secret is *correct*, so it's * possible that it will return an invalid secret. That's okay, because * the server checks the provided secret for each Support request. + * + * DEPRECATED: Use `useSupport` instead! */ function useSupportSecret() { return React.useMemo(() => localStorage.getItem("supportSecret"), []); } +export function useIsSupportUser() { + const supportSecret = useSupportSecret(); + return supportSecret != null; +} + export default useSupportSecret; diff --git a/src/images/twemoji/question.svg b/src/images/twemoji/question.svg new file mode 100644 index 0000000..ab6b64b --- /dev/null +++ b/src/images/twemoji/question.svg @@ -0,0 +1 @@ + \ No newline at end of file