Disable faces that can't be the chosen color
This commit is contained in:
parent
8de85fbc63
commit
a293dc56b5
1 changed files with 34 additions and 21 deletions
|
@ -871,11 +871,16 @@ function SpeciesFacesPicker({
|
||||||
speciesName={speciesFace.speciesName}
|
speciesName={speciesFace.speciesName}
|
||||||
colorId={speciesFace.colorId}
|
colorId={speciesFace.colorId}
|
||||||
neopetsImageHash={speciesFace.neopetsImageHash}
|
neopetsImageHash={speciesFace.neopetsImageHash}
|
||||||
isCompatible={
|
isSelected={speciesFace.speciesId === selectedSpeciesId}
|
||||||
|
// If the face color doesn't match the current color, this is a
|
||||||
|
// fallback face for an invalid species/color pair.
|
||||||
|
isValid={
|
||||||
|
speciesFace.colorId === selectedColorId || selectedColorIsBasic
|
||||||
|
}
|
||||||
|
bodyIsCompatible={
|
||||||
allBodiesAreCompatible ||
|
allBodiesAreCompatible ||
|
||||||
compatibleBodyIds.includes(speciesFace.bodyId)
|
compatibleBodyIds.includes(speciesFace.bodyId)
|
||||||
}
|
}
|
||||||
isSelected={speciesFace.speciesId === selectedSpeciesId}
|
|
||||||
couldProbablyModelMoreData={couldProbablyModelMoreData}
|
couldProbablyModelMoreData={couldProbablyModelMoreData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
isLoading={isLoading || loadingGQL}
|
isLoading={isLoading || loadingGQL}
|
||||||
|
@ -919,8 +924,9 @@ function SpeciesFaceOption({
|
||||||
speciesName,
|
speciesName,
|
||||||
colorId,
|
colorId,
|
||||||
neopetsImageHash,
|
neopetsImageHash,
|
||||||
isCompatible,
|
|
||||||
isSelected,
|
isSelected,
|
||||||
|
bodyIsCompatible,
|
||||||
|
isValid,
|
||||||
couldProbablyModelMoreData,
|
couldProbablyModelMoreData,
|
||||||
onChange,
|
onChange,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
@ -945,24 +951,31 @@ function SpeciesFaceOption({
|
||||||
const [labelIsHovered, setLabelIsHovered] = React.useState(false);
|
const [labelIsHovered, setLabelIsHovered] = React.useState(false);
|
||||||
const [inputIsFocused, setInputIsFocused] = React.useState(false);
|
const [inputIsFocused, setInputIsFocused] = React.useState(false);
|
||||||
|
|
||||||
const isHappy = isLoading || isCompatible;
|
const isDisabled = isLoading || !isValid || !bodyIsCompatible;
|
||||||
|
const isHappy = isLoading || (isValid && bodyIsCompatible);
|
||||||
const emotionId = isHappy ? "1" : "2";
|
const emotionId = isHappy ? "1" : "2";
|
||||||
|
const cursor = isLoading ? "wait" : isDisabled ? "not-allowed" : "pointer";
|
||||||
|
|
||||||
|
let disabledExplanation = null;
|
||||||
|
if (!isValid) {
|
||||||
|
disabledExplanation = "(Can't be this color)";
|
||||||
|
} else if (!bodyIsCompatible) {
|
||||||
|
disabledExplanation = couldProbablyModelMoreData
|
||||||
|
? "(Not modeled yet)"
|
||||||
|
: "(Not compatible)";
|
||||||
|
}
|
||||||
|
|
||||||
const tooltipLabel = (
|
const tooltipLabel = (
|
||||||
<div style={{ textAlign: "center" }}>
|
<div style={{ textAlign: "center" }}>
|
||||||
{speciesName}
|
{speciesName}
|
||||||
{!isLoading && !isCompatible && (
|
{disabledExplanation && (
|
||||||
<div style={{ fontStyle: "italic", fontSize: "0.75em" }}>
|
<div style={{ fontStyle: "italic", fontSize: "0.75em" }}>
|
||||||
{couldProbablyModelMoreData
|
{disabledExplanation}
|
||||||
? "(Not modeled yet)"
|
|
||||||
: "(Not compatible)"}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const cursor = isLoading ? "wait" : !isCompatible ? "not-allowed" : "pointer";
|
|
||||||
|
|
||||||
// NOTE: Because we render quite a few of these, avoiding using Chakra
|
// NOTE: Because we render quite a few of these, avoiding using Chakra
|
||||||
// elements like Box helps with render performance!
|
// elements like Box helps with render performance!
|
||||||
return (
|
return (
|
||||||
|
@ -992,7 +1005,7 @@ function SpeciesFaceOption({
|
||||||
// It's possible to get this selected via the SpeciesColorPicker,
|
// It's possible to get this selected via the SpeciesColorPicker,
|
||||||
// even if this would normally be disabled. If so, make this
|
// even if this would normally be disabled. If so, make this
|
||||||
// option enabled, so keyboard users can focus and change it.
|
// option enabled, so keyboard users can focus and change it.
|
||||||
disabled={!isSelected && (isLoading || !isCompatible)}
|
disabled={isDisabled && !isSelected}
|
||||||
onChange={() => onChange({ speciesId, colorId })}
|
onChange={() => onChange({ speciesId, colorId })}
|
||||||
onFocus={() => setInputIsFocused(true)}
|
onFocus={() => setInputIsFocused(true)}
|
||||||
onBlur={() => setInputIsFocused(false)}
|
onBlur={() => setInputIsFocused(false)}
|
||||||
|
@ -1040,13 +1053,13 @@ function SpeciesFaceOption({
|
||||||
width={50}
|
width={50}
|
||||||
height={50}
|
height={50}
|
||||||
data-is-loading={isLoading}
|
data-is-loading={isLoading}
|
||||||
data-is-compatible={!isLoading && isCompatible}
|
data-is-disabled={isDisabled}
|
||||||
className={css`
|
className={css`
|
||||||
filter: saturate(90%);
|
filter: saturate(90%);
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
|
||||||
&[data-is-compatible="false"] {
|
&[data-is-disabled="true"] {
|
||||||
filter: saturate(0%);
|
filter: saturate(0%);
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
@ -1056,15 +1069,15 @@ function SpeciesFaceOption({
|
||||||
pulse;
|
pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:checked + * &[data-is-compatible="false"] {
|
input:checked + * &[data-body-is-disabled="false"] {
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked + * &[data-is-compatible="true"] {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
filter: saturate(110%);
|
filter: saturate(110%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:checked + * &[data-body-is-disabled="true"] {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
from {
|
from {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
@ -1190,9 +1203,9 @@ function CrossFadeImage(incomingImageProps) {
|
||||||
// If the current image _is_ the incoming image, we'll allow
|
// If the current image _is_ the incoming image, we'll allow
|
||||||
// new props to come in and affect it. But if it's a new image
|
// new props to come in and affect it. But if it's a new image
|
||||||
// incoming, we want to stick to the last props the current
|
// incoming, we want to stick to the last props the current
|
||||||
// image had! (This matters for e.g. `isCompatible` becoming
|
// image had! (This matters for e.g. `bodyIsCompatible`
|
||||||
// true in `SpeciesFaceOption` and restoring color, before
|
// becoming true in `SpeciesFaceOption` and restoring color,
|
||||||
// the new color's image loads in.)
|
// before the new color's image loads in.)
|
||||||
{...(incomingImageIsCurrentImage ? incomingImageProps : {})}
|
{...(incomingImageIsCurrentImage ? incomingImageProps : {})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue