"use client"; import { useEffect, useRef, useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import type { ImageModelInfo } from "@/lib/types"; import { fetchModels } from "@/lib/api"; import { slideUp } from "@/components/ui/motion-presets"; import { getStoreUserId } from "@/lib/store"; function getModelStorageKey() { const uid = getStoreUserId() || "_anonymous"; return `epeekit-${uid}-selected-image-model`; } interface ModelSelectorProps { value: string; onChange: (modelId: string) => void; } export function ModelSelector({ value, onChange }: ModelSelectorProps) { const [models, setModels] = useState([]); const [open, setOpen] = useState(false); const containerRef = useRef(null); useEffect(() => { fetchModels() .then(({ models: list, default: defaultId }) => { setModels(list); const saved = localStorage.getItem(getModelStorageKey()); const validIds = new Set(list.map((m) => m.id)); if (saved && validIds.has(saved)) { onChange(saved); } else if (!value || !validIds.has(value)) { onChange(defaultId); } }) .catch(() => {}); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { if (!open) return; const handler = (e: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(e.target as Node)) { setOpen(false); } }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [open]); const selected = models.find((m) => m.id === value); if (models.length === 0) return null; return (
{open && ( {models.map((m) => { const isActive = m.id === value; return ( ); })} )}
); }