import React, { useState, useEffect, useRef } from 'react'; import TextareaAutosize from 'react-textarea-autosize'; import { useSelector, useDispatch } from 'react-redux'; import { setModel, setDisabled, setCustomGpt } from '~/store/submitSlice'; // import { setModels } from '~/store/modelSlice'; import ModelItem from './ModelItem'; import GPTIcon from '../svg/GPTIcon'; import BingIcon from '../svg/BingIcon'; import { Button } from '../ui/Button.tsx'; import { Input } from '../ui/Input.tsx'; import { Label } from '../ui/Label.tsx'; import { DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuRadioGroup, // DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger } from '../ui/DropdownMenu.tsx'; import { Dialog, // DialogTrigger, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/Dialog.tsx'; export default function ModelMenu() { const dispatch = useDispatch(); const { model } = useSelector((state) => state.submit); const { models } = useSelector((state) => state.models); const [chatGptLabel, setChatGptLabel] = useState(''); const [promptPrefix, setPromptPrefix] = useState(''); const [required, setRequired] = useState(false); const inputRef = useRef(null); useEffect(() => { const lastSelectedModel = JSON.parse(localStorage.getItem('model')); if (lastSelectedModel && lastSelectedModel !== 'chatgptCustom') { dispatch(setModel(lastSelectedModel)); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { localStorage.setItem('model', JSON.stringify(model)); }, [model]); const onChange = (value) => { if (value === 'chatgptCustom') { // dispatch(setDisabled(true)); } else { dispatch(setModel(value)); dispatch(setDisabled(false)); } }; const submitHandler = (e) => { if (chatGptLabel.length === 0) { e.preventDefault(); setRequired(true); inputRef.current.focus(); return; } dispatch(setCustomGpt({ chatGptLabel, promptPrefix })); dispatch(setModel('chatgptCustom')); dispatch(setDisabled(false)); }; const defaultColorProps = [ 'text-gray-500', 'hover:bg-gray-100', 'disabled:hover:bg-transparent', 'dark:hover:bg-opacity-20', 'dark:hover:bg-gray-900', 'dark:hover:text-gray-400', // 'dark:data-[state=open]:bg-transparent', 'dark:disabled:hover:bg-transparent' ]; const chatgptColorProps = [ 'text-green-700', 'dark:text-emerald-300', 'hover:bg-green-100', 'disabled:hover:bg-transparent', 'dark:hover:bg-opacity-50', 'dark:hover:bg-green-900', 'dark:hover:text-gray-100', // 'dark:data-[state=open]:bg-gray-700', 'dark:disabled:hover:bg-transparent' ]; const requiredProp = required ? { required: true } : {}; const colorProps = model === 'chatgpt' ? chatgptColorProps : defaultColorProps; const icon = model === 'bingai' ? : ; return ( Select a Model {models.map((modelItem, i) => ( ))} {/* ChatGPT $ CustomGPT $ BingAI ChatGPT */} Customize ChatGPT Note: important instructions are often better placed in your message rather than the prefix.{' '} More info here
setChatGptLabel(e.target.value)} placeholder="Set a custom name for ChatGPT" className="col-span-3 shadow-[0_0_10px_rgba(0,0,0,0.10)] invalid:border-red-400 invalid:text-red-600 invalid:placeholder-red-600 invalid:placeholder-opacity-70 invalid:ring-opacity-20 focus:ring-opacity-20 focus:invalid:border-red-400 focus:invalid:ring-red-400 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:invalid:border-red-600 dark:invalid:text-red-300 dark:invalid:placeholder-opacity-80 dark:focus:invalid:ring-red-600 dark:focus:invalid:ring-opacity-50" {...requiredProp} />
setPromptPrefix(e.target.value)} placeholder="Set custom instructions. Defaults to: 'You are ChatGPT, a large language model trained by OpenAI.'" className="col-span-3 flex h-20 w-full resize-none rounded-md border border-slate-300 bg-transparent py-2 px-3 text-sm shadow-[0_0_10px_rgba(0,0,0,0.10)] placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-slate-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900" />
Cancel Submit
); }