2020-08-01 12:50:01 -07:00
|
|
|
import * as React from "react";
|
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
Box,
|
2020-08-01 14:12:57 -07:00
|
|
|
FormControl,
|
|
|
|
FormErrorMessage,
|
|
|
|
FormHelperText,
|
|
|
|
FormLabel,
|
2020-08-01 12:50:01 -07:00
|
|
|
HStack,
|
|
|
|
Modal,
|
|
|
|
ModalBody,
|
|
|
|
ModalCloseButton,
|
|
|
|
ModalContent,
|
2020-08-01 14:30:10 -07:00
|
|
|
ModalFooter,
|
2020-08-01 12:50:01 -07:00
|
|
|
ModalHeader,
|
|
|
|
ModalOverlay,
|
2020-08-01 14:12:57 -07:00
|
|
|
Radio,
|
|
|
|
RadioGroup,
|
2020-08-01 14:30:10 -07:00
|
|
|
Spinner,
|
2020-08-01 12:50:01 -07:00
|
|
|
} from "@chakra-ui/core";
|
|
|
|
import { ExternalLinkIcon } from "@chakra-ui/icons";
|
|
|
|
|
2020-08-01 14:12:57 -07:00
|
|
|
import { OutfitLayers } from "../../components/OutfitPreview";
|
|
|
|
import SpeciesColorPicker from "../../components/SpeciesColorPicker";
|
|
|
|
import useOutfitAppearance from "../../components/useOutfitAppearance";
|
|
|
|
|
|
|
|
function ItemSupportAppearanceLayerModal({
|
|
|
|
item,
|
|
|
|
itemLayer,
|
|
|
|
outfitState,
|
|
|
|
isOpen,
|
|
|
|
onClose,
|
|
|
|
}) {
|
2020-08-01 12:50:01 -07:00
|
|
|
return (
|
|
|
|
<Modal size="xl" isOpen={isOpen} onClose={onClose}>
|
|
|
|
<ModalOverlay>
|
2020-08-01 14:12:57 -07:00
|
|
|
<ModalContent color="green.800">
|
2020-08-01 12:50:01 -07:00
|
|
|
<ModalHeader>
|
|
|
|
Layer {itemLayer.id}: {item.name}
|
|
|
|
</ModalHeader>
|
|
|
|
<ModalCloseButton />
|
2020-08-01 14:30:10 -07:00
|
|
|
<ModalBody>
|
2020-08-01 14:12:57 -07:00
|
|
|
<Metadata>
|
|
|
|
<MetadataLabel>ID:</MetadataLabel>
|
|
|
|
<MetadataValue>{itemLayer.id}</MetadataValue>
|
|
|
|
<MetadataLabel>Zone:</MetadataLabel>
|
|
|
|
<MetadataValue>
|
2020-08-01 12:50:01 -07:00
|
|
|
{itemLayer.zone.label} ({itemLayer.zone.id})
|
2020-08-01 14:12:57 -07:00
|
|
|
</MetadataValue>
|
|
|
|
<MetadataLabel>Assets:</MetadataLabel>
|
|
|
|
<MetadataValue>
|
|
|
|
<HStack spacing="2">
|
|
|
|
{itemLayer.svgUrl ? (
|
|
|
|
<Button
|
|
|
|
as="a"
|
|
|
|
size="xs"
|
|
|
|
target="_blank"
|
|
|
|
href={itemLayer.svgUrl}
|
|
|
|
colorScheme="teal"
|
|
|
|
>
|
|
|
|
SVG <ExternalLinkIcon ml="1" />
|
|
|
|
</Button>
|
|
|
|
) : (
|
|
|
|
<Button size="xs" isDisabled>
|
|
|
|
No SVG
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
{itemLayer.imageUrl ? (
|
|
|
|
<Button
|
|
|
|
as="a"
|
|
|
|
size="xs"
|
|
|
|
target="_blank"
|
|
|
|
href={itemLayer.imageUrl}
|
|
|
|
colorScheme="teal"
|
|
|
|
>
|
|
|
|
PNG <ExternalLinkIcon ml="1" />
|
|
|
|
</Button>
|
|
|
|
) : (
|
|
|
|
<Button size="xs" isDisabled>
|
|
|
|
No PNG
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</HStack>
|
|
|
|
</MetadataValue>
|
|
|
|
</Metadata>
|
|
|
|
<Box height="8" />
|
|
|
|
<ItemSupportAppearanceLayerPetCompatibility
|
|
|
|
item={item}
|
|
|
|
itemLayer={itemLayer}
|
|
|
|
outfitState={outfitState}
|
|
|
|
/>
|
2020-08-01 12:50:01 -07:00
|
|
|
</ModalBody>
|
2020-08-01 14:30:10 -07:00
|
|
|
<ModalFooter>
|
|
|
|
<Button colorScheme="green">Save changes</Button>
|
|
|
|
</ModalFooter>
|
2020-08-01 12:50:01 -07:00
|
|
|
</ModalContent>
|
|
|
|
</ModalOverlay>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-01 14:12:57 -07:00
|
|
|
function ItemSupportAppearanceLayerPetCompatibility({
|
|
|
|
item,
|
|
|
|
itemLayer,
|
|
|
|
outfitState,
|
|
|
|
}) {
|
2020-08-01 14:30:10 -07:00
|
|
|
const [bodyId, setBodyId] = React.useState(itemLayer.bodyId);
|
2020-08-01 14:12:57 -07:00
|
|
|
const [selectedBiology, setSelectedBiology] = React.useState({
|
|
|
|
speciesId: outfitState.speciesId,
|
|
|
|
colorId: outfitState.colorId,
|
|
|
|
pose: outfitState.pose,
|
|
|
|
isValid: true,
|
|
|
|
});
|
|
|
|
const [visibleBiology, setVisibleBiology] = React.useState(selectedBiology);
|
|
|
|
|
2020-08-01 14:30:10 -07:00
|
|
|
const {
|
|
|
|
loading,
|
|
|
|
error,
|
|
|
|
visibleLayers,
|
|
|
|
bodyId: appearanceBodyId,
|
|
|
|
} = useOutfitAppearance({
|
2020-08-01 14:12:57 -07:00
|
|
|
speciesId: visibleBiology.speciesId,
|
|
|
|
colorId: visibleBiology.colorId,
|
|
|
|
pose: visibleBiology.pose,
|
|
|
|
wornItemIds: [item.id],
|
|
|
|
});
|
|
|
|
|
|
|
|
const biologyLayers = visibleLayers.filter((l) => l.source === "pet");
|
|
|
|
|
2020-08-01 14:30:10 -07:00
|
|
|
// When the appearance body ID changes, select it as the new body ID. (This
|
|
|
|
// is an effect because it happens after the appearance finishes loading!)
|
|
|
|
React.useEffect(() => {
|
|
|
|
if (bodyId !== "0") {
|
|
|
|
setBodyId(appearanceBodyId);
|
|
|
|
}
|
|
|
|
}, [bodyId, appearanceBodyId]);
|
|
|
|
|
2020-08-01 14:12:57 -07:00
|
|
|
return (
|
|
|
|
<FormControl isInvalid={error || !selectedBiology.isValid ? true : false}>
|
|
|
|
<FormLabel>Pet compatibility</FormLabel>
|
|
|
|
<RadioGroup
|
|
|
|
colorScheme="green"
|
2020-08-01 14:30:10 -07:00
|
|
|
value={bodyId}
|
|
|
|
onChange={(newBodyId) => setBodyId(newBodyId)}
|
2020-08-01 14:12:57 -07:00
|
|
|
marginBottom="4"
|
|
|
|
>
|
|
|
|
<Radio value="0">
|
|
|
|
Fits all pets{" "}
|
|
|
|
<Box display="inline" color="gray.400" fontSize="sm">
|
|
|
|
(Body ID: 0)
|
|
|
|
</Box>
|
|
|
|
</Radio>
|
2020-08-01 14:30:10 -07:00
|
|
|
<Radio as="div" value={appearanceBodyId} marginTop="2">
|
2020-08-01 14:12:57 -07:00
|
|
|
Fits all pets with the same body as:{" "}
|
|
|
|
<Box display="inline" color="gray.400" fontSize="sm">
|
2020-08-01 14:30:10 -07:00
|
|
|
(Body ID:{" "}
|
|
|
|
{appearanceBodyId == null ? (
|
|
|
|
<Spinner size="sm" />
|
|
|
|
) : (
|
|
|
|
appearanceBodyId
|
|
|
|
)}
|
|
|
|
)
|
2020-08-01 14:12:57 -07:00
|
|
|
</Box>
|
|
|
|
</Radio>
|
|
|
|
</RadioGroup>
|
|
|
|
<Box display="flex" flexDirection="column" alignItems="center">
|
|
|
|
<Box
|
|
|
|
width="150px"
|
|
|
|
height="150px"
|
|
|
|
marginTop="2"
|
|
|
|
marginBottom="2"
|
|
|
|
boxShadow="md"
|
|
|
|
borderRadius="md"
|
|
|
|
>
|
|
|
|
<OutfitLayers
|
|
|
|
loading={loading}
|
|
|
|
visibleLayers={[...biologyLayers, itemLayer]}
|
|
|
|
/>
|
|
|
|
</Box>
|
|
|
|
<SpeciesColorPicker
|
|
|
|
speciesId={selectedBiology.speciesId}
|
|
|
|
colorId={selectedBiology.colorId}
|
|
|
|
idealPose={outfitState.pose}
|
|
|
|
size="sm"
|
|
|
|
showPlaceholders
|
|
|
|
onChange={(species, color, isValid, pose) => {
|
|
|
|
const speciesId = species.id;
|
|
|
|
const colorId = color.id;
|
|
|
|
|
|
|
|
setSelectedBiology({ speciesId, colorId, isValid, pose });
|
|
|
|
if (isValid) {
|
|
|
|
setVisibleBiology({ speciesId, colorId, isValid, pose });
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Box height="1" />
|
|
|
|
{!error && (
|
|
|
|
<FormHelperText>
|
|
|
|
If it doesn't look right, try some other options until it does!
|
|
|
|
</FormHelperText>
|
|
|
|
)}
|
|
|
|
{error && <FormErrorMessage>{error.message}</FormErrorMessage>}
|
|
|
|
</Box>
|
|
|
|
</FormControl>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function Metadata({ children }) {
|
|
|
|
return (
|
|
|
|
<Box
|
|
|
|
as="dl"
|
|
|
|
display="grid"
|
|
|
|
gridTemplateColumns="max-content auto"
|
|
|
|
gridRowGap="1"
|
|
|
|
gridColumnGap="2"
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function MetadataLabel({ children }) {
|
|
|
|
return (
|
|
|
|
<Box as="dt" gridColumn="1" fontWeight="bold">
|
|
|
|
{children}
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function MetadataValue({ children }) {
|
|
|
|
return (
|
|
|
|
<Box as="dd" gridColumn="2">
|
|
|
|
{children}
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-01 12:50:01 -07:00
|
|
|
export default ItemSupportAppearanceLayerModal;
|