Files
grungnet/src/components/map/MapTiles.js

213 lines
5.8 KiB
JavaScript
Raw Normal View History

2021-05-20 12:22:07 +10:00
import React, { useEffect, useState } from "react";
import { Flex, Box, Text, IconButton, Close, Grid } from "theme-ui";
2020-04-25 00:42:23 +10:00
import SimpleBar from "simplebar-react";
import RemoveMapIcon from "../../icons/RemoveMapIcon";
import ResetMapIcon from "../../icons/ResetMapIcon";
import MapTile from "./MapTile";
2021-05-14 18:02:50 +10:00
import MapTileGroup from "./MapTileGroup";
import Link from "../Link";
import FilterBar from "../FilterBar";
2021-05-13 16:26:59 +10:00
import Sortable from "../drag/Sortable";
import SortableTiles from "../drag/SortableTiles";
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
2021-05-20 12:22:07 +10:00
import { groupsFromIds, itemsFromGroups } from "../../helpers/select";
function MapTiles({
maps,
2021-05-20 12:22:07 +10:00
mapStates,
2020-10-01 15:05:30 +10:00
groups,
2021-05-20 12:22:07 +10:00
selectedGroupIds,
onTileSelect,
onMapsRemove,
onMapsReset,
onMapAdd,
onMapEdit,
onDone,
selectMode,
onSelectModeChange,
2020-09-30 15:39:56 +10:00
search,
onSearchChange,
2020-10-01 15:05:30 +10:00
onMapsGroup,
2021-05-20 12:22:07 +10:00
databaseDisabled,
}) {
const layout = useResponsiveLayout();
2021-05-20 12:22:07 +10:00
const [hasMapState, setHasMapState] = useState(false);
const [hasSelectedDefaultMap, setHasSelectedDefaultMap] = useState(false);
useEffect(() => {
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
const selectedMaps = itemsFromGroups(selectedGroups, maps);
const selectedMapStates = itemsFromGroups(
selectedGroups,
mapStates,
"mapId"
);
setHasSelectedDefaultMap(
selectedMaps.some((map) => map.type === "default")
);
let _hasMapState = false;
for (let state of selectedMapStates) {
if (
Object.values(state.tokens).length > 0 ||
Object.values(state.drawShapes).length > 0 ||
Object.values(state.fogShapes).length > 0 ||
Object.values(state.notes).length > 0
) {
_hasMapState = true;
break;
}
2020-09-30 13:58:43 +10:00
}
2021-05-20 12:22:07 +10:00
setHasMapState(_hasMapState);
}, [selectedGroupIds, maps, mapStates, groups]);
2021-05-14 18:02:50 +10:00
function groupToMapTile(group) {
if (group.type === "item") {
const map = maps.find((map) => map.id === group.id);
2021-05-20 12:22:07 +10:00
const isSelected = selectedGroupIds.includes(group.id);
2021-05-14 18:02:50 +10:00
return (
<MapTile
key={map.id}
map={map}
isSelected={isSelected}
2021-05-20 12:22:07 +10:00
onSelect={onTileSelect}
onEdit={onMapEdit}
2021-05-14 18:02:50 +10:00
onDone={onDone}
canEdit={
2021-05-20 12:22:07 +10:00
isSelected &&
selectMode === "single" &&
selectedGroupIds.length === 1
2021-05-14 18:02:50 +10:00
}
badges={[`${map.grid.size.x}x${map.grid.size.y}`]}
/>
);
} else {
2021-05-20 12:22:07 +10:00
const isSelected = selectedGroupIds.includes(group.id);
2021-05-14 18:02:50 +10:00
return (
<MapTileGroup
key={group.id}
group={group}
maps={group.items.map((item) =>
maps.find((map) => map.id === item.id)
)}
2021-05-20 12:22:07 +10:00
isSelected={isSelected}
onSelect={onTileSelect}
2021-05-14 18:02:50 +10:00
/>
);
}
2020-10-01 15:05:30 +10:00
}
2021-05-20 12:22:07 +10:00
const multipleSelected = selectedGroupIds.length > 1;
2020-10-01 15:05:30 +10:00
return (
2021-05-13 16:26:59 +10:00
<SortableTiles
groups={groups}
onGroupChange={onMapsGroup}
2021-05-14 18:02:50 +10:00
renderTile={groupToMapTile}
2021-05-13 16:26:59 +10:00
>
<Box sx={{ position: "relative" }}>
<FilterBar
2021-05-20 12:22:07 +10:00
onFocus={() => onTileSelect()}
2021-05-13 16:26:59 +10:00
search={search}
onSearchChange={onSearchChange}
selectMode={selectMode}
onSelectModeChange={onSelectModeChange}
onAdd={onMapAdd}
addTitle="Add Map"
/>
<SimpleBar
style={{
height: layout.screenSize === "large" ? "600px" : "400px",
}}
>
<Grid
p={2}
pb={4}
2021-05-20 12:22:07 +10:00
pt={databaseDisabled ? 4 : 2}
2021-05-13 16:26:59 +10:00
bg="muted"
sx={{
borderRadius: "4px",
minHeight: layout.screenSize === "large" ? "600px" : "400px",
overflow: "hidden",
}}
gap={2}
columns={layout.gridTemplate}
2021-05-20 12:22:07 +10:00
onClick={() => onTileSelect()}
2021-05-13 16:26:59 +10:00
>
2021-05-14 18:02:50 +10:00
{groups.map((group) => (
<Sortable id={group.id} key={group.id}>
{groupToMapTile(group)}
2021-05-13 16:26:59 +10:00
</Sortable>
))}
</Grid>
</SimpleBar>
2021-05-20 12:22:07 +10:00
{databaseDisabled && (
2021-05-13 16:26:59 +10:00
<Box
sx={{
position: "absolute",
top: "39px",
left: 0,
right: 0,
textAlign: "center",
borderRadius: "2px",
}}
bg="highlight"
p={1}
>
<Text as="p" variant="body2">
Map saving is unavailable. See <Link to="/faq#saving">FAQ</Link>{" "}
for more information.
</Text>
</Box>
)}
2021-05-20 12:22:07 +10:00
{selectedGroupIds.length > 0 && (
2021-05-13 16:26:59 +10:00
<Flex
sx={{
position: "absolute",
bottom: 0,
left: 0,
right: 0,
justifyContent: "space-between",
}}
2021-05-13 16:26:59 +10:00
bg="overlay"
>
2021-05-13 16:26:59 +10:00
<Close
title="Clear Selection"
aria-label="Clear Selection"
2021-05-20 12:22:07 +10:00
onClick={() => onTileSelect()}
2021-05-13 16:26:59 +10:00
/>
<Flex>
<IconButton
aria-label={multipleSelected ? "Reset Maps" : "Reset Map"}
title={multipleSelected ? "Reset Maps" : "Reset Map"}
onClick={() => onMapsReset()}
disabled={!hasMapState}
>
<ResetMapIcon />
</IconButton>
<IconButton
aria-label={multipleSelected ? "Remove Maps" : "Remove Map"}
title={multipleSelected ? "Remove Maps" : "Remove Map"}
onClick={() => onMapsRemove()}
disabled={hasSelectedDefaultMap}
>
<RemoveMapIcon />
</IconButton>
</Flex>
2021-05-13 16:26:59 +10:00
</Flex>
2021-05-09 19:17:55 +10:00
)}
2021-05-13 16:26:59 +10:00
</Box>
</SortableTiles>
);
}
export default MapTiles;