Skip to content

Commit

Permalink
Fix hold item feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmi committed Jan 15, 2024
1 parent 306fb36 commit e5e3d7d
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 32 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"react-icons": "^4.8.0",
"react-query": "^3.39.3",
"react-router-dom": "^6.8.0",
"react-sync-board": "^1.2.1",
"react-sync-board": "^1.2.3",
"react-toastify": "^6.1.0",
"recoil": "^0.7.4",
"socket.io-client": "^4.1.2",
Expand Down
2 changes: 1 addition & 1 deletion src/gameComponents/ActionList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const ActionList = ({ name, initialValue, availableActions }) => {
{(availableActions || []).map((name) => {
return (
<option key={name} value={name}>
{actionMap[name].genericLabel || actionMap[name].label()}
{actionMap[name]?.genericLabel || actionMap[name].label()}
</option>
);
})}
Expand Down
57 changes: 34 additions & 23 deletions src/gameComponents/Image/Image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { memo } from "react";
import { useUsers } from "react-sync-board";
import styled from "styled-components";
import { FiEye } from "react-icons/fi";
import { useItemInteraction } from "react-sync-board";
import { useItemInteraction, useItemActions } from "react-sync-board";

import { isItemCenterInsideElement, getItemElement } from "../../utils/item";
import { areItemsInside } from "../../utils/item";
import Canvas from "../Canvas";
import { media2Url } from "../../mediaLibrary";
import { getImage } from "../../utils/image";
Expand Down Expand Up @@ -65,11 +65,14 @@ const Image = ({
overlay,
holdItems,
setState,
id: currentItemId,
}) => {
const { currentUser, localUsers: users } = useUsers();
const { register } = useItemInteraction("place");
const wrapperRef = React.useRef(null);

const { getItemList } = useItemActions();

const imageContent = media2Url(content) || "/default.png";
const backContent = media2Url(rawBackContent);
const overlayContent = media2Url(overlay?.content);
Expand Down Expand Up @@ -118,47 +121,55 @@ const Image = ({
}
}, [imageContent, backContent]);

const onInsideItem = React.useCallback(
const onPlaceItem = React.useCallback(
(itemIds) => {
const whetherCenterItemIsInside = Object.fromEntries(
itemIds.map((itemId) => [
itemId,
isItemCenterInsideElement(getItemElement(itemId), wrapperRef.current),
])
);
const insideItems = itemIds.filter(
(itemId) => whetherCenterItemIsInside[itemId]
);

if (holdItems) {
let before = true;
const afterItemIds = getItemList()
.filter(({ id }) => {
if (id === currentItemId) {
before = false;
}
return !before && itemIds.includes(id);
})
.map(({ id }) => id);
setState((item) => {
const { linkedItems = [] } = item;
// Remove outside items from linkedItems
const linkedItemsCleaned = linkedItems.filter(
(itemId) => whetherCenterItemIsInside[itemId] !== false
);
const newLinkedItems = Array.from(
new Set(linkedItemsCleaned.concat(insideItems))
);
const newLinkedItems = Object.entries(
areItemsInside(
wrapperRef.current,
afterItemIds,
item.linkedItems || [],
true
)
)
.filter(([, { inside }]) => inside)
.map(([itemId]) => itemId);

return {
...item,
linkedItems: newLinkedItems,
};
});
} else {
setState((item) => {
return {
...item,
linkedItems: [],
};
});
}
},
[holdItems, setState]
);

React.useEffect(() => {
const unregisterList = [];
unregisterList.push(register(onInsideItem));
unregisterList.push(register(onPlaceItem));

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

return (
<Wrapper ref={wrapperRef}>
Expand Down
24 changes: 24 additions & 0 deletions src/utils/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ export const isItemCenterInsideElement = (itemElement, otherElem) => {
return isPointInsideRect(itemCenter, rect);
};

export const areItemsInside = (
DOMelement,
itemIds,
previousIds,
centerOnly = false
) => {
return Object.fromEntries(
[...itemIds, ...previousIds].map((itemId) => {
const inside = centerOnly
? isItemCenterInsideElement(getItemElement(itemId), DOMelement)
: isItemInsideElement(getItemElement(itemId), DOMelement);

return [
itemId,
{
inside,
added: inside && !previousIds.includes(itemId),
removed: !inside && previousIds.includes(itemId),
},
];
})
);
};

export const pointInItem = (itemElement, point) => {
return isPointInPolygon(point, getItemPolygon(itemElement));
};
Expand Down

1 comment on commit e5e3d7d

@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.