import { useNavigate } from "react-router-dom"; import { ModelType, Theme, useAppConfig } from "@/app/store/config"; import { useChatStore } from "@/app/store/chat"; import { ChatControllerPool } from "@/app/client/controller"; import { useAllModels } from "@/app/utils/hooks"; import { useEffect, useMemo, useState } from "react"; import { isVisionModel } from "@/app/utils"; import { Selector, showToast } from "@/app/components/ui-lib"; import Locale from "@/app/locales"; import { Path } from "@/app/constant"; import LightIcon from "@/app/icons/light.svg"; import DarkIcon from "@/app/icons/dark.svg"; import AutoIcon from "@/app/icons/auto.svg"; import BottomIcon from "@/app/icons/bottom.svg"; import StopIcon from "@/app/icons/pause.svg"; import RobotIcon from "@/app/icons/robot.svg"; import LoadingButtonIcon from "@/app/icons/loading.svg"; import PromptIcon from "@/app/icons/prompt.svg"; import MaskIcon from "@/app/icons/mask.svg"; import BreakIcon from "@/app/icons/break.svg"; import SettingsIcon from "@/app/icons/chat-settings.svg"; import ImageIcon from "@/app/icons/image.svg"; import ChatAction from "./ChatAction"; import styles from "./index.module.scss"; export function ChatActions(props: { uploadImage: () => void; setAttachImages: (images: string[]) => void; setUploading: (uploading: boolean) => void; showPromptModal: () => void; scrollToBottom: () => void; showPromptHints: () => void; hitBottom: boolean; uploading: boolean; }) { const config = useAppConfig(); const navigate = useNavigate(); const chatStore = useChatStore(); // switch themes const theme = config.theme; function nextTheme() { const themes = [Theme.Auto, Theme.Light, Theme.Dark]; const themeIndex = themes.indexOf(theme); const nextIndex = (themeIndex + 1) % themes.length; const nextTheme = themes[nextIndex]; config.update((config) => (config.theme = nextTheme)); } // stop all responses const couldStop = ChatControllerPool.hasPending(); const stopAll = () => ChatControllerPool.stopAll(); // switch model const currentModel = chatStore.currentSession().mask.modelConfig.model; const allModels = useAllModels(); const models = useMemo( () => allModels.filter((m) => m.available), [allModels], ); const [showModelSelector, setShowModelSelector] = useState(false); const [showUploadImage, setShowUploadImage] = useState(false); useEffect(() => { const show = isVisionModel(currentModel); setShowUploadImage(show); if (!show) { props.setAttachImages([]); props.setUploading(false); } // if current model is not available // switch to first available model const isUnavaliableModel = !models.some((m) => m.name === currentModel); if (isUnavaliableModel && models.length > 0) { const nextModel = models[0].name as ModelType; chatStore.updateCurrentSession( (session) => (session.mask.modelConfig.model = nextModel), ); showToast(nextModel); } }, [chatStore, currentModel, models]); return (