diff --git a/src/components/GenerateGuide/AIGuideChat.tsx b/src/components/GenerateGuide/AIGuideChat.tsx index f10a76f86..6a81e606b 100644 --- a/src/components/GenerateGuide/AIGuideChat.tsx +++ b/src/components/GenerateGuide/AIGuideChat.tsx @@ -35,13 +35,17 @@ export function AIGuideChat(props: AIGuideChatProps) { const [inputValue, setInputValue] = useState(''); const [showScrollToBottom, setShowScrollToBottom] = useState(false); - const { data: tokenUsage, isLoading: isTokenUsageLoading } = useQuery( - getAiCourseLimitOptions(), - queryClient, - ); + const { + data: tokenUsage, + isLoading: isTokenUsageLoading, + refetch: refetchTokenUsage, + } = useQuery(getAiCourseLimitOptions(), queryClient); - const { data: userBillingDetails, isLoading: isBillingDetailsLoading } = - useQuery(billingDetailsOptions(), queryClient); + const { + data: userBillingDetails, + isLoading: isBillingDetailsLoading, + refetch: refetchBillingDetails, + } = useQuery(billingDetailsOptions(), queryClient); const isLimitExceeded = (tokenUsage?.used || 0) >= (tokenUsage?.limit || 0); const isPaidUser = userBillingDetails?.status === 'active'; @@ -61,6 +65,9 @@ export function AIGuideChat(props: AIGuideChatProps) { data: { guideSlug, }, + onFinish: () => { + refetchTokenUsage(); + }, }); const scrollToBottom = useCallback( @@ -122,6 +129,9 @@ export function AIGuideChat(props: AIGuideChatProps) { return () => scrollArea.removeEventListener('scroll', checkScrollPosition); }, [checkScrollPosition]); + const isLoading = + isGuideLoading || isTokenUsageLoading || isBillingDetailsLoading; + return (
@@ -131,13 +141,13 @@ export function AIGuideChat(props: AIGuideChatProps) {
- {isGuideLoading && ( + {isLoading && (
)} - {!isGuideLoading && ( + {!isLoading && ( <>
diff --git a/src/hooks/use-chat.ts b/src/hooks/use-chat.ts index 45084cdfb..48eedb666 100644 --- a/src/hooks/use-chat.ts +++ b/src/hooks/use-chat.ts @@ -15,10 +15,11 @@ type UseChatOptions = { initialMessages?: ChatMessage[]; onError?: (error: Error) => void; data?: Record; + onFinish?: () => void; }; export function useChat(options: UseChatOptions) { - const { endpoint, initialMessages, onError, data = {} } = options; + const { endpoint, initialMessages, onError, data = {}, onFinish } = options; const abortControllerRef = useRef(null); const [messages, setMessages] = useState( @@ -100,7 +101,14 @@ export function useChat(options: UseChatOptions) { }); abortControllerRef.current = null; + onFinish?.(); } catch (error) { + if (abortControllerRef.current?.signal.aborted) { + // we don't want to show error if the user stops the chat + // so we just return + return; + } + onError?.(error as Error); } },