Add token category to token menu

This commit is contained in:
Mitchell McCaffrey 2021-08-05 13:30:03 +10:00
parent 73c549102b
commit 7db02fa492
5 changed files with 118 additions and 15 deletions

View File

@ -12,6 +12,10 @@ import LockIcon from "../../icons/TokenLockIcon";
import UnlockIcon from "../../icons/TokenUnlockIcon";
import ShowIcon from "../../icons/TokenShowIcon";
import HideIcon from "../../icons/TokenHideIcon";
import TokenCharacterIcon from "../../icons/TokenCharacterIcon";
import TokenPropIcon from "../../icons/TokenPropIcon";
import TokenMountIcon from "../../icons/TokenMountIcon";
import TokenAttachmentIcon from "../../icons/TokenAttachmentIcon";
import { useUserId } from "../../contexts/UserIdContext";
@ -21,6 +25,33 @@ import {
} from "../../types/Events";
import { TokenState } from "../../types/TokenState";
import { Map } from "../../types/Map";
import { TokenCategory } from "../../types/Token";
const tokenCategories: Record<
TokenCategory,
{ title: string; icon: React.ReactNode; next: TokenCategory }
> = {
character: {
title: "Character",
icon: <TokenCharacterIcon />,
next: "prop",
},
prop: {
title: "Prop",
icon: <TokenPropIcon />,
next: "vehicle",
},
vehicle: {
title: "Mount",
icon: <TokenMountIcon />,
next: "attachment",
},
attachment: {
title: "Attachment",
icon: <TokenAttachmentIcon />,
next: "character",
},
};
type TokenMenuProps = {
isOpen: boolean;
@ -98,6 +129,15 @@ function TokenMenu({
});
}
function handleCategoryChange() {
tokenState &&
onTokenStateChange({
[tokenState.id]: {
category: tokenCategories[tokenState.category].next,
},
});
}
function handleModalContent(node: HTMLElement) {
if (node) {
// Focus input
@ -206,29 +246,28 @@ function TokenMenu({
))}
</Box>
{/* Only show hide and lock token actions to map owners */}
{map && map.owner === userId && (
{map && map.owner === userId && tokenState && (
<Flex sx={{ alignItems: "center", justifyContent: "space-around" }}>
<IconButton
onClick={handleVisibleChange}
title={
tokenState && tokenState.visible ? "Hide Token" : "Show Token"
}
aria-label={
tokenState && tokenState.visible ? "Hide Token" : "Show Token"
}
title={tokenState.visible ? "Hide Token" : "Show Token"}
aria-label={tokenState.visible ? "Hide Token" : "Show Token"}
>
{tokenState && tokenState.visible ? <ShowIcon /> : <HideIcon />}
{tokenState.visible ? <ShowIcon /> : <HideIcon />}
</IconButton>
<IconButton
onClick={handleLockChange}
title={
tokenState && tokenState.locked ? "Unlock Token" : "Lock Token"
}
aria-label={
tokenState && tokenState.locked ? "Unlock Token" : "Lock Token"
}
title={tokenState.locked ? "Unlock Token" : "Lock Token"}
aria-label={tokenState.locked ? "Unlock Token" : "Lock Token"}
>
{tokenState && tokenState.locked ? <LockIcon /> : <UnlockIcon />}
{tokenState.locked ? <LockIcon /> : <UnlockIcon />}
</IconButton>
<IconButton
onClick={handleCategoryChange}
title={tokenCategories[tokenState.category].title}
aria-label={tokenCategories[tokenState.category].title}
>
{tokenCategories[tokenState.category].icon}
</IconButton>
</Flex>
)}

View File

@ -0,0 +1,16 @@
function TokenAttachmentIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10s10-4.49,10-10S17.51,2,12,2z M12,20c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8 S16.41,20,12,20z M15,12c0,1.66-1.34,3-3,3s-3-1.34-3-3s1.34-3,3-3S15,10.34,15,12z" />
</svg>
);
}
export default TokenAttachmentIcon;

View File

@ -0,0 +1,16 @@
function TokenCharacterIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M20.75 6.99c-.14-.55-.69-.87-1.24-.75-2.38.53-5.03.76-7.51.76s-5.13-.23-7.51-.76c-.55-.12-1.1.2-1.24.75-.14.56.2 1.13.75 1.26 1.61.36 3.35.61 5 .75v12c0 .55.45 1 1 1s1-.45 1-1v-5h2v5c0 .55.45 1 1 1s1-.45 1-1V9c1.65-.14 3.39-.39 4.99-.75.56-.13.9-.7.76-1.26zM12 6c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" />
</svg>
);
}
export default TokenCharacterIcon;

View File

@ -0,0 +1,16 @@
function TokenMountIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M22.006 6v2.71c0 .472-.302.89-.75 1.04a1.005 1.005 0 01-1.17-.42l-1.12-1.79c-.13-.21-.46-.12-.46.13v3.58c0 .98-.39 1.86-1 2.53v5.97a1.25 1.25 0 01-2.5 0V15h-.25c-.21 0-.42-.03-.62-.06l-4.44-.74-1.12 2.01.712 3.55A1.037 1.037 0 018.27 21a1.559 1.559 0 01-1.525-1.238l-.74-3.512c-.03-.3 0-.6.16-.86l1.02-1.81a3.272 3.272 0 01-1.68-2.77c-.04.15-.06.37-.03.69.03.44.14 1.09.07 1.81-.04.72-.37 1.46-.79 1.95-.43.49-.9.83-1.4 1.09-.5.26-.89-.23-.7-.7.19-.47.38-.89.42-1.28.06-.37-.01-.67-.12-.94l-.53-1.13c-.21-.51-.47-1.25-.42-2.12.03-.85.5-1.96 1.39-2.57.9-.61 1.87-.69 2.66-.53.5.1 1.01.34 1.45.68.37-.17.8-.26 1.25-.26h5.75V7c0-2.21 1.79-4 4-4h3.5l-.89 1.34c.54.36.89.97.89 1.66z" />
</svg>
);
}
export default TokenMountIcon;

View File

@ -0,0 +1,16 @@
function TokenPropIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M16.96,12h0.08c0.81,0,1.28-0.91,0.82-1.57l-5.08-7.25c-0.4-0.57-1.24-0.57-1.64,0L6.1,10.43C5.64,11.09,6.12,12,6.93,12 h0.04l-2.9,4.46C3.63,17.12,4.11,18,4.91,18h5.08v2.02c0,1.09,0.89,1.98,1.98,1.98h0c1.09,0,1.98-0.89,1.98-1.98V18h5.15 c0.8,0,1.28-0.89,0.83-1.55L16.96,12z" />
</svg>
);
}
export default TokenPropIcon;