Add back tile search and action bar
This commit is contained in:
parent
d6b6d6a1eb
commit
e3353c1c44
@ -20,18 +20,10 @@ function MapEditBar({ currentMap, disabled, onMapChange, onMapReset, onLoad }) {
|
|||||||
|
|
||||||
const { maps, mapStates, removeMaps, resetMap } = useMapData();
|
const { maps, mapStates, removeMaps, resetMap } = useMapData();
|
||||||
|
|
||||||
const {
|
const { activeGroups, selectedGroupIds, onGroupSelect } = useGroup();
|
||||||
groups: allGroups,
|
|
||||||
selectedGroupIds,
|
|
||||||
onGroupSelect,
|
|
||||||
openGroupId,
|
|
||||||
openGroupItems,
|
|
||||||
} = useGroup();
|
|
||||||
|
|
||||||
const groups = openGroupId ? openGroupItems : allGroups;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
|
const selectedGroups = groupsFromIds(selectedGroupIds, activeGroups);
|
||||||
const selectedMaps = itemsFromGroups(selectedGroups, maps);
|
const selectedMaps = itemsFromGroups(selectedGroups, maps);
|
||||||
const selectedMapStates = itemsFromGroups(
|
const selectedMapStates = itemsFromGroups(
|
||||||
selectedGroups,
|
selectedGroups,
|
||||||
@ -57,10 +49,10 @@ function MapEditBar({ currentMap, disabled, onMapChange, onMapReset, onLoad }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setHasMapState(_hasMapState);
|
setHasMapState(_hasMapState);
|
||||||
}, [selectedGroupIds, maps, mapStates, groups]);
|
}, [selectedGroupIds, maps, mapStates, activeGroups]);
|
||||||
|
|
||||||
function getSelectedMaps() {
|
function getSelectedMaps() {
|
||||||
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
|
const selectedGroups = groupsFromIds(selectedGroupIds, activeGroups);
|
||||||
return itemsFromGroups(selectedGroups, maps);
|
return itemsFromGroups(selectedGroups, maps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,18 +6,11 @@ import { useGroup } from "../../contexts/GroupContext";
|
|||||||
import { findGroup } from "../../helpers/group";
|
import { findGroup } from "../../helpers/group";
|
||||||
|
|
||||||
function SelectMapSelectButton({ onMapSelect, disabled }) {
|
function SelectMapSelectButton({ onMapSelect, disabled }) {
|
||||||
const {
|
const { activeGroups, selectedGroupIds } = useGroup();
|
||||||
groups: allGroups,
|
|
||||||
selectedGroupIds,
|
|
||||||
openGroupId,
|
|
||||||
openGroupItems,
|
|
||||||
} = useGroup();
|
|
||||||
|
|
||||||
const groups = openGroupId ? openGroupItems : allGroups;
|
|
||||||
|
|
||||||
function handleSelectClick() {
|
function handleSelectClick() {
|
||||||
if (selectedGroupIds.length === 1) {
|
if (selectedGroupIds.length === 1) {
|
||||||
const group = findGroup(groups, selectedGroupIds[0]);
|
const group = findGroup(activeGroups, selectedGroupIds[0]);
|
||||||
if (group && group.type === "item") {
|
if (group && group.type === "item") {
|
||||||
onMapSelect(group.id);
|
onMapSelect(group.id);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ function SortableTile({
|
|||||||
setDraggableNodeRef,
|
setDraggableNodeRef,
|
||||||
over,
|
over,
|
||||||
active,
|
active,
|
||||||
} = useSortable({ id, disabled: disableSorting });
|
} = useSortable({ id });
|
||||||
|
|
||||||
const { setNodeRef: setGroupNodeRef } = useDroppable({
|
const { setNodeRef: setGroupNodeRef } = useDroppable({
|
||||||
id: `${GROUP_ID_PREFIX}${id}`,
|
id: `${GROUP_ID_PREFIX}${id}`,
|
||||||
@ -42,7 +42,7 @@ function SortableTile({
|
|||||||
width: "2px",
|
width: "2px",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
borderRadius: "2px",
|
borderRadius: "2px",
|
||||||
visibility: over?.id === id ? "visible" : "hidden",
|
visibility: over?.id === id && !disableSorting ? "visible" : "hidden",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Group div center aligned
|
// Group div center aligned
|
||||||
|
@ -22,22 +22,29 @@ import { useGroup } from "../../contexts/GroupContext";
|
|||||||
function SortableTiles({ renderTile, subgroup }) {
|
function SortableTiles({ renderTile, subgroup }) {
|
||||||
const { dragId, overId, dragCursor } = useTileDrag();
|
const { dragId, overId, dragCursor } = useTileDrag();
|
||||||
const {
|
const {
|
||||||
groups: allGroups,
|
groups,
|
||||||
selectedGroupIds: allSelectedIds,
|
selectedGroupIds: allSelectedIds,
|
||||||
|
filter,
|
||||||
openGroupId,
|
openGroupId,
|
||||||
openGroupItems,
|
openGroupItems,
|
||||||
|
filteredGroupItems,
|
||||||
} = useGroup();
|
} = useGroup();
|
||||||
|
|
||||||
|
const activeGroups = subgroup
|
||||||
|
? openGroupItems
|
||||||
|
: filter
|
||||||
|
? filteredGroupItems
|
||||||
|
: groups;
|
||||||
|
|
||||||
const sortableId = subgroup ? GROUP_SORTABLE_ID : BASE_SORTABLE_ID;
|
const sortableId = subgroup ? GROUP_SORTABLE_ID : BASE_SORTABLE_ID;
|
||||||
|
|
||||||
const groups = subgroup ? openGroupItems : allGroups;
|
|
||||||
// Only populate selected groups if needed
|
// Only populate selected groups if needed
|
||||||
let selectedGroupIds = [];
|
let selectedGroupIds = [];
|
||||||
if ((subgroup && openGroupId) || (!subgroup && !openGroupId)) {
|
if ((subgroup && openGroupId) || (!subgroup && !openGroupId)) {
|
||||||
selectedGroupIds = allSelectedIds;
|
selectedGroupIds = allSelectedIds;
|
||||||
}
|
}
|
||||||
const disableSorting = openGroupId && !subgroup;
|
const disableSorting = (openGroupId && !subgroup) || filter;
|
||||||
const disableGrouping = subgroup || disableSorting;
|
const disableGrouping = subgroup || disableSorting || filter;
|
||||||
|
|
||||||
const dragBounce = useSpring({
|
const dragBounce = useSpring({
|
||||||
transform: !!dragId ? "scale(0.9)" : "scale(1)",
|
transform: !!dragId ? "scale(0.9)" : "scale(1)",
|
||||||
@ -63,9 +70,9 @@ function SortableTiles({ renderTile, subgroup }) {
|
|||||||
|
|
||||||
function renderDragOverlays() {
|
function renderDragOverlays() {
|
||||||
let selectedIndices = selectedGroupIds.map((groupId) =>
|
let selectedIndices = selectedGroupIds.map((groupId) =>
|
||||||
groups.findIndex((group) => group.id === groupId)
|
activeGroups.findIndex((group) => group.id === groupId)
|
||||||
);
|
);
|
||||||
const activeIndex = groups.findIndex((group) => group.id === dragId);
|
const activeIndex = activeGroups.findIndex((group) => group.id === dragId);
|
||||||
// Sort so the draging tile is the first element
|
// Sort so the draging tile is the first element
|
||||||
selectedIndices = selectedIndices.sort((a, b) =>
|
selectedIndices = selectedIndices.sort((a, b) =>
|
||||||
a === activeIndex ? -1 : b === activeIndex ? 1 : 0
|
a === activeIndex ? -1 : b === activeIndex ? 1 : 0
|
||||||
@ -81,7 +88,7 @@ function SortableTiles({ renderTile, subgroup }) {
|
|||||||
selectedIndices = selectedIndices.reverse();
|
selectedIndices = selectedIndices.reverse();
|
||||||
coords = coords.reverse();
|
coords = coords.reverse();
|
||||||
|
|
||||||
const selectedGroups = selectedIndices.map((index) => groups[index]);
|
const selectedGroups = selectedIndices.map((index) => activeGroups[index]);
|
||||||
|
|
||||||
return selectedGroups.map((group, index) => (
|
return selectedGroups.map((group, index) => (
|
||||||
<DragOverlay dropAnimation={null} key={group.id}>
|
<DragOverlay dropAnimation={null} key={group.id}>
|
||||||
@ -113,7 +120,7 @@ function SortableTiles({ renderTile, subgroup }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderTiles() {
|
function renderTiles() {
|
||||||
const groupsByIds = keyBy(groups, "id");
|
const groupsByIds = keyBy(activeGroups, "id");
|
||||||
const selectedGroupIdsSet = new Set(selectedGroupIds);
|
const selectedGroupIdsSet = new Set(selectedGroupIds);
|
||||||
let selectedGroups = [];
|
let selectedGroups = [];
|
||||||
let hasSelectedContainerGroup = false;
|
let hasSelectedContainerGroup = false;
|
||||||
@ -126,7 +133,7 @@ function SortableTiles({ renderTile, subgroup }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return groups.map((group) => {
|
return activeGroups.map((group) => {
|
||||||
const isDragging = dragId && selectedGroupIdsSet.has(group.id);
|
const isDragging = dragId && selectedGroupIdsSet.has(group.id);
|
||||||
const disableTileGrouping =
|
const disableTileGrouping =
|
||||||
disableGrouping || isDragging || hasSelectedContainerGroup;
|
disableGrouping || isDragging || hasSelectedContainerGroup;
|
||||||
@ -147,7 +154,7 @@ function SortableTiles({ renderTile, subgroup }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SortableContext items={groups} id={sortableId}>
|
<SortableContext items={activeGroups} id={sortableId}>
|
||||||
{renderTiles()}
|
{renderTiles()}
|
||||||
{createPortal(dragId && renderDragOverlays(), document.body)}
|
{createPortal(dragId && renderDragOverlays(), document.body)}
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Flex, IconButton } from "theme-ui";
|
import { Flex, IconButton } from "theme-ui";
|
||||||
|
|
||||||
import AddIcon from "../icons/AddIcon";
|
import AddIcon from "../../icons/AddIcon";
|
||||||
import SelectMultipleIcon from "../icons/SelectMultipleIcon";
|
import SelectMultipleIcon from "../../icons/SelectMultipleIcon";
|
||||||
import SelectSingleIcon from "../icons/SelectSingleIcon";
|
import SelectSingleIcon from "../../icons/SelectSingleIcon";
|
||||||
|
|
||||||
import Search from "./Search";
|
import Search from "../Search";
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "../RadioIconButton";
|
||||||
|
|
||||||
|
import { useGroup } from "../../contexts/GroupContext";
|
||||||
|
|
||||||
|
function TileActionBar({ onAdd, addTitle }) {
|
||||||
|
const {
|
||||||
|
selectMode,
|
||||||
|
onSelectModeChange,
|
||||||
|
onGroupSelect,
|
||||||
|
filter,
|
||||||
|
onFilterChange,
|
||||||
|
} = useGroup();
|
||||||
|
|
||||||
function FilterBar({
|
|
||||||
onFocus,
|
|
||||||
search,
|
|
||||||
onSearchChange,
|
|
||||||
selectMode,
|
|
||||||
onSelectModeChange,
|
|
||||||
onAdd,
|
|
||||||
addTitle,
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
bg="muted"
|
bg="muted"
|
||||||
@ -31,9 +33,9 @@ function FilterBar({
|
|||||||
outlineOffset: "0px",
|
outlineOffset: "0px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onFocus={onFocus}
|
onFocus={() => onGroupSelect()}
|
||||||
>
|
>
|
||||||
<Search value={search} onChange={onSearchChange} />
|
<Search value={filter} onChange={(e) => onFilterChange(e.target.value)} />
|
||||||
<Flex
|
<Flex
|
||||||
mr={1}
|
mr={1}
|
||||||
px={1}
|
px={1}
|
||||||
@ -66,4 +68,4 @@ function FilterBar({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FilterBar;
|
export default TileActionBar;
|
@ -18,31 +18,23 @@ import shortcuts from "../../shortcuts";
|
|||||||
function TokenEditBar({ disabled, onLoad }) {
|
function TokenEditBar({ disabled, onLoad }) {
|
||||||
const { tokens, removeTokens, updateTokensHidden } = useTokenData();
|
const { tokens, removeTokens, updateTokensHidden } = useTokenData();
|
||||||
|
|
||||||
const {
|
const { activeGroups, selectedGroupIds, onGroupSelect } = useGroup();
|
||||||
groups: allGroups,
|
|
||||||
selectedGroupIds,
|
|
||||||
onGroupSelect,
|
|
||||||
openGroupId,
|
|
||||||
openGroupItems,
|
|
||||||
} = useGroup();
|
|
||||||
|
|
||||||
const groups = openGroupId ? openGroupItems : allGroups;
|
|
||||||
|
|
||||||
const [hasSelectedDefaultToken, setHasSelectedDefaultToken] = useState(false);
|
const [hasSelectedDefaultToken, setHasSelectedDefaultToken] = useState(false);
|
||||||
const [allTokensVisible, setAllTokensVisisble] = useState(false);
|
const [allTokensVisible, setAllTokensVisisble] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
|
const selectedGroups = groupsFromIds(selectedGroupIds, activeGroups);
|
||||||
const selectedTokens = itemsFromGroups(selectedGroups, tokens);
|
const selectedTokens = itemsFromGroups(selectedGroups, tokens);
|
||||||
|
|
||||||
setHasSelectedDefaultToken(
|
setHasSelectedDefaultToken(
|
||||||
selectedTokens.some((token) => token.type === "default")
|
selectedTokens.some((token) => token.type === "default")
|
||||||
);
|
);
|
||||||
setAllTokensVisisble(selectedTokens.every((token) => !token.hideInSidebar));
|
setAllTokensVisisble(selectedTokens.every((token) => !token.hideInSidebar));
|
||||||
}, [selectedGroupIds, tokens, groups]);
|
}, [selectedGroupIds, tokens, activeGroups]);
|
||||||
|
|
||||||
function getSelectedTokens() {
|
function getSelectedTokens() {
|
||||||
const selectedGroups = groupsFromIds(selectedGroupIds, groups);
|
const selectedGroups = groupsFromIds(selectedGroupIds, activeGroups);
|
||||||
return itemsFromGroups(selectedGroups, tokens);
|
return itemsFromGroups(selectedGroups, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState, useContext, useEffect } from "react";
|
import React, { useState, useContext, useEffect } from "react";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
|
import Fuse from "fuse.js";
|
||||||
|
|
||||||
import { useKeyboard, useBlur } from "./KeyboardContext";
|
import { useKeyboard, useBlur } from "./KeyboardContext";
|
||||||
|
|
||||||
@ -11,17 +12,18 @@ const GroupContext = React.createContext();
|
|||||||
|
|
||||||
export function GroupProvider({
|
export function GroupProvider({
|
||||||
groups,
|
groups,
|
||||||
|
itemNames,
|
||||||
onGroupsChange,
|
onGroupsChange,
|
||||||
onGroupsSelect,
|
onGroupsSelect,
|
||||||
disabled,
|
disabled,
|
||||||
children,
|
children,
|
||||||
}) {
|
}) {
|
||||||
const [selectedGroupIds, setSelectedGroupIds] = useState([]);
|
const [selectedGroupIds, setSelectedGroupIds] = useState([]);
|
||||||
const [openGroupId, setOpenGroupId] = useState();
|
|
||||||
const [openGroupItems, setOpenGroupItems] = useState([]);
|
|
||||||
// Either single, multiple or range
|
// Either single, multiple or range
|
||||||
const [selectMode, setSelectMode] = useState("single");
|
const [selectMode, setSelectMode] = useState("single");
|
||||||
|
|
||||||
|
const [openGroupId, setOpenGroupId] = useState();
|
||||||
|
const [openGroupItems, setOpenGroupItems] = useState([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (openGroupId) {
|
if (openGroupId) {
|
||||||
setOpenGroupItems(getGroupItems(groupsFromIds([openGroupId], groups)[0]));
|
setOpenGroupItems(getGroupItems(groupsFromIds([openGroupId], groups)[0]));
|
||||||
@ -117,16 +119,58 @@ export function GroupProvider({
|
|||||||
|
|
||||||
useBlur(handleBlur);
|
useBlur(handleBlur);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search
|
||||||
|
*/
|
||||||
|
const [filter, setFilter] = useState();
|
||||||
|
const [filteredGroupItems, setFilteredGroupItems] = useState([]);
|
||||||
|
const [fuse, setFuse] = useState();
|
||||||
|
// Update search index when items change
|
||||||
|
useEffect(() => {
|
||||||
|
let items = [];
|
||||||
|
for (let group of groups) {
|
||||||
|
const itemsToAdd = getGroupItems(group);
|
||||||
|
const namedItems = itemsToAdd.map((item) => ({
|
||||||
|
...item,
|
||||||
|
name: itemNames[item.id],
|
||||||
|
}));
|
||||||
|
items.push(...namedItems);
|
||||||
|
}
|
||||||
|
setFuse(new Fuse(items, { keys: ["name"] }));
|
||||||
|
}, [groups, itemNames]);
|
||||||
|
|
||||||
|
// Perform search when search changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (filter) {
|
||||||
|
const query = fuse.search(filter);
|
||||||
|
setFilteredGroupItems(query.map((result) => result.item));
|
||||||
|
setOpenGroupId();
|
||||||
|
} else {
|
||||||
|
setFilteredGroupItems([]);
|
||||||
|
}
|
||||||
|
}, [filter, fuse]);
|
||||||
|
|
||||||
|
const activeGroups = openGroupId
|
||||||
|
? openGroupItems
|
||||||
|
: filter
|
||||||
|
? filteredGroupItems
|
||||||
|
: groups;
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
groups,
|
groups,
|
||||||
|
activeGroups,
|
||||||
openGroupId,
|
openGroupId,
|
||||||
openGroupItems,
|
openGroupItems,
|
||||||
|
filter,
|
||||||
|
filteredGroupItems,
|
||||||
selectedGroupIds,
|
selectedGroupIds,
|
||||||
selectMode,
|
selectMode,
|
||||||
|
onSelectModeChange: setSelectMode,
|
||||||
onGroupOpen: handleGroupOpen,
|
onGroupOpen: handleGroupOpen,
|
||||||
onGroupClose: handleGroupClose,
|
onGroupClose: handleGroupClose,
|
||||||
onGroupsChange: handleGroupsChange,
|
onGroupsChange: handleGroupsChange,
|
||||||
onGroupSelect: handleGroupSelect,
|
onGroupSelect: handleGroupSelect,
|
||||||
|
onFilterChange: setFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -136,6 +180,7 @@ export function GroupProvider({
|
|||||||
|
|
||||||
GroupProvider.defaultProps = {
|
GroupProvider.defaultProps = {
|
||||||
groups: [],
|
groups: [],
|
||||||
|
itemNames: {},
|
||||||
onGroupsChange: () => {},
|
onGroupsChange: () => {},
|
||||||
onGroupsSelect: () => {},
|
onGroupsSelect: () => {},
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
@ -23,19 +23,16 @@ export const ADD_TO_MAP_ID_PREFIX = "__add__";
|
|||||||
|
|
||||||
export function TileDragProvider({ onDragAdd, children }) {
|
export function TileDragProvider({ onDragAdd, children }) {
|
||||||
const {
|
const {
|
||||||
groups: allGroups,
|
groups,
|
||||||
|
activeGroups,
|
||||||
openGroupId,
|
openGroupId,
|
||||||
openGroupItems,
|
|
||||||
selectedGroupIds,
|
selectedGroupIds,
|
||||||
onGroupsChange,
|
onGroupsChange,
|
||||||
onGroupSelect,
|
onGroupSelect,
|
||||||
onGroupClose,
|
onGroupClose,
|
||||||
|
filter,
|
||||||
} = useGroup();
|
} = useGroup();
|
||||||
|
|
||||||
const groupOpen = !!openGroupId;
|
|
||||||
|
|
||||||
const groups = groupOpen ? openGroupItems : allGroups;
|
|
||||||
|
|
||||||
const mouseSensor = useSensor(MouseSensor, {
|
const mouseSensor = useSensor(MouseSensor, {
|
||||||
activationConstraint: { delay: 250, tolerance: 5 },
|
activationConstraint: { delay: 250, tolerance: 5 },
|
||||||
});
|
});
|
||||||
@ -83,7 +80,7 @@ export function TileDragProvider({ onDragAdd, children }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let selectedIndices = selectedGroupIds.map((groupId) =>
|
let selectedIndices = selectedGroupIds.map((groupId) =>
|
||||||
groups.findIndex((group) => group.id === groupId)
|
activeGroups.findIndex((group) => group.id === groupId)
|
||||||
);
|
);
|
||||||
// Maintain current group sorting
|
// Maintain current group sorting
|
||||||
selectedIndices = selectedIndices.sort((a, b) => a - b);
|
selectedIndices = selectedIndices.sort((a, b) => a - b);
|
||||||
@ -96,15 +93,17 @@ export function TileDragProvider({ onDragAdd, children }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const overGroupIndex = groups.findIndex((group) => group.id === overId);
|
const overGroupIndex = activeGroups.findIndex(
|
||||||
|
(group) => group.id === overId
|
||||||
|
);
|
||||||
onGroupsChange(
|
onGroupsChange(
|
||||||
moveGroupsInto(groups, overGroupIndex, selectedIndices),
|
moveGroupsInto(activeGroups, overGroupIndex, selectedIndices),
|
||||||
openGroupId
|
openGroupId
|
||||||
);
|
);
|
||||||
} else if (over.id.startsWith(UNGROUP_ID_PREFIX)) {
|
} else if (over.id.startsWith(UNGROUP_ID_PREFIX)) {
|
||||||
onGroupSelect();
|
onGroupSelect();
|
||||||
// Handle tile ungroup
|
// Handle tile ungroup
|
||||||
const newGroups = ungroup(allGroups, openGroupId, selectedIndices);
|
const newGroups = ungroup(groups, openGroupId, selectedIndices);
|
||||||
// Close group if it was removed
|
// Close group if it was removed
|
||||||
if (!newGroups.find((group) => group.id === openGroupId)) {
|
if (!newGroups.find((group) => group.id === openGroupId)) {
|
||||||
onGroupClose();
|
onGroupClose();
|
||||||
@ -112,11 +111,13 @@ export function TileDragProvider({ onDragAdd, children }) {
|
|||||||
onGroupsChange(newGroups);
|
onGroupsChange(newGroups);
|
||||||
} else if (over.id.startsWith(ADD_TO_MAP_ID_PREFIX)) {
|
} else if (over.id.startsWith(ADD_TO_MAP_ID_PREFIX)) {
|
||||||
onDragAdd && onDragAdd(selectedGroupIds, over.rect);
|
onDragAdd && onDragAdd(selectedGroupIds, over.rect);
|
||||||
} else {
|
} else if (!filter) {
|
||||||
// Hanlde tile move
|
// Hanlde tile move only if we have no filter
|
||||||
const overGroupIndex = groups.findIndex((group) => group.id === over.id);
|
const overGroupIndex = activeGroups.findIndex(
|
||||||
|
(group) => group.id === over.id
|
||||||
|
);
|
||||||
onGroupsChange(
|
onGroupsChange(
|
||||||
moveGroups(groups, overGroupIndex, selectedIndices),
|
moveGroups(activeGroups, overGroupIndex, selectedIndices),
|
||||||
openGroupId
|
openGroupId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -124,7 +125,7 @@ export function TileDragProvider({ onDragAdd, children }) {
|
|||||||
|
|
||||||
function customCollisionDetection(rects, rect) {
|
function customCollisionDetection(rects, rect) {
|
||||||
// Handle group rects
|
// Handle group rects
|
||||||
if (groupOpen) {
|
if (openGroupId) {
|
||||||
const ungroupRects = rects.filter(([id]) =>
|
const ungroupRects = rects.filter(([id]) =>
|
||||||
id.startsWith(UNGROUP_ID_PREFIX)
|
id.startsWith(UNGROUP_ID_PREFIX)
|
||||||
);
|
);
|
||||||
|
@ -208,3 +208,16 @@ export function findGroup(groups, groupId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform and item array to a record of item ids to item names
|
||||||
|
* @param {any[]} items
|
||||||
|
* @param {string=} itemKey
|
||||||
|
*/
|
||||||
|
export function getItemNames(items, itemKey = "id") {
|
||||||
|
let names = {};
|
||||||
|
for (let item of items) {
|
||||||
|
names[item[itemKey]] = item.name;
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState, useEffect } from "react";
|
||||||
import { Flex, Label, Box } from "theme-ui";
|
import { Flex, Label, Box } from "theme-ui";
|
||||||
import { useToasts } from "react-toast-notifications";
|
import { useToasts } from "react-toast-notifications";
|
||||||
import ReactResizeDetector from "react-resize-detector";
|
import ReactResizeDetector from "react-resize-detector";
|
||||||
@ -17,8 +17,9 @@ import SelectMapSelectButton from "../components/map/SelectMapSelectButton";
|
|||||||
import TilesOverlay from "../components/tile/TilesOverlay";
|
import TilesOverlay from "../components/tile/TilesOverlay";
|
||||||
import TilesContainer from "../components/tile/TilesContainer";
|
import TilesContainer from "../components/tile/TilesContainer";
|
||||||
import TilesAddDroppable from "../components/tile/TilesAddDroppable";
|
import TilesAddDroppable from "../components/tile/TilesAddDroppable";
|
||||||
|
import TileActionBar from "../components/tile/TileActionBar";
|
||||||
|
|
||||||
import { findGroup } from "../helpers/group";
|
import { findGroup, getItemNames } from "../helpers/group";
|
||||||
import { createMapFromFile } from "../helpers/map";
|
import { createMapFromFile } from "../helpers/map";
|
||||||
|
|
||||||
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
||||||
@ -54,6 +55,12 @@ function SelectMapModal({
|
|||||||
} = useMapData();
|
} = useMapData();
|
||||||
const { addAssets } = useAssets();
|
const { addAssets } = useAssets();
|
||||||
|
|
||||||
|
// Get map names for group filtering
|
||||||
|
const [mapNames, setMapNames] = useState(getItemNames(maps));
|
||||||
|
useEffect(() => {
|
||||||
|
setMapNames(getItemNames(maps));
|
||||||
|
}, [maps]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Upload
|
* Image Upload
|
||||||
*/
|
*/
|
||||||
@ -102,6 +109,12 @@ function SelectMapModal({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openImageDialog() {
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleLargeImageWarningCancel() {
|
function handleLargeImageWarningCancel() {
|
||||||
largeImageWarningFiles.current = undefined;
|
largeImageWarningFiles.current = undefined;
|
||||||
setShowLargeImageWarning(false);
|
setShowLargeImageWarning(false);
|
||||||
@ -201,6 +214,7 @@ function SelectMapModal({
|
|||||||
>
|
>
|
||||||
<GroupProvider
|
<GroupProvider
|
||||||
groups={mapGroups}
|
groups={mapGroups}
|
||||||
|
itemNames={mapNames}
|
||||||
onGroupsChange={updateMapGroups}
|
onGroupsChange={updateMapGroups}
|
||||||
onGroupsSelect={handleGroupsSelect}
|
onGroupsSelect={handleGroupsSelect}
|
||||||
disabled={!isOpen}
|
disabled={!isOpen}
|
||||||
@ -213,6 +227,7 @@ function SelectMapModal({
|
|||||||
<Label pt={2} pb={1}>
|
<Label pt={2} pb={1}>
|
||||||
Select or import a map
|
Select or import a map
|
||||||
</Label>
|
</Label>
|
||||||
|
<TileActionBar onAdd={openImageDialog} addTitle="Import Map(s)" />
|
||||||
<Box sx={{ position: "relative" }}>
|
<Box sx={{ position: "relative" }}>
|
||||||
<TileDragProvider onDragAdd={canAddDraggedMap && handleDragAdd}>
|
<TileDragProvider onDragAdd={canAddDraggedMap && handleDragAdd}>
|
||||||
<TilesAddDroppable containerSize={modalSize} />
|
<TilesAddDroppable containerSize={modalSize} />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useState } from "react";
|
import React, { useRef, useState, useEffect } from "react";
|
||||||
import { Flex, Label, Button, Box } from "theme-ui";
|
import { Flex, Label, Button, Box } from "theme-ui";
|
||||||
import { useToasts } from "react-toast-notifications";
|
import { useToasts } from "react-toast-notifications";
|
||||||
import ReactResizeDetector from "react-resize-detector";
|
import ReactResizeDetector from "react-resize-detector";
|
||||||
@ -16,8 +16,9 @@ import TokenEditBar from "../components/token/TokenEditBar";
|
|||||||
import TilesOverlay from "../components/tile/TilesOverlay";
|
import TilesOverlay from "../components/tile/TilesOverlay";
|
||||||
import TilesContainer from "../components/tile/TilesContainer";
|
import TilesContainer from "../components/tile/TilesContainer";
|
||||||
import TilesAddDroppable from "../components/tile/TilesAddDroppable";
|
import TilesAddDroppable from "../components/tile/TilesAddDroppable";
|
||||||
|
import TileActionBar from "../components/tile/TileActionBar";
|
||||||
|
|
||||||
import { getGroupItems } from "../helpers/group";
|
import { getGroupItems, getItemNames } from "../helpers/group";
|
||||||
import {
|
import {
|
||||||
createTokenFromFile,
|
createTokenFromFile,
|
||||||
createTokenState,
|
createTokenState,
|
||||||
@ -49,6 +50,12 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
|
|||||||
} = useTokenData();
|
} = useTokenData();
|
||||||
const { addAssets } = useAssets();
|
const { addAssets } = useAssets();
|
||||||
|
|
||||||
|
// Get token names for group filtering
|
||||||
|
const [tokenNames, setTokenNames] = useState(getItemNames(tokens));
|
||||||
|
useEffect(() => {
|
||||||
|
setTokenNames(getItemNames(tokens));
|
||||||
|
}, [tokens]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Upload
|
* Image Upload
|
||||||
*/
|
*/
|
||||||
@ -97,6 +104,12 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openImageDialog() {
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleLargeImageWarningCancel() {
|
function handleLargeImageWarningCancel() {
|
||||||
largeImageWarningFiles.current = undefined;
|
largeImageWarningFiles.current = undefined;
|
||||||
setShowLargeImageWarning(false);
|
setShowLargeImageWarning(false);
|
||||||
@ -202,6 +215,7 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
|
|||||||
>
|
>
|
||||||
<GroupProvider
|
<GroupProvider
|
||||||
groups={tokenGroups}
|
groups={tokenGroups}
|
||||||
|
itemNames={tokenNames}
|
||||||
onGroupsChange={updateTokenGroups}
|
onGroupsChange={updateTokenGroups}
|
||||||
disabled={!isOpen}
|
disabled={!isOpen}
|
||||||
>
|
>
|
||||||
@ -213,6 +227,10 @@ function SelectTokensModal({ isOpen, onRequestClose, onMapTokensStateCreate }) {
|
|||||||
<Label pt={2} pb={1}>
|
<Label pt={2} pb={1}>
|
||||||
Edit or import a token
|
Edit or import a token
|
||||||
</Label>
|
</Label>
|
||||||
|
<TileActionBar
|
||||||
|
onAdd={openImageDialog}
|
||||||
|
addTitle="Import Token(s)"
|
||||||
|
/>
|
||||||
<Box sx={{ position: "relative" }}>
|
<Box sx={{ position: "relative" }}>
|
||||||
<TileDragProvider onDragAdd={handleTokensAddToMap}>
|
<TileDragProvider onDragAdd={handleTokensAddToMap}>
|
||||||
<TilesAddDroppable containerSize={modalSize} />
|
<TilesAddDroppable containerSize={modalSize} />
|
||||||
|
Loading…
Reference in New Issue
Block a user