Styled global drop and allow for adding to map on drop

This commit is contained in:
Mitchell McCaffrey 2021-06-07 22:25:36 +10:00
parent eb9afcc66a
commit 3ef61cac26
3 changed files with 66 additions and 14 deletions

View File

@ -8,22 +8,30 @@ import ConfirmModal from "../../modals/ConfirmModal";
import { createMapFromFile } from "../../helpers/map"; import { createMapFromFile } from "../../helpers/map";
import { createTokenFromFile } from "../../helpers/token"; import { createTokenFromFile } from "../../helpers/token";
import {
createTokenState,
clientPositionToMapPosition,
} from "../../helpers/token";
import Vector2 from "../../helpers/Vector2";
import { useAuth } from "../../contexts/AuthContext"; import { useAuth } from "../../contexts/AuthContext";
import { useMapData } from "../../contexts/MapDataContext"; import { useMapData } from "../../contexts/MapDataContext";
import { useTokenData } from "../../contexts/TokenDataContext"; import { useTokenData } from "../../contexts/TokenDataContext";
import { useAssets } from "../../contexts/AssetsContext"; import { useAssets } from "../../contexts/AssetsContext";
import { useMapStage } from "../../contexts/MapStageContext";
import useImageDrop from "../../hooks/useImageDrop"; import useImageDrop from "../../hooks/useImageDrop";
function GlobalImageDrop({ children, onMapTokensStateCreate }) { function GlobalImageDrop({ children, onMapChange, onMapTokensStateCreate }) {
const { addToast } = useToasts(); const { addToast } = useToasts();
const { userId } = useAuth(); const { userId } = useAuth();
const { addMap } = useMapData(); const { addMap, getMapState } = useMapData();
const { addToken } = useTokenData(); const { addToken } = useTokenData();
const { addAssets } = useAssets(); const { addAssets } = useAssets();
const mapStageRef = useMapStage();
const [isLargeImageWarningModalOpen, setShowLargeImageWarning] = useState( const [isLargeImageWarningModalOpen, setShowLargeImageWarning] = useState(
false false
); );
@ -80,24 +88,57 @@ function GlobalImageDrop({ children, onMapTokensStateCreate }) {
async function handleMaps() { async function handleMaps() {
setIsLoading(true); setIsLoading(true);
let maps = [];
for (let file of droppedImagesRef.current) { for (let file of droppedImagesRef.current) {
const { map, assets } = await createMapFromFile(file, userId); const { map, assets } = await createMapFromFile(file, userId);
await addMap(map); await addMap(map);
await addAssets(assets); await addAssets(assets);
maps.push(map);
} }
// Change map if only 1 dropped
if (maps.length === 1) {
const mapState = await getMapState(maps[0].id);
onMapChange(maps[0], mapState);
}
setIsLoading(false); setIsLoading(false);
droppedImagesRef.current = undefined; droppedImagesRef.current = undefined;
} }
async function handleTokens() { async function handleTokens() {
setIsLoading(true); setIsLoading(true);
// Keep track of tokens so we can add them to the map
let tokens = [];
for (let file of droppedImagesRef.current) { for (let file of droppedImagesRef.current) {
const { token, assets } = await createTokenFromFile(file, userId); const { token, assets } = await createTokenFromFile(file, userId);
await addToken(token); await addToken(token);
await addAssets(assets); await addAssets(assets);
tokens.push(token);
} }
setIsLoading(false); setIsLoading(false);
droppedImagesRef.current = undefined; droppedImagesRef.current = undefined;
const dropPosition = dropPositionRef.current;
const mapStage = mapStageRef.current;
if (mapStage && dropPosition) {
const mapPosition = clientPositionToMapPosition(mapStage, dropPosition);
if (mapPosition) {
let tokenStates = [];
let offset = new Vector2(0, 0);
for (let token of tokens) {
if (token) {
tokenStates.push(
createTokenState(token, Vector2.add(mapPosition, offset), userId)
);
offset = Vector2.add(offset, 0.01);
}
}
if (tokenStates.length > 0) {
onMapTokensStateCreate(tokenStates);
}
}
}
} }
function handleMapsOver() { function handleMapsOver() {
@ -131,31 +172,39 @@ function GlobalImageDrop({ children, onMapTokensStateCreate }) {
<Flex <Flex
bg="overlay" bg="overlay"
sx={{ sx={{
width: "100%", height: "10%",
height: "20%",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
opacity: droppingType === "maps" ? 1 : 0.5, color: droppingType === "maps" ? "primary" : "text",
opacity: droppingType === "maps" ? 1 : 0.8,
margin: "4px 16px",
border: "1px dashed",
width: "calc(100% - 32px)",
borderRadius: "12px",
}} }}
onDragEnter={handleMapsOver} onDragEnter={handleMapsOver}
> >
<Text sx={{ pointerEvents: "none" }}> <Text sx={{ pointerEvents: "none", userSelect: "none" }}>
{"Drop image to import as a map"} Drop as map
</Text> </Text>
</Flex> </Flex>
<Flex <Flex
bg="overlay" bg="overlay"
sx={{ sx={{
width: "100%", flexGrow: 1,
height: "80%",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
opacity: droppingType === "tokens" ? 1 : 0.5, color: droppingType === "tokens" ? "primary" : "text",
opacity: droppingType === "tokens" ? 1 : 0.8,
margin: "4px 16px",
border: "1px dashed",
width: "calc(100% - 32px)",
borderRadius: "12px",
}} }}
onDragEnter={handleTokensOver} onDragEnter={handleTokensOver}
> >
<Text sx={{ pointerEvents: "none" }}> <Text sx={{ pointerEvents: "none", userSelect: "none" }}>
{"Drop image to import as a token"} Drop as token
</Text> </Text>
</Flex> </Flex>
</Flex> </Flex>

View File

@ -25,7 +25,7 @@ function ImageDrop({ onDrop, dropText, children }) {
}} }}
{...overlayListeners} {...overlayListeners}
> >
<Text sx={{ pointerEvents: "none" }}> <Text sx={{ pointerEvents: "none", color: "primary" }}>
{dropText || "Drop image to import"} {dropText || "Drop image to import"}
</Text> </Text>
</Flex> </Flex>

View File

@ -459,7 +459,10 @@ function NetworkedMapAndTokens({ session }) {
} }
return ( return (
<GlobalImageDrop> <GlobalImageDrop
onMapChange={handleMapChange}
onMapTokensStateCreate={handleMapTokensStateCreate}
>
<Map <Map
map={currentMap} map={currentMap}
mapState={currentMapState} mapState={currentMapState}