From 2c961e18c2ea3c8c4d573d573d0ce4106656e57c Mon Sep 17 00:00:00 2001 From: bhushan6 Date: Sun, 13 Aug 2023 21:10:35 +0530 Subject: [PATCH] adds : global state --- package-lock.json | 117 ++++++++++++++++++++++++++ package.json | 1 + src/components/3D/BrickOutline.jsx | 7 +- src/components/3D/ChangeColor.jsx | 6 +- src/components/3D/ControlsWrapper.jsx | 3 +- src/components/3D/DeleteBrick.jsx | 13 ++- src/components/3D/Scene.jsx | 23 ++--- src/components/3D/Select/index.jsx | 46 +++------- src/components/3D/Translate.jsx | 35 -------- src/components/3D/index.js | 3 +- src/store/index.js | 20 +++++ src/utils/helpers.js | 4 +- 12 files changed, 186 insertions(+), 92 deletions(-) delete mode 100644 src/components/3D/Translate.jsx diff --git a/package-lock.json b/package-lock.json index 071b400..4cdef92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-menubar": "^1.0.3", "@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-toggle-group": "^1.0.4", "@react-three/drei": "^9.80.2", @@ -1302,6 +1303,78 @@ } } }, + "node_modules/@radix-ui/react-menu": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.5.tgz", + "integrity": "sha512-Gw4f9pwdH+w5w+49k0gLjN0PfRDHvxmAgG16AbyJZ7zhwZ6PBHKtWohvnSwfusfnK3L68dpBREHpVkj8wEM7ZA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.2", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.0.3.tgz", + "integrity": "sha512-GqjdxzYCjjKhcgEODDP8SrYfbWNh/Hm3lyuFkP5Q5IbX0QfXklLF1o1AqA3oTV2kulUgN/kOZVS92hIIShEgpA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.5", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", @@ -6272,6 +6345,50 @@ "@radix-ui/react-use-layout-effect": "1.0.1" } }, + "@radix-ui/react-menu": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.5.tgz", + "integrity": "sha512-Gw4f9pwdH+w5w+49k0gLjN0PfRDHvxmAgG16AbyJZ7zhwZ6PBHKtWohvnSwfusfnK3L68dpBREHpVkj8wEM7ZA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.2", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + } + }, + "@radix-ui/react-menubar": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.0.3.tgz", + "integrity": "sha512-GqjdxzYCjjKhcgEODDP8SrYfbWNh/Hm3lyuFkP5Q5IbX0QfXklLF1o1AqA3oTV2kulUgN/kOZVS92hIIShEgpA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.5", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" + } + }, "@radix-ui/react-popper": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", diff --git a/package.json b/package.json index 596749b..3a90702 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-menubar": "^1.0.3", "@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-toggle-group": "^1.0.4", "@react-three/drei": "^9.80.2", diff --git a/src/components/3D/BrickOutline.jsx b/src/components/3D/BrickOutline.jsx index 637f9a1..355f1e3 100644 --- a/src/components/3D/BrickOutline.jsx +++ b/src/components/3D/BrickOutline.jsx @@ -2,7 +2,7 @@ /* eslint-disable no-unused-vars */ /* eslint-disable react/prop-types */ /* eslint-disable react/display-name */ -import { useSelect } from "."; +// import { useSelect } from "."; import React, { useLayoutEffect, useMemo, useRef } from "react"; import { createGeometry, @@ -11,6 +11,7 @@ import { outlineWidth, } from "../../utils"; import { BackSide, Object3D } from "three"; +import { useStore } from "../../store"; const dummy = new Object3D(); @@ -81,7 +82,9 @@ const OutlineMesh = ({ meshesData }) => { }; export const BrickOutline = () => { - const selected = useSelect().map((sel) => sel.userData); + const selected = useStore((state) => state.selectedBricks).map( + (sel) => sel.userData + ); const selectedMeshes = useMemo(() => { const meshesAccrodingToType = {}; diff --git a/src/components/3D/ChangeColor.jsx b/src/components/3D/ChangeColor.jsx index 8197d27..6ab046d 100644 --- a/src/components/3D/ChangeColor.jsx +++ b/src/components/3D/ChangeColor.jsx @@ -3,10 +3,12 @@ /* eslint-disable react/prop-types */ /* eslint-disable react/display-name */ import React, { useDeferredValue, useEffect, useRef } from "react"; -import { useSelect } from "."; +import { useStore } from "../../store"; export const ChangeColor = ({ color, setBricks }) => { - const selected = useSelect().map((sel) => sel.userData.uID); + const selected = useStore((state) => state.selectedBricks).map( + (sel) => sel.userData.uID + ); const prevColor = useRef(color); diff --git a/src/components/3D/ControlsWrapper.jsx b/src/components/3D/ControlsWrapper.jsx index 8a3371f..b08afda 100644 --- a/src/components/3D/ControlsWrapper.jsx +++ b/src/components/3D/ControlsWrapper.jsx @@ -2,9 +2,8 @@ /* eslint-disable no-unused-vars */ /* eslint-disable react/prop-types */ /* eslint-disable react/display-name */ -import React, { useEffect, useRef } from "react"; +import React, { useRef } from "react"; import { useThree } from "@react-three/fiber"; -import { useControls } from "leva"; import { OrbitControls } from "@react-three/drei"; export const ControlsWrapper = () => { diff --git a/src/components/3D/DeleteBrick.jsx b/src/components/3D/DeleteBrick.jsx index 18dff8f..745d025 100644 --- a/src/components/3D/DeleteBrick.jsx +++ b/src/components/3D/DeleteBrick.jsx @@ -2,13 +2,16 @@ /* eslint-disable no-unused-vars */ /* eslint-disable react/prop-types */ /* eslint-disable react/display-name */ -import { useSelect, useSetSelection } from "."; +// import { useSelect, useSetSelection } from "."; import React from "react"; import { useDeleteShortcut } from "../../utils"; +import { useStore } from "../../store"; export const DeleteBrick = ({ setBricks }) => { - const selected = useSelect().map((sel) => sel.userData.uID); - const setSelection = useSetSelection(); + const selected = useStore((state) => state.selectedBricks).map( + (sel) => sel.userData.uID + ); + const setSelection = useStore((state) => state.setSelectedBricks); const onDelete = () => { setSelection({}); @@ -16,5 +19,9 @@ export const DeleteBrick = ({ setBricks }) => { useDeleteShortcut(selected, setBricks, onDelete); + const bricks = useStore((state) => state.bricks); + + console.log(bricks, ":::::::"); + return <>; }; diff --git a/src/components/3D/Scene.jsx b/src/components/3D/Scene.jsx index 47bc9d8..6908d31 100644 --- a/src/components/3D/Scene.jsx +++ b/src/components/3D/Scene.jsx @@ -9,7 +9,6 @@ import { BrickOutline, DeleteBrick, Select, - useSetSelection, } from "."; import { Vector3, Box3 } from "three"; import { @@ -25,7 +24,9 @@ import { useStore } from "../../store"; import { BorderPlane } from "./BorderPlane"; export const Scene = () => { - const [bricks, setBricks] = useState([]); + // const [bricks, setBricks] = useState([]); + const bricks = useStore((state) => state.bricks); + const setBricks = useStore((state) => state.setBricks); const bricksBoundBox = useRef([]); @@ -43,15 +44,15 @@ export const Scene = () => { const color = useStore((state) => state.color); // useAnchorShorcuts(anchorX, anchorZ, set); - const setSelection = useSetSelection(); + // const setSelection = useStore(state => state.setSelectedBricks) - function undoAddedBrick() { - setSelection({}); // this should unselect the bricks but Doesn't work for now because of undo is button within leva - setBricks((prevBricks) => { - prevBricks.pop(); - return [...prevBricks]; - }); - } + // function undoAddedBrick() { + // setSelection({}); // this should unselect the bricks but Doesn't work for now because of undo is button within leva + // setBricks((prevBricks) => { + // prevBricks.pop(); + // return [...prevBricks]; + // }); + // } const addBrick = (e) => { e.stopPropagation(); @@ -179,7 +180,7 @@ export const Scene = () => { return ( <> - {bricks.map((b, i) => { return ( {}); - export function Select({ box, multiple, @@ -30,38 +27,34 @@ export function Select({ const enable = mode === EDIT_MODE; - const [active, dispatch] = React.useReducer((state, { object, shift }) => { - if (object === undefined) return []; - else if (Array.isArray(object)) return object; - else if (!shift) return state[0] === object ? [] : [object]; - else if (state.includes(object)) return state.filter((o) => o !== object); - else return [object, ...state]; - }, []); + const setSelectedBricks = useStore((state) => state.setSelectedBricks); - React.useEffect(() => { - if (downed) onChange?.(active); - else onChangePointerUp?.(active); - }, [active, downed]); + // React.useEffect(() => { + // if (downed) onChange?.(active); + // else onChangePointerUp?.(active); + // }, [active, downed]); const onClick = React.useCallback( (e) => { e.stopPropagation(); if (!enable) return; - dispatch({ + setSelectedBricks({ object: customFilter([e.object])[0], shift: multiple && e.shiftKey, }); }, - [enable] + [enable, multiple] ); React.useEffect(() => { if (!enable) { - dispatch({}); + setSelectedBricks({}); } }, [enable]); - const onPointerMissed = React.useCallback((e) => dispatch({}), []); + const onPointerMissed = React.useCallback((e) => { + setSelectedBricks({}); + }, []); const ref = React.useRef(null); @@ -166,7 +159,6 @@ export function Select({ pos.copy(camera.position).add(vec.multiplyScalar(distance)); - console.log(pos, "start"); onSelectStart(event); prepareRay(event, selBox.startPoint); } @@ -183,7 +175,7 @@ export function Select({ .filter((o) => o.isMesh); if (!shallow(allSelected, previous)) { previous = allSelected; - dispatch({ object: customFilter(allSelected) }); + setSelectedBricks({ object: customFilter(allSelected) }); } } } @@ -214,19 +206,7 @@ export function Select({ onPointerMissed={onPointerMissed} {...props} > - - - {children} - - + {children} ); } - -export function useSelect() { - return React.useContext(context); -} - -export function useSetSelection() { - return React.useContext(dispatchContext); -} diff --git a/src/components/3D/Translate.jsx b/src/components/3D/Translate.jsx deleted file mode 100644 index 9c46eaf..0000000 --- a/src/components/3D/Translate.jsx +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable react/no-unknown-property */ -/* eslint-disable no-unused-vars */ -/* eslint-disable react/prop-types */ -/* eslint-disable react/display-name */ -import React, { useEffect } from "react"; -import { useSelect } from "."; -import { useControls } from "leva"; -import { Group } from "three"; - -const group = new Group(); - -export const Translate = () => { - const [{ Translate }, set] = useControls(() => ({ - Translate: false, - })); - - const selected = useSelect(); - - useEffect(() => { - const keypress = (e) => { - if (!Translate) return; - console.log(e.key); - if (e.key === "6") { - selected.forEach((mesh) => group.add(mesh)); - console.log(group); - } - }; - - document.addEventListener("keypress", keypress); - - return () => document.removeEventListener("keypress", keypress); - }, [Translate, selected]); - - return <>; -}; diff --git a/src/components/3D/index.js b/src/components/3D/index.js index 3f0a82a..848f442 100644 --- a/src/components/3D/index.js +++ b/src/components/3D/index.js @@ -5,7 +5,6 @@ export { DeleteBrick } from "./DeleteBrick"; export { LegoRoom } from "./LegoRoom"; export { Lights } from "./Lights"; export { Scene } from "./Scene"; -export { Translate } from "./Translate"; export { Workspace } from "./Workspace"; export { Brick } from "./Brick"; -export { Select, useSelect, useSetSelection } from "./Select/index"; +export { Select } from "./Select/index"; diff --git a/src/store/index.js b/src/store/index.js index b78b587..e009511 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -22,4 +22,24 @@ export const useStore = create((set) => ({ color: "#ff0000", setColor: (newColor) => set({ color: newColor }), + + selectedBricks: [], + setSelectedBricks: ({ object, shift }) => + set((state) => { + if (object === undefined) return { selectedBricks: [] }; + else if (Array.isArray(object)) return { selectedBricks: object }; + else if (!shift) + return state.selectedBricks[0] === object + ? { selectedBricks: [] } + : { selectedBricks: [object] }; + else if (state.selectedBricks.includes(object)) + return { + selectedBricks: state.selectedBricks.filter((o) => o !== object), + }; + else return { selectedBricks: [object, ...state.selectedBricks] }; + }), + + bricks: [], + setBricks: (getBricks) => + set((state) => ({ bricks: getBricks(state.bricks) })), })); diff --git a/src/utils/helpers.js b/src/utils/helpers.js index 7b717b1..4c2e001 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -9,7 +9,7 @@ export function CSSToHex(cssColor) { export function getMeasurementsFromDimensions({ x, y, z }) { return { width: base * x, - height: base * y || base, + height: base * y || (base * 2) / 1.5, depth: base * z, }; } @@ -34,7 +34,7 @@ export function createGeometry({ for (let j = 0; j < dimensions.z; j++) { const cylinder = new CylinderGeometry(knobDim, knobDim, knobDim, 20); const x = base * i - ((dimensions.x - 1) * base) / 2; - const y = base - 12.5; + const y = base / 1.5; const z = base * j - ((dimensions.z - 1) * base) / 2; cylinder.translate(x, y, z); geometries.push(cylinder);