Skip to content

Commit

Permalink
Fix holding feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmi committed May 13, 2024
1 parent 77e481e commit 6e6ac7e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 32 deletions.
37 changes: 33 additions & 4 deletions src/gameComponents/Image/Image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ const Image = ({
id: currentItemId,
}) => {
const { currentUser, localUsers: users } = useUsers();
const { register } = useItemInteraction("place");
const { register: registerPlace } = useItemInteraction("place");
const { register: registerDelete } = useItemInteraction("delete");
const { getItemList } = useItemActions();

const wrapperRef = React.useRef(null);
Expand Down Expand Up @@ -131,7 +132,6 @@ const Image = ({
itemIds,
shouldHoldItems: item.holdItems,
});

if (item.linkedItems !== newLinkedItems) {
return {
linkedItems: newLinkedItems,
Expand All @@ -142,16 +142,45 @@ const Image = ({
[currentItemId, getItemList, setState]
);

const onDeleteItem = React.useCallback(
(itemIds) => {
setState((item) => {
const safeLinkedItems = item.linkedItems || [];
const newLinkedItems = safeLinkedItems.filter(
(id) => !itemIds.includes(id)
);

if (safeLinkedItems.length !== newLinkedItems.length) {
return {
linkedItems: newLinkedItems,
};
}
}, true);
},
[setState]
);

React.useEffect(() => {
const unregisterList = [];
if (currentItemId) {
unregisterList.push(registerPlace(onPlaceItem));
}

return () => {
unregisterList.forEach((callback) => callback());
};
}, [currentItemId, onPlaceItem, registerPlace]);

React.useEffect(() => {
const unregisterList = [];
if (currentItemId) {
unregisterList.push(register(onPlaceItem));
unregisterList.push(registerDelete(onDeleteItem));
}

return () => {
unregisterList.forEach((callback) => callback());
};
}, [currentItemId, onPlaceItem, register]);
}, [currentItemId, onDeleteItem, registerDelete]);

return (
<Wrapper ref={wrapperRef}>
Expand Down
34 changes: 24 additions & 10 deletions src/gameComponents/useGameItemActions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import React from "react";

import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";
import { useItemActions, useUsers, useSelectedItems } from "react-sync-board";
import {
useItemActions,
useUsers,
useSelectedItems,
useItemInteraction,
} from "react-sync-board";

import {
shuffle as shuffleArray,
Expand Down Expand Up @@ -53,6 +58,7 @@ export const useGameItemActions = () => {
swapItems,
getItems,
} = useItemActions();
const { call: callPlaceInteractions } = useItemInteraction("place");

const { t } = useTranslation();

Expand Down Expand Up @@ -125,7 +131,7 @@ export const useGameItemActions = () => {

batchUpdateItems(
ids,
(item) => {
() => {
const newItem = {
x: newX,
y: newY,
Expand All @@ -136,8 +142,9 @@ export const useGameItemActions = () => {
},
true
);
callPlaceInteractions(ids);
},
[batchUpdateItems, getItemListOrSelected]
[batchUpdateItems, getItemListOrSelected, callPlaceInteractions]
);

// Stack selection to Top Left
Expand All @@ -162,7 +169,7 @@ export const useGameItemActions = () => {

batchUpdateItems(
ids,
(item) => {
() => {
const newItem = {
x: newX,
y: newY,
Expand All @@ -173,8 +180,9 @@ export const useGameItemActions = () => {
},
true
);
callPlaceInteractions(ids);
},
[batchUpdateItems, getItemListOrSelected]
[batchUpdateItems, getItemListOrSelected, callPlaceInteractions]
);

// Align selection to a line
Expand All @@ -198,8 +206,9 @@ export const useGameItemActions = () => {
},
true
);
callPlaceInteractions(ids);
},
[getItemListOrSelected, batchUpdateItems]
[getItemListOrSelected, batchUpdateItems, callPlaceInteractions]
);

// Align selection to an array
Expand Down Expand Up @@ -235,8 +244,9 @@ export const useGameItemActions = () => {
},
true
);
callPlaceInteractions(ids);
},
[getItemListOrSelected, batchUpdateItems]
[getItemListOrSelected, batchUpdateItems, callPlaceInteractions]
);

const snapToPoint = React.useCallback(
Expand All @@ -256,8 +266,9 @@ export const useGameItemActions = () => {
},
true
);
callPlaceInteractions(itemIds);
},
[batchUpdateItems]
[batchUpdateItems, callPlaceInteractions]
);

const roll = React.useCallback(
Expand Down Expand Up @@ -386,8 +397,10 @@ export const useGameItemActions = () => {
swapItems(ids, shuffledItems);

playAudio(shuffleAudio, 0.5);

callPlaceInteractions(ids);
},
[getItemListOrSelected, swapItems]
[getItemListOrSelected, callPlaceInteractions, swapItems]
);

const randomlyRotateSelectedItems = React.useCallback(
Expand Down Expand Up @@ -492,12 +505,13 @@ export const useGameItemActions = () => {
);
if (reverseOrder) {
reverseItemsOrder(itemIdsToFlip);
callPlaceInteractions(itemIds);
}
if (itemIdsToFlip.length) {
playAudio(flipAudio, 0.2);
}
},
[batchUpdateItems, getItems, reverseItemsOrder]
[batchUpdateItems, callPlaceInteractions, getItems, reverseItemsOrder]
);

// Toggle flip state
Expand Down
50 changes: 32 additions & 18 deletions src/utils/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,35 +117,49 @@ export const getHeldItems = ({
itemIds,
shouldHoldItems,
}) => {
const safeCurrentLinkedItems = currentLinkedItemIds || [];
const safeCurrentLinkedItems = Array.isArray(currentLinkedItemIds)
? currentLinkedItemIds
: [];

if (shouldHoldItems) {
let before = true;
const afterItemIds = itemList
.filter(({ id }) => {
const result = !before && itemIds.includes(id);
if (id === currentItemId) {
before = false;
}
return result;
const currentItemIndex = itemList.findIndex(
({ id }) => id === currentItemId
);
const currentItemLayer = itemList[currentItemIndex].layer || 0;

const afterMap = Object.fromEntries(
itemList.map(({ id, layer = 0 }, index) => {
return [
id,
layer > currentItemLayer ||
(layer === currentItemLayer && index > currentItemIndex),
];
})
.map(({ id }) => id);
);
const afterItemIds = itemIds.filter((id) => afterMap[id]);

const afterCurrentLinkedItemIds = (currentLinkedItemIds || []).filter(
(id) => afterMap[id]
);

const newHeldItems = Object.entries(
areItemsInside(element, afterItemIds, safeCurrentLinkedItems, true)
areItemsInside(element, afterItemIds, afterCurrentLinkedItemIds, true)
)
.filter(([, { inside }]) => inside)
.map(([itemId]) => itemId);

const oldLinked = new Set(safeCurrentLinkedItems);
const newLinked = new Set(newHeldItems);

if (
safeCurrentLinkedItems.length !== newHeldItems.length ||
!safeCurrentLinkedItems.every((itemId) => newHeldItems.includes(itemId))
newLinked.size !== oldLinked.size ||
!Array.from(oldLinked).every((id) => newLinked.has(id))
) {
return newHeldItems;
}
} else {
if (
!Array.isArray(safeCurrentLinkedItems) ||
safeCurrentLinkedItems.length !== 0
) {
return [];
if (safeCurrentLinkedItems.length !== 0) {
return safeCurrentLinkedItems;
}
}

Expand Down

1 comment on commit 6e6ac7e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.