-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6e46e50
Showing
12 changed files
with
914 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<!DOCTYPE html> | ||
|
||
<html lang="en" dir="ltr"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>ChatBot</title> | ||
<link rel="stylesheet" href="chatstyle.css"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<!-- Google Fonts Link For Icons --> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" /> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" /> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" /> | ||
<style> | ||
.material-symbols-outlined { | ||
font-variation-settings: | ||
'FILL' 0, | ||
'wght' 400, | ||
'GRAD' 0, | ||
'opsz' 24 | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<!-- Chats container --> | ||
<div class="chat-container"></div> | ||
|
||
<!-- Typing container --> | ||
<div class="typing-container"> | ||
<div class="typing-content"> | ||
<div class="typing-textarea"> | ||
<textarea id="chat-input" spellcheck="false" placeholder="Enter a prompt here" required></textarea> | ||
<span id="send-btn" class="material-symbols-rounded">send</span> | ||
</div> | ||
<div class="typing-controls"> | ||
<span id="theme-btn" class="material-symbols-rounded">light_mode</span> | ||
<span id="delete-btn" class="material-symbols-rounded">delete</span> | ||
<span id="logout-btn" class="material-symbols-outlined">event_busy</span> | ||
</div> | ||
</div> | ||
</body> | ||
<script src="chat.js" defer></script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
const chatInput = document.querySelector("#chat-input"); | ||
const sendButton = document.querySelector("#send-btn"); | ||
const chatContainer = document.querySelector(".chat-container"); | ||
const themeButton = document.querySelector("#theme-btn"); | ||
const deleteButton = document.querySelector("#delete-btn"); | ||
let userText = "Hello"; | ||
|
||
const API_KEY = fetch("https://hostapi-ipwd.onrender.com/env").then(response=>response.json()).then(data=>data.API_KEY); | ||
const loadDataFromLocalstorage = () => { | ||
const themeColor = localStorage.getItem("themeColor"); | ||
document.body.classList.toggle("light-mode", themeColor === "light_mode"); | ||
themeButton.innerText = document.body.classList.contains("light-mode") | ||
? "dark_mode" | ||
: "light_mode"; | ||
const defaultText = `<div class="default-text"> | ||
<h1>ChatGPT</h1> | ||
<p>Start a conversation and explore the power of AI.<br> Your chat history will be displayed here.</p> | ||
</div>`; | ||
chatContainer.innerHTML = localStorage.getItem("all-chats") || defaultText; | ||
chatContainer.scrollTo(0, chatContainer.scrollHeight); | ||
}; | ||
const createChatElement = (content, className) => { | ||
const chatDiv = document.createElement("div"); | ||
chatDiv.classList.add("chat", className); | ||
chatDiv.innerHTML = content; | ||
return chatDiv; | ||
}; | ||
const getGitHubInfo = async () => { | ||
const githubToken = "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"; | ||
const headers = { | ||
"Authorization": `Bearer ${githubToken}`, | ||
"Content-Type": "application/json" | ||
}; | ||
|
||
try { | ||
const reposResponse = await fetch("https://api.github.com/user/repos", { | ||
method: "GET", | ||
headers: headers | ||
}); | ||
|
||
if (!reposResponse.ok) { | ||
throw new Error("Failed to fetch GitHub repositories."); | ||
} | ||
|
||
const reposData = await reposResponse.json(); | ||
const repositories = reposData.map(repo => repo.full_name); | ||
|
||
const userResponse = await fetch("https://api.github.com/user", { | ||
method: "GET", | ||
headers: headers | ||
}); | ||
|
||
if (!userResponse.ok) { | ||
throw new Error("Failed to fetch GitHub username."); | ||
} | ||
|
||
const userData = await userResponse.json(); | ||
const username = userData.login; | ||
|
||
return { username, repositories }; | ||
} catch (error) { | ||
console.error("Error fetching GitHub info:", error); | ||
return { username: "", repositories: [] }; | ||
} | ||
}; | ||
|
||
const getChatResponse = async (incomingChatDiv) => { | ||
const API_URL = "https://api.openai.com/v1/chat/completions"; | ||
const pElement = document.createElement("p"); | ||
|
||
userText = userText.toLowerCase(); | ||
|
||
const GitHubInfo = await getGitHubInfo(); | ||
const username = GitHubInfo.username; | ||
const repositories = GitHubInfo.repositories; | ||
|
||
if (userText.includes("hello")) { | ||
pElement.textContent = `Hello ${username}`; | ||
} else if (userText.includes("what are my repos")) { | ||
pElement.textContent = `Your repos are: ${repositories.join(", ")}`; | ||
} else { | ||
const messages = [{ role: "user", content: userText }]; | ||
try { | ||
const response = await fetch(API_URL, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bearer ${API_KEY}`, | ||
}, | ||
body: JSON.stringify({ | ||
model: "gpt-3.5-turbo", | ||
messages: messages, | ||
}), | ||
}); | ||
if (!response.ok) { | ||
throw new Error("Failed to fetch response from the API."); | ||
} | ||
const data = await response.json(); | ||
pElement.textContent = data.choices[0].message.content.trim(); | ||
} catch (error) { | ||
pElement.classList.add("error"); | ||
pElement.textContent = "Oops! Something went wrong. Please try again."; | ||
console.error("Error fetching response:", error); | ||
} | ||
} | ||
|
||
incomingChatDiv.querySelector(".typing-animation").remove(); | ||
incomingChatDiv.querySelector(".chat-details").appendChild(pElement); | ||
localStorage.setItem("all-chats", chatContainer.innerHTML); | ||
chatContainer.scrollTo(0, chatContainer.scrollHeight); | ||
}; | ||
|
||
|
||
|
||
|
||
const copyResponse = (copyBtn) => { | ||
const reponseTextElement = copyBtn.parentElement.querySelector("p"); | ||
navigator.clipboard.writeText(reponseTextElement.textContent); | ||
copyBtn.textContent = "done"; | ||
setTimeout(() => (copyBtn.textContent = "content_copy"), 1000); | ||
}; | ||
const showTypingAnimation = () => { | ||
const html = `<div class="chat-content"> | ||
<div class="chat-details"> | ||
<img src="images/chatbot.png" alt="chatbot-img"> | ||
<div class="typing-animation"> | ||
<div class="typing-dot" style="--delay: 0.2s"></div> | ||
<div class="typing-dot" style="--delay: 0.3s"></div> | ||
<div class="typing-dot" style="--delay: 0.4s"></div> | ||
</div> | ||
</div> | ||
<span onclick="copyResponse(this)" class="material-symbols-rounded">content_copy</span> | ||
</div>`; | ||
const incomingChatDiv = createChatElement(html, "incoming"); | ||
chatContainer.appendChild(incomingChatDiv); | ||
chatContainer.scrollTo(0, chatContainer.scrollHeight); | ||
getChatResponse(incomingChatDiv); | ||
}; | ||
const handleOutgoingChat = () => { | ||
userText = chatInput.value.trim(); | ||
if (!userText) return; | ||
|
||
chatInput.value = ""; | ||
chatInput.style.height = `${initialInputHeight}px`; | ||
const html = `<div class="chat-content"> | ||
<div class="chat-details"> | ||
<img src="images/user.png" alt="user-img"> | ||
<p>${userText}</p> | ||
</div> | ||
</div>`; | ||
|
||
const outgoingChatDiv = createChatElement(html, "outgoing"); | ||
chatContainer.querySelector(".default-text")?.remove(); | ||
chatContainer.appendChild(outgoingChatDiv); | ||
chatContainer.scrollTo(0, chatContainer.scrollHeight); | ||
setTimeout(showTypingAnimation, 500); | ||
}; | ||
deleteButton.addEventListener("click", () => { | ||
|
||
if (confirm("Are you sure you want to delete all the chats?")) { | ||
localStorage.removeItem("all-chats"); | ||
loadDataFromLocalstorage(); | ||
} | ||
}); | ||
themeButton.addEventListener("click", () => { | ||
document.body.classList.toggle("light-mode"); | ||
localStorage.setItem("themeColor", themeButton.innerText); | ||
themeButton.innerText = document.body.classList.contains("light-mode") | ||
? "dark_mode" | ||
: "light_mode"; | ||
}); | ||
const initialInputHeight = chatInput.scrollHeight; | ||
chatInput.addEventListener("input", () => { | ||
chatInput.style.height = `${initialInputHeight}px`; | ||
chatInput.style.height = `${chatInput.scrollHeight}px`; | ||
}); | ||
chatInput.addEventListener("keydown", (e) => { | ||
|
||
if (e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) { | ||
e.preventDefault(); | ||
handleOutgoingChat(); | ||
} | ||
}); | ||
loadDataFromLocalstorage(); | ||
sendButton.addEventListener("click", handleOutgoingChat); |
Oops, something went wrong.