feat: add FlowPilot prefill handoff from command palette to AssistantChatPage
When navigated to /assistant with location.state.prefill, automatically creates a new chat and sends the prefill message without user interaction. Clears location state after handling to prevent re-trigger on back navigation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect, useRef, useCallback } from 'react'
|
import { useState, useEffect, useRef, useCallback } from 'react'
|
||||||
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import { Sparkles, Send, Loader2, Flag } from 'lucide-react'
|
import { Sparkles, Send, Loader2, Flag } from 'lucide-react'
|
||||||
import { PageMeta } from '@/components/common/PageMeta'
|
import { PageMeta } from '@/components/common/PageMeta'
|
||||||
import { assistantChatApi } from '@/api/assistantChat'
|
import { assistantChatApi } from '@/api/assistantChat'
|
||||||
@@ -14,6 +15,8 @@ interface MessageWithMeta extends ChatMessageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function AssistantChatPage() {
|
export default function AssistantChatPage() {
|
||||||
|
const location = useLocation()
|
||||||
|
const navigate = useNavigate()
|
||||||
const [chats, setChats] = useState<ChatListItem[]>([])
|
const [chats, setChats] = useState<ChatListItem[]>([])
|
||||||
const [activeChatId, setActiveChatId] = useState<string | null>(null)
|
const [activeChatId, setActiveChatId] = useState<string | null>(null)
|
||||||
const [messages, setMessages] = useState<MessageWithMeta[]>([])
|
const [messages, setMessages] = useState<MessageWithMeta[]>([])
|
||||||
@@ -22,12 +25,56 @@ export default function AssistantChatPage() {
|
|||||||
const [showConclude, setShowConclude] = useState(false)
|
const [showConclude, setShowConclude] = useState(false)
|
||||||
const messagesEndRef = useRef<HTMLDivElement>(null)
|
const messagesEndRef = useRef<HTMLDivElement>(null)
|
||||||
const inputRef = useRef<HTMLTextAreaElement>(null)
|
const inputRef = useRef<HTMLTextAreaElement>(null)
|
||||||
|
const prefillHandledRef = useRef(false)
|
||||||
|
|
||||||
// Load chat list
|
// Load chat list
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadChats()
|
loadChats()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// Handle prefill from command palette handoff
|
||||||
|
useEffect(() => {
|
||||||
|
const prefill = (location.state as { prefill?: string } | null)?.prefill
|
||||||
|
if (!prefill || prefillHandledRef.current) return
|
||||||
|
prefillHandledRef.current = true
|
||||||
|
|
||||||
|
// Clear the location state so back-navigation doesn't retrigger
|
||||||
|
navigate(location.pathname, { replace: true, state: {} })
|
||||||
|
|
||||||
|
const sendPrefill = async () => {
|
||||||
|
try {
|
||||||
|
const chat = await assistantChatApi.createChat()
|
||||||
|
setChats(prev => [
|
||||||
|
{ id: chat.id, title: chat.title, message_count: 0, pinned: false, created_at: chat.created_at, updated_at: chat.updated_at },
|
||||||
|
...prev,
|
||||||
|
])
|
||||||
|
setActiveChatId(chat.id)
|
||||||
|
setMessages([{ role: 'user', content: prefill }])
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
const response = await assistantChatApi.sendMessage(chat.id, prefill)
|
||||||
|
setMessages(prev => [
|
||||||
|
...prev,
|
||||||
|
{ role: 'assistant', content: response.content, suggestedFlows: response.suggested_flows },
|
||||||
|
])
|
||||||
|
setChats(prev =>
|
||||||
|
prev.map(c =>
|
||||||
|
c.id === chat.id
|
||||||
|
? { ...c, message_count: 2, title: prefill.slice(0, 100), updated_at: new Date().toISOString() }
|
||||||
|
: c
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
toast.error('Failed to start AI conversation')
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPrefill()
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
// Auto-scroll
|
// Auto-scroll
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
|
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
|||||||
Reference in New Issue
Block a user