Refactor AiChat component to enhance message history navigation and input handling
- Introduced state management for message history, allowing users to navigate through previous messages using the up and down arrow keys. - Updated input handling to reset history index when the user types a new message, improving user experience. - Changed the key event handler from 'onKeyPress' to 'onKeyDown' for better control over key events during message input. - Adjusted appsettings.json to simplify the default model configuration for Gemini integration.
This commit is contained in:
@@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"Llm": {
|
"Llm": {
|
||||||
"Gemini": {
|
"Gemini": {
|
||||||
"DefaultModel": "gemini/gemini-3-flash-preview"
|
"DefaultModel": "gemini-3-flash-preview"
|
||||||
},
|
},
|
||||||
"OpenAI": {
|
"OpenAI": {
|
||||||
"DefaultModel": "gpt-4o"
|
"DefaultModel": "gpt-4o"
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ function AiChat({ onClose }: AiChatProps): JSX.Element {
|
|||||||
const [provider, setProvider] = useState<string>('auto')
|
const [provider, setProvider] = useState<string>('auto')
|
||||||
const [availableProviders, setAvailableProviders] = useState<string[]>([])
|
const [availableProviders, setAvailableProviders] = useState<string[]>([])
|
||||||
const [currentProgress, setCurrentProgress] = useState<LlmProgressUpdate | null>(null)
|
const [currentProgress, setCurrentProgress] = useState<LlmProgressUpdate | null>(null)
|
||||||
|
const [messageHistory, setMessageHistory] = useState<string[]>([])
|
||||||
|
const [historyIndex, setHistoryIndex] = useState<number>(-1)
|
||||||
|
const [tempInput, setTempInput] = useState<string>('')
|
||||||
const messagesEndRef = useRef<HTMLDivElement>(null)
|
const messagesEndRef = useRef<HTMLDivElement>(null)
|
||||||
const { apiUrl, userToken } = useApiUrlStore()
|
const { apiUrl, userToken } = useApiUrlStore()
|
||||||
|
|
||||||
@@ -66,6 +69,11 @@ function AiChat({ onClose }: AiChatProps): JSX.Element {
|
|||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to message history
|
||||||
|
setMessageHistory(prev => [...prev, input.trim()])
|
||||||
|
setHistoryIndex(-1)
|
||||||
|
setTempInput('')
|
||||||
|
|
||||||
setMessages(prev => [...prev, userMessage])
|
setMessages(prev => [...prev, userMessage])
|
||||||
setInput('')
|
setInput('')
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@@ -167,10 +175,54 @@ function AiChat({ onClose }: AiChatProps): JSX.Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
// Handle Enter key
|
||||||
if (e.key === 'Enter' && !e.shiftKey) {
|
if (e.key === 'Enter' && !e.shiftKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
sendMessage()
|
sendMessage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Up arrow - navigate backward through history
|
||||||
|
if (e.key === 'ArrowUp') {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (messageHistory.length === 0) return
|
||||||
|
|
||||||
|
// If we're at the beginning (no history navigation yet), save current input
|
||||||
|
if (historyIndex === -1) {
|
||||||
|
setTempInput(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate backward
|
||||||
|
const newIndex = historyIndex === -1
|
||||||
|
? messageHistory.length - 1
|
||||||
|
: Math.max(0, historyIndex - 1)
|
||||||
|
|
||||||
|
setHistoryIndex(newIndex)
|
||||||
|
setInput(messageHistory[newIndex])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Down arrow - navigate forward through history
|
||||||
|
if (e.key === 'ArrowDown') {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (messageHistory.length === 0) return
|
||||||
|
|
||||||
|
// If we're at the last message, clear input and reset
|
||||||
|
if (historyIndex >= messageHistory.length - 1) {
|
||||||
|
setHistoryIndex(-1)
|
||||||
|
setInput(tempInput)
|
||||||
|
setTempInput('')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate forward
|
||||||
|
const newIndex = historyIndex + 1
|
||||||
|
setHistoryIndex(newIndex)
|
||||||
|
setInput(messageHistory[newIndex])
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,8 +313,20 @@ function AiChat({ onClose }: AiChatProps): JSX.Element {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<textarea
|
<textarea
|
||||||
value={input}
|
value={input}
|
||||||
onChange={(e) => setInput(e.target.value)}
|
onChange={(e) => {
|
||||||
onKeyPress={handleKeyPress}
|
const newValue = e.target.value
|
||||||
|
setInput(newValue)
|
||||||
|
|
||||||
|
// Reset history index if user manually types something different
|
||||||
|
if (historyIndex !== -1) {
|
||||||
|
const currentHistoryItem = messageHistory[historyIndex]
|
||||||
|
if (newValue !== currentHistoryItem) {
|
||||||
|
setHistoryIndex(-1)
|
||||||
|
setTempInput('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
placeholder="Ask me anything about your backtests..."
|
placeholder="Ask me anything about your backtests..."
|
||||||
className="textarea textarea-bordered flex-1 resize-none"
|
className="textarea textarea-bordered flex-1 resize-none"
|
||||||
rows={2}
|
rows={2}
|
||||||
|
|||||||
Reference in New Issue
Block a user