mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-03 06:12:53 +02:00
Chat history UI
This commit is contained in:
@@ -61,91 +61,93 @@ export function AIChatHistory(props: AIChatHistoryProps) {
|
|||||||
setIsChatHistoryLoading(false);
|
setIsChatHistoryLoading(false);
|
||||||
}, [hasError]);
|
}, [hasError]);
|
||||||
|
|
||||||
|
if (isLoading || isBillingDetailsLoading) {
|
||||||
|
return (
|
||||||
|
<AIChatLayout>
|
||||||
|
<div className="relative flex grow">
|
||||||
|
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
||||||
|
<Loader2Icon className="h-8 w-8 animate-spin stroke-[2.5] text-gray-400/80" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AIChatLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AIChatLayout>
|
<AIChatLayout>
|
||||||
<div className="relative flex grow">
|
<div className="relative flex grow">
|
||||||
{showGlobalLoader && (
|
{isPaidUser && (
|
||||||
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
<ListChatHistory
|
||||||
<Loader2Icon className="h-8 w-8 animate-spin stroke-[2.5]" />
|
activeChatHistoryId={chatHistoryId}
|
||||||
</div>
|
onChatHistoryClick={(chatHistoryId) => {
|
||||||
|
setKeyTrigger((keyTrigger) => keyTrigger + 1);
|
||||||
|
|
||||||
|
if (chatHistoryId === null) {
|
||||||
|
setChatHistoryId(undefined);
|
||||||
|
window.history.replaceState(null, '', '/ai/chat');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// so that we can show the loading state when the chat history is not fetched yet
|
||||||
|
// it will help us to avoid the flash of content
|
||||||
|
const hasAlreadyFetched = queryClient.getQueryData(
|
||||||
|
chatHistoryOptions(chatHistoryId).queryKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasAlreadyFetched) {
|
||||||
|
setIsChatHistoryLoading(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
setChatHistoryId(chatHistoryId);
|
||||||
|
window.history.replaceState(
|
||||||
|
null,
|
||||||
|
'',
|
||||||
|
`/ai/chat/${chatHistoryId}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onDelete={(deletedChatHistoryId) => {
|
||||||
|
const isCurrentChatHistory =
|
||||||
|
deletedChatHistoryId === chatHistoryId;
|
||||||
|
if (!isCurrentChatHistory) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setChatHistoryId(undefined);
|
||||||
|
window.history.replaceState(null, '', '/ai/chat');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!showGlobalLoader && (
|
<div className="relative flex grow">
|
||||||
<>
|
{isChatHistoryLoading && !hasError && (
|
||||||
{isPaidUser && (
|
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
||||||
<ListChatHistory
|
<Loader2Icon className="h-8 w-8 animate-spin stroke-[2.5]" />
|
||||||
activeChatHistoryId={chatHistoryId}
|
|
||||||
onChatHistoryClick={(chatHistoryId) => {
|
|
||||||
setKeyTrigger((keyTrigger) => keyTrigger + 1);
|
|
||||||
|
|
||||||
if (chatHistoryId === null) {
|
|
||||||
setChatHistoryId(undefined);
|
|
||||||
window.history.replaceState(null, '', '/ai/chat');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// so that we can show the loading state when the chat history is not fetched yet
|
|
||||||
// it will help us to avoid the flash of content
|
|
||||||
const hasAlreadyFetched = queryClient.getQueryData(
|
|
||||||
chatHistoryOptions(chatHistoryId).queryKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!hasAlreadyFetched) {
|
|
||||||
setIsChatHistoryLoading(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
setChatHistoryId(chatHistoryId);
|
|
||||||
window.history.replaceState(
|
|
||||||
null,
|
|
||||||
'',
|
|
||||||
`/ai/chat/${chatHistoryId}`,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
onDelete={(deletedChatHistoryId) => {
|
|
||||||
const isCurrentChatHistory =
|
|
||||||
deletedChatHistoryId === chatHistoryId;
|
|
||||||
if (!isCurrentChatHistory) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setChatHistoryId(undefined);
|
|
||||||
window.history.replaceState(null, '', '/ai/chat');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="relative flex grow">
|
|
||||||
{isChatHistoryLoading && !hasError && (
|
|
||||||
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
|
||||||
<Loader2Icon className="h-8 w-8 animate-spin stroke-[2.5]" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isChatHistoryLoading && hasError && (
|
|
||||||
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
|
||||||
<ChatHistoryError error={hasError} className="mt-0" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isChatHistoryLoading && !hasError && (
|
|
||||||
<AIChat
|
|
||||||
key={keyTrigger}
|
|
||||||
messages={data?.messages}
|
|
||||||
chatHistoryId={chatHistoryId}
|
|
||||||
setChatHistoryId={(id) => {
|
|
||||||
setChatHistoryId(id);
|
|
||||||
window.history.replaceState(null, '', `/ai/chat/${id}`);
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
predicate: (query) => {
|
|
||||||
return query.queryKey[0] === 'list-chat-history';
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
)}
|
||||||
)}
|
|
||||||
|
{!isChatHistoryLoading && hasError && (
|
||||||
|
<div className="absolute inset-0 z-20 flex items-center justify-center">
|
||||||
|
<ChatHistoryError error={hasError} className="mt-0" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isChatHistoryLoading && !hasError && (
|
||||||
|
<AIChat
|
||||||
|
key={keyTrigger}
|
||||||
|
messages={data?.messages}
|
||||||
|
chatHistoryId={chatHistoryId}
|
||||||
|
setChatHistoryId={(id) => {
|
||||||
|
setChatHistoryId(id);
|
||||||
|
window.history.replaceState(null, '', `/ai/chat/${id}`);
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
predicate: (query) => {
|
||||||
|
return query.queryKey[0] === 'list-chat-history';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AIChatLayout>
|
</AIChatLayout>
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user