Add token edit bar back

This commit is contained in:
Mitchell McCaffrey 2021-06-05 13:04:12 +10:00
parent 0f2776d774
commit 1a34dc756a
2 changed files with 184 additions and 100 deletions

View File

@ -0,0 +1,147 @@
import React, { useState, useEffect } from "react";
import { Flex, Close, IconButton } from "theme-ui";
import { groupsFromIds, itemsFromGroups } from "../../helpers/group";
import ConfirmModal from "../../modals/ConfirmModal";
import TokenShowIcon from "../../icons/TokenShowIcon";
import TokenHideIcon from "../../icons/TokenHideIcon";
import RemoveTokenIcon from "../../icons/RemoveTokenIcon";
import { useGroup } from "../../contexts/GroupContext";
import { useTokenData } from "../../contexts/TokenDataContext";
import { useKeyboard } from "../../contexts/KeyboardContext";
import shortcuts from "../../shortcuts";
function TokenEditBar({ disabled, onLoad }) {
const { tokens, removeTokens, updateTokens } = useTokenData();
const {
groups: allGroups,
selectedGroupIds,
onGroupSelect,
openGroupId,
openGroupItems,
} = useGroup();
const groups = openGroupId ? openGroupItems : allGroups;
const [hasSelectedDefaultToken, setHasSelectedDefaultToken] = useState(false);
const [allTokensVisible, setAllTokensVisisble] = useState(false);
useEffect(() => {
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
const selectedTokens = itemsFromGroups(selectedGroups, tokens);
setHasSelectedDefaultToken(
selectedTokens.some((token) => token.type === "default")
);
setAllTokensVisisble(selectedTokens.every((token) => !token.hideInSidebar));
}, [selectedGroupIds, tokens, groups]);
function getSelectedTokens() {
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
return itemsFromGroups(selectedGroups, tokens);
}
const [isTokensRemoveModalOpen, setIsTokensRemoveModalOpen] = useState(false);
async function handleTokensRemove() {
onLoad(true);
setIsTokensRemoveModalOpen(false);
const selectedTokens = getSelectedTokens();
const selectedTokenIds = selectedTokens.map((token) => token.id);
await removeTokens(selectedTokenIds);
onGroupSelect();
onLoad(false);
}
async function handleTokensHide(hideInSidebar) {
onLoad(true);
const selectedTokens = getSelectedTokens();
const selectedTokenIds = selectedTokens.map((token) => token.id);
await updateTokens(selectedTokenIds, { hideInSidebar });
onLoad(false);
}
/**
* Shortcuts
*/
function handleKeyDown(event) {
if (disabled) {
return;
}
if (shortcuts.delete(event)) {
const selectedTokens = getSelectedTokens();
// Selected tokens and none are default
if (
selectedTokens.length > 0 &&
!selectedTokens.some((token) => token.type === "default")
) {
// Ensure all other modals are closed
setIsTokensRemoveModalOpen(true);
}
}
}
useKeyboard(handleKeyDown);
if (selectedGroupIds.length === 0) {
return null;
}
let hideTitle = "";
if (allTokensVisible) {
hideTitle = "Hide Selected Token(s) in Sidebar";
} else {
hideTitle = "Show Selected Token(s) in Sidebar";
}
return (
<Flex
sx={{
position: "absolute",
bottom: 0,
left: 0,
right: 0,
justifyContent: "space-between",
}}
bg="overlay"
>
<Close
title="Clear Selection"
aria-label="Clear Selection"
onClick={() => onGroupSelect()}
/>
<Flex>
<IconButton
aria-label={hideTitle}
title={hideTitle}
disabled={hasSelectedDefaultToken}
onClick={() => handleTokensHide(allTokensVisible)}
>
{allTokensVisible ? <TokenShowIcon /> : <TokenHideIcon />}
</IconButton>
<IconButton
aria-label="Remove Selected Token(s)"
title="Remove Selected Token(s)"
onClick={() => handleTokensRemove()}
disabled={hasSelectedDefaultToken}
>
<RemoveTokenIcon />
</IconButton>
</Flex>
<ConfirmModal
isOpen={isTokensRemoveModalOpen}
onRequestClose={() => setIsTokensRemoveModalOpen(false)}
onConfirm={handleTokensRemove}
confirmText="Remove"
label="Remove Selected Token(s)"
description="This operation cannot be undone."
/>
</Flex>
);
}
export default TokenEditBar;

View File

