"use client"; import Image from "next/image"; import { memo, useCallback, useMemo } from "react"; import { PanelBaseView as BaseView } from "@/components/editor/panels/panel-base-view"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { BLUR_INTENSITY_PRESETS, DEFAULT_BLUR_INTENSITY, DEFAULT_COLOR, FPS_PRESETS, } from "@/constants/project-constants"; import { patternCraftGradients } from "@/data/colors/pattern-craft"; import { colors } from "@/data/colors/solid"; import { syntaxUIGradients } from "@/data/colors/syntax-ui"; import { useEditor } from "@/hooks/use-editor"; import { useEditorStore } from "@/stores/editor-store"; import type { TProject } from "@/types/project"; import { dimensionToAspectRatio } from "@/utils/geometry"; import { cn } from "@/utils/ui"; import { PropertyGroup, PropertyItem, PropertyItemLabel, PropertyItemValue, } from "@/components/editor/panels/properties/property-item"; import { HugeiconsIcon } from "@hugeicons/react"; import { DropperIcon } from "@hugeicons/core-free-icons"; export function SettingsView() { return ; } function ProjectSettingsTabs() { return ( ), }, { value: "background", label: "Background", content: ( {/* Custom background */} {/* another ui */} {/* Custom */} ), }, ]} className="flex h-full flex-col justify-between p-0" /> ); } function getCurrentCanvasSize({ activeProject }: { activeProject: TProject }) { const { canvasSize } = activeProject.settings; return { width: canvasSize.width, height: canvasSize.height, }; } function ProjectInfoView() { const editor = useEditor(); const activeProject = editor.project.getActive(); const { canvasPresets } = useEditorStore(); const findPresetIndexByAspectRatio = ({ presets, targetAspectRatio, }: { presets: Array<{ width: number; height: number }>; targetAspectRatio: string; }) => { for (let index = 0; index < presets.length; index++) { const preset = presets[index]; const presetAspectRatio = dimensionToAspectRatio({ width: preset.width, height: preset.height, }); if (presetAspectRatio === targetAspectRatio) { return index; } } return -1; }; const currentCanvasSize = getCurrentCanvasSize({ activeProject }); const currentAspectRatio = dimensionToAspectRatio(currentCanvasSize); const originalCanvasSize = activeProject.settings.originalCanvasSize ?? null; const presetIndex = findPresetIndexByAspectRatio({ presets: canvasPresets, targetAspectRatio: currentAspectRatio, }); const originalPresetValue = "original"; const selectedPresetValue = presetIndex !== -1 ? presetIndex.toString() : originalPresetValue; const handleAspectRatioChange = ({ value }: { value: string }) => { if (value === originalPresetValue) { const canvasSize = originalCanvasSize ?? currentCanvasSize; editor.project.updateSettings({ settings: { canvasSize }, }); return; } const index = parseInt(value, 10); const preset = canvasPresets[index]; if (preset) { editor.project.updateSettings({ settings: { canvasSize: preset } }); } }; const handleFpsChange = (value: string) => { const fps = parseFloat(value); editor.project.updateSettings({ settings: { fps } }); }; return ( Name {activeProject.metadata.name} Aspect ratio handleAspectRatioChange({ value })} > Original {canvasPresets.map((preset, index) => { const label = dimensionToAspectRatio({ width: preset.width, height: preset.height, }); return ( {label} ); })} Frame rate {FPS_PRESETS.map((preset) => ( {preset.label} ))} ); } const BlurPreview = memo( ({ blur, isSelected, onSelect, }: { blur: { label: string; value: number }; isSelected: boolean; onSelect: () => void; }) => ( {blur.label} ), ); BlurPreview.displayName = "BlurPreview"; const BackgroundPreviews = memo( ({ backgrounds, currentBackgroundColor, isColorBackground, handleColorSelect, useBackgroundColor = false, }: { backgrounds: string[]; currentBackgroundColor: string; isColorBackground: boolean; handleColorSelect: ({ bg }: { bg: string }) => void; useBackgroundColor?: boolean; }) => { return useMemo( () => backgrounds.map((bg, index) => ( handleColorSelect({ bg })} type="button" aria-label={`Select background ${useBackgroundColor ? bg : index + 1}`} /> )), [ backgrounds, isColorBackground, currentBackgroundColor, handleColorSelect, useBackgroundColor, ], ); }, ); BackgroundPreviews.displayName = "BackgroundPreviews"; function BackgroundView() { const editor = useEditor(); const activeProject = editor.project.getActive(); const blurLevels = useMemo(() => BLUR_INTENSITY_PRESETS, []); const handleBlurSelect = useCallback( async ({ blurIntensity }: { blurIntensity: number }) => { await editor.project.updateSettings({ settings: { background: { type: "blur", blurIntensity } }, }); }, [editor.project], ); const handleColorSelect = useCallback( async ({ color }: { color: string }) => { await editor.project.updateSettings({ settings: { background: { type: "color", color } }, }); }, [editor.project], ); const currentBlurIntensity = activeProject.settings.background.type === "blur" ? activeProject.settings.background.blurIntensity : DEFAULT_BLUR_INTENSITY; const currentBackgroundColor = activeProject.settings.background.type === "color" ? activeProject.settings.background.color : DEFAULT_COLOR; const isBlurBackground = activeProject.settings.background.type === "blur"; const isColorBackground = activeProject.settings.background.type === "color"; const blurPreviews = useMemo( () => blurLevels.map((blur) => ( handleBlurSelect({ blurIntensity: blur.value })} /> )), [blurLevels, isBlurBackground, currentBlurIntensity, handleBlurSelect], ); return ( {blurPreviews} handleColorSelect({ color: bg })} useBackgroundColor={true} /> handleColorSelect({ color: bg })} /> handleColorSelect({ color: bg })} /> ); }