File size: 4,083 Bytes
862b14b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
import React, { useState, useEffect, useRef } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import Navbar from "./Components/Navbar";
import axios from "axios";
import "./App.css";
import YouTube from "react-youtube";
function App() {
const navigate = useNavigate();
const [messages, setMessages] = useState([]);
const [userInput, setUserInput] = useState("");
const location = useLocation(); // Access the location object
const videoLink = location.state?.videoLink; // Access the videoLink from the state
const [embedLink, setEmbedLink] = useState("");
const [videoId, setVideoId] = useState("");
const endOfMessagesRef = useRef(null);
const scrollToBottom = () => {
if (endOfMessagesRef.current) {
endOfMessagesRef.current.scrollIntoView({ behavior: "smooth" });
}
};
useEffect(() => {
scrollToBottom();
}, [messages]);
const [loading, setLoading] = useState(false);
console.log(videoLink);
useEffect(() => {
function convertToEmbedUrl(watchUrl) {
return watchUrl.replace("/watch?v=", "/embed/");
}
if (videoLink) {
setEmbedLink(convertToEmbedUrl(videoLink));
setVideoId(videoLink.split("v=")[1]);
} else {
navigate("/");
}
}, []);
const sendMessage = async () => {
try {
console.log("Sending message...");
setLoading(true);
const response = await axios.post("http://localhost:5000/message", {
prompt: userInput,
});
setMessages([
...messages,
{ role: "user", content: userInput },
{ role: "assistant", content: response.data.assistant_message },
]);
setUserInput("");
setLoading(false);
} catch (error) {
console.log(error);
}
};
const handleKeyPress = (e) => {
if (e.key === "Enter" && userInput.trim() !== "") {
sendMessage();
e.preventDefault(); // To prevent any default behavior, such as a line break in a textarea
}
};
return (
<div className="flex flex-col h-screen">
<Navbar />
<div className="flex flex-grow">
{/* YouTube Video Player */}
<div className="w-1/2 bg-white">
<div className="p-4">
<h1></h1>
<YouTube
className="w-full h-96"
videoId={videoId}
opts={{
width: "100%",
playerVars: {
autoplay: 1,
},
}}
/>
</div>
</div>
<div>
<div className="border-r-2 border-gray-300 h-screen"></div>
</div>
<div className="w-1/2 bg-white">
<div className=" p-6">
<h1 className="text-2xl font-bold">Chat with Video!</h1>
<div
ref={endOfMessagesRef}
className="mt-4 overflow-y-auto flex-grow max-h-full border border-gray-300 rounded-md p-4 bg-gray-100"
id="chat-message"
>
{messages.map((msg, idx) => (
<div
key={idx}
className={`${
msg.role === "user"
? "text-indigo-600 font-semibold"
: "text-gray-700 "
}`}
ref={idx === messages.length - 1 ? endOfMessagesRef : null}
>
{msg.content}
</div>
))}
{loading && (
<div className="text-green-400">Getting response...</div>
)}
</div>
<div className="mb-4 flex sticky bottom-0 bg-white" id="chat-input">
<input
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Type your query here..."
className="flex-grow px-2 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring focus:border-indigo-500"
/>
<button
onClick={sendMessage}
className={`ml-2 px-4 py-2 bg-indigo-600 text-white rounded-md font-semibold text-lg hover:bg-indigo-700 focus:outline-none focus:ring ${
loading && "cursor-not-allowed opacity-35"
}`}
disabled={loading}
>
Send
</button>
</div>
</div>
</div>
</div>
</div>
);
}
export default App;
|