import React, { useContext, useMemo, useState } from "react"; import { Container, Graphics, Sprite, Stage } from "@pixi/react"; import { CanvasContext } from "@/context/Canvas"; import { TexturesContext } from "@/context/Textures"; import { ThemeContext } from "@/context/Theme"; import { getBlockData } from "@/utils/getBlockData"; interface Props { stageWidth: number; searchInput: string; selectedBlocks: string[]; setSelectedBlocks: React.Dispatch>; userModifiedBlocks: React.MutableRefObject; } function BlockSelector({ stageWidth, searchInput, selectedBlocks, setSelectedBlocks, userModifiedBlocks }: Props) { const { version } = useContext(CanvasContext); const { missingTexture, textures } = useContext(TexturesContext); const { isDark } = useContext(ThemeContext); const blockData = getBlockData(version); const [hoverPosition, setHoverPosition] = useState(null); const filteredBlocks = useMemo(() => Object.keys(blockData).filter((value) => value.includes(searchInput)), [searchInput, blockData]); const blocksPerColumn = Math.floor(stageWidth / (32 + 2)); const onClick = (block: string) => { userModifiedBlocks.current = true; if (selectedBlocks.includes(block)) { setSelectedBlocks((prev) => prev.filter((blockName) => blockName !== block)); } else { setSelectedBlocks((prev) => [...prev, block]); } }; return ( setHoverPosition(null)} > {filteredBlocks.map((block, index) => { const texture = textures[`${block}.png`] ?? missingTexture; const x = (index % blocksPerColumn) * (32 + 2) + 2; const y = Math.floor(index / blocksPerColumn) * (32 + 2) + 2; return ( <> setHoverPosition({ x, y })} click={() => onClick(block)} /> {selectedBlocks.includes(block) && ( { g.clear(); g.beginFill(0x000000, 0.5); g.lineStyle(2, isDark ? 0xffffff : 0x000000, 1, 1); g.drawRect(0, 0, 32, 32); }} /> )} ); })} {hoverPosition && ( { g.clear(); g.lineStyle(2, isDark ? 0xffffff : 0x000000, 1, 1); g.drawRect(0, 0, 32, 32); }} /> )} ); } export default BlockSelector;