Skip to content

Commit

Permalink
performance (#901)
Browse files Browse the repository at this point in the history
* performance

* performance
  • Loading branch information
0xk4b1r authored Sep 15, 2024
1 parent ea3901a commit b54ca16
Show file tree
Hide file tree
Showing 62 changed files with 1,375 additions and 724 deletions.
3 changes: 2 additions & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const App = () => {
<Route exact path={"/resetPassword/:token"} element={<ResetPassword />} />
<Route exact path={"/register"} element={<Register />} />

<Route exact path={"/aichat"} element={<AiChat />} />
<Route exact path={"/aichat/*"} element={<AiChat />} />

<Route path={"/explore/*"} element={<ExploreRoutes />} />
<Route path={"/feeds/*"} element={<FeedsRoute />} />
Expand Down Expand Up @@ -192,6 +192,7 @@ const App = () => {
{/* <ChatBot /> */}
{!hideHomeHeader() && <Footer />}
</Container>

<ToastContainer
position="bottom-right"
autoClose={5000}
Expand Down
6 changes: 3 additions & 3 deletions src/app/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import blogCommentsReducer from "src/features/blogs/blogComments/blogCommentSlic
import ctfReducer from "src/features/ctf/ctfSlice";
import bookmarkReduces from "src/features/bookmarks/bookmarkSlice";
import resetPasswordReducer from "src/features/resetPassword/resetPasswordSlice";
import followReducer from "src/features/follow/followSlice";
import connectionReducer from "src/features/connections/connectionSlice";
import followReducer from "src/features/userDetail/follow/followSlice";
import connectionReducer from "src/features/userDetail/connections/connectionSlice";

import eventsReducer from "src/features/events/eventsSlice";

Expand All @@ -44,7 +44,7 @@ export default configureStore({
userDetail: userDetailReducer,
ctfs: ctfReducer,
resetPassword: resetPasswordReducer,
followData: followReducer,
follow: followReducer,
connectionData: connectionReducer,

events: eventsReducer,
Expand Down
188 changes: 89 additions & 99 deletions src/components/AIChat/AIChat.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useCallback } from "react";
import axios from "axios";
import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements";
import { AIChatContainer, ChatHeader, ChatInput, ChatBox, ChatTitle, ToggleSection } from "./AIChatElements";
import ChatMessages from "./ChatMessages";
import { AIChatContainer } from "./AIChatElements";
import RecentChats from "./RecentChats";
import { useSelector } from "react-redux";
import { BiSend } from "react-icons/bi";
import { CircleSpinner } from "react-spinners-kit";
import { getApiUrl } from "src/features/apiUrl";
import { toast } from "react-toastify";
import { SlOptionsVertical } from "react-icons/sl";
import { FaAngleLeft, FaAngleRight } from "react-icons/fa";
import AuthPopup from "src/pages/AuthPopup/AuthPopup";
import Prompts from "./Prompts/Prompts";
import { TbMessage2Plus } from "react-icons/tb";
import { RecentChatsHeader } from "src/components/AIChat/RecentChatsElements.jsx";
import { Route, Routes } from "react-router-dom";
import Chat from "src/components/AIChat/Chat.jsx";
import NewChat from "src/components/AIChat/NewChat.jsx";

const API_BASE_URL = getApiUrl("api/aiChat");

const AiChat = () => {
// const navigate = useNavigate();
const { user } = useSelector((state) => state.auth);

// if (!user) {
// navigate("/login");
// }

const [chats, setChats] = useState([]);
const [chat, setChat] = useState({});
const [isTrailEnded, setIsTrailEnded] = useState(false);

const trailMessage = [
{
type: "user",
Expand All @@ -43,13 +32,12 @@ const AiChat = () => {
_id: "65b7507df24f3468473bb983",
},
];

const [userInput, setUserInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [selectedChatId, setSelectedChatId] = useState(null);

const [toggle, setToggle] = useState(false);
const [showAuthPopup, setShowAuthPopup] = useState(false);
const [fetchError, setFetchError] = useState(null);

useEffect(() => {
const handleResize = () => {
Expand All @@ -64,6 +52,7 @@ const AiChat = () => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);

const handleSendDummyMessage = async (dummyMessage) => {
setUserInput(dummyMessage);
setIsLoading(true);
Expand Down Expand Up @@ -111,6 +100,8 @@ const AiChat = () => {
return;
}

console.log(userInput);

try {
const response = await axios.post(
`${API_BASE_URL}/ask/${selectedChatId}`,
Expand All @@ -123,7 +114,9 @@ const AiChat = () => {
},
);

const { chats } = response.data;
const { chats, updatedChat } = response.data;

setChat(updatedChat);
setChats(chats);
setUserInput("");
} catch (error) {
Expand All @@ -132,9 +125,6 @@ const AiChat = () => {
toast("Your trial period has ended");
return;
}
// toast("Please enter your API Key");

// toast(error.response.data);
console.error(error);
} finally {
setIsLoading(false);
Expand All @@ -146,7 +136,6 @@ const AiChat = () => {
setIsLoading(true);
setShowAuthPopup(true);
setIsLoading(false);

}
};

Expand All @@ -158,14 +147,40 @@ const AiChat = () => {
Authorization: `Bearer ${user.token}`,
},
});
const { chats } = response.data;
setChats(chats);
setChats(response.data);
setSelectedChatId(chats.length > 0 ? chats.reverse()[0]?._id : null);
} catch (error) {
console.error(error);
}
};

const getChat = useCallback(async () => {
try {
setFetchError(null);
const response = await axios.get(`${API_BASE_URL}/${selectedChatId}`, {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${user.token}`,
},
});
setChat(response.data);
} catch (error) {
console.error("Error fetching chat:", error);
setFetchError("Failed to load chat. Please try again.");
}
}, [API_BASE_URL, selectedChatId, user.token]);

useEffect(() => {
if (!user) return;
getMessages();
}, []);

useEffect(() => {
if (!selectedChatId) return;

getChat();
}, [getChat, selectedChatId]);

const handleNewChat = async () => {
setIsLoading(true);

Expand Down Expand Up @@ -225,10 +240,9 @@ const AiChat = () => {
}
};

useEffect(() => {
if (!user) return;
getMessages();
}, []);
const handleCloseAuthPopup = () => {
setShowAuthPopup(false);
};

useEffect(() => {
if (chats.length === 0) {
Expand All @@ -238,9 +252,7 @@ const AiChat = () => {
}
}, []);

const handleCloseAuthPopup = () => {
setShowAuthPopup(false);
};
console.log(fetchError);

return (
<Wrapper>
Expand All @@ -258,72 +270,50 @@ const AiChat = () => {
/>
)}

{selectedChatId ? (
chats.map(
(chat) =>
chat._id === selectedChatId && (
<ChatBox key={chat?._id}>
<ChatHeader>
<ToggleSection onClick={() => setToggle(!toggle)}>
{toggle ? <FaAngleRight /> : <FaAngleLeft />}
</ToggleSection>
<ChatTitle>{chat?.title}</ChatTitle>
<SlOptionsVertical />
</ChatHeader>

<ChatMessages
messages={chat.messages}
isTrailEnded={isTrailEnded}
trailMessage={trailMessage}
/>

{!isTrailEnded ? (
<>
{chat.title !== "New Chat" ? null : (
<Prompts handleSendDummyMessage={handleSendDummyMessage} />
)}

<ChatInput onSubmit={handleSendMessage}>
<input
type="text"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
/>
{isLoading ? (
<button>
<CircleSpinner size={20} color={"#131313"} />
</button>
) : (
<button type="submit">
<BiSend size={25} />
</button>
)}
</ChatInput>
</>
) : null}
</ChatBox>
),
)
) : (
<ChatBox key={selectedChatId}>
<ChatHeader>
<ToggleSection onClick={() => setToggle(!toggle)}>
{toggle ? <FaAngleRight /> : <FaAngleLeft />}
</ToggleSection>
<ChatTitle>{"New Chat"}</ChatTitle>
<SlOptionsVertical className="hidden" />
</ChatHeader>

<ChatInput onClick={handleIsUserExit} className="cursor-pointer" onSubmit={handleSendMessage}>
<p>Start a New Chat</p>
<RecentChatsHeader>
<div className="new-chat-button" onClick={handleNewChat}>
<TbMessage2Plus size={30} />
</div>
</RecentChatsHeader>
</ChatInput>
</ChatBox>
)}
<Routes>
<Route
index
exac
path={""}
element={
<NewChat
trailMessage={trailMessage}
setToggle={setToggle}
toggle={toggle}
handleIsUserExit={handleIsUserExit}
handleNewChat={handleNewChat}
handleSendMessage={handleSendMessage}
/>
}
/>

<Route
path={"/:id"}
element={
<Chat
selectedChatId={selectedChatId}
isTrailEnded={isTrailEnded}
isLoading={isLoading}
userInput={userInput}
setUserInput={setUserInput}
handleSendDummyMessage={handleSendDummyMessage}
handleSendMessage={handleSendMessage}
handleIsUserExit={handleIsUserExit}
API_BASE_URL={API_BASE_URL}
setToggle={setToggle}
toggle={toggle}
user={user}
chats={chats}
chat={chat}
setChats={setChats}
handleDeleteChat={handleDeleteChat}
handleNewChat={handleNewChat}
trailMessage={trailMessage}
setSelectedChatId={setSelectedChatId}
/>
}
/>
</Routes>
</AIChatContainer>
</Wrapper>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/AIChat/AIChatElements.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export const UserMessage = styled.div`
align-self: flex-end;
border: 1px solid #333;
margin-top: 10px;
border-radius: 10px 1px 0 0;
border-radius: 10px 10px 0 0;
font-size: 18px;
font-weight: bold;
padding: 15px 20px;
Expand Down
63 changes: 63 additions & 0 deletions src/components/AIChat/Chat.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import { ChatBox, ChatHeader, ChatInput, ChatTitle, ToggleSection } from "src/components/AIChat/AIChatElements.jsx";
import { FaAngleLeft, FaAngleRight } from "react-icons/fa";
import { SlOptionsVertical } from "react-icons/sl";
import ChatMessages from "src/components/AIChat/ChatMessages.jsx";
import Prompts from "src/components/AIChat/Prompts/Prompts.jsx";
import { CircleSpinner } from "react-spinners-kit";
import { BiSend } from "react-icons/bi";

const Chat = ({
isTrailEnded,
isLoading,
userInput,
setUserInput,
handleSendDummyMessage,
toggle,
setToggle,
trailMessage,
chat,
handleSendMessage,
}) => {
return (
<ChatBox>
<ChatHeader>
<ToggleSection onClick={() => setToggle(!toggle)}>
{toggle ? <FaAngleRight /> : <FaAngleLeft />}
</ToggleSection>
<ChatTitle>{chat?.title}</ChatTitle>
<SlOptionsVertical />
</ChatHeader>

<div
style={{
display: "flex",
gap: "10px",
flexDirection: "column",
}}
>
<ChatMessages messages={chat?.messages} isTrailEnded={isTrailEnded} trailMessage={trailMessage} />

{!isTrailEnded && (
<>
{chat?.title === "New Chat" && <Prompts handleSendDummyMessage={handleSendDummyMessage} />}

<ChatInput onSubmit={handleSendMessage}>
<input
type="text"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
placeholder="Type your message here..."
/>
<button type="submit" disabled={isLoading}>
{isLoading ? <CircleSpinner size={20} color={"#131313"} /> : <BiSend size={25} />}
</button>
</ChatInput>
</>
)}
</div>
</ChatBox>
);
};

export default Chat;
Loading

0 comments on commit b54ca16

Please sign in to comment.