Items.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import React from "react";
  2. import { useRecoilState, atom } from "recoil";
  3. import Item from "../components/Item";
  4. import { useC2C } from "../hooks/useC2C";
  5. export const ItemListAtom = atom({
  6. key: "itemList",
  7. default: [],
  8. });
  9. const Items = () => {
  10. const [c2c] = useC2C();
  11. const [itemList, setItemList] = useRecoilState(ItemListAtom);
  12. const updateItem = React.useCallback(
  13. (id, callbackOrItem, sync = true) => {
  14. let callback = callbackOrItem;
  15. if (typeof callbackOrItem === "object") {
  16. callback = (item) => callbackOrItem;
  17. }
  18. setItemList((prevList) => {
  19. return prevList.map((item) => {
  20. if (item.id === id) {
  21. const newItem = {
  22. ...callback(item),
  23. id: item.id, // Prevent id modification
  24. };
  25. if (sync) {
  26. c2c.publish(`itemStateUpdate.${newItem.id}`, newItem);
  27. }
  28. return newItem;
  29. }
  30. return item;
  31. });
  32. });
  33. },
  34. [setItemList, c2c]
  35. );
  36. React.useEffect(() => {
  37. const unsub = c2c.subscribe(`selectedItemsMove`, ({ itemIds, move }) => {
  38. setItemList((prevList) => {
  39. return prevList.map((item) => {
  40. if (itemIds.includes(item.id)) {
  41. const x = item.x + move.x;
  42. const y = item.y + move.y;
  43. const newItem = { ...item, x, y };
  44. return newItem;
  45. }
  46. return item;
  47. });
  48. });
  49. });
  50. return unsub;
  51. }, [c2c, setItemList]);
  52. React.useEffect(() => {
  53. const unsub = c2c.subscribe(`updateItemListOrder`, (itemIds) => {
  54. setItemList((prevList) => {
  55. const itemsMap = prevList.reduce((prev, item) => {
  56. prev[item.id] = item;
  57. return prev;
  58. }, {});
  59. const result = prevList.map((item, index) => {
  60. return itemsMap[itemIds[index]];
  61. });
  62. return result;
  63. });
  64. });
  65. return unsub;
  66. }, [c2c, setItemList]);
  67. return itemList.map((item) => (
  68. <Item key={item.id} state={item} setState={updateItem} />
  69. ));
  70. };
  71. export default Items;