* feat: adding create bot functionality Signed-off-by: James <james@jan.ai> * update the temperature progress bar Signed-off-by: James <james@jan.ai> * WIP baselayout * Mapping plugins with available preferences * Added loader component * WIP working another screen * Cleanup types and avoid import one by one * Prepare bottom bar * Add css variables colors to enable user select the accent * Enable change accent color * Seperate css variable * Fix conflict * Add blank state of my model empty * Restyle explore models page * Enable user config left sidebar * Restyle my models page * WIP styling chat page * Restyling chat message * Fix conflict * Adde form preferences setting plugins * Fixed form bot info * Sidebar bot chat * Showing rightbar for both setting when user created bot * Fix style bot info * Using overflow auto intead of scroll * Remove script built UI from root package * Fix missig import * Resolve error linter * fix e2e tests Signed-off-by: James <james@jan.ai> --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai>
96 lines
2.9 KiB
TypeScript
96 lines
2.9 KiB
TypeScript
'use client'
|
|
|
|
import { currentPromptAtom } from '@helpers/JotaiWrapper'
|
|
import { getActiveConvoIdAtom } from '@helpers/atoms/Conversation.atom'
|
|
import { selectedModelAtom } from '@helpers/atoms/Model.atom'
|
|
import useCreateConversation from '@hooks/useCreateConversation'
|
|
import useInitModel from '@hooks/useInitModel'
|
|
import useSendChatMessage from '@hooks/useSendChatMessage'
|
|
import { useAtom, useAtomValue } from 'jotai'
|
|
import { ChangeEvent, useEffect, useRef } from 'react'
|
|
|
|
const BasicPromptInput: React.FC = () => {
|
|
const activeConversationId = useAtomValue(getActiveConvoIdAtom)
|
|
const selectedModel = useAtomValue(selectedModelAtom)
|
|
const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom)
|
|
const { sendChatMessage } = useSendChatMessage()
|
|
const { requestCreateConvo } = useCreateConversation()
|
|
|
|
const { initModel } = useInitModel()
|
|
|
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
|
|
|
const handleKeyDown = async (
|
|
event: React.KeyboardEvent<HTMLTextAreaElement>
|
|
) => {
|
|
if (event.key === 'Enter') {
|
|
if (!event.shiftKey) {
|
|
if (activeConversationId) {
|
|
event.preventDefault()
|
|
sendChatMessage()
|
|
} else {
|
|
if (!selectedModel) {
|
|
console.log('No model selected')
|
|
return
|
|
}
|
|
|
|
await requestCreateConvo(selectedModel)
|
|
await initModel(selectedModel)
|
|
sendChatMessage()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
adjustTextareaHeight()
|
|
}, [currentPrompt])
|
|
|
|
const handleMessageChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
|
setCurrentPrompt(event.target.value)
|
|
}
|
|
|
|
// Auto adjust textarea height based on content
|
|
const MAX_ROWS = 30
|
|
|
|
const adjustTextareaHeight = () => {
|
|
if (textareaRef.current) {
|
|
textareaRef.current.style.height = 'auto' // 1 row
|
|
const scrollHeight = textareaRef.current.scrollHeight
|
|
const maxScrollHeight =
|
|
parseInt(window.getComputedStyle(textareaRef.current).lineHeight, 10) *
|
|
MAX_ROWS
|
|
textareaRef.current.style.height = `${Math.min(
|
|
scrollHeight,
|
|
maxScrollHeight
|
|
)}px`
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className=" border-border rounded-lg border shadow-sm">
|
|
<textarea
|
|
ref={textareaRef}
|
|
onKeyDown={handleKeyDown}
|
|
value={currentPrompt}
|
|
onChange={handleMessageChange}
|
|
name="comment"
|
|
id="comment"
|
|
className="text-background-reverse block w-full resize-none border-0 bg-transparent py-1.5 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
|
|
placeholder="Message ..."
|
|
rows={1}
|
|
style={{ overflow: 'auto' }}
|
|
/>
|
|
{/* Spacer element to match the height of the toolbar */}
|
|
<div className="py-2" aria-hidden="true">
|
|
{/* Matches height of button in toolbar (1px border + 36px content height) */}
|
|
<div className="py-px">
|
|
<div className="h-9" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default BasicPromptInput
|