'use client' import type { inferRouterOutputs } from '@trpc/server'; import { useUser } from '@clerk/nextjs' import { createContext, useContext, useEffect, useState, type ReactNode } from 'react' import { trpc } from '~/app/_trpc/Client' import { type ChatRouter } from '~/server/routers/chat' const MessageContext = createContext<{ session?: inferRouterOutputs['getSession'] messages?: inferRouterOutputs['getMessages'] refetchMessages: () => void clearChat: (callback?: () => void) => void error: string|null isLoading: boolean clearingChat: boolean clearedChat: boolean }>({ session: undefined, messages: undefined, refetchMessages: () => undefined, clearChat: () => undefined, error: null, isLoading: true, clearingChat: false, clearedChat: false }) export const useMessages = () => useContext(MessageContext) export const MessagesProvider = ({children}:{children:ReactNode}) => { const [error,setError] = useState(null) const [isLoading,setIsLoading] = useState(true) const { isLoaded, isSignedIn } = useUser() const { data: session,error:sessionError,isLoading:sessionLoading} = trpc.chat.getSession.useQuery(undefined, { enabled: isSignedIn === true, }) const { data: messages, refetch, error:messageError, isLoading:messagesLoading } = trpc.chat.getMessages.useQuery(session?.id ? session.id : "", { enabled: isSignedIn === true && session?.id != undefined, }) const { mutate ,isPending:clearingChat,isSuccess:clearedChat } = trpc.chat.clearChat.useMutation() const utils = trpc.useUtils() const refetchMessages = () => { if (!isSignedIn) { return; } utils.chat.getMessages.invalidate() refetch() } const clearChat = (callback?: () => void) => { if (!isSignedIn) { if (callback) { callback() } return; } mutate(undefined,{onSuccess: () => { if (callback) { callback() } utils.chat.getMessages.invalidate() }}) } useEffect(() => { if (isSignedIn !== true) { setError(null) return; } messageError && setError(messageError.message) sessionError && setError(sessionError.message) },[messageError,sessionError,isSignedIn]) useEffect(() => { if (!isLoaded) { setIsLoading(true) return; } if (isSignedIn !== true) { setIsLoading(false) return; } setIsLoading(sessionLoading || messagesLoading) },[isLoaded,isSignedIn,sessionLoading,messagesLoading]) return ( {children} ) }