@ -11,16 +11,13 @@ import ImageDrop from "../components/ImageDrop";
import LoadingOverlay from "../components/LoadingOverlay";
import TokenTiles from "../components/token/TokenTiles";
import TokenEditBar from "../components/token/TokenEditBar";
import TilesOverlay from "../components/tile/TilesOverlay";
import TilesContainer from "../components/tile/TilesContainer";
import TilesAddDroppable from "../components/tile/TilesAddDroppable";
import {
groupsFromIds,
itemsFromGroups,
getGroupItems,
} from "../helpers/group";
import { getGroupItems } from "../helpers/group";
import {
createTokenFromFile,
createTokenState,
@ -32,14 +29,11 @@ import useResponsiveLayout from "../hooks/useResponsiveLayout";
import { useTokenData } from "../contexts/TokenDataContext";
import { useAuth } from "../contexts/AuthContext";
import { useKeyboard } from "../contexts/KeyboardContext";
import { useAssets } from "../contexts/AssetsContext";
import { GroupProvider } from "../contexts/GroupContext";
import { TileDragProvider } from "../contexts/TileDragContext";
import { useMapStage } from "../contexts/MapStageContext";
import shortcuts from "../shortcuts";
function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
const { addToast } = useToasts();
@ -47,8 +41,6 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
const {
tokens,
addToken,
removeTokens,
// updateTokens,
tokensLoading,
tokenGroups,
updateTokenGroups,
@ -132,32 +124,7 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
/**
* Token controls
*/
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [selectedGroupIds, setSelectedGroupIds] = useState([]);
function getSelectedTokens() {
const groups = groupsFromIds(selectedGroupIds, tokenGroups);
return itemsFromGroups(groups, tokens);
}
const [isTokensRemoveModalOpen, setIsTokensRemoveModalOpen] = useState(false);
async function handleTokensRemove() {
setIsLoading(true);
setIsTokensRemoveModalOpen(false);
const selectedTokens = getSelectedTokens();
const selectedTokenIds = selectedTokens.map((token) => token.id);
await removeTokens(selectedTokenIds);
setSelectedGroupIds([]);
setIsLoading(false);
}
// async function handleTokensHide(hideInSidebar) {
// setIsLoading(true);
// const selectedTokens = getSelectedTokens();
// const selectedTokenIds = selectedTokens.map((token) => token.id);
// await updateTokens(selectedTokenIds, { hideInSidebar });
// setIsLoading(false);
// }
const [editingTokenId, setEditingTokenId] = useState();
const mapStageRef = useMapStage();
function handleTokensAddToMap(groupIds, rect) {
@ -206,29 +173,6 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
}
}
/**
* Shortcuts
*/
function handleKeyDown(event) {
if (!isOpen) {
return;
}
if (shortcuts.delete(event)) {
const selectedTokens = getSelectedTokens();
// Selected tokens and none are default
if (
selectedTokens.length > 0 &&
!selectedTokens.some((token) => token.type === "default")
) {
// Ensure all other modals are closed
setIsEditModalOpen(false);
setIsTokensRemoveModalOpen(true);
}
}
}
useKeyboard(handleKeyDown);
const layout = useResponsiveLayout();
const [modalSize, setModalSize] = useState({ width: 0, height: 0 });
@ -256,27 +200,26 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
handleHeight
onResize={handleModalResize}
>
<Flex
sx={{
flexDirection: "column",
}}
<GroupProvider
groups={tokenGroups}
onGroupsChange={updateTokenGroups}
disabled={!isOpen}
>
<Label pt={2} pb={1}>
Edit or import a token
</Label>
<Box sx={{ position: "relative" }}>
<GroupProvider
groups={tokenGroups}
onGroupsChange={updateTokenGroups}
onGroupsSelect={setSelectedGroupIds}
disabled={!isOpen}
>
<Flex
sx={{
flexDirection: "column",
}}
>
<Label pt={2} pb={1}>
Edit or import a token
</Label>
<Box sx={{ position: "relative" }}>
<TileDragProvider onDragAdd={handleTokensAddToMap}>
<TilesAddDroppable containerSize={modalSize} />
<TilesContainer>
<TokenTiles
tokens={tokens}
onTokenEdit={() => setIsEditModalOpen(true)}
onTokenEdit={setEditingTokenId}
/>
</TilesContainer>
</TileDragProvider>
@ -285,42 +228,36 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
<TilesOverlay>
<TokenTiles
tokens={tokens}
onTokenEdit={() => setIsEditModalOpen(true)}
onTokenEdit={setEditingTokenId}
subgroup
/>
</TilesOverlay>
</TileDragProvider>
</GroupProvider>
</Box>
<Button
variant="primary"
disabled={isLoading}
onClick={onRequestClose}
mt={2}
>
Done
</Button>
</Flex>
<TokenEditBar
onLoad={setIsLoading}
disabled={isLoading || !isOpen}
/>
</Box>
<Button
variant="primary"
disabled={isLoading}
onClick={onRequestClose}
mt={2}
>
Done
</Button>
</Flex>
</GroupProvider>
</ReactResizeDetector>
</ImageDrop>
{(isLoading || tokensLoading) && <LoadingOverlay bg="overlay" />}
<EditTokenModal
isOpen={isEditModalOpen}
onDone={() => setIsEditModalOpen(false)}
isOpen={!!editingTokenId}
onDone={() => setEditingTokenId()}
token={
selectedGroupIds.length === 1 &&
tokens.find((token) => token.id === selectedGroupIds[0])
editingTokenId && tokens.find((token) => token.id === editingTokenId)
}
onTokenUpdate={updateToken}
/>
<ConfirmModal
isOpen={isTokensRemoveModalOpen}
onRequestClose={() => setIsTokensRemoveModalOpen(false)}
onConfirm={handleTokensRemove}
confirmText="Remove"
label="Remove Token(s)"
description="This operation cannot be undone."
onUpdateToken={updateToken}
/>
<ConfirmModal
isOpen={isLargeImageWarningModalOpen}