import { useVariationOverride } from '@agent/hooks/useVariationOverride'; import { useChatStore } from '@agent/state/chat'; import { useEffect, useMemo, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; const colorsArrayToMap = (colors) => { const map = {}; colors.forEach(({ slug, color }) => { map[slug] = color; }); return map; }; const getBackgroundColor = (colors) => { const bgSlugs = ['base', 'background', 'bg']; for (const slug of bgSlugs) { if (colors[slug]) return colors[slug]; } return '#ffffff'; }; const buildPreviewCss = (colorsMap) => { const styleEl = document.getElementById('global-styles-inline-css'); if (!styleEl) return ''; let css = styleEl.innerHTML; Object.entries(colorsMap).forEach(([slug, hex]) => { const regex = new RegExp( `(--wp--preset--color--${slug}\\s*:\\s*)([^;]+)(;)`, 'g', ); css = css.replace(regex, `$1${hex}$3`); }); return css; }; const themeDuotonePresets = window.extAgentData?.context?.themePresets?.duotone || []; const themeColorPresets = window.extAgentData?.context?.themePresets?.colors || {}; const buildDuotoneTheme = (newColorsMap) => { if (!themeDuotonePresets.length) return null; const duotone = []; for (const preset of themeDuotonePresets) { const { slug, colors: originalColors } = preset; if (!originalColors || originalColors.length !== 2) continue; const newColors = originalColors.map((originalHex) => { const matchingSlug = Object.entries(themeColorPresets).find( ([, hex]) => hex.toLowerCase() === originalHex.toLowerCase(), )?.[0]; if (matchingSlug && newColorsMap[matchingSlug]) { return newColorsMap[matchingSlug]; } return originalHex; }); duotone.push({ slug, colors: newColors }); } return duotone.length > 0 ? duotone : null; }; export const SelectGeneratedPalette = ({ inputs, onConfirm, onCancel, onRetry, }) => { const [selected, setSelected] = useState(null); const [previewCss, setPreviewCss] = useState(''); const [duotoneTheme, setDuotoneTheme] = useState(null); const { addMessage, messages } = useChatStore(); const aiPalettes = inputs?.palettes; const palettes = useMemo( () => aiPalettes?.map(({ name, colors }) => { return { name, colors: colorsArrayToMap(colors), colorsArray: colors, }; }) || [], [aiPalettes], ); const noPalettes = !aiPalettes?.length || palettes.length === 0; const { undoChange } = useVariationOverride({ css: previewCss, duotoneTheme, }); const confirmed = useRef(false); useEffect(() => { return () => { if (!confirmed.current) undoChange(); }; }, []); useEffect(() => { if (!noPalettes) return; const timer = setTimeout(() => onCancel(), 100); const content = __( 'We were unable to generate color palettes. Please try again.', 'extendify-local', ); const last = messages.at(-1)?.details?.content; if (content === last) return () => clearTimeout(timer); addMessage('message', { role: 'assistant', content, error: true }); return () => clearTimeout(timer); }, [addMessage, onCancel, noPalettes, messages]); const handleRetry = () => { undoChange(); onRetry(); }; const handleConfirm = () => { if (!selected) return; confirmed.current = true; const palette = palettes.find((p) => p.name === selected); onConfirm({ data: { palette: { name: palette.name, colors: palette.colorsArray.map(({ slug, color }) => ({ slug, color, name: slug, })), }, duotone: duotoneTheme, }, shouldRefreshPage: true, }); }; if (noPalettes) return null; return (