Ensure order of selected tiles is kept when moving them
This commit is contained in:
parent
dd130a008e
commit
69eafb868c
@ -66,7 +66,6 @@ function MapTiles({ maps, onMapEdit, onMapSelect, subgroup, columns }) {
|
||||
onTileSelect={onGroupSelect}
|
||||
disableGrouping={subgroup}
|
||||
openGroupId={openGroupId}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ import {
|
||||
useSensors,
|
||||
closestCenter,
|
||||
} from "@dnd-kit/core";
|
||||
import { SortableContext, arrayMove } from "@dnd-kit/sortable";
|
||||
import { SortableContext } from "@dnd-kit/sortable";
|
||||
import { animated, useSpring, config } from "react-spring";
|
||||
import { Badge } from "theme-ui";
|
||||
|
||||
import { moveGroups } from "../../helpers/group";
|
||||
import { moveGroupsInto, moveGroups } from "../../helpers/group";
|
||||
import { keyBy } from "../../helpers/shared";
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
|
||||
@ -27,7 +27,6 @@ function SortableTiles({
|
||||
onTileSelect,
|
||||
disableGrouping,
|
||||
openGroupId,
|
||||
columns,
|
||||
}) {
|
||||
const mouseSensor = useSensor(MouseSensor, {
|
||||
activationConstraint: { delay: 250, tolerance: 5 },
|
||||
@ -60,29 +59,28 @@ function SortableTiles({
|
||||
return;
|
||||
}
|
||||
|
||||
let selectedIndices = selectedGroupIds.map((groupId) =>
|
||||
groups.findIndex((group) => group.id === groupId)
|
||||
);
|
||||
// Maintain current group sorting
|
||||
selectedIndices = selectedIndices.sort((a, b) => a - b);
|
||||
|
||||
if (over.id.startsWith("__group__")) {
|
||||
const overId = over.id.slice(9);
|
||||
if (overId === active.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newGroups = groups;
|
||||
const overGroupIndex = groups.findIndex((group) => group.id === overId);
|
||||
const selectedGroupIndices = selectedGroupIds.map((groupId) =>
|
||||
groups.findIndex((group) => group.id === groupId)
|
||||
);
|
||||
onGroupChange(
|
||||
moveGroups(newGroups, overGroupIndex, selectedGroupIndices)
|
||||
);
|
||||
onGroupChange(moveGroupsInto(groups, overGroupIndex, selectedIndices));
|
||||
onTileSelect();
|
||||
} else if (active.id !== over.id) {
|
||||
let newGroups = groups;
|
||||
for (let groupId of selectedGroupIds) {
|
||||
const oldIndex = newGroups.findIndex((group) => group.id === groupId);
|
||||
const newIndex = newGroups.findIndex((group) => group.id === over.id);
|
||||
newGroups = arrayMove(newGroups, oldIndex, newIndex);
|
||||
} else {
|
||||
if (active.id === over.id) {
|
||||
return;
|
||||
}
|
||||
onGroupChange(newGroups);
|
||||
|
||||
const overGroupIndex = groups.findIndex((group) => group.id === over.id);
|
||||
onGroupChange(moveGroups(groups, overGroupIndex, selectedIndices));
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +96,7 @@ function SortableTiles({
|
||||
function renderSortableGroup(group, selectedGroups) {
|
||||
if (overGroupId === group.id && dragId && group.id !== dragId) {
|
||||
// If dragging over a group render a preview of that group
|
||||
const previewGroup = moveGroups(
|
||||
const previewGroup = moveGroupsInto(
|
||||
[group, ...selectedGroups],
|
||||
0,
|
||||
selectedGroups.map((_, i) => i + 1)
|
||||
|
@ -6,7 +6,7 @@ import { useGroup } from "../../contexts/GroupContext";
|
||||
|
||||
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
|
||||
|
||||
function TilesContainer({ columns, children }) {
|
||||
function TilesContainer({ children }) {
|
||||
const { onGroupSelect } = useGroup();
|
||||
|
||||
const layout = useResponsiveLayout();
|
||||
@ -31,7 +31,7 @@ function TilesContainer({ columns, children }) {
|
||||
overflow: "hidden",
|
||||
}}
|
||||
gap={2}
|
||||
columns={`repeat(${columns}, 1fr)`}
|
||||
columns={`repeat(${layout.tileGridColumns}, 1fr)`}
|
||||
>
|
||||
{children}
|
||||
</Grid>
|
||||
|
@ -6,9 +6,13 @@ import SimpleBar from "simplebar-react";
|
||||
|
||||
import { useGroup } from "../../contexts/GroupContext";
|
||||
|
||||
function TilesOverlay({ columns, children }) {
|
||||
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
|
||||
|
||||
function TilesOverlay({ children }) {
|
||||
const { openGroupId, onGroupClose, onGroupSelect } = useGroup();
|
||||
|
||||
const layout = useResponsiveLayout();
|
||||
|
||||
const openAnimation = useSpring({
|
||||
opacity: openGroupId ? 1 : 0,
|
||||
transform: openGroupId ? "scale(1)" : "scale(0.99)",
|
||||
@ -88,7 +92,7 @@ function TilesOverlay({ columns, children }) {
|
||||
overflow: "hidden",
|
||||
}}
|
||||
gap={2}
|
||||
columns={`repeat(${columns}, 1fr)`}
|
||||
columns={`repeat(${layout.groupGridColumns}, 1fr)`}
|
||||
px={3}
|
||||
>
|
||||
{children}
|
||||
|
@ -9,7 +9,7 @@ import { getGroupItems } from "../../helpers/group";
|
||||
|
||||
import { useGroup } from "../../contexts/GroupContext";
|
||||
|
||||
function TokenTiles({ tokens, onTokenEdit, subgroup, columns }) {
|
||||
function TokenTiles({ tokens, onTokenEdit, subgroup }) {
|
||||
const {
|
||||
groups,
|
||||
selectedGroupIds,
|
||||
@ -71,7 +71,6 @@ function TokenTiles({ tokens, onTokenEdit, subgroup, columns }) {
|
||||
onTileSelect={onGroupSelect}
|
||||
disableGrouping={subgroup}
|
||||
openGroupId={openGroupId}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -99,28 +99,28 @@ export function combineGroups(a, b) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Immutably move group at indices `from` into index `to`
|
||||
* Immutably move group at indices `indices` into group at index `into`
|
||||
* @param {Group[]} groups
|
||||
* @param {number} to
|
||||
* @param {number[]} from
|
||||
* @param {number} into
|
||||
* @param {number[]} indices
|
||||
* @returns {Group[]}
|
||||
*/
|
||||
export function moveGroups(groups, to, from) {
|
||||
export function moveGroupsInto(groups, into, indices) {
|
||||
const newGroups = cloneDeep(groups);
|
||||
|
||||
const toGroup = newGroups[to];
|
||||
const intoGroup = newGroups[into];
|
||||
let fromGroups = [];
|
||||
for (let i of from) {
|
||||
for (let i of indices) {
|
||||
fromGroups.push(newGroups[i]);
|
||||
}
|
||||
|
||||
let combined = toGroup;
|
||||
let combined = intoGroup;
|
||||
for (let fromGroup of fromGroups) {
|
||||
combined = combineGroups(combined, fromGroup);
|
||||
}
|
||||
|
||||
// Replace and remove old groups
|
||||
newGroups[to] = combined;
|
||||
newGroups[into] = combined;
|
||||
for (let fromGroup of fromGroups) {
|
||||
const i = newGroups.findIndex((group) => group.id === fromGroup.id);
|
||||
newGroups.splice(i, 1);
|
||||
@ -129,6 +129,33 @@ export function moveGroups(groups, to, from) {
|
||||
return newGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Immutably move group at indices `indices` to index `to`
|
||||
* @param {Group[]} groups
|
||||
* @param {number} into
|
||||
* @param {number[]} indices
|
||||
* @returns {Group[]}
|
||||
*/
|
||||
export function moveGroups(groups, to, indices) {
|
||||
const newGroups = cloneDeep(groups);
|
||||
|
||||
let fromGroups = [];
|
||||
for (let i of indices) {
|
||||
fromGroups.push(newGroups[i]);
|
||||
}
|
||||
|
||||
// Remove old groups
|
||||
for (let fromGroup of fromGroups) {
|
||||
const i = newGroups.findIndex((group) => group.id === fromGroup.id);
|
||||
newGroups.splice(i, 1);
|
||||
}
|
||||
|
||||
// Add back at new index
|
||||
newGroups.splice(to, 0, ...fromGroups);
|
||||
|
||||
return newGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively find a group within a group array
|
||||
* @param {Group[]} groups
|
||||
|
@ -259,21 +259,19 @@ function SelectMapModal({
|
||||
onGroupsSelect={setSelectedGroupIds}
|
||||
disabled={!isOpen}
|
||||
>
|
||||
<TilesContainer columns={layout.tileGridColumns}>
|
||||
<TilesContainer>
|
||||
<MapTiles
|
||||
maps={maps}
|
||||
onMapEdit={() => setIsEditModalOpen(true)}
|
||||
onMapSelect={handleMapSelect}
|
||||
columns={layout.tileGridColumns}
|
||||
/>
|
||||
</TilesContainer>
|
||||
<TilesOverlay columns={layout.groupGridColumns}>
|
||||
<TilesOverlay>
|
||||
<MapTiles
|
||||
maps={maps}
|
||||
onMapEdit={() => setIsEditModalOpen(true)}
|
||||
onMapSelect={handleMapSelect}
|
||||
subgroup
|
||||
columns={layout.groupGridColumns}
|
||||
/>
|
||||
</TilesOverlay>
|
||||
</GroupProvider>
|
||||
|
@ -200,19 +200,17 @@ function SelectTokensModal({ isOpen, onRequestClose }) {
|
||||
onGroupsSelect={setSelectedGroupIds}
|
||||
disabled={!isOpen}
|
||||
>
|
||||
<TilesContainer columns={layout.tileGridColumns}>
|
||||
<TilesContainer>
|
||||
<TokenTiles
|
||||
tokens={tokens}
|
||||
onTokenEdit={() => setIsEditModalOpen(true)}
|
||||
columns={layout.tileGridColumns}
|
||||
/>
|
||||
</TilesContainer>
|
||||
<TilesOverlay columns={layout.groupGridColumns}>
|
||||
<TilesOverlay>
|
||||
<TokenTiles
|
||||
tokens={tokens}
|
||||
onTokenEdit={() => setIsEditModalOpen(true)}
|
||||
subgroup
|
||||
columns={layout.groupGridColumns}
|
||||
/>
|
||||
</TilesOverlay>
|
||||
</GroupProvider>
|
||||
|
Loading…
Reference in New Issue
Block a user