203 lines
5.0 KiB
TypeScript
203 lines
5.0 KiB
TypeScript
import {
|
|
useQuery,
|
|
useInfiniteQuery,
|
|
QueryClient,
|
|
useMutation,
|
|
} from "@tanstack/react-query";
|
|
import { useAuthToken } from "../hooks/use-root-data";
|
|
import { MessageList } from "../../src/api/types/models";
|
|
import { createChatApi } from "~/utils/api-client-factory";
|
|
|
|
/**
|
|
* Custom hook to get the list of user's threads
|
|
*/
|
|
export function useGetUserThreads() {
|
|
const token = useAuthToken();
|
|
|
|
return useQuery({
|
|
queryKey: ["getUserThreads"],
|
|
queryFn: async () => {
|
|
if (!token) {
|
|
throw new Error("Authentication token is required");
|
|
}
|
|
const chatApi = createChatApi(token);
|
|
return await chatApi.apiChatV1ThreadsList();
|
|
},
|
|
enabled: !!token,
|
|
retry: 1,
|
|
retryDelay: 3000,
|
|
refetchOnWindowFocus: false,
|
|
refetchInterval: 20 * 1000, // 30 seconds refetch
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Server-side function to get thread details
|
|
*/
|
|
export async function getThreadDetails(token: string, threadId: string) {
|
|
if (!token) {
|
|
throw new Error("Authentication token is required");
|
|
}
|
|
|
|
const chatApi = createChatApi(token);
|
|
return await chatApi.apiChatV1ThreadsRead({ threadId });
|
|
}
|
|
|
|
/**
|
|
* Custom hook to get thread details by ID
|
|
*/
|
|
export function useGetThreadDetails(threadId: string) {
|
|
const token = useAuthToken();
|
|
|
|
return useQuery({
|
|
queryKey: ["getThreadDetails", threadId],
|
|
queryFn: async () => {
|
|
if (!token) {
|
|
throw new Error("Authentication token is required");
|
|
}
|
|
const chatApi = createChatApi(token);
|
|
return await chatApi.apiChatV1ThreadsRead({ threadId });
|
|
},
|
|
enabled: !!token && !!threadId,
|
|
retry: 1,
|
|
retryDelay: 3000,
|
|
refetchOnWindowFocus: false,
|
|
});
|
|
}
|
|
|
|
export const deleteMessageFromCache = (
|
|
queryClient: QueryClient,
|
|
threadId: string,
|
|
messageId: string
|
|
) => {
|
|
queryClient.setQueryData(
|
|
["getThreadMessages", threadId],
|
|
(
|
|
oldData:
|
|
| {
|
|
pages: Array<{
|
|
results: MessageList[];
|
|
nextCursor: string | null;
|
|
}>;
|
|
pageParams: Array<string | undefined>;
|
|
}
|
|
| undefined
|
|
) => {
|
|
if (!oldData) return oldData;
|
|
return {
|
|
...oldData,
|
|
pages: oldData.pages.map((page) => {
|
|
return {
|
|
...page,
|
|
results: page.results.filter((message) => message.id !== messageId),
|
|
};
|
|
}),
|
|
};
|
|
}
|
|
);
|
|
};
|
|
export const setMessagesCache = (
|
|
queryClient: QueryClient,
|
|
threadId: string,
|
|
data: MessageList
|
|
) => {
|
|
queryClient.setQueryData(
|
|
["getThreadMessages", threadId],
|
|
(
|
|
oldData:
|
|
| {
|
|
pages: Array<{
|
|
results: MessageList[];
|
|
nextCursor: string | null;
|
|
}>;
|
|
pageParams: Array<string | undefined>;
|
|
}
|
|
| undefined
|
|
) => {
|
|
if (!oldData) return oldData;
|
|
return {
|
|
...oldData,
|
|
pages: oldData.pages.map((page, index: number) => {
|
|
if (index === 0) {
|
|
return {
|
|
...page,
|
|
results: [data, ...page.results],
|
|
};
|
|
}
|
|
return page;
|
|
}),
|
|
};
|
|
}
|
|
);
|
|
};
|
|
/**
|
|
* Custom hook to get thread messages with infinite scrolling
|
|
*/
|
|
export function useGetThreadMessages(threadId: string) {
|
|
const token = useAuthToken();
|
|
|
|
return useInfiniteQuery({
|
|
queryKey: ["getThreadMessages", threadId],
|
|
queryFn: async ({ pageParam }) => {
|
|
if (!token) {
|
|
throw new Error("Authentication token is required");
|
|
}
|
|
const chatApi = createChatApi(token);
|
|
|
|
// Using cursor-based pagination
|
|
const response = await chatApi.apiChatV1ThreadsMessagesList({
|
|
threadId,
|
|
cursor: pageParam ? String(pageParam) : undefined,
|
|
});
|
|
|
|
// Check if response has next cursor
|
|
let nextCursor;
|
|
if (response.next) {
|
|
const nextUrlParts = response.next.split("?cursor=");
|
|
nextCursor = nextUrlParts.length > 1 ? nextUrlParts[1] : null;
|
|
} else {
|
|
nextCursor = null;
|
|
}
|
|
|
|
const messages = response.results || [];
|
|
// Get the ID of the last message to use as next cursor
|
|
|
|
return {
|
|
results: messages,
|
|
nextCursor,
|
|
};
|
|
},
|
|
initialPageParam: undefined as string | undefined,
|
|
getNextPageParam: (lastPage) => {
|
|
return lastPage.nextCursor || undefined;
|
|
},
|
|
enabled: !!token && !!threadId,
|
|
refetchOnWindowFocus: false,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Custom hook to create a new chat thread
|
|
*/
|
|
export function useCreateChatThread() {
|
|
const token = useAuthToken();
|
|
return useMutation({
|
|
mutationFn: async (participantId: string) => {
|
|
if (!token) {
|
|
throw new Error("Authentication token and user ID are required");
|
|
}
|
|
try {
|
|
const chatApi = createChatApi(token);
|
|
return await chatApi.apiChatV1ThreadsCreateCreate({
|
|
data: {
|
|
participantId: participantId,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error("Error creating chat thread:", error);
|
|
throw error;
|
|
}
|
|
},
|
|
});
|
|
}
|