fix: save state toggle input box setting (#3402)

* fix: save input box setting

* fix: active icon state when model tab is active, and increased textarea instruction

* chore: update button modal inference
This commit is contained in:
Faisal Amir 2024-08-20 19:00:00 +07:00 committed by GitHub
parent e9c30450b9
commit 73ec5de001
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 16 deletions

View File

@ -284,6 +284,7 @@ const ModelDropdown = ({
{chatInputMode ? (
<Badge
theme="secondary"
variant={open ? 'solid' : 'outline'}
className="cursor-pointer"
onClick={() => setOpen(!open)}
>

View File

@ -7,6 +7,7 @@ import {
} from '@janhq/core'
import { atom } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
export const engineParamsUpdateAtom = atom<boolean>(false)
@ -131,3 +132,9 @@ export const setThreadModelParamsAtom = atom(
set(threadModelParamsAtom, currentState)
}
)
const ACTIVE_SETTING_INPUT_BOX = 'activeSettingInputBox'
export const activeSettingInputBoxAtom = atomWithStorage<boolean>(
ACTIVE_SETTING_INPUT_BOX,
false
)

View File

@ -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<HTMLTextAreaElement>) => {
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'
)}
>
<ul>
@ -320,12 +328,12 @@ const ChatInput = () => {
<div className={twMerge('absolute right-3 top-1.5')}>
<div className="flex items-center gap-x-4">
{!activeSetting && (
{!activeSettingInputBox && (
<div className="flex h-8 items-center">
<Button
theme="icon"
onClick={() => {
setActiveSetting(!activeSetting)
setActiveSettingInputBox(!activeSettingInputBox)
}}
>
<SettingsIcon
@ -378,7 +386,7 @@ const ChatInput = () => {
</div>
</div>
{activeSetting && (
{activeSettingInputBox && (
<div
className={twMerge(
'absolute bottom-[6px] left-[1px] flex w-[calc(100%-2px)] items-center justify-between rounded-lg bg-[hsla(var(--textarea-bg))] p-3',
@ -386,10 +394,14 @@ const ChatInput = () => {
stateModel.loading && 'bg-transparent'
)}
>
<div className="flex items-center gap-x-3">
<div className="flex items-center gap-x-2">
<ModelDropdown chatInputMode />
<Button
theme="icon"
<Badge
theme="secondary"
className="flex cursor-pointer items-center gap-x-1"
variant={
activeTabThreadRightPanel === 'model' ? 'solid' : 'outline'
}
onClick={() => {
setActiveTabThreadRightPanel('model')
if (matches) {
@ -403,11 +415,15 @@ const ChatInput = () => {
size={16}
className="flex-shrink-0 cursor-pointer text-[hsla(var(--text-secondary))]"
/>
</Button>
<span>Inference</span>
</Badge>
{experimentalFeature && (
<Badge
className="flex cursor-pointer items-center gap-x-1"
theme="secondary"
variant={
activeTabThreadRightPanel === 'tools' ? 'solid' : 'outline'
}
onClick={() => {
setActiveTabThreadRightPanel('tools')
if (matches) {
@ -425,7 +441,10 @@ const ChatInput = () => {
</Badge>
)}
</div>
<Button theme="icon" onClick={() => setActiveSetting(false)}>
<Button
theme="icon"
onClick={() => setActiveSettingInputBox(false)}
>
<ChevronUpIcon
size={16}
className="cursor-pointer text-[hsla(var(--text-secondary))]"

View File

@ -207,6 +207,7 @@ const ThreadRightPanel = () => {
id="assistant-instructions"
placeholder="Eg. You are a helpful assistant."
value={activeThread?.assistants[0].instructions ?? ''}
rows={8}
onChange={onAssistantInstructionChanged}
/>
</div>