mirror of
https://github.com/ibelick/webclaw.git
synced 2026-08-14 00:57:51 +00:00
refactor(chat): replace effect-based auth redirect with render navigation and remove unused idle-finish hook
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { Navigate, useNavigate } from '@tanstack/react-router'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
|
||||
import {
|
||||
@@ -38,7 +38,7 @@ import { useChatSessions } from './hooks/use-chat-sessions'
|
||||
import { useChatStream } from './hooks/use-chat-stream'
|
||||
import { useChatPendingSend } from './hooks/use-chat-pending-send'
|
||||
import { useChatGenerationGuard } from './hooks/use-chat-generation-guard'
|
||||
import { useChatErrorState } from './hooks/use-chat-error-state'
|
||||
import { shouldRedirectToConnect } from './hooks/use-chat-error-state'
|
||||
import { useChatRedirect } from './hooks/use-chat-redirect'
|
||||
import type { AttachmentFile } from '@/components/attachment-button'
|
||||
import type { ChatComposerHelpers } from './components/chat-composer'
|
||||
@@ -66,7 +66,6 @@ export function ChatScreen({
|
||||
const queryClient = useQueryClient()
|
||||
const [sending, setSending] = useState(false)
|
||||
const [creatingSession, setCreatingSession] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [isRedirecting, setIsRedirecting] = useState(false)
|
||||
const { headerRef, composerRef, mainRef, pinGroupMinHeight, headerHeight } =
|
||||
useChatMeasurements()
|
||||
@@ -144,7 +143,6 @@ export function ChatScreen({
|
||||
}, [gatewayStatusQuery])
|
||||
const isSidebarCollapsed = uiQuery.data.isSidebarCollapsed
|
||||
const handleActiveSessionDelete = useCallback(() => {
|
||||
setError(null)
|
||||
setIsRedirecting(true)
|
||||
navigate({ to: '/new', replace: true })
|
||||
}, [navigate])
|
||||
@@ -253,7 +251,6 @@ export function ChatScreen({
|
||||
|
||||
setPendingGeneration(true)
|
||||
setSending(true)
|
||||
setError(null)
|
||||
setWaitingForResponse(true)
|
||||
setPinToTop(true)
|
||||
|
||||
@@ -304,7 +301,6 @@ export function ChatScreen({
|
||||
},
|
||||
)
|
||||
}
|
||||
setError(`Failed to send message. ${messageText}`)
|
||||
setPendingGeneration(false)
|
||||
setWaitingForResponse(false)
|
||||
setPinToTop(false)
|
||||
@@ -383,7 +379,7 @@ export function ChatScreen({
|
||||
replace: true,
|
||||
})
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
.catch(() => {
|
||||
removeHistoryMessageByClientId(
|
||||
queryClient,
|
||||
'new',
|
||||
@@ -392,9 +388,6 @@ export function ChatScreen({
|
||||
optimisticId,
|
||||
)
|
||||
helpers.setValue(body)
|
||||
setError(
|
||||
`Failed to create session. ${err instanceof Error ? err.message : String(err)}`,
|
||||
)
|
||||
setPendingGeneration(false)
|
||||
setWaitingForResponse(false)
|
||||
setPinToTop(false)
|
||||
@@ -460,6 +453,15 @@ export function ChatScreen({
|
||||
const showGatewayNotice =
|
||||
showGatewayDown &&
|
||||
gatewayStatusQuery.errorUpdatedAt > gatewayStatusMountRef.current
|
||||
const redirectToConnect = shouldRedirectToConnect({
|
||||
isRedirecting,
|
||||
shouldRedirectToNew,
|
||||
sessionsReady: sessionsQuery.isSuccess,
|
||||
activeExists,
|
||||
sessionsError,
|
||||
historyError,
|
||||
gatewayStatusError,
|
||||
})
|
||||
const historyEmpty = !historyLoading && displayMessages.length === 0
|
||||
const gatewayNotice = useMemo(() => {
|
||||
if (!showGatewayNotice) return null
|
||||
@@ -512,18 +514,6 @@ export function ChatScreen({
|
||||
},
|
||||
})
|
||||
|
||||
useChatErrorState({
|
||||
error,
|
||||
setError,
|
||||
isRedirecting,
|
||||
shouldRedirectToNew,
|
||||
sessionsReady: sessionsQuery.isSuccess,
|
||||
activeExists,
|
||||
sessionsError,
|
||||
historyError,
|
||||
gatewayStatusError,
|
||||
})
|
||||
|
||||
useChatRedirect({
|
||||
activeFriendlyId,
|
||||
isNewChat,
|
||||
@@ -567,6 +557,10 @@ export function ChatScreen({
|
||||
/>
|
||||
)
|
||||
|
||||
if (redirectToConnect) {
|
||||
return <Navigate to="/connect" replace />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-screen bg-surface text-primary-900">
|
||||
<div
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
|
||||
import { isMissingGatewayAuth } from '../utils'
|
||||
|
||||
type UseChatErrorStateInput = {
|
||||
error: string | null
|
||||
setError: (value: string | null) => void
|
||||
isRedirecting: boolean
|
||||
shouldRedirectToNew: boolean
|
||||
sessionsReady: boolean
|
||||
@@ -15,9 +10,7 @@ type UseChatErrorStateInput = {
|
||||
gatewayStatusError: string | null
|
||||
}
|
||||
|
||||
export function useChatErrorState({
|
||||
error,
|
||||
setError,
|
||||
export function shouldRedirectToConnect({
|
||||
isRedirecting,
|
||||
shouldRedirectToNew,
|
||||
sessionsReady,
|
||||
@@ -26,49 +19,9 @@ export function useChatErrorState({
|
||||
historyError,
|
||||
gatewayStatusError,
|
||||
}: UseChatErrorStateInput) {
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
if (isRedirecting) {
|
||||
if (error) setError(null)
|
||||
return
|
||||
}
|
||||
if (shouldRedirectToNew) {
|
||||
if (error) setError(null)
|
||||
return
|
||||
}
|
||||
if (sessionsReady && !activeExists) {
|
||||
if (error) setError(null)
|
||||
return
|
||||
}
|
||||
const messageText = sessionsError ?? historyError ?? gatewayStatusError
|
||||
if (!messageText) {
|
||||
if (error?.startsWith('Failed to load')) {
|
||||
setError(null)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (isMissingGatewayAuth(messageText)) {
|
||||
navigate({ to: '/connect', replace: true })
|
||||
}
|
||||
const message = sessionsError
|
||||
? `Failed to load sessions. ${sessionsError}`
|
||||
: historyError
|
||||
? `Failed to load history. ${historyError}`
|
||||
: gatewayStatusError
|
||||
? `Gateway unavailable. ${gatewayStatusError}`
|
||||
: null
|
||||
if (message) setError(message)
|
||||
}, [
|
||||
activeExists,
|
||||
error,
|
||||
gatewayStatusError,
|
||||
historyError,
|
||||
isRedirecting,
|
||||
navigate,
|
||||
sessionsError,
|
||||
sessionsReady,
|
||||
setError,
|
||||
shouldRedirectToNew,
|
||||
])
|
||||
if (isRedirecting || shouldRedirectToNew) return false
|
||||
if (sessionsReady && !activeExists) return false
|
||||
const messageText = sessionsError ?? historyError ?? gatewayStatusError
|
||||
if (!messageText) return false
|
||||
return isMissingGatewayAuth(messageText)
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import { textFromMessage } from '../utils'
|
||||
import { setPendingGeneration } from '../pending-send'
|
||||
import type { GatewayMessage } from '../types'
|
||||
|
||||
type UseChatIdleFinishInput = {
|
||||
historyMessages: Array<GatewayMessage>
|
||||
streamStop: () => void
|
||||
setWaitingForResponse: (value: boolean) => void
|
||||
}
|
||||
|
||||
export function useChatIdleFinish({
|
||||
historyMessages,
|
||||
streamStop,
|
||||
setWaitingForResponse,
|
||||
}: UseChatIdleFinishInput) {
|
||||
const lastAssistantSignature = useRef('')
|
||||
const streamIdleTimer = useRef<number | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (historyMessages.length === 0) return
|
||||
const latestMessage = historyMessages[historyMessages.length - 1]
|
||||
if (latestMessage.role !== 'assistant') return
|
||||
const signature = `${historyMessages.length}:${textFromMessage(latestMessage).slice(-64)}`
|
||||
if (signature !== lastAssistantSignature.current) {
|
||||
lastAssistantSignature.current = signature
|
||||
if (streamIdleTimer.current) {
|
||||
window.clearTimeout(streamIdleTimer.current)
|
||||
}
|
||||
streamIdleTimer.current = window.setTimeout(() => {
|
||||
streamStop()
|
||||
setPendingGeneration(false)
|
||||
setWaitingForResponse(false)
|
||||
}, 12000)
|
||||
}
|
||||
return () => {
|
||||
if (streamIdleTimer.current) {
|
||||
window.clearTimeout(streamIdleTimer.current)
|
||||
streamIdleTimer.current = null
|
||||
}
|
||||
}
|
||||
}, [historyMessages, setWaitingForResponse, streamStop])
|
||||
}
|
||||
Reference in New Issue
Block a user