diff --git a/components/editor/background-options/normal-gradient-picker.tsx b/components/editor/background-options/normal-gradient-picker.tsx index b00690c..f0b5f10 100644 --- a/components/editor/background-options/normal-gradient-picker.tsx +++ b/components/editor/background-options/normal-gradient-picker.tsx @@ -39,7 +39,7 @@ export default function NormalGradientPicker() { setNoise, } = useBackgroundOptions() - const { images, setImages } = useImageOptions() + const { images, updateImage } = useImageOptions() const { selectedImage } = useSelectedLayers() const [dominantColor, setDominantColor] = useState(null) @@ -132,20 +132,15 @@ export default function NormalGradientPicker() { return gradient }) - setImages( - images.map((image, index) => - index === images.length - 1 - ? { - ...image, - dominantColor, - palletes, - linearGradients, - meshGradients, - radialGradients, - } - : image - ) - ) + if (images.length > 0) { + updateImage(images[images.length - 1].id, { + dominantColor, + palletes, + linearGradients, + meshGradients, + radialGradients, + }) + } return { linearGradients, diff --git a/components/editor/canvas-options/resolution-button.tsx b/components/editor/canvas-options/resolution-button.tsx index a52796d..ffeb2c2 100644 --- a/components/editor/canvas-options/resolution-button.tsx +++ b/components/editor/canvas-options/resolution-button.tsx @@ -30,7 +30,7 @@ export function ResolutionButton({ const [isHovering, setIsHovering] = useState(false) const { setResolution, setScaleFactor, domResolution } = useResizeCanvas() - const { images, setImages, initialImageUploaded } = useImageOptions() + const { images, updateImageStyle, initialImageUploaded } = useImageOptions() const { selectedImage } = useSelectedLayers() const [domWidth]: number[] = domResolution.split('x').map(Number) @@ -84,20 +84,9 @@ export function ResolutionButton({ padding ) setResolution(newResolution.toString()) - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - imageSize: '0.75', - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { imageSize: '0.75' }) + } } }} aria-label={name} @@ -129,20 +118,9 @@ export function ResolutionButton({ padding ) setResolution(newResolution.toString()) - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - imageSize: '0.75', - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { imageSize: '0.75' }) + } } }} aria-label={name} diff --git a/components/editor/frame-options/frame-picker.tsx b/components/editor/frame-options/frame-picker.tsx index 0e2926f..4e2c1da 100644 --- a/components/editor/frame-options/frame-picker.tsx +++ b/components/editor/frame-options/frame-picker.tsx @@ -13,26 +13,18 @@ import { cn } from '@/utils/button-utils' export default function FramePicker() { const { setFrameHeight, frameHeight } = useFrameOptions() const { selectedImage } = useSelectedLayers() - const { setImages, images } = useImageOptions() + const { updateImage, images } = useImageOptions() const { setShowControls } = useMoveable() const frameChangeHandler = (frame: FrameTypes) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - frame, - style: { - ...image.style, - imageRoundness: - frame === 'None' ? 0.4 : frame === 'Arc' ? 1.5 : 0.7, - }, - } - : image - ) - ) + if (selectedImage) { + updateImage(selectedImage, { + frame, + style: { + imageRoundness: frame === 'None' ? 0.4 : frame === 'Arc' ? 1.5 : 0.7, + }, + }) + } setShowControls(false) } diff --git a/components/editor/image-context-menu.tsx b/components/editor/image-context-menu.tsx index 6c5fa51..4a117a9 100644 --- a/components/editor/image-context-menu.tsx +++ b/components/editor/image-context-menu.tsx @@ -50,7 +50,7 @@ export default function ContextMenuImage({ height: 50, }) const imgRef = useRef(null) - const { setImages, images } = useImageOptions() + const { updateImage, updateImageStyle, images } = useImageOptions() const [isRemovingBackground, setIsRemovingBackground] = useState(false) const [isBgRemovalDialogOpen, setIsBgRemovalDialogOpen] = useState(false) const [isProcessingBackground, setIsProcessingBackground] = useState(false) @@ -70,16 +70,7 @@ export default function ContextMenuImage({ } if (selectedImage) { - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - image: '', - } - : image - ) - ) + updateImage(selectedImage, { image: '' }) } setSelectedImage(null) @@ -87,22 +78,12 @@ export default function ContextMenuImage({ const bringToFrontOrBack = (direction: 'front' | 'back') => { if (selectedImage) { - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - zIndex: - direction === 'front' - ? image.style.zIndex + 1 - : image.style.zIndex - 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + zIndex: + direction === 'front' + ? images[selectedImage - 1]?.style.zIndex + 1 + : images[selectedImage - 1]?.style.zIndex - 1, + }) } } @@ -201,17 +182,9 @@ export default function ContextMenuImage({ ) const base64Image = canvas.toDataURL('image/png') - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - image: base64Image, - } - : image - ) - ) + if (selectedImage) { + updateImage(selectedImage, { image: base64Image }) + } } return ( @@ -429,21 +402,13 @@ export default function ContextMenuImage({ @@ -61,20 +50,9 @@ export default function RotateOptions() { : [2000] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - perspective: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { perspective: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} @@ -82,38 +60,18 @@ export default function RotateOptions() { if (selectedImage) { if (images[selectedImage - 1]?.style.perspective >= 6500) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - perspective: Number(image.style.perspective) + 500, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + perspective: Number(images[selectedImage - 1]?.style.perspective) + 500, + }) } }} onDecrement={() => { if (selectedImage) { if (images[selectedImage - 1]?.style.perspective <= 0) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - perspective: Number(image.style.perspective) - 500, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + perspective: Number(images[selectedImage - 1]?.style.perspective) - 500, + }) } }} /> @@ -135,20 +93,9 @@ export default function RotateOptions() { size="sm" className="ml-auto translate-x-2" onClick={() => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateX: 0.0001, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { rotateX: 0.0001 }) + } }} > @@ -165,20 +112,9 @@ export default function RotateOptions() { selectedImage ? [images[selectedImage - 1]?.style.rotateX] : [0] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateX: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { rotateX: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} @@ -186,38 +122,18 @@ export default function RotateOptions() { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateX >= 180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateX: Number(image.style.rotateX) + 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateX: Number(images[selectedImage - 1]?.style.rotateX) + 1, + }) } }} onDecrement={() => { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateX <= -180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateX: Number(image.style.rotateX) - 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateX: Number(images[selectedImage - 1]?.style.rotateX) - 1, + }) } }} /> @@ -237,20 +153,9 @@ export default function RotateOptions() { size="sm" className="ml-auto translate-x-2" onClick={() => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateY: 0, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { rotateY: 0 }) + } }} > @@ -267,20 +172,9 @@ export default function RotateOptions() { selectedImage ? [images[selectedImage - 1]?.style.rotateY] : [0] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateY: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { rotateY: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} @@ -288,38 +182,18 @@ export default function RotateOptions() { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateY >= 180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateY: Number(image.style.rotateY) + 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateY: Number(images[selectedImage - 1]?.style.rotateY) + 1, + }) } }} onDecrement={() => { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateY <= -180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateY: Number(image.style.rotateY) - 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateY: Number(images[selectedImage - 1]?.style.rotateY) - 1, + }) } }} /> @@ -338,22 +212,11 @@ export default function RotateOptions() { variant="secondary" size="sm" className="ml-auto translate-x-2" - onClick={() => - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateZ: 0, - }, - } - : image - ) - ) - } + onClick={() => { + if (selectedImage) { + updateImageStyle(selectedImage, { rotateZ: 0 }) + } + }} > @@ -369,20 +232,9 @@ export default function RotateOptions() { selectedImage ? [images[selectedImage - 1]?.style.rotateZ] : [0] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateZ: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { rotateZ: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} @@ -390,38 +242,18 @@ export default function RotateOptions() { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateZ >= 180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateZ: Number(image.style.rotateZ) + 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateZ: Number(images[selectedImage - 1]?.style.rotateZ) + 1, + }) } }} onDecrement={() => { if (selectedImage) { if (images[selectedImage - 1]?.style.rotateZ <= -180) return - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - rotateZ: Number(image.style.rotateZ) - 1, - }, - } - : image - ) - ) + updateImageStyle(selectedImage, { + rotateZ: Number(images[selectedImage - 1]?.style.rotateZ) - 1, + }) } }} /> diff --git a/components/editor/position-options/position-control.tsx b/components/editor/position-options/position-control.tsx index c4435b2..3c1456e 100644 --- a/components/editor/position-options/position-control.tsx +++ b/components/editor/position-options/position-control.tsx @@ -15,30 +15,19 @@ import { useEffect, useCallback } from 'react' import { useImageOptions, useSelectedLayers } from '@/store/use-image-options' export default function PositionControl() { - const { images, setImages } = useImageOptions() + const { images, updateImageStyle } = useImageOptions() const { selectedImage } = useSelectedLayers() const move = useCallback( (deltaX: number, deltaY: number) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: - images[selectedImage - 1]?.style.translateX + deltaX, - translateY: - images[selectedImage - 1]?.style.translateY + deltaY, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { + translateX: images[selectedImage - 1]?.style.translateX + deltaX, + translateY: images[selectedImage - 1]?.style.translateY + deltaY, + }) + } }, - [images, setImages, selectedImage] + [images, updateImageStyle, selectedImage] ) useEffect(() => { @@ -68,21 +57,9 @@ export default function PositionControl() { }, [move]) const centerImage = () => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: 0, - translateY: 0, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { translateX: 0, translateY: 0 }) + } } return ( diff --git a/components/editor/position-options/translate-control.tsx b/components/editor/position-options/translate-control.tsx index 866c6e3..18962de 100644 --- a/components/editor/position-options/translate-control.tsx +++ b/components/editor/position-options/translate-control.tsx @@ -5,7 +5,7 @@ import { RotateCcw } from 'lucide-react' import { useImageOptions, useSelectedLayers } from '@/store/use-image-options' export default function TranslateOption() { - const { images, setImages } = useImageOptions() + const { images, updateImageStyle } = useImageOptions() const { selectedImage } = useSelectedLayers() const { setShowControls } = useMoveable() @@ -24,20 +24,9 @@ export default function TranslateOption() { size="sm" className="ml-auto translate-x-2" onClick={() => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: 0, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { translateX: 0 }) + } }} > @@ -54,56 +43,27 @@ export default function TranslateOption() { selectedImage ? [images[selectedImage - 1]?.style.translateX] : [0] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { translateX: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} onIncrement={() => { - selectedImage && - (images[selectedImage - 1]?.style.translateX >= 1000 || - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: image.style.translateX + 1, - }, - } - : image - ) - )) + if (selectedImage) { + if (images[selectedImage - 1]?.style.translateX >= 1000) return + updateImageStyle(selectedImage, { + translateX: images[selectedImage - 1]?.style.translateX + 1, + }) + } }} onDecrement={() => { - selectedImage && - (images[selectedImage - 1]?.style.translateX <= -1000 || - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateX: image.style.translateX - 1, - }, - } - : image - ) - )) + if (selectedImage) { + if (images[selectedImage - 1]?.style.translateX <= -1000) return + updateImageStyle(selectedImage, { + translateX: images[selectedImage - 1]?.style.translateX - 1, + }) + } }} /> @@ -121,20 +81,9 @@ export default function TranslateOption() { size="sm" className="ml-auto translate-x-2" onClick={() => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateY: 0, - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { translateY: 0 }) + } }} > @@ -151,56 +100,27 @@ export default function TranslateOption() { selectedImage ? [images[selectedImage - 1]?.style.translateY] : [0] } onValueChange={(value: number[]) => { - selectedImage && - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateY: value[0], - }, - } - : image - ) - ) + if (selectedImage) { + updateImageStyle(selectedImage, { translateY: value[0] }) + } setShowControls(false) }} onValueCommit={() => setShowControls(true)} onIncrement={() => { - selectedImage && - (images[selectedImage - 1]?.style.translateY >= 500 || - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateY: image.style.translateY + 1, - }, - } - : image - ) - )) + if (selectedImage) { + if (images[selectedImage - 1]?.style.translateY >= 500) return + updateImageStyle(selectedImage, { + translateY: images[selectedImage - 1]?.style.translateY + 1, + }) + } }} onDecrement={() => { - selectedImage && - (images[selectedImage - 1]?.style.translateY <= -500 || - setImages( - images.map((image, index) => - index === selectedImage - 1 - ? { - ...image, - style: { - ...image.style, - translateY: image.style.translateY - 1, - }, - } - : image - ) - )) + if (selectedImage) { + if (images[selectedImage - 1]?.style.translateY <= -500) return + updateImageStyle(selectedImage, { + translateY: images[selectedImage - 1]?.style.translateY - 1, + }) + } }} /> diff --git a/components/editor/text-context-menu.tsx b/components/editor/text-context-menu.tsx index 0cdc33d..d7fe0f5 100644 --- a/components/editor/text-context-menu.tsx +++ b/components/editor/text-context-menu.tsx @@ -17,7 +17,7 @@ export default function ContextMenuText({ }: { children: React.ReactNode }) { - const { setTexts, texts } = useImageOptions() + const { setTexts, texts, updateText, updateTextStyle } = useImageOptions() const { selectedText, setSelectedText } = useSelectedLayers() const { showTextControls, setShowTextControls } = useMoveable() @@ -26,38 +26,19 @@ export default function ContextMenuText({ setTexts([]) return } - selectedText && - setTexts( - texts.map((text, index) => - index === selectedText - 1 - ? { - ...text, - content: '', - text: '', - } - : text - ) - ) + if (selectedText) { + updateText(selectedText, { content: '' }) + } } const bringToFrontOrBack = (direction: 'front' | 'back') => { if (selectedText) { - setTexts( - texts.map((text, index) => - index === selectedText - 1 - ? { - ...text, - style: { - ...text.style, - zIndex: - direction === 'front' - ? text.style.zIndex + 1 - : text.style.zIndex - 1, - }, - } - : text - ) - ) + updateTextStyle(selectedText, { + zIndex: + direction === 'front' + ? texts[selectedText - 1].style.zIndex + 1 + : texts[selectedText - 1].style.zIndex - 1, + }) } } diff --git a/components/editor/text-options/add-text-layer.tsx b/components/editor/text-options/add-text-layer.tsx index 639ab8a..ed1d43d 100644 --- a/components/editor/text-options/add-text-layer.tsx +++ b/components/editor/text-options/add-text-layer.tsx @@ -5,19 +5,16 @@ import { Button } from '@/components/ui/button' import { useImageOptions } from '@/store/use-image-options' export default function AddTextLayer() { - const { setTexts, defaultTextStyle, texts } = useImageOptions() + const { addText, defaultTextStyle, texts } = useImageOptions() return (