diff --git a/web/containers/ModelDropdown/index.tsx b/web/containers/ModelDropdown/index.tsx index 745f26ed1..0f0db390f 100644 --- a/web/containers/ModelDropdown/index.tsx +++ b/web/containers/ModelDropdown/index.tsx @@ -284,6 +284,7 @@ const ModelDropdown = ({ {chatInputMode ? ( setOpen(!open)} > diff --git a/web/helpers/atoms/Thread.atom.ts b/web/helpers/atoms/Thread.atom.ts index c3fdb8260..ef7a88e17 100644 --- a/web/helpers/atoms/Thread.atom.ts +++ b/web/helpers/atoms/Thread.atom.ts @@ -7,6 +7,7 @@ import { } from '@janhq/core' import { atom } from 'jotai' +import { atomWithStorage } from 'jotai/utils' export const engineParamsUpdateAtom = atom(false) @@ -131,3 +132,9 @@ export const setThreadModelParamsAtom = atom( set(threadModelParamsAtom, currentState) } ) + +const ACTIVE_SETTING_INPUT_BOX = 'activeSettingInputBox' +export const activeSettingInputBoxAtom = atomWithStorage( + ACTIVE_SETTING_INPUT_BOX, + false +) diff --git a/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx index c5f35cce8..0c7ec0d4f 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx @@ -11,7 +11,7 @@ import { Badge, useMediaQuery, } from '@janhq/joi' -import { useAtom, useAtomValue, useSetAtom } from 'jotai' +import { useAtom, useAtomValue } from 'jotai' import { FileTextIcon, ImageIcon, @@ -40,6 +40,7 @@ import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' import { spellCheckAtom } from '@/helpers/atoms/Setting.atom' import { + activeSettingInputBoxAtom, activeThreadAtom, getActiveThreadIdAtom, isGeneratingResponseAtom, @@ -52,10 +53,13 @@ const ChatInput = () => { const activeThread = useAtomValue(activeThreadAtom) const { stateModel } = useActiveModel() const messages = useAtomValue(getCurrentChatMessagesAtom) - const [activeSetting, setActiveSetting] = useState(false) + // const [activeSetting, setActiveSetting] = useState(false) const spellCheck = useAtomValue(spellCheckAtom) const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom) + const [activeSettingInputBox, setActiveSettingInputBox] = useAtom( + activeSettingInputBoxAtom + ) const { sendChatMessage } = useSendChatMessage() const activeThreadId = useAtomValue(getActiveThreadIdAtom) @@ -70,7 +74,9 @@ const ChatInput = () => { const threadStates = useAtomValue(threadStatesAtom) const { stopInference } = useActiveModel() - const setActiveTabThreadRightPanel = useSetAtom(activeTabThreadRightPanelAtom) + const [activeTabThreadRightPanel, setActiveTabThreadRightPanel] = useAtom( + activeTabThreadRightPanelAtom + ) const isStreamingResponse = Object.values(threadStates).some( (threadState) => threadState.waitingForResponse @@ -106,12 +112,14 @@ const ChatInput = () => { useEffect(() => { if (textareaRef.current?.clientHeight) { - textareaRef.current.style.height = activeSetting ? '100px' : '40px' + textareaRef.current.style.height = activeSettingInputBox + ? '100px' + : '40px' textareaRef.current.style.height = textareaRef.current.scrollHeight + 'px' textareaRef.current.style.overflow = textareaRef.current.clientHeight >= 390 ? 'auto' : 'hidden' } - }, [textareaRef.current?.clientHeight, currentPrompt, activeSetting]) + }, [textareaRef.current?.clientHeight, currentPrompt, activeSettingInputBox]) const onKeyDown = async (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { @@ -162,11 +170,11 @@ const ChatInput = () => { 'relative max-h-[400px] resize-none pr-20', fileUpload.length && 'rounded-t-none', experimentalFeature && 'pl-10', - activeSetting && 'pb-14 pr-16' + activeSettingInputBox && 'pb-14 pr-16' )} spellCheck={spellCheck} data-testid="txt-input-chat" - style={{ height: activeSetting ? '100px' : '40px' }} + style={{ height: activeSettingInputBox ? '100px' : '40px' }} ref={textareaRef} onKeyDown={onKeyDown} placeholder="Ask me anything" @@ -237,7 +245,7 @@ const ChatInput = () => { ref={refAttachmentMenus} className={twMerge( 'absolute bottom-14 left-0 z-30 w-36 cursor-pointer rounded-lg border border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] py-1 shadow-sm', - activeSetting && 'bottom-28' + activeSettingInputBox && 'bottom-28' )} >
    @@ -320,12 +328,12 @@ const ChatInput = () => {
    - {!activeSetting && ( + {!activeSettingInputBox && (
    - {activeSetting && ( + {activeSettingInputBox && (
    { stateModel.loading && 'bg-transparent' )} > -
    +
    - + Inference + {experimentalFeature && ( { setActiveTabThreadRightPanel('tools') if (matches) { @@ -425,7 +441,10 @@ const ChatInput = () => { )}
    